1. 程式人生 > >caffe mnist實例 --lenet_train_test.prototxt 網絡配置詳解

caffe mnist實例 --lenet_train_test.prototxt 網絡配置詳解

learn root backend .proto word 初始 固定 get alt

1.mnist實例

##1.數據下載 獲得mnist的數據包,在caffe根目錄下執行./data/mnist/get_mnist.sh腳本。 get_mnist.sh腳本先下載樣本庫並進行解壓縮,得到四個文件。 技術分享

2.生成LMDB

成功解壓縮下載的樣本庫後,然後執行./examples/mnist/create_mnist.sh。 create_mnist.sh腳本先利用caffe-master/build/examples/mnist/目錄下的convert_mnist_data.bin工具,將mnist data轉化為caffe可用的lmdb格式文件,然後將生成的mnist-train-lmdb和mnist-test-lmdb兩個文件放在caffe-master/example/mnist目錄下面。

3.網絡配置

LeNet網絡定義在./examples/mnist/lenet_train_test.prototxt 文件中。

name: "LeNet"
layer {
  name: "mnist"    //輸入層的名稱mnist
  type: "Data"     //輸入層的類型為Data  top: "data"      //本層下一場連接data層和label blob空間
  top: "label"
  include {
    phase: TRAIN   //訓練階段
  }
  transform_param {
    scale: 0.00390625  //輸入圖片像素歸一到[0,1].1除以256為0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_train_lmdb"  //從mnist_train_lmdb中讀入數據
    batch_size: 64    //batch大小為64,一次訓練64條數據
    backend: LMDB
  }
}
layer {
  name: "mnist"    //輸入層的名稱mnist
  type: "Data"     //輸入層的類型為Data  top: "data"      //本層下一場連接data層和label blob空間
  top: "label"
  include {
    phase: TEST   //測試階段
  }
  transform_param {
    scale: 0.00390625  //輸入圖片像素歸一到[0,1].1除以256為0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_test_lmdb"  //從mnist_test_lmdb中讀入數據
    batch_size: 100    //batch大小為100,一次訓練100條數據
    backend: LMDB
  }
}
layer {
  name: "conv1"    //卷積層名稱conv1
  type: "Convolution"    //層類型為卷積層
  bottom: "data"    //本層使用上一層的data,生成下一層conv1的blob
  top: "conv1"
  param {
    lr_mult: 1    //權重參數w的學習率倍數
  }
  param {
    lr_mult: 2    //偏置參數b的學習率倍數
  }
  convolution_param {
    num_output: 20    //輸出單元數20
    kernel_size: 5    //卷積核大小為5*5
    stride: 1         //步長為1
    weight_filler {   //允許用隨機值初始化權重和偏置值
      type: "xavier"  //使用xavier算法自動確定基於輸入—輸出神經元數量的初始規模
    }
    bias_filler {
      type: "constant"    //偏置值初始化為常數,默認為0
    }
  }
}
layer {
  name: "pool1"      //層名稱為pool1
  type: "Pooling"    //層類型為pooling
  bottom: "conv1"    //本層的上一層是conv1,生成下一層pool1的blob
  top: "pool1"
  pooling_param {    //pooling層的參數
    pool: MAX        //pooling的方式是MAX
    kernel_size: 2   //pooling核是2*2
    stride: 2        //pooling步長是2
  }
}
layer {
  name: "conv2"    //第二個卷積層,同第一個卷積層相同,只是卷積核為50
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "pool2"     //第二個pooling層,與第一個pooling層相同
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {            //全連接層
  name: "ip1"      //全連接層名稱ip1
  type: "InnerProduct"    //層類型為全連接層
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {     //全連接層的參數
    num_output: 500         //輸出500個節點
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "relu1"       //ReLU  type: "ReLU"        //層名稱為relu1
  bottom: "ip1"       //層類型為ReLU
  top: "ip1"
}
layer {
  name: "ip2"         //第二個全連接層
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10     //輸出10個單元
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip2"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {        //loss層,softmax_loss層實現softmax和多項Logistic損失
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip2"
  bottom: "label"
  top: "loss"
}

4.訓練網絡

運行./examples/mnist/train_lenet.sh。 執行此腳本是,實際運行的是lenet_solver.prototxt中的定義。

# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"    //網絡具體定義
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100    //test叠代次數,若batch_size=100,則100張圖一批,訓練100次,可覆蓋1000張圖
# Carry out testing every 500 training iterations.
test_interval: 500    //訓練叠代500次,測試一次
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01    //網絡參數:學習率,動量,權重的衰減
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy    //學習策略:有固定學習率和每步遞減學習率
lr_policy: "inv"    //當前使用遞減學習率
gamma: 0.0001
power: 0.75
# Display every 100 iterations    //每叠代100次顯示一次
display: 100
# The maximum number of iterations   //最大叠代數
max_iter: 10000
# snapshot intermediate results    //每5000次叠代存儲一次數據
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
# solver mode: CPU or GPU
solver_mode: CPU    //本例用CPU訓練

數據訓練結束後,會生成以下四個文件: 技術分享

5.測試網絡

運行./build/tools/caffe.bin test -model=examples/mnist/lenet_train_test.prototxt -weights=examples/mnist/lenet_iter_10000.caffemodel

test:表示對訓練好的模型進行Testing,而不是training。其他參數包括train, time, device_query。

-model=XXX:指定模型prototxt文件,這是一個文本文件,詳細描述了網絡結構和數據集信息。 技術分享

從上面的打印輸出可看出,測試數據中的accruacy平均成功率為98%。

mnist手寫測試

手寫數字的圖片必須滿足以下條件:

  • 必須是256位黑白色
  • 必須是黑底白字
  • 像素大小必須是28*28
  • 數字在圖片中間,上下左右沒有過多的空白。

測試圖片

技術分享 技術分享 技術分享 技術分享 技術分享

手寫數字識別腳本

import os
import sys
import numpy as np
import matplotlib.pyplot as plt

caffe_root = ‘/home/lynn/caffe/‘
sys.path.insert(0, caffe_root + ‘python‘)
import caffe

MODEL_FILE = ‘/home/lynn/caffe/examples/mnist/lenet.prototxt‘
PRETRAINED = ‘/home/lynn/caffe/examples/mnist/lenet_iter_10000.caffemodel‘

IMAGE_FILE = ‘/home/lynn/test.bmp‘
input_image = caffe.io.load_image(IMAGE_FILE, color=False)

#print input_image
net = caffe.Classifier(MODEL_FILE, PRETRAINED)
prediction = net.predict([input_image], oversample = False)
caffe.set_mode_cpu()
print ‘predicted class: ‘, prediction[0].argmax()

測試結果

技術分享 技術分享
技術分享 技術分享
技術分享

caffe mnist實例 --lenet_train_test.prototxt 網絡配置詳解