CNN模型合集 | 1 LeNet
1.1 LeNet的設計思想
1998年LeCun提出,經典結構,3層,五臟俱全(卷積層、Pooling層、FC網路、Sigmod層),對標傳統神經網路。
主要設計貢獻
區域性感受野(local receptive fields),區域性連線
權值共享(引數共享)
下采樣(sub-sampling),pooling層
核心結構
LeNet-5是LeCun最新的卷積網路,專為手寫和機器列印的字元識別而設計,下面是LeNet-5實際應用的一個例子。
傳統網路的全連線FC
(VS區域性連線)
傳統神經網路連線方式是透過全連線,上一層的所有神經元節點x會和下一層的每一個節點y進行互連,線性變換y=w*x_all+b
權值引數多,系統開銷大,稠密
對平移、形變不具有不變性,對區域性資訊不敏感,完全忽略了影象的區域性結構,因為考慮到了所有點。
圖如果發生一點變化就會導致輸出結果產生很大差異(病態問題:對輸入輸出敏不敏感,收集到是資料往往帶有噪聲,若模型對此偏差敏感就是病態系統,不魯棒)
全連線相當於1*1的卷積核
引數共享的區域性連線
(VS純區域性連線還是不夠好,想進一步減少引數規模)
減小引數規模,如下圖引數共享的區域性連線引數減少到了10k,後階段做模型時越小越好,大的話終端執行時空間很大載入會很慢,很佔記憶體。
引數共享就是每種(個)filter學習一種feature,同一種filter權值當然是共享,所有的區域性感受野就是用同一種引數,所以就每個卷積層需要很多種filter,也就是depth來學習很多種不同的特徵。
用一組固定的引數和不同視窗做卷積,來得到下一層特徵。每一種濾波器(卷積)就是一種特徵,就像高斯濾波等保留了高頻或低頻的訊號。
神經網路的卷積就是用一種濾波器提取一種特徵,學習多種濾波器,保證多樣性;又在經過下采樣的不同層上來學習不同濾波器,這樣就在不同的力度上提取了不同的特徵,比較完善。
卷積
感受野下的各畫素與卷積核相乘,再相加賦給中心畫素。
傅立葉變換與訊號處理的知識,跟高斯濾波、銳化、邊緣檢測等一樣提取高頻訊號。
邊緣檢測時手動設計卷積核為按列遞減的值[[1,0,-1], [1,0,-1],[1,0,-1]],與它相乘就相當於左邊的畫素減去右邊的,就能檢測出垂直邊緣資訊。以前傳統機器學習是手動設計卷積核特徵(如顏色資訊、紋理資訊、形狀資訊)。
下采樣(sub-sampling),pooling層
縮小影象,但不會長寬比形變(區別resize),獲得多尺度的資訊,以免單一,相當於均值濾波器
忽略目標的傾斜、旋轉之類的相對位置的變化,以此提高精度,不管怎麼轉獲得的最大值會均值都是不變的
降低了特徵圖的維度,推理時能適應多尺度的影象,
可以避免過擬合,因為維度小了,引數少了,計算量少了
Sigmod層
連續的函式,這裡分類用,逼近不可導的0-1階躍啟用函式,高斯連線,邏輯迴歸函式,1維的,輸出是0~1間的數
而常用的Softmax是2維的,輸出是2個機率值,正樣本的機率和負樣本的機率。
1.2 Caffe實現LeNet
參考:
https://
github。com/XuekuanWang/
demoCaffe
或者
https://
github。com/BVLC/caffe/t
ree/master/examples/mnist
或者
https://
github。com/jklhj222/caf
fe_LeNet/tree/master/LeNet
(1)lenet_solver.prototxt 訓練引數
net:網路模型檔案的路徑
test_iter:在測試的時候需要迭代的次數,即test_iter* batchsize(測試集的)=測試集的大小,測試集batchsize可以在tran_test。prototxt檔案裡設定
test_interval:測試間隔,訓練的時候每迭代500次就進行一次測試。
caffe在訓練的過程是邊訓練邊測試的。訓練過程中每500次迭代(也就是32000個訓練樣本參與了計算,batchsize為64),計算一次測試誤差。計算一次測試誤差就需要包含所有的測試圖片(這裡為10000),這樣可以認為在一個epoch裡,訓練集中的所有樣本都遍歷一遍,但測試集的所有樣本至少要遍歷一次,至於具體要多少次,也許不是整數次,這就要看程式碼。
base_lr 基本學習率:loss降不下去可能是學習率太大了
momentum 動量:梯度下降最佳化器的引數,為了自適應調整學習率(後面學習率要降低)
weight_decay 權值衰減
# 網路模型檔案,train_test代表訓練網路和測試網路寫到一個檔案裡了,若分開寫注意修改
net: “lenet_train_test。prototxt”
# 在測試的時候需要迭代的次數
test_iter: 100
# 訓練的時候每迭代多少次就進行一次測試
test_interval: 1000
# 網路的基本學習率、動量和權值衰減
base_lr: 0。01
momentum: 0。9
weight_decay: 0。0005
# The learning rate policy,學習率政策
lr_policy: “inv”
gamma: 0。0001
power: 0。75
# 每100次迭代顯示一次
display: 10
# 最大迭代次數
max_iter: 10000
# 每多少次儲存一次快照
snapshot: 1000
# 快照儲存的路徑字首
snapshot_prefix: “/home/kuan/PycharmProjects/demo_cnn_net/cnn_model/mnist/lenet/lenet”
# solver mode: CPU or GPU
solver_mode: GPU
(2)lenet_train_test.prototxt
網路結構
(訓練和測試),區別lenet。prototxt(只預測)
訓練和測試選項:
include { phase: TRAIN }:相位,加上此條代表它這一層只用於訓練,沒有寫明就代表測試和訓練通用
include { phase: TEST}:相位,加上此條代表它這一層只用於測試
data_param {}:
source訓練或測試的資料集路徑
batch_size批次值,每次迭代訓練圖片的數量
隨機梯度下降:每一個樣本訓練下降一次,容易震盪,容易陷入區域性最優
批次梯度下降:引數調整慢,計算所有樣本後求均值,可能會磨滅好的資訊
小批次隨機梯度下降:折中方案,設定batch_size批次值,跑batch_size個後下降一次
層選項:
layer {}:每個layer代表一個層,網路連線就是一層一層堆起來的,
type:每個layer有它的type(Data、Input、Convolution、Pooling、ReLU、InnerProduct全連線層、Softmax、Accuracy、SoftmaxWithLoss),
top、bottom:每個layer還有它的輸入和輸出(top、bottom),輸入層只有top輸出,卷積層bottom是輸入,top是輸出。這三個必須要有。
層的引數:
param {}:
lr_mult:學習率引數,第一個是引數w,第二個是b,如果不寫就是預設
convolution_param {}:卷積核引數,
num_output個數,kernel_size大小,stride步長,我們主要調參是這三個。
weight_filler{}權值初始化方式,bias_filler{}偏差值初始化方式,這倆影響不大。
name: “LeNet”
layer {
name: “mnist”
type: “Data”
top: “data”
top: “label”
include {
phase: TRAIN # 相位
}
transform_param {
scale: 0。00390625
}
data_param {
source: “/home/kuan/PycharmProjects/demo_cnn_net/mnist/mnist_train_lmdb”
batch_size: 16
backend: LMDB
}
}
layer {
name: “mnist”
type: “Data”
top: “data”
top: “label”
include {
phase: TEST
}
transform_param {
scale: 0。00390625
}
data_param {
source: “/home/kuan/PycharmProjects/demo_cnn_net/mnist/mnist_test_lmdb”
batch_size: 16
backend: LMDB
}
}
layer {
name: “conv1”
type: “Convolution”
bottom: “data” # 輸入
top: “conv1” # 輸出
param {
lr_mult: 1 # 引數w
}
param {
lr_mult: 2 # 引數b
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: “xavier” # xavier法初始化權重
}
bias_filler {
type: “constant”
}
}
}
layer {
name: “pool1”
type: “Pooling”
bottom: “conv1”
top: “pool1”
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: “conv2”
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”
type: “Pooling”
bottom: “conv2”
top: “pool2”
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: “ip1”
type: “InnerProduct”
bottom: “pool2”
top: “ip1”
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: “xavier”
}
bias_filler {
type: “constant”
}
}
}
layer {
name: “relu1”
type: “ReLU”
bottom: “ip1”
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
weight_filler {
type: “xavier”
}
bias_filler {
type: “constant”
}
}
}
layer {
name: “accuracy”
type: “Accuracy”
bottom: “ip2”
bottom: “label”
top: “accuracy”
include {
phase: TEST
}
}
layer {
name: “loss”
type: “SoftmaxWithLoss”
bottom: “ip2”
bottom: “label”
top: “loss”
}
(3)視覺化caffe網路結構
把caffe給的例程複製到網站
https://
ethereon。github。io/nets
cope/#/editor
或
http://
ethereon。github。io/nets
cope/#/editor
,按shift+enter得到。
與最原始的相比,這裡實現的LeNet加了relu,卷積核個數、全連線單元數也不一樣,Sigmod也改為了softmax。如圖左邊的是訓練和測試的lenet_train_test。prototxt,中間的是預測的lenet_depoly。prototxt(input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } } #64是batch_size),最右邊的是lenet。prototxt(input_param { shape: { dim: 1 dim: 3 dim: 28 dim: 28 } } )。
(4)訓練
編寫好lenet_solver。prototxt和lenet_train_test。prototxt後執行:
# coding utf-8
import caffe
caffe。set_device(0) # GPU的裝置號
caffe。set_mode_gpu() # gpu模式
solver = caffe。SGDSolver(“。/cnn_net/lenet/lenet_solver。prototxt”) # SGD,訓練引數檔案
solver。solve()
(5)預測結果
使用訓練好的模型lenet_iter_10000。caffemodel,按照預測網路結構lenet。prototxt來推斷。參考
https://
github。com/jklhj222/caf
fe_LeNet/blob/master/LeNet/caffe_test。py
#!/usr/bin/env python3
import os
import sys
import numpy as np
import matplotlib。pyplot as plt
caffe_root = ‘/home/s2c/pkg/local/caffe-master_cuDNN’
sys。path。insert(0, caffe_root + ‘python’) # Add the path of pycaffe into environment
import caffe
# Assign the structure of network, differ with lenet_train_test。prototxt
MODEL_FILE = ‘/home/s2c/pkg/local/caffe-master_cuDNN/examples/mnist/lenet。prototxt’
#MODEL_FILE = ‘lenet_train_test。prototxt’
PRETRAINED = ‘/home/s2c/pkg/local/caffe-master_cuDNN/examples/mnist/lenet_iter_10000。caffemodel’
# lenet。prototxt, picture size (28x28), black and white
IMAGE_FILE = ‘/home/s2c/pkg/local/caffe-master_cuDNN/examples/images/test4。png’
input_image = caffe。io。load_image(IMAGE_FILE, color=False)
net = caffe。Classifier(MODEL_FILE, PRETRAINED)
prediction = net。predict([input_image], oversample = False)
caffe。set_mode_gpu()
print( ‘predicted class:’, prediction[0]。argmax() )
print( ‘predicted class2:’, prediction[0] )
轉載請提前告知
上一篇:第六章 追求共同利益最大化