网络中的参数共享与nn.SpatialBatchNormalization
问题描述:
我有一个网络与三个并行分支,我想分享他们的所有参数,使他们在训练结束时是相同的。 以some_model
为标准nn.Sequential
模块由cudnn.SpatialConvolution
,nn.PReLU
,nn.SpatialBatchNormalization
组成。此外,有一个nn.SpatialDropout
,但它的概率设置为0
,所以它没有效果。网络中的参数共享与nn.SpatialBatchNormalization
ptb=nn.ParallelTable()
ptb:add(some_model)
ptb:add(some_model:clone('weight','bias', 'gradWeight','gradBias'))
ptb:add(some_model:clone('weight','bias', 'gradWeight','gradBias'))
triplet=nn.Sequential()
triplet:add(ptb)
我不认为损失函数是相关的,但以防万一,我使用nn.DistanceRatioCriterion。为了检查所有权重是否正确共享,我将一个包含三个相同示例{A,A,A}
的表格传递给网络。显然,如果权重正确共享,那么所有三个分支的输出应该是相同的。这在网络初始化时保持不变,但是一旦参数已被更新(例如,在一次小批量迭代之后),三个分支的结果变得不同。通过逐层检查,我发现这个输出差异来自于some_model
中的nn.SpatialBatchNormalization
层。因此,来自这些层的参数看起来似乎没有正确共享。在this之后,我试着拨打clone
,附加参数为running_mean
和running_std
,但蝙蝠蛾的层数仍然不同。而且,这似乎也取消了所有其他网络参数的共享。在nn.SpatialBatchNormalization
模块之间共享参数的正确方法是什么?
答
好的,我找到了解决方案!从the discussion I had linked to in the question开始,似乎参数running_std
已更改为running_var
。调用构造函数
ptb:add(some_model:clone('weight','bias', 'gradWeight','gradBias','running_mean','running_var'))
解决问题。