caffe的python接口學習(4):mnist實例---手寫數字識別

深度學習的第一個實例通常都是mnist,只要這個例子徹底弄懂了,其它的就是觸類旁通的事了。因爲篇幅緣由,本文不具體介紹配置文件裏面每一個參數的具體函義,若是想弄明白的,請參看我之前的博文:html

數據層及參數python

視覺層及參數linux

solver配置文件及參數算法

1、數據準備windows

官網提供的mnist數據並非圖片,但咱們之後作的實際項目多是圖片。所以有些人並不知道該怎麼辦。在此我將mnist數據進行了轉化,變成了一張張的圖片,咱們練習就從圖片開始。mnist圖片數據我放在了百度雲盤。app

mnist圖片數據下載:http://pan.baidu.com/s/1pLMV4Kz編輯器

數據分紅了訓練集(60000張共10類)和測試集(共10000張10類),每一個類別放在一個單獨的文件夾裏。而且將全部的圖片,都生成了txt列表清單(train.txt和test.txt)。你們下載下來後,直接解壓到當前用戶根目錄下就能夠了。因爲我是在windows下壓縮的,所以是winrar文件。若是你們要在linux下解壓縮,須要安裝rar的linux版本,也是十分簡單ide

sudo apt-get install rar

2、導入caffe庫,並設定文件路徑函數

我是將mnist直接放在根目錄下的,因此代碼以下:學習

# -*- coding: utf-8 -*-

import caffe
from caffe import layers as L,params as P,proto,to_proto
#設定文件的保存路徑
root='/home/xxx/'                           #根目錄
train_list=root+'mnist/train/train.txt'     #訓練圖片列表
test_list=root+'mnist/test/test.txt'        #測試圖片列表
train_proto=root+'mnist/train.prototxt'     #訓練配置文件
test_proto=root+'mnist/test.prototxt'       #測試配置文件
solver_proto=root+'mnist/solver.prototxt'   #參數文件

其中train.txt 和test.txt文件已經有了,其它三個文件,咱們須要本身編寫。

此處注意:通常caffe程序都是先將圖片轉換成lmdb文件,但這樣作有點麻煩。所以我就不轉換了,我直接用原始圖片進行操做,所不一樣的就是直接用圖片操做,均值很難計算,所以能夠不減均值。

2、生成配置文件

配置文件實際上就是一些txt文檔,只是後綴名是prototxt,咱們能夠直接到編輯器裏編寫,也能夠用代碼生成。此處,我用python來生成。

#編寫一個函數,生成配置文件prototxt
def Lenet(img_list,batch_size,include_acc=False):
    #第一層,數據輸入層,以ImageData格式輸入
    data, label = L.ImageData(source=img_list, batch_size=batch_size, ntop=2,root_folder=root,
        transform_param=dict(scale= 0.00390625))
    #第二層:卷積層
    conv1=L.Convolution(data, kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))
    #池化層
    pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    #卷積層
    conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))
    #池化層
    pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    #全鏈接層
    fc3=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type='xavier'))
    #激活函數層
    relu3=L.ReLU(fc3, in_place=True)
    #全鏈接層
    fc4 = L.InnerProduct(relu3, num_output=10,weight_filler=dict(type='xavier'))
    #softmax層
    loss = L.SoftmaxWithLoss(fc4, label)
    
    if include_acc:             # test階段須要有accuracy層
        acc = L.Accuracy(fc4, label)
        return to_proto(loss, acc)
    else:
        return to_proto(loss)
    
def write_net():
    #寫入train.prototxt
    with open(train_proto, 'w') as f:
        f.write(str(Lenet(train_list,batch_size=64)))

    #寫入test.prototxt    
    with open(test_proto, 'w') as f:
        f.write(str(Lenet(test_list,batch_size=100, include_acc=True)))

配置文件裏面存放的,就是咱們所說的network。我這裏生成的network,可能和原始的Lenet不太同樣,不過影響不大。

3、生成參數文件solver

一樣,能夠在編輯器裏面直接書寫,也能夠用代碼生成。

#編寫一個函數,生成參數文件
def gen_solver(solver_file,train_net,test_net):
    s=proto.caffe_pb2.SolverParameter()
    s.train_net =train_net
    s.test_net.append(test_net)
    s.test_interval = 938    #60000/64,測試間隔參數:訓練完一次全部的圖片,進行一次測試  
    s.test_iter.append(100)  #10000/100 測試迭代次數,須要迭代100次,才完成一次全部數據的測試
    s.max_iter = 9380       #10 epochs , 938*10,最大訓練次數
    s.base_lr = 0.01    #基礎學習率
    s.momentum = 0.9    #動量
    s.weight_decay = 5e-4  #權值衰減項
    s.lr_policy = 'step'   #學習率變化規則
    s.stepsize=3000         #學習率變化頻率
    s.gamma = 0.1          #學習率變化指數
    s.display = 20         #屏幕顯示間隔
    s.snapshot = 938       #保存caffemodel的間隔
    s.snapshot_prefix =root+'mnist/lenet'   #caffemodel前綴
    s.type ='SGD'         #優化算法
    s.solver_mode = proto.caffe_pb2.SolverParameter.GPU    #加速
    #寫入solver.prototxt
    with open(solver_file, 'w') as f:
        f.write(str(s))

4、開始訓練模型

訓練過程當中,也在不停的測試。

#開始訓練
def training(solver_proto):
    caffe.set_device(0)
    caffe.set_mode_gpu()
    solver = caffe.SGDSolver(solver_proto)
    solver.solve()

最後,調用以上的函數就能夠了。

if __name__ == '__main__':
    write_net()
    gen_solver(solver_proto,train_proto,test_proto) 
    training(solver_proto)

5、完成的python文件

mnist.py

# -*- coding: utf-8 -*-

import caffe
from caffe import layers as L,params as P,proto,to_proto
#設定文件的保存路徑
root='/home/xxx/'                           #根目錄
train_list=root+'mnist/train/train.txt'     #訓練圖片列表
test_list=root+'mnist/test/test.txt'        #測試圖片列表
train_proto=root+'mnist/train.prototxt'     #訓練配置文件
test_proto=root+'mnist/test.prototxt'       #測試配置文件
solver_proto=root+'mnist/solver.prototxt'   #參數文件

#編寫一個函數,生成配置文件prototxt
def Lenet(img_list,batch_size,include_acc=False):
    #第一層,數據輸入層,以ImageData格式輸入
    data, label = L.ImageData(source=img_list, batch_size=batch_size, ntop=2,root_folder=root,
        transform_param=dict(scale= 0.00390625))
    #第二層:卷積層
    conv1=L.Convolution(data, kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))
    #池化層
    pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    #卷積層
    conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))
    #池化層
    pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    #全鏈接層
    fc3=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type='xavier'))
    #激活函數層
    relu3=L.ReLU(fc3, in_place=True)
    #全鏈接層
    fc4 = L.InnerProduct(relu3, num_output=10,weight_filler=dict(type='xavier'))
    #softmax層
    loss = L.SoftmaxWithLoss(fc4, label)
    
    if include_acc:             # test階段須要有accuracy層
        acc = L.Accuracy(fc4, label)
        return to_proto(loss, acc)
    else:
        return to_proto(loss)
    
def write_net():
    #寫入train.prototxt
    with open(train_proto, 'w') as f:
        f.write(str(Lenet(train_list,batch_size=64)))

    #寫入test.prototxt    
    with open(test_proto, 'w') as f:
        f.write(str(Lenet(test_list,batch_size=100, include_acc=True)))

#編寫一個函數,生成參數文件
def gen_solver(solver_file,train_net,test_net):
    s=proto.caffe_pb2.SolverParameter()
    s.train_net =train_net
    s.test_net.append(test_net)
    s.test_interval = 938    #60000/64,測試間隔參數:訓練完一次全部的圖片,進行一次測試  
    s.test_iter.append(500)  #50000/100 測試迭代次數,須要迭代500次,才完成一次全部數據的測試
    s.max_iter = 9380       #10 epochs , 938*10,最大訓練次數
    s.base_lr = 0.01    #基礎學習率
    s.momentum = 0.9    #動量
    s.weight_decay = 5e-4  #權值衰減項
    s.lr_policy = 'step'   #學習率變化規則
    s.stepsize=3000         #學習率變化頻率
    s.gamma = 0.1          #學習率變化指數
    s.display = 20         #屏幕顯示間隔
    s.snapshot = 938       #保存caffemodel的間隔
    s.snapshot_prefix = root+'mnist/lenet'   #caffemodel前綴
    s.type ='SGD'         #優化算法
    s.solver_mode = proto.caffe_pb2.SolverParameter.GPU    #加速
    #寫入solver.prototxt
    with open(solver_file, 'w') as f:
        f.write(str(s))
  
#開始訓練
def training(solver_proto):
    caffe.set_device(0)
    caffe.set_mode_gpu()
    solver = caffe.SGDSolver(solver_proto)
    solver.solve()
#
if __name__ == '__main__':
    write_net()
    gen_solver(solver_proto,train_proto,test_proto) 
    training(solver_proto)
View Code

 

我將此文件放在根目錄下的mnist文件夾下,所以可用如下代碼執行

sudo python mnist/mnist.py

在訓練過程當中,會保存一些caffemodel。多久保存一次,保存多少次,均可以在solver參數文件裏進行設置。

我設置爲訓練10 epoch,9000屢次,測試精度能夠達到99%

相關文章
相關標籤/搜索