引言
记录学习官网的例程中的一些重要语句,遇到的问题等,内容分散,建议顺序查看。
主要是调用Caffe的Python接口
源文件就在{caffe_root}/examples中,安装sudo pip install jupyter
打开即可运行,初学者最好是放在它指定的目录,如,否则要改很多路径。
注:eaxmples是用jupyter notebook写的,部分Cell中出现了一些特殊的用法:
1. 感叹号‘!’:用于执行系统命令,如 !pwd
2. 百分号‘%’:用法太多,如 %matplotlib inline 显示绘图窗口 详见Jupyter Notebook Viewer
目录
图像分类和卷积核可视化
用一个预训练模型进行即时识别并通过访问网络接口来可视化特征和逐层参数。
加载网络并设置输入预处理
设置模式CPU or GPU(如果是多GPU,可指定设备号):
caffe.set_mode_cpu()
orcaffe.set_device(0);caffe.set_mode_gpu()
加载Caffe网络模型:
net = caffe.Net(model_def, model_weights, caffe.TEST)
- 输入数据预处理的配置(独立于Caffe的其他部分,可以用任何惯用的方法)
- 对输入数据’data’创建一个transformer:
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
- 设置输入预处理参数
- innermost dimension 到outermost dimension,即HxWxC-> CxHxW.:
transformer.set_transpose('data', (2,0,1))
- 每个通道减去图像均值:
transformer.set_mean('data', mu)
- 从[0, 1]区间映射回[0, 255]:
transformer.set_raw_scale('data', 255)
- 改变输入图像的通道顺序RGB->BGR:
transformer.set_channel_swap('data', (2,1,0))
- innermost dimension 到outermost dimension,即HxWxC-> CxHxW.:
- 对输入数据’data’创建一个transformer:
分类单张图片
- 设置输入大小:
net.blobs['data'].reshape(50,3,227,227)
利用Caffe加载一张图片并执行我们前面设置的数据预处理
image = caffe.io.load_image(caffe_root + 'examples/images/cat.jpg') transformed_image = transformer.preprocess('data', image)
- 复制图片数据到网络分配的内存中:
net.blobs['data'].data[...] = transformed_image
- 执行一次前向预测:
output = net.forward()
输出结果的处理:
从输出中取出一个batch的第一幅图像的概率向量:
output_prob = output['prob'][0]
取出一幅图像概率向量中最大值对应的索引,对应到数据集的标签列表,可找到对应类别。
查看中间输出
先查看网络结构(activation and parameter shapes)
# 每一层输出数据shape,(batch_size, channel_dim, height, width) for layer_name, blob in net.blobs.iteritems(): print layer_name + '\t' + str(blob.data.shape)
# 查看卷积核参数shape,(output_channels, input_channels, filter_height, filter_width) for layer_name, param in net.params.iteritems(): print layer_name + '\t' + str(param[0].data.shape), str(param[1].data.shape)
定义辅助显示函数,用于可视化
def vis_square(data): """Take an array of shape (n, height, width) or (n, height, width, 3) and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)""" # normalize data for display 归一化 data = (data - data.min()) / (data.max() - data.min()) # force the number of filters to be square 方便显示为正方形小格 n = int(np.ceil(np.sqrt(data.shape[0]))) padding = (((0, n ** 2 - data.shape[0]), (0, 1), (0, 1)) # add some space between filters 填充图片的底部和右侧,隔离开来。 + ((0, 0),) * (data.ndim - 3)) # don't pad the last dimension (if there is one) 一个图片/核的各通道间不需要填充 data = np.pad(data, padding, mode='constant', constant_values=1) # pad with ones (white) 对整个大数组进行填充,padding对应四个维度的前后分别填多少个 # tile the filters into an image 平铺成一幅图像 data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1))) #后面的元组,主要针对四维输入,平铺过程会出现五维的情况。 data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:]) #reshape为正常图片格式 plt.imshow(data); plt.axis('off')
绘制图像
# the parameters are a list of [weights, biases] 可视化卷积核 filters = net.params['conv1'][0].data vis_square(filters.transpose(0, 2, 3, 1)) # 注意需要对通道顺序进行转置
# 可视化各层输出数据 feat = net.blobs['conv1'].data[0, :36] vis_square(feat)
绘制全连接层的输出值
feat = net.blobs['fc6'].data[0] plt.subplot(2, 1, 1) plt.plot(feat.flat) # np.flat 为数组一维迭代器 plt.subplot(2, 1, 2) _ = plt.hist(feat.flat[feat.flat > 0], bins=100) # (大于零)的直方图,bins为柱数
绘制最终概率输出
feat = net.blobs['prob'].data[0] plt.figure(figsize=(15, 3)) plt.plot(feat.flat)
尝试自己的图片
# download an image
my_image_url = "..." # paste your URL here
# for example:
# my_image_url = "https://upload.wikimedia.org/wikipedia/commons/b/be/Orang_Utan%2C_Semenggok_Forest_Reserve%2C_Sarawak%2C_Borneo%2C_Malaysia.JPG"
!wget -O image.jpg $my_image_url
# transform it and copy it into the net
image = caffe.io.load_image('image.jpg')
net.blobs['data'].data[...] = transformer.preprocess('data', image)
# perform classification
net.forward()
# obtain the output probabilities
output_prob = net.blobs['prob'].data[0]
# sort top five predictions from softmax output
top_inds = output_prob.argsort()[::-1][:5]
plt.imshow(image)
print 'probabilities and labels:'
zip(output_prob[top_inds], labels[top_inds])