网络手术: 如何在caffe中重新塑造caffemodel文件的卷积层?

3
我正在尝试改变caffemodel卷积层的大小(这是this question的后续问题)。虽然有一个如何进行网络手术的教程,但它只展示了如何将权重参数从一个caffemodel复制到另一个相同大小的caffemodel。
相反,我需要向我的卷积滤波器添加一个新通道(全部为0),以便将其大小从当前的(64x3x3x3)更改为(64x4x3x3)。

假设卷积层被称为'conv1'。这是我迄今为止尝试过的:

# Load the original network and extract the fully connected layers' parameters.
net = caffe.Net('../models/train.prototxt', 
                '../models/train.caffemodel', 
                caffe.TRAIN)

现在我可以执行这个:
net.blobs['conv1'].reshape(64,4,3,3);
net.save('myNewTrainModel.caffemodel');

但是似乎保存的模型没有改变。我已经读过实际卷积权重存储在net.params['conv1'][0].data而不是net.blobs中,但我无法弄清如何重新塑造net.params对象。有人有想法吗?
1个回答

6
正如你所指出的,net.blobs 不存储学习参数/权重,而是存储将过滤器/激活应用于网络输入后的结果。学习到的权重存储在 net.params 中。(有关更多详细信息,请参见此处)。
据我所知,您不能直接reshape net.params 并添加一个通道。
您可以使用两个网络deploy_trained_net_with_3ch.prototxtdeploy_empty_net_with_4ch.prototxt。这两个文件几乎相同,除了输入形状定义和第一层的名称之外。
然后,您可以将两个网络加载到Python中并复制相关部分:
net3ch = caffe.Net('deploy_trained_net_with_3ch.prototxt', 'train.caffemodel', caffe.TEST) 
net4ch = caffe.Net('deploy_empty_net_with_4ch.prototxt', 'train.caffemodel', caffe.TEST) 

自从所有层的名称都相同(除了conv1),net4ch.params将具有train.caffemodel的权重。至于第一层,您现在可以手动复制相关部分:
net4ch.params['conv1_4ch'][0].data[:,:3,:,:] = net3ch.params['conv1'][0].data[...]

最后:

net4ch.save('myNewTrainModel.caffemodel')

2
感谢您回答了这么多问题。您真的帮了我很多!不过,将来可能还会有一些问题要问您 ;) - mcExchange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接