分享

请教keras中生成CAM图时的求梯度问题

我的网络使用了预训练过的vgg16,然后加上自己的全连接层,所以model.sumary()中只显示4层,就是vgg16,flatten,两个全连接层。
这是一个二分类网络,所以输出是一个标量。
为了分析出错样本,我想生成CAM图(class activation map),需要计算最终输出对最后一个卷积层输出的梯度。
结果使用backend.gradients求梯度时,总是出错,返回的梯度根本不是一个tensor,而是一个list。
但是如果我计算输出对输入(model.input)的梯度,则正常。

相关代码如下:

(1)对卷积层输出求梯度,出错

conv_layer = model.get_layer( 'vgg16' )
last_conv_layer = conv_layer.get_layer( 'block5_conv3' )
grads = backend.gradients( model.output[:,0], last_conv_layer.output )[0]   #出错位置,返回的grads不是tensor

(2)对输入求梯度,正常
grads = backend.gradients( model.output[:,0], model.input )[0]

请问是哪里犯错了?谢谢!


已有(6)人评论

跳转到指定楼层
levycui 发表于 2019-2-20 18:25:57
这个输入的数据 类型不同  下面的正常,上边的异常,需要从上边的last_conv_layer.output这里查原因
回复

使用道具 举报

forsolitude 发表于 2019-2-20 21:56:27
本帖最后由 forsolitude 于 2019-2-20 22:14 编辑
levycui 发表于 2019-2-20 18:25
这个输入的数据 类型不同  下面的正常,上边的异常,需要从上边的last_conv_layer.output这里查原因

查看last_conv_layer.output的type是tensor,shape也正常,可是求梯度结果就不正常了,返回的grads成list而不是tensor了,并且这个list长度为1,里头元素的dtype是NoneType
不知道如何检查了

回复

使用道具 举报

forsolitude 发表于 2019-2-20 22:40:57
forsolitude 发表于 2019-2-20 21:56
查看last_conv_layer.output的type是tensor,shape也正常,可是求梯度结果就不正常了,返回的grads成list ...

跟踪代码发现在这里出现差异:
-----------------------------------------------------------------
def _GetGrad(grads, t):
  """Gets gradient for tensor "t"."""
  op = t.op
  op_grads = grads.get(op)   
  if not op_grads:
    return None
  t_grad = op_grads[t.value_index]
  assert not isinstance(
      t_grad, list), ("gradients list should have been aggregated by now.")
  return t_grad

-----------------------------------------------------------------
出错时(对卷积层输出求导),if not op_grads这个地方进去了,于是return None……
如果对model.input求导,这个地方op_grads不为空。


可是还是不知道根本原因是什么,以及,如何解决……


回复

使用道具 举报

s060403072 发表于 2019-2-22 09:28:12
forsolitude 发表于 2019-2-20 22:40
跟踪代码发现在这里出现差异:
-----------------------------------------------------------------
d ...

和原先能返回的Tensor对比下。
可以多对比下。
回复

使用道具 举报

小白东 发表于 2020-6-14 08:45:16
老哥 这个问题最后解决了吗?我和你是一样的问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条