首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有Keras的GradientTape返回0

带有Keras的GradientTape返回0
EN

Stack Overflow用户
提问于 2020-05-13 09:46:33
回答 2查看 1.6K关注 0票数 3

我尝试将GradientTape与Keras模型(简化)一起使用,如下所示:

代码语言:javascript
复制
import tensorflow as tf
tf.enable_eager_execution()

input_ = tf.keras.layers.Input(shape=(28, 28))
flat = tf.keras.layers.Flatten()(input_)
output = tf.keras.layers.Dense(10, activation='softmax')(flat)
model = tf.keras.Model(input_, output)
model.compile(loss='categorical_crossentropy', optimizer='sgd')

import numpy as np
inp = tf.Variable(np.random.random((1,28,28)), dtype=tf.float32, name='input')
target = tf.constant([[1,0,0,0,0,0,0,0,0,0]], dtype=tf.float32)
with tf.GradientTape(persistent=True) as g:
    g.watch(inp)
    result = model(inp, training=False)

print(tf.reduce_max(tf.abs(g.gradient(result, inp))))

但是对于inp的一些随机值,梯度在任何地方都是零的,而对于其余的,梯度幅度实际上很小(<1e-7)。

我也尝试过用MNIST训练的3层MLP,结果是一样的,但是用一个没有激活的1层线性模型来尝试。

这里发生了什么事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-13 11:19:12

您正在计算一个softmax输出层的梯度--因为softmax总是总和为1,所以有意义的是,梯度(在多个putput情况下,是在维度AFAIK上求和/平均)必须是0 --层的整体输出不能改变。小值>0的情况是数值上的打嗝,我想。

当您移除激活函数时,这个限制不再成立,激活可能变得更大(意味着大小>0的梯度)。

您是否试图使用梯度下降来构造输入,从而对某个类产生非常大的概率(如果不是,忽略此.)?@jdehesa已经包括了通过损失函数实现此操作的一种方法。请注意,您也可以通过softmax来完成这一任务,如下所示:

代码语言:javascript
复制
import tensorflow as tf
tf.enable_eager_execution()

input_ = tf.keras.layers.Input(shape=(28, 28))
flat = tf.keras.layers.Flatten()(input_)
output = tf.keras.layers.Dense(10, activation='softmax')(flat)
model = tf.keras.Model(input_, output)
model.compile(loss='categorical_crossentropy', optimizer='sgd')

import numpy as np
inp = tf.Variable(np.random.random((1,28,28)), dtype=tf.float32, name='input')   
with tf.GradientTape(persistent=True) as g:
    g.watch(inp)
    result = model(inp, training=False)[:,0]

print(tf.reduce_max(tf.abs(g.gradient(result, inp))))

注意,我只获取与第一个类对应的第0列中的结果(我删除了target,因为它没有使用)。这将只计算这个类的softmax值的梯度,这是有意义的。

一些注意事项:

  • --在梯度磁带上下文管理器中进行索引非常重要!如果在外部执行(例如,在调用g.gradient的行中),这将不能工作(没有梯度)
  • ,您也可以使用logits的渐变(pre值)。这是不同的,因为可以通过降低其他类的可能性来增加softmax概率,而只有增加所涉类的“分数”才能增加logits。
票数 4
EN

Stack Overflow用户

发布于 2020-05-13 10:13:48

根据模型的输出计算梯度通常不是很有意义的,通常是计算损失的梯度,这就是告诉模型变量应该去哪里才能达到目标的方法。在这种情况下,您将优化输入而不是模型参数,但这是相同的。

代码语言:javascript
复制
import tensorflow as tf
import numpy as np
tf.enable_eager_execution()  # Not necessary in TF 2.x

tf.random.set_random_seed(0)  # tf.random.set_seed in TF 2.x
np.random.seed(0)
input_ = tf.keras.layers.Input(shape=(28, 28))
flat = tf.keras.layers.Flatten()(input_)
output = tf.keras.layers.Dense(10, activation='softmax')(flat)
model = tf.keras.Model(input_, output)
model.compile(loss='categorical_crossentropy', optimizer='sgd')

inp = tf.Variable(np.random.random((1, 28, 28)), dtype=tf.float32, name='input')
target = tf.constant([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=tf.float32)
with tf.GradientTape(persistent=True) as g:
    g.watch(inp)
    result = model(inp, training=False)
    # Get the loss for the example
    loss = tf.keras.losses.categorical_crossentropy(target, result)

print(tf.reduce_max(tf.abs(g.gradient(loss, inp))))
# tf.Tensor(0.118953675, shape=(), dtype=float32)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61771330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档