Caffe之学习网络参数

来源:互联网 发布:免费的小学英语软件 编辑:程序博客网 时间:2024/04/26 07:33

已知条件

1)预处理好的LMDB格式的训练数据和测试数据(这里是mnist数据源)

步骤

1)准备工作

导入一些包,设置工作路径。

主函数main.py内容1:

import osimport matplotlib.pyplot as pltimport numpy as npfrom tool.net_func import *      #tool为自定义包,有两个文件:                                 #__init__.py和net_func.py,                                 #后文会介绍。os.chdir('/home/yekui/caffe-master/examples')#设置工作路径,之后的路径都是基于此!!

2)得到solver

这里有两个函数需要指出:

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

3)开始训练

主函数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()

显示结果为:

4)自定义包

#此文件名为net_func.py#在tool文件夹下#tool文件夹与main.py在相同路径下caffe_root = '/home/yekui/caffe-master/'import syssys.path.insert(0,caffe_root + 'python')import caffefrom caffe import layers as L, params as Pdef 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

0 0