问题描述
WARNING:tensorflow:Gradients do not exist for variables [‘conv2d/kernel:0’, ‘conv2d/bias:0’, ‘conv2d_1/kernel:0’, ‘conv2d_1/bias:0’, ‘batch_normalization_2/gamma:0’, ‘batch_normalization_2/beta:0’] when minimizing the loss.
WARNING:tensorflow:Gradients do not exist for variables [‘conv2d/kernel:0’, ‘conv2d/bias:0’, ‘conv2d_1/kernel:0’, ‘conv2d_1/bias:0’, ‘batch_normalization_2/gamma:0’, ‘batch_normalization_2/beta:0’] when minimizing the loss.
WARNING:tensorflow:Gradients do not exist for variables [‘conv2d/kernel:0’, ‘conv2d/bias:0’, ‘conv2d_1/kernel:0’, ‘conv2d_1/bias:0’, ‘batch_normalization_2/gamma:0’, ‘batch_normalization_2/beta:0’] when minimizing the loss.
Process finished with exit code 0
错误解析
tensorflow在最小化损失时,变量不存在梯度。分别有以下情况:
- 情况一: 该变量没有参与最后loss的计算
(1)如果直接没有参与计算,其实很好就能找出来,删掉无用变量即可;
(2)有时直接参与计算了,但是由于程序中的 if 等条件语句,在某个batch的数据恰巧不适用某个变量,而其他batch可能就是使用了该变量,这种情况下,忽略该警告即可。 - 情况二: 该变量在model 的 call 之前就进行了运算,或者在 tf.GradientTape()之外进行了运算,比如:concat,dense之类的都不行。
- 情况三: 错误写法:
创建一个变量或者常量,将计算出的结果一行一行 assign进去 修改后的写法: 创建一个空list,每次将计算出的结果 append加入,最后使用 tf.stack() 操作
根据以上判断和调试代码,发现是梯度更新参数问题,如下:
class Discriminator(keras.Model):
def __init__(self):
super(Discriminator, self).__init__()
#[b,64,64,3] -> [b,1]
self.conv1 = layers.Conv2D(64, 5, 3, 'valid')
self.conv2 = layers.Conv2D(128, 5, 3, 'valid')
self.bn2 = layers.BatchNormalization()
self.conv3 = layers.Conv2D(256, 5, 3, 'valid')
self.bn3 = layers.BatchNormalization()
# [b,h,w,3] -> [b, -1]
self.flatten = layers.Flatten()
self.fc = layers.Dense(1)
def call(self, inputs, training=None):
x = tf.nn.leaky_relu(self.conv1(inputs))
x = tf.nn.leaky_relu(self.bn2(self.conv2(inputs), training=training))
x = tf.nn.leaky_relu(self.bn3(self.conv3(inputs), training=training))
# [b,h,w,c] -> [b,-1]
x = self.flatten(x)
# [b,-1] -> [b,1]二分类
logits = self.fc(x)
return logits
在call方法中,卷积层2和卷积层3都未使用x来进行卷积,而是使用初始值input,导致报错。
参考链接:https://blog.csdn.net/weixin_37913042/article/details/115428695