1)预处理好的LMDB格式的训练数据和测试数据(这里是mnist数据源)
导入一些包,设置工作路径。
主函数main.py
内容1:
import os
import matplotlib.pyplot as plt
import numpy as np
from tool.net_func import * #tool为自定义包,有两个文件:
#__init__.py和net_func.py,
#后文会介绍。
os.chdir('/home/yekui/caffe-master/examples')#设置工作路径,之后的路径都是基于此!!
这里有两个函数需要指出:
custom_net(train_net_path, LMDB, batch_size)
功能:定义网络结构,并写入train_net_path。
LMDB:是指数据源的路径,
batch_size:一次训练(或测试)多少数据。
custom_solver(train_net_path,test_net_path,solver_config_path)
功能:定义solver参数(用来优化),并写入solver_config_path。
train_net_path:训练网络路径
test_net_path:测试网络路径
solver_config_path:solver路径
主函数main.py
内容2:
train_net_path = 'mnist/yk_auto_train.prototxt' #训练网络路径
test_net_path = 'mnist/yk_auto_test.prototxt' #测试网络路径
solver_config_path = 'mnist/yk_auto_solver.prototxt' #solver路径
custom_net(train_net_path, 'mnist/mnist_train_lmdb', 64)#网络定义
custom_net(test_net_path, 'mnist/mnist_test_lmdb', 100) #网络定义
custom_solver(train_net_path, test_net_path, solver_config_path)#solver定义
solver = caffe.get_solver(solver_config_path) #得到solver
主函数main.py
内容3:
#演示一下,在训练过程中,记录一些自己想记录的数据
#设置一些参数
niter = 250 # 训练次数
test_interval = niter / 10 #隔多久(迭代次数)检验测试准确率
train_loss = np.zeros(niter) #保存每次迭代的loss值
test_acc = np.zeros(int(np.ceil(niter / test_interval))) #保存测试准确率
# 开始训练啦~
for it in range(niter):
solver.step(1) # 取一个batch_size的训练数据训练一下
# 保存每次迭代的loss值
train_loss[it] = solver.net.blobs['loss'].data
# 计算并保存测试准确率
if it % test_interval == 0:
print 'Iteration', it, 'testing...'
correct = 0
for test_it in range(100):
solver.test_nets[0].forward() #取一个batch_size的测试数据计算各层结果。
#不像solver.step(),它没有反向传播,所以
#不会改变权重,只是单纯地计算一下而已。
correct += sum(solver.test_nets[0].blobs['score'].data.argmax(1)
== solver.test_nets[0].blobs['label'].data)
test_acc[it // test_interval] = correct / 1e4 #1e4 = batch_size * 迭代次数(100)
#结果图示化,意会一下就懂了^_^
_, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(np.arange(niter), train_loss)
ax2.plot(test_interval * np.arange(len(test_acc)), test_acc, 'r')
ax1.set_xlabel('iteration')
ax1.set_ylabel('train loss')
ax2.set_ylabel('test accuracy')
ax2.set_title('Custom Test Accuracy: {:.2f}'.format(test_acc[-1]))
plt.show()
显示结果为:
#此文件名为net_func.py
#在tool文件夹下
#tool文件夹与main.py在相同路径下
caffe_root = '/home/yekui/caffe-master/'
import sys
sys.path.insert(0,caffe_root + 'python')
import caffe
from caffe import layers as L, params as P
def custom_net(save_path, lmdb, batch_size):
#custom_net(train_net_path, LMDB, batch_size)
#功能:定义网络结构,并写入train_net_path。
#LMDB:是指数据源的路径,
#batch_size:一次训练(或测试)多少数据。
#定义自己的网络,可以自己修改
#各层含义不细讲了,可以自己去官网学学
n = caffe.NetSpec() #结构化初始
n.data, n.label = L.Data(batch_size=batch_size, backend=P.Data.LMDB, source=lmdb,
transform_param=dict(scale=1. / 255), ntop=2)
n.conv1 = L.Convolution(n.data, kernel_size=5, num_output=20, weight_filler=dict(type='xavier'))
n.pool1 = L.Pooling(n.conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
n.conv2 = L.Convolution(n.pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
n.pool2 = L.Pooling(n.conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)
n.fc1 = L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier'))
n.relu1 = L.ReLU(n.fc1, in_place=True)
n.score = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier'))
n.loss = L.SoftmaxWithLoss(n.score, n.label)
with open(save_path, 'w') as f:
f.write(str(n.to_proto())) #n.to_proto()结构化结束
def custom_solver(train_net_path, test_net_path, solver_config_path):
#功能:定义solver参数(用来优化),并写入solver_config_path。
#train_net_path:训练网络路径
#test_net_path:测试网络路径
#solver_config_path:solver路径
from caffe.proto import caffe_pb2
s = caffe_pb2.SolverParameter() #结构化初始
# 设置一个种子,这样可以重复实验
# 这控制训练过程中的随机性
s.random_seed = 0xCAFFE
# 指明训练和测试网络的位置
s.train_net = train_net_path
s.test_net.append(test_net_path)
s.test_interval = 500 # 500次训练迭代后,测试一下
s.test_iter.append(100) # 每次测试时测试100个
s.max_iter = 10000 # 训练10000次结束
s.type = "SGD" # 还可以选择 "SGD"、"Adam"、"Nesterov"等
s.base_lr = 0.01 # 初始学习率
s.momentum = 0.9 #设置动量
s.weight_decay = 5e-4 #设置weight decay,可预防过拟合
s.lr_policy = 'inv' #学习率如何变化的策略,还有'fixed'等
s.gamma = 0.0001
s.power = 0.75
s.display = 1000 #每训练1000次就显示一下loss和accuracy
s.snapshot = 250 #每训练250次就保存一下训练好的权重,
#这里为演示,设置有点小,一般为5000.
s.snapshot_prefix = 'mnist/custom_net'
s.solver_mode = caffe_pb2.SolverParameter.GPU #设置为GPU模式
# 将定义好的solver写入文件
with open(solver_config_path, 'w') as f:
f.write(str(s))
不出差错的话,你会得到一个custom_net_iter_250.caffemodel
的文件,那么恭喜你,你的权重参数训练好啦~~
训练数据在:http://pan.baidu.com/s/1sk8x2Dv