修改caffemodel文件

1 修改某层名称

先把prototxt新修改出一份,然后分别用新旧prototxt去加载caffemodel文件,再把旧参数付给新网络的相应层。

#! python
#coding=utf-8
import sys
from caffe import Net
n_orig = Net('test_o.prototxt', 'orig.caffemodel', 0)
n_new = Net('test_n.prototxt', 'orig.caffemodel', 0)
n_new.params['newlayername'] = n_orig.params['origlayername']
n_new.save('new.caffemodel')

2 修改层shape

如添加一个新类,直接修改classification全连接层,修改后继续训练就可以了。

#! python
#coding=utf-8
import sys,caffe
import numpy as np

n = caffe.Net('train.prototxt','orig.caffemodel',0)

# 这里直接用原有数值的均值初始化新数据空间。
cls_score0=n.params['cls_score'][0].data.copy()
cls_score0_n = np.append(cls_score0, np.mean(cls_score0)*np.ones((1,4096), dtype=cls_score0.dtype),axis=0)

cls_score1 = n.params['cls_score'][1].data.copy()
cls_score1_n = np.append(cls_score1, np.mean(cls_score1))

n.params['cls_score'][0].reshape(22,4096)
n.params['cls_score'][0].data[...] = cls_score0_n
n.params['cls_score'][1].reshape (*cls_score1_n.shape)
n.params['cls_score'][1].data[...] = cls_score1_n
 
n.save('newclass22.caffemodel')

3 从caffemodel中恢复出prototxt结构

可以从caffemodel反推出网络结构,但不会完全一致,主要是原来隐含层会被显式表达出来。

#! python
#coding=utf-8
 
from caffe.proto import caffe_pb2
 
def Caffemodel2Prototxt(modelName,deployName):
  with open(modelName, 'rb') as f:
    caffemodel = caffe_pb2.NetParameter()
    caffemodel.ParseFromString(f.read())
  for item in caffemodel.layers:
    item.ClearField('blobs')
  for item in caffemodel.layer:
    item.ClearField('blobs')
 
  with open(deployName, 'w') as f:
    f.write(str(caffemodel))
 
if __name__ == '__main__':
  modelName = 'VGG16_iter_28000.caffemodel'
  deployName = 'VGG16_deploy.prototxt'
  Caffemodel2Prototxt(modelName,deployName)

发表评论

电子邮件地址不会被公开。 必填项已用*标注