BatchNorm反向传播出问题
收藏
RuntimeError: (NotFound) No Output(X@GRAD) found for BatchNormGrad operator.
[Hint: Expected ctx->HasOutput(framework::GradVarName("X")) == true, but received ctx->HasOutput(framework::GradVarName("X")):0 != true:1.] (at /paddle/paddle/fluid/operators/batch_norm_op.cc:467)
看到别人说channel=1出的问题,但是,我的模型中并没有出现BatchNorm的channel为1.
0
收藏
请登录后评论
我也遇到这个问题了,我觉得代码逻辑结构上没有错的,我3维的BatchNorm1D和4维的BatchNorm都试了,都报这个错,怀疑这个API是不是有问题。Keras上用相同的结构是没问题的。
别说keras,pytorch代码都基本一样都没问题
我经常用BN、IN没发现过问题啊
BN上一句接的什么语句呢?
class conv_bn_relu(nn.Layer):
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, act=True):
super(conv_bn_relu, self).__init__()
self.conv = Conv2D(in_channels=in_channels, out_channels=out_channels,
kernel_size=kernel_size, stride=stride, padding=padding)
self.bn = BatchNorm(num_channels=out_channels)
# self.bn = BatchNorm2D(num_features = out_channels)
if act:
self.relu = ReLU()
else:
self.relu = None
def forward(self, inputs):
x = self.conv(inputs)
x = self.bn(x)
if self.relu is not None:
x = self.relu(x)
return x
怎么说呢,就是有时候运行一轮了是正常的,第二轮开始就出错。感觉是我的模型有问题,就是找不到问题所在
还是推荐使用2D系列的api,包括各种卷积和正则化层
如果第一轮没出错,第二轮出错,这可能和代码重复执行有关,检查下是否有些变量重用了
比如包括这句的cell执行两次就会出错
data = paddle.to_tensor(data)
这句第一次将numpy转为tensor了,就不能再执行一次转换了
或者也可以检查一下是否内存\显存溢出
还有就是如果给某些子层指定了 name 名称,同一个模型类就不能二次实例化了
你说的基本不可能。BactNorm2D也用过,甚至fluid的BN api都用过了;至于内存溢出也不太可能,因为有时候batchsize设置为2,刚开始就报错了;关于名称,给每个层加名称这个习惯还没养成。由于观察到不是每一轮,每个batch都会报错,所以,现在我都用上try..except..来控制了,这样勉强还是可以运行的,也发现有些epoch一轮下来512个batch都没问题,而有些epoch,有4、5个batch的backward出现问题。
try:
loss.backward()
# 更新参数
optimizer.step()
# 梯度清零
optimizer.clear_grad()
except:
print()
# 梯度清零
optimizer.clear_grad()
loss.backward()
# 更新参数
optimizer.step()
换成先清除梯度再反向试试
这个应该没问题,因为在paddle的官网的一些使用文档就是先反向传播,然后在更新参数和清除梯度的。https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/02_paddle2.0_develop/05_train_eval_predict_cn.html
如果是单个网络的模型两种写法没区别,如果包含多个网络最好还是先清梯度
我写的cyclegan就踩过那个坑。。。