最近為了得到CNN中每一層激活值對應的梯度(自動計算的梯度只有每一層對應的權值和偏置轿钠,MX又沒有pytorch那樣的backward_hook那樣的神器),考慮用autograd.中的一些函數(shù)來實現(xiàn).
- autograd.attach_grad()只能對最后一個attach的變量進行求梯度(不懂怎么用赛不,目前沒見過對多個變量用attach_grad)
想到兩種方法:- register_forward_hook,雖然mx有一個這樣的函數(shù)罢洲,確沒有任何官方用例踢故,google: mxnet register_forward_hook出來的全是pytorch的問答,真的氣惹苗。另外殿较,gluon.nn.Conv2D還沒有register_forward_hook這個接口。這條路是死了
- 參考 這個桩蓉,自己寫一個conv層淋纲。但是這里又碰到另一個坑,不知道怎么用另一模型中的參數(shù)初始化新的模型院究。后來用了以下代碼來初始化:
@mx.init.register class myInitializer(mx.init.Initializer): def __init__(self, weight,bias): super(myInitializer,self).__init__() self.weight = weight[0] self.bias = bias[0] def _init_weight(self, _, arr): arr[:] = self.weight def _init_bias(self, _, arr): arr[:] = self.bias for ii, layer in enumerate(model.features): if isinstance(layer, nn.Conv2D): fsize = layer.weight.shape[2] new_layer = gradcam.Conv2D(layer._channels,(fsize,fsize)) new_layer.initialize(init=myInitializer(layer.weight._data, layer.bias._data), ctx=ctx) self.features.add(new_layer) elif ii<31: self.features.add(layer)
- 然后在需要獲取梯度的地方用gradcam中的get_conv_out_grad方法就行了洽瞬,不過這個方法一次只能獲取一個梯度。
- 需要注意的是业汰,在官方文檔上有說明如果在autograd.record(train_mode=False)伙窃,那么backward(train_mode=False),否則梯度將不被定義