引言
如果用公式 y = f (wx + b) 来表示整个运算过程的话,那么 w 和 b 就是我们需要训练的东西, w 称为权值, 在 cnn 中也可以叫做卷积核(filter), b 是偏置项。 f 是激活函数, 有relu、sigmoid 等。 x 就是输入的数据。
在数据训练完成后,保存的 caffemodel 里面实际上就是各层的 w 和 b 的值。
我们运行代码:
deploy=root + 'mnist/deploy.prototxt' #deploy文件
caffe_model=root + 'mnist/lenet_iter_9380.caffemodel' #训练好的 caffemodel
net = caffe.Net(net_file,caffe_model,caffe.TEST) #加载model和network
就把所有的参数和数据都加载到一个 net 变量里面了,但是 net 是一个很复杂的 object,想直接显示出来是不行的。其中
net.params: 保存各层的参数值(w 和 b) net.blobs: 保存各层的数据值(x)
可用命令:
[(k,v[0].data) for k,v in net.params.items()]
查看各层的参数值,其中 k 表示层的名称, v[0].data 就是各层的 w 值,而 v[1].data 是各层的 b 值。注意:并不是所有的层都有参数,只有卷积层和全连接层才有。
也可以不查看具体的值,只想看 shape,可用命令:
[(k,v[0].data.shape) for k,v in net.params.items()]
假设我们想知道其中一个卷积层的名字叫做 “Convolution1”,则我们可以提取这个层的参数:
w1=net.params['Convolution1'][0].data
b1=net.params['Convolution1'][1].data
输入这些代码,实际查看一下,对我们学习 network 非常有帮助。
同理,除了可以查看参数,我们还可以查看数据,但要注意的是,net 里面刚开始是没有数据的,需要运行:
net.forward()
之后才会有数据。我们可以用代码:
[(k,v.data.shape) for k,v in net.blobs.items()]
# 或者
[(k,v.data) for k,v in net.blobs.items()
来查看各层的数据。注意和上面查看参数的区别。一个是 net.params,一个是 net.blobs。
实际上数据在刚输入的时候,我们叫做图片数据,卷积之后我们就叫特征了。
如果抽取一个全连接层,则可用命令:
fea=net.blobs['InnerProduct1'].data
只要知道某一个层的名称,就可以抽取这个层的特征。
最后,总结上述代码:
import caffe
import numpy as np
root='/home/xxx/' #根目录
deploy=root + 'mnist/deploy.prototxt' #deploy文件
caffe_model=root + 'mnist/lenet_iter_9380.caffemodel' #训练好的 caffemodel
net = caffe.Net(deploy,caffe_model,caffe.TEST) #加载model和network
[(k,v[0].data.shape) for k,v in net.params.items()] #查看各层参数规模
w1=net.params['Convolution1'][0].data #提取参数w
b1=net.params['Convolution1'][1].data #提取参数b
net.forward() #运行测试
[(k,v.data.shape) for k,v in net.blobs.items()] #查看各层数据规模
fea=net.blobs['InnerProduct1'].data #提取某层数据(特征)