在训练我的网络时,我偶尔会遇到警告:
W0722 11:47:35.101842 140641577297728 optimizer_v2.py:928] Gradients does not exist for variables ['model/conv1d_x/Variable:0'] when minimizing the loss.
这种情况偶尔会偶尔发生(可能每 20 步成功一次)。我的模型基本上有两条路径,它们在网络的不同位置连接在一起。为了说明这一点,这里有一个简化的例子来说明我的意思。
class myModel(tf.keras.Model):
def __init__(self):
self.conv1 = Conv2D(32)
self.conv2 = Conv2D(32)
self.conv3 = Conv2D(16)
def call(self, inputs):
net1 = self.conv1(inputs)
net2 = self.conv2(inputs)
net = tf.concat([net1, net2], axis=2)
net = self.conv3(net)
end_points = tf.nn.softmax(net)
model = myModel()
with tf.GradientTape() as tape:
predicition = model(image)
loss = myloss(labels, prediction)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
实际上我的网络要大得多,但通常没有梯度的变量往往是网络顶部的变量。在每个 Conv2D
层之前我还有一个自定义渐变。有时当我出现错误时,我会注意到尚未调用该层的渐变函数。
我的问题是,当通过我的网络向后传播时,渐变带为什么有时会采取看似不同的路径。我的第二个问题是,这是通过我的网络(即 conv1 和 conv2)有两条单独的路由引起的。这种网络架构是否存在根本性缺陷?
理想情况下,我可以为 GradientTape()
定义它必须找到每个顶层的梯度吗?
原文由 D.Griffiths 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个看起来类似的问题 - 可能有帮助或不确定,具体取决于您的网络实际是什么样子,但基本上,我有一个多输出网络,我意识到当我应用分别对应于输出的梯度时,所以对于每个单独的损失,都有一个梯度为零的网络分支,但这是完全有效的,并且对应于每次非目标输出之前的终端层。出于这个原因,我最终用 tf.zeros_like 替换了所有 None 梯度,并且可以继续进行训练。如果网络的多个输入头始终位于图表的顶部,您是否会遇到同样的问题?
(下面 Nguyễn Thu 的 ETA 解决方案是我在上面描述的代码版本 - 与我处理它的方式完全相同)
我看到其他答案没有计算梯度,因为默认情况下不监视张量 - 你必须添加它们,但看起来这不是你的问题,因为你应该只处理 model.trainable_variables,或者你的 myLoss 函数根据您的批次组成,偶尔会得到 NaN 结果或转换为 numpy 数组,这可以解释零星的性质(例如,如果您的数据非常不平衡,它可能在没有少数类实例的批次上?)