【调参实战】如何开始你的第一个深度学习调参任务?不妨从图像分类中的学习率入手。...
大家好,歡迎來到專欄《調參實戰》,雖然當前自動化調參研究越來越火,但那其實只是換了一些參數來調,對參數的理解和調試在機器學習相關任務中是最基本的素質,在這個專欄中我們會帶領大家一步一步理解和學習調參。
本次主要講述圖像分類項目中的學習率的調參實踐。
作者&編輯 | 言有三
本文資源與結果展示
本文篇幅:3500字
背景要求:會使用Python和任一深度學習開源框架
附帶資料:Caffe代碼和數據集一份
同步平臺:有三AI知識星球(一周內)
1 項目背景與準備工作
對于很多初入機器學習/深度學習領域的朋友來說,往往只會套用公開的模型,對參數的理解和調試非常欠缺經驗,很多經驗豐富的老鳥則往往自稱“煉丹師”,這就是因為參數的調試對于模型性能的影響確實非常大,輕則損害模型性能,重則甚至使得模型無法正常收斂。
圖像分類是整個計算機視覺領域中最基礎的任務,實驗起來比較簡單,在學術界也常用于新模型的比較,因此我們選擇圖像分類任務來進行調參的學習。
本次項目開發需要以下環境:
(1) Linux系統,推薦ubuntu16.04或者ubuntu18.04。使用windows系統也可以完成,但是使用Linux效率更高。
(2) 最好擁有一塊顯存不低于6G的GPU顯卡,如果沒有使用CPU進行訓練速度較慢。
(3)?安裝好的Caffe開源框架。
2 數據集和基準模型
下面我們首先介紹一下數據集和基準模型。
2.1?數據集
在計算機視覺領域中,MNIST,CIFAR,ImageNet常常被用于任務比較,但是它們都有各自的問題。MNIST和CIFAR數據集圖像太小,與真實的計算機視覺任務相去甚遠。ImageNet數據集超過100G,對于大部分個人研究者來說,不適合拿來快速進行學習驗證。
基于此,我們選擇了GHIM-10k數據集,這是一個圖像檢索數據集,包含20個類別,分別是日落,船舶,花卉,建筑物,汽車,山脈,昆蟲等自然圖像,各個類別擁有較好的多樣性,而類別之間也有比較好的區分度。數據集共10000張圖像,每個類別包含500張JPEG格式的大小為400×300或300×400的圖像。
這個數據集有以下幾個比較重要的優點。
(1) 數據集規模不大,獲取也很容易,所有的讀者都可以輕易驗證我們的實驗結果。
(2) 全部都是真實圖片,來自于用戶相機拍攝,而且圖片清晰度足夠高。
(3) 數據集多樣性適中,包含了20類場景的自然場景,每一類的場景非常的均勻。圖片的尺寸是300*400或者400*300,規格統一,符合大多數深度學習圖像任務的處理分辨率,尤其是圖像分類。
(4) 數據集類別分布非常的均勻,我們選擇數據集的方式也是隨機但均勻的選取。我們將數據集按照9:1的比率進行劃分,訓練集中包含20類,每一類450張圖,測試集中包含20類,每一類50張圖。
2.2 基準模型
如今深度學習模型已經有了非常多的變種,而它的本質并沒有變,就是以卷積+非線性激活函數組成的基礎單元進行疊加的模式。
經典的AlexNet是一個8層的網絡,包含了5層卷積和3層全連接,這里我們也選擇一個類似的模型,包括5層卷積,1層全局池化,1層全連接,因為公開的學術研究表明全連接層并不需要過多。
采用Caffe和Proto協議來定義網絡,這樣的模型配置可以手動進行,非常適合一邊調試一邊進行可視化,模型細節如下:
layer {
? ?name: "data"
? ?type: "ImageData"
? ?top: "data"
? ?top: "label"
? ?include {
? ? ?phase: TRAIN
? ?}
? ?transform_param {
? ? ?mirror: true
? ? ?crop_size: 224
? ? ?mean_value: 104.0
? ? ?mean_value: 117.0
? ? ?mean_value: 124.0
? ?}
? ?image_data_param {
? ? ?source: "list_train_shuffle.txt"
? ? ?batch_size: 16
? ? ?shuffle: true
? ? ?new_height: 256
? ? ?new_width: 256
? ?}
?}
layer {
? ?name: "data"
? ?type: "ImageData"
? ?top: "data"
? ?top: "label"
? ?include {
? ? ?phase: TEST
? ?}
? ?transform_param {
? ? ?mirror: false
? ? ?crop_size: 224
? ? ?mean_value: 104.0
? ? ?mean_value: 117.0
? ? ?mean_value: 124.0
? ?}
? ?image_data_param {
? ? ?source: "list_val_shuffle.txt"
? ? ?batch_size: 16
? ? ?shuffle: false
? ? ?new_height: 224
? ? ?new_width: 224
? ?}
?}
layer {
? bottom: "data"
? top: "conv1"
? name: "conv1"
? type: "Convolution"
? param {
? ? lr_mult: 1
? ? decay_mult: 1
? }
? param {
? ? lr_mult: 2
? ? decay_mult: 0
? }
? convolution_param {
? ? num_output: 64
? ? pad: 1
? ? kernel_size: 3? ??
? ? stride: 2
? ? weight_filler {
? ? ? type: "gaussian"
? ? ? std: 0.01
? ? }
? ? bias_filler {
? ? ? type: "constant"
? ? ? value: 0
? ? }
? }
}
layer {
? bottom: "conv1"
? top: "conv1"
? name: "relu1"
? type: "ReLU"
}
layer {
? bottom: "conv1"
? top: "conv2"
? name: "conv2"
? type: "Convolution"
? param {
? ? lr_mult: 1
? ? decay_mult: 1
? }
? param {
? ? lr_mult: 2
? ? decay_mult: 0
? }
? convolution_param {
? ? num_output: 64
? ? pad: 1
? ? kernel_size: 3
? ? stride: 2
? ? weight_filler {
? ? ? type: "gaussian"
? ? ? std: 0.01
? ? }
? ? bias_filler {
? ? ? type: "constant"
? ? ? value: 0
? ? }
? }
}
layer {
? bottom: "conv2"
? top: "conv2"
? name: "relu2"
? type: "ReLU"
}
layer {
? bottom: "conv2"
? top: "conv3"
? name: "conv3"
? type: "Convolution"
? param {
? ? lr_mult: 1
? ? decay_mult: 1
? }
? param {
? ? lr_mult: 2
? ? decay_mult: 0
? }
? convolution_param {
? ? num_output: 128
? ? pad: 1
? ? kernel_size: 3
? ? stride: 2
? ? weight_filler {
? ? ? type: "gaussian"
? ? ? std: 0.01
? ? }
? ? bias_filler {
? ? ? type: "constant"
? ? ? value: 0
? ? }
? }
}
layer {
? bottom: "conv3"
? top: "conv3"
? name: "relu3"
? type: "ReLU"
}
layer {
? bottom: "conv3"
? top: "conv4"
? name: "conv4"
? type: "Convolution"
? param {
? ? lr_mult: 1
? ? decay_mult: 1
? }
? param {
? ? lr_mult: 2
? ? decay_mult: 0
? }
? convolution_param {
? ? num_output: 128
? ? pad: 1
? ? stride: 2
? ? kernel_size: 3
? ? weight_filler {
? ? ? type: "gaussian"
? ? ? std: 0.01
? ? }
? ? bias_filler {
? ? ? type: "constant"
? ? ? value: 0
? ? }
? }
}
layer {
? bottom: "conv4"
? top: "conv4"
? name: "relu4"
? type: "ReLU"
}
layer {
? bottom: "conv4"
? top: "conv5"
? name: "conv5"
? type: "Convolution"
? param {
? ? lr_mult: 1
? ? decay_mult: 1
? }
? param {
? ? lr_mult: 2
? ? decay_mult: 0
? }
? convolution_param {
? ? num_output: 256
? ? pad: 1
? ? stride: 2
? ? kernel_size: 3
? ? weight_filler {
? ? ? type: "gaussian"
? ? ? std: 0.01
? ? }
? ? bias_filler {
? ? ? type: "constant"
? ? ? value: 0
? ? }
? }
}
layer {
? bottom: "conv5"
? top: "conv5"
? name: "relu5"
? type: "ReLU"
}
layer {
? ? bottom: "conv5"
? ? top: "pool5"
? ? name: "pool5"
? ? type: "Pooling"
? ? pooling_param {
? ? ? ? kernel_size: 7
? ? ? ? stride: 1
? ? ? ? pool: AVE
? ? }
}
layer {
? bottom: "pool5"
? top: "fc"
? name: "fc"
? type: "InnerProduct"
? ? inner_product_param {
? ? ? ? num_output: 20
? ? ? ? weight_filler {
? ? ? ? ? ? type: "xavier"
? ? ? ? }
? ? ? ? bias_filler {
? ? ? ? ? ? type: "constant"
? ? ? ? ? ? value: 0
? ? ? ? }
? ? }
}
layer {
? name: "accuracy_at_1"
? type: "Accuracy"
? bottom: "fc"
? bottom: "label"
? top: "accuracy_at_1"
? accuracy_param {
? ? top_k: 1
? }
}
layer {
? name: "accuracy_at_5"
? type: "Accuracy"
? bottom: "fc"
? bottom: "label"
? top: "accuracy_at_5"
? accuracy_param {
? ? top_k: 5
? }
}
layer {
? bottom: "fc"
? bottom: "label"
? top: "loss"
? name: "loss"
? type: "SoftmaxWithLoss"
}
使用在線工具http://ethereon.github.io/netscope/#/editor
對模型的可視化結果如下:
總結
以上是生活随笔為你收集整理的【调参实战】如何开始你的第一个深度学习调参任务?不妨从图像分类中的学习率入手。...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【杂谈】有三AI秋季划增加生成对抗网络小
- 下一篇: 【调参实战】那些优化方法的性能究竟如何,