使用caffe框架训练后得到的权重通过Google Protobuf来存储为.caffemodel的二进制文件,为了更好地更改网络结构和对已有的caffemodel进行finetune,通常我们需要修改一些参数,去为了更好的适应我们自己设计的网络结构并进行训练
好在caffe的Python接口提供了针对caffemodel文件的修改方法
为了更好地可视化,这里使用了Python的jupyter notebook工具
1、读取caffemodel里的权值
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
caffe_root = 'F:/caffe_BLVC_VS2013/caffe-windows/' # 设置caffe的根目录
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe #导入caffe
caffe.set_mode_gpu() #设置为gpu模式
# 载入网络,列出各个层的名字
net = caffe.Net('F:/python/make_prototxt/mnist/deploy.prototxt', caffe.TEST)
print("blobs {}\nparams {}".format(net.blobs.keys(), net.params.keys()))
输出如下:
blobs [‘data’, ‘conv1’, ‘pool1’, ‘conv2’, ‘pool2’, ‘fc1’, ‘ADD’, ‘ADD2’, ‘fc2’, ‘prob’]
params [‘conv1’, ‘conv2’, ‘fc1’, ‘ADD’, ‘ADD2’, ‘fc2’]
将全连接层的维度打印出来
# Load the original network and extract the fully connected layers' parameters.
net = caffe.Net('F:/python/make_prototxt/mnist/deploy.prototxt',
'F:/python/make_prototxt/mnist/model/mnist_iter_9380.caffemodel',
caffe.TEST)
params = ['fc1','ADD','ADD2','fc2']
# fc_params = {name: (weights, biases)}
fc_params = {pr: (net.params[pr][0].data, net.params[pr][1].data) for pr in params}
for fc in params:
print '{} weights are {} dimensional and biases are {} dimensional'.format(fc, fc_params[fc][0].shape, fc_params[fc][1].shape)
输出如下:
fc1 weights are (500L, 800L) dimensional and biases are (500L,) dimensional
ADD weights are (500L, 500L) dimensional and biases are (500L,) dimensional
ADD2 weights are (500L, 500L) dimensional and biases are (500L,) dimensional
fc2 weights are (10L, 500L) dimensional and biases are (10L,) dimensional
2、将网络中的参数保存为新的model
net.save('F:/python/make_prototxt/mnist/get.caffemodel')
# Load the original network and extract the fully connected layers' parameters.
net = caffe.Net('F:/python/make_prototxt/mnist/deploy.prototxt',
'F:/python/make_prototxt/mnist/get.caffemodel',
caffe.TEST)
params = ['fc1','ADD','ADD2','fc2']
# fc_params = {name: (weights, biases)}
fc_params = {pr: (net.params[pr][0].data, net.params[pr][1].data) for pr in params}
for fc in params:
print '{} weights are {} dimensional and biases are {} dimensional'.format(fc, fc_params[fc][0].shape, fc_params[fc][1].shape)
输出如下:
fc1 weights are (500L, 800L) dimensional and biases are (500L,) dimensional
ADD weights are (500L, 500L) dimensional and biases are (500L,) dimensional
ADD2 weights are (500L, 500L) dimensional and biases are (500L,) dimensional
fc2 weights are (10L, 500L) dimensional and biases are (10L,) dimensional
这种方法只能在原有的结构上进行权值的修改,而不能对原有结构进行修改