我正在尝试重塑caffe模型文件中卷积层的大小(这是这个问题的后续问题)。虽然有一个关于如何进行网络手术的教程,但它只展示了如何将权重参数从一个caffe模型复制到另一个相同大小的模型。
而我需要在我的卷积滤波器中添加一个新的通道(全部为0),以便将其大小从当前的(64
x3
x3
x3
)更改为(64
x4
x3
x3
)。
假设卷积层被称为'conv1'
。这是我目前尝试过的方法:
# 加载原始网络并提取全连接层的参数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
对象。有人有想法吗?
回答:
正如你所指出的,net.blobs
不存储学习的参数/权重,而是存储将滤波器/激活应用于网络输入的结果。学习的权重存储在net.params
中。(更多详情见这里)。
据我所知,你不能直接reshape
net.params
并添加一个通道。
你可以做的,是有两个网络deploy_trained_net_with_3ch.prototxt
和deploy_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')