1. 程式人生 > >Caffe學習筆記(六):mnist手寫數字識別訓練例項

Caffe學習筆記(六):mnist手寫數字識別訓練例項

一、前言

   深度學習的一個簡單例項就是mnist手寫數字識別,只要這個例子弄明白,其它的內容就可以舉一反三了。之前的內容如有遺忘,可以進行回顧。

二、準備資料

   資料集可以直接從我的github下載,包括資料集和程式碼,使用如下指令:

git clone https://github.com/Jack-Cherish/DeepLearning/tree/master/mnist

   如果github網速過慢,也可以從百度雲下載:

   獲取的資料是zip格式的,在linux下可以使用如下指令進行解壓(已安裝unzip,沒有安裝使用指令unzip):

unzip mnist.zip

   資料分成了訓練集(60000張共10類)和測試集(共10000張10類),每個類別放在一個單獨的資料夾裡。並且將所有的圖片,都生成了txt列表清單(train.txt和test.txt)。下載下來後,直接解壓到當前使用者根目錄下即可。

三、開始訓練

   之前講解的訓練方法是,將原始圖片轉換成db(leveldb/lmdb)檔案,並計算影象均值。然後在網路的第一層資料層Data中指定db檔案和均值檔案的位置,建立資料層的方法還有幾種,另一種常見的方法是把原始圖片做成一個列表清單txt檔案(一行一張圖),則省去了圖片格式轉化和圖片均值計算的過程,提供的資料集中已經包括了txt列表清單檔案,因此也省卻了我們手動生成的步驟,直接使用即可。因此我們可以使用ImageData作為資料來源輸入。訓練步驟如下:

  • 獲取資料集
  • 生成txt列表清單檔案(已有)
  • 生成train.prototxt、test.prototxt、solver.prototxt檔案
  • 訓練資料,生成模型

1.編寫程式碼

   在my-caffe-project根目錄下解壓檔案後,即可建立mnist.py檔案,編寫如下程式碼:

# -*- coding: UTF-8 -*-
import caffe                                                     #匯入caffe包

def create_net(img_list, batch_size, include_acc=False)
:
#網路規範 net = caffe.NetSpec() #ImageData資料層 net.data, net.labels = caffe.layers.ImageData(batch_size = batch_size, source = img_list, transform_param = dict(scale = 1./255), ntop = 2) #卷積層 net.conv1 = caffe.layers.Convolution(net.data, kernel_size = 5, num_output = 20, weight_filler = dict(type = 'xavier')) #池化層 net.pool1 = caffe.layers.Pooling(net.conv1, kernel_size = 2, stride = 2, pool = caffe.params.Pooling.MAX) #卷積層 net.conv2 = caffe.layers.Convolution(net.pool1, kernel_size = 5, num_output = 50, weight_filler = dict(type = 'xavier')) #池化層 net.pool2 = caffe.layers.Pooling(net.conv2, kernel_size = 2, stride = 2, pool = caffe.params.Pooling.MAX) #全連層 net.fc1 = caffe.layers.InnerProduct(net.pool2, num_output = 500, weight_filler = dict(type = 'xavier')) #啟用函式層 net.relu1 = caffe.layers.ReLU(net.fc1, in_place = True) #全連層 net.score = caffe.layers.InnerProduct(net.relu1, num_output = 10, weight_filler = dict(type = 'xavier')) #softmax層 net.loss = caffe.layers.SoftmaxWithLoss(net.score, net.labels) if include_acc: net.acc = caffe.layers.Accuracy(net.score, net.labels) return net.to_proto() return net.to_proto() def write_net(train_proto, train_list, test_proto, test_list): #寫入prototxt檔案 with open(train_proto, 'w') as f: f.write(str(create_net(train_list, batch_size = 64))) #寫入prototxt檔案 with open(test_proto, 'w') as f: f.write(str(create_net(test_list, batch_size = 100, include_acc = True))) def write_sovler(my_project_root, solver_proto, train_proto, test_proto): sovler_string = caffe.proto.caffe_pb2.SolverParameter() #sovler儲存 sovler_string.train_net = train_proto #train.prototxt位置指定 sovler_string.test_net.append(test_proto) #test.prototxt位置指定 sovler_string.test_iter.append(100) #10000/100 測試迭代次數 sovler_string.test_interval = 938 #60000/64 每訓練迭代test_interval次進行一次測試 sovler_string.base_lr = 0.01 #基礎學習率 sovler_string.momentum = 0.9 #動量 sovler_string.weight_decay = 5e-4 #權重衰減 sovler_string.lr_policy = 'step' #學習策略 sovler_string.stepsize = 3000 #學習率變化頻率 sovler_string.gamma = 0.1 #學習率變化指數 sovler_string.display = 20 #每迭代display次顯示結果 sovler_string.max_iter = 9380 #10 epoch 938*10 最大迭代數 sovler_string.snapshot = 938 #儲存臨時模型的迭代數 sovler_string.snapshot_prefix = my_project_root + 'mnist' #模型字首 sovler_string.solver_mode = caffe.proto.caffe_pb2.SolverParameter.GPU #優化模式 with open(solver_proto, 'w') as f: f.write(str(sovler_string)) def train(solver_proto): caffe.set_device(1) caffe.set_mode_gpu() solver = caffe.SGDSolver(solver_proto) solver.solve() if __name__ == '__main__': my_project_root = "/home/Jack-Cui/caffe-master/my-caffe-project/" #my-caffe-project目錄 train_list = my_project_root + "mnist/train/train.txt" #train.txt檔案的位置 test_list = my_project_root + "mnist/test/test.txt" #test.txt檔案的位置 train_proto = my_project_root + "mnist/train.prototxt" #儲存train.prototxt檔案的位置 test_proto = my_project_root + "mnist/test.prototxt" #儲存test.prototxt檔案的位置 solver_proto = my_project_root + "mnist/solver.prototxt" #儲存solver.prototxt檔案的位置 write_net(train_proto, train_list, test_proto, test_list) print "生成train.prototxt test.prototxt成功" write_sovler(my_project_root, solver_proto, train_proto, test_proto) print "生成solver.prototxt成功" train(solver_proto) print "訓練完成"

   由於以上內容在之前已經進行詳細講解,如有遺忘請回顧之前筆記。

2.執行結果:

3.總結

   從執行結果可以看出,訓練準確率高達99.11%。訓練生成的mnist_iter_9380.caffemodel即為最終訓練得到的模型,下篇筆記將繼續講解,如何使用這個訓練好的模型做預測。