solver.prototxt
net: "/caffe/examples/lmdb_test/train/bvlc_reference_caffenet/train_val.prototxt"
# 训练的prototxt在哪,路径
test_iter: 1000
# 测试要迭代多少个Batch test_iter * batchsize(测试集的)= 测试集的大小
test_interval: 500
# 每500次迭代,就在用测试集进行测试
base_lr: 0.01
# 设置初始化的学习率为0.01
lr_policy: "step"
# 权重衰减策略。
gamma: 0.1
stepsize: 100000
# 初始的学习率为0.01,并且每100000次迭代中进行学习率下降
display: 20
# 每20次epoch就显示出一些数据信息
max_iter: 50000
# 迭代次数
momentum: 0.9
# 一直都是0.9,固定不变;迭代的数据更快,步伐更快
weight_decay: 0.0005
# 权重衰减因子为0.0005
snapshot: 10000
# 每10000次迭代中,就生成当前状态的快照
snapshot_prefix: "/caffe/examples/lmdb_test/train/bvlc_reference_caffenet"
# 模型快照保存
solver_mode: CPU
# 可以设定GPU还是cpu
将mean.binaryproto转mean.npy
import caffe
import numpy as np
MEAN_PROTO_PATH = 'mean.binaryproto' # 待转换的pb格式图像均值文件路径
MEAN_NPY_PATH = 'mean.npy' # 转换后的numpy格式图像均值文件路径
blob = caffe.proto.caffe_pb2.BlobProto() # 创建protobuf blob
data = open(MEAN_PROTO_PATH, 'rb' ).read() # 读入mean.binaryproto文件内容
blob.ParseFromString(data) # 解析文件内容到blob
array = np.array(caffe.io.blobproto_to_array(blob))# 将blob中的均值转换成numpy格式,array的shape (mean_number,channel, hight, width)
mean_npy = array[0] # 一个array中可以有多组均值存在,故需要通过下标选择其中一组均值
np.save(MEAN_NPY_PATH ,mean_npy)
构造mean.npy
import numpy as np
MEAN_NPY_PATH = 'mean.npy'
mean = np.ones([3,256, 256], dtype=np.float)
mean[0,:,:] = 104
mean[1,:,:] = 117
mean[2,:,:] = 123
np.save(MEAN_NPY, mean)
caffe.io.Transformer
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
# 那么reshape操作,就是自动将验证图片进行放缩
transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension
# transpose将RGB变为BGR,都要做transpose
# BGR谁放在前面,譬如3*300*100,这里设定3在前面
transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255]
# 像素点rescale操作,将数据的像素点集中在[0,255]区间内
transformer.set_channel_swap('data', (2,1,0))
# CPU classification
net.blobs['data'].reshape(50, # batch size
3, # 3-channel (BGR) images
227, 227)
image = caffe.io.load_image("/caffe/data/trainlmdb/val/test_female/image_00010.jpg")
# 导入图片
transformed_image = transformer.preprocess('data', image)
# 预处理图片
output = net.forward()
# 前向传播一次,找出参数
net.blobs['data'].data[...] = transformed_image
output_prob = output['prob'][0]
# 输出概率
print 'predicted class is:', output_prob.argmax()
# 输出最大可能性
coding=utf-8
#加载必要的库
import numpy as np
import sys,os
#设置当前目录
caffe_root = '/home/xxx/caffe/'
sys.path.insert(0, caffe_root + 'python')
import caffe
os.chdir(caffe_root)
net_file=caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt'
caffe_model=caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
mean_file=caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy'
net = caffe.Net(net_file,caffe_model,caffe.TEST)
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_mean('data', np.load(mean_file).mean(1).mean(1))
transformer.set_raw_scale('data', 255)
transformer.set_channel_swap('data', (2,1,0))
im=caffe.io.load_image(caffe_root+'examples/images/cat.jpg')
net.blobs['data'].data[...] = transformer.preprocess('data',im)
out = net.forward()
imagenet_labels_filename = caffe_root + 'data/ilsvrc12/synset_words.txt'
labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]
for i in np.arange(top_k.size):
print top_k[i], labels[top_k[i]]
Caffe初始化设置
# ------------- 设置计算设备 ------------- #
caffe.set_mode_gpu() # 使用GPU,注意默认使用CPU,要使用GPU就不能缺少这一句
caffe.set_mode_cpu() # 使用CPU
caffe.set_device(device_id) # 不设置默认为0
Model训练
# --------------- Solver --------------- #
# ------- 加载Solver,有2种方法 -------
# 1. 无论Solver类型是什么,统一设置为SGD
solver = caffe.SGDSolver('path/to/solver.prototxt')
# 2. 根据solver.prototxt中指定的Solver类型读取,默认为SGD
solver = caffe.get_solver('path/to/solver.prototxt')
# ------- 前向传播 -------
solver.net.forward() # train net forward
solver.test_nets[0].forward() # test net forward, test net允许有多个(train net只能有1个)
# ------- 反向传播 -------
solver.net.backward()
# ------- 模型训练 -------
solver.step(n) # 模型进行n次forward和backward,完成n次训练
solver.solver() # 模型根据solver.prototxt中的设置,进行完整模型训练
# ------- 模型保存 -------
solver.net.save('name.caffemodel')
加载已训练Model
# ------- 从已有caffemodel中加载 -------
net = caffe.Net(
deploy_prototxt_path, # deploy网络定义prototxt文件
caffe_model_path, # 已训练模型的caffemodel文件
caffe.TEST # phase设置为Test
)
# ------- 从已有solverstate中恢复训练 -------
solver.restore('path/to/solver.solverstate')
net2.copy_from('path/to/net.caffemodel')
# ------- 从已有Net对象中共享得到 -------
net2.share_with(net1) # net2共享net1的权重(权重指针指向同一地址)
# ------- 读取均值文件 -------
mean_blob = caffe.proto.caffe_pb2.BlobProto()
mean_blob.ParseFromString(open('mean.binaryproto','rb').read())
mean_npy = caffe.io.blobproto_to_array(mean_blob)
# ------- 图片预处理 -------
from scipy.misc import imread, imresize
img = imread(filename)
img = imresize(img, dst_size)
if len(img.shape) == 3:
mean_val = np.mean(mean_npy, axis=(2,3))
img -= mean_val[:,np.newaxis,np.newaxis]*np.ones(img.shape) # ndarray broadcasting
img_batch = np.array([img.transpose((2,0,1))])
img_batch.astype(np.float32)
elif len(img.shape) == 2:
mean_val = np.mean(mean_npy)
img -= mean_val
img_batch = np.array([img[np.newaxis,:,:]])
img_batch.astype(np.float32)
net.blobs['data'].data[...] = img_batch
# ------- 网络参数 -------
conv1_weight = net.params['conv1'][0].data # type: np.ndarray
conv1_bias = net.params['conv1'][1].data
# ------- 网络参数的梯度 -------
conv1_weight = net.params['conv1'][0].diff # type: np.ndarray
conv1_bias = net.params['conv1'][1].diff
# ------- feature map -------
conv1_feat = net.blobs['conv1'].data[0] # type: np.ndarray
conv1_feat = net.blobs['conv1'].diff[0] # 梯度
for layer_name, param in net.params.items():
print layer_name + 't' + str(param[0].data.shape), str(param[1].data.shape)
for layer_name, blob in net.blobs.items():
print layer_name + 't' + str(blob.data.shape)