寫在前面
本系列博客記錄了作者上手MXNet的全過程。作者在接觸MXNet之前主要使用keras,和一點tensorflow,因此在上手MXNet之前有一點deep learning的項目基礎。主要參考資料爲MXNet官方教程,也閱讀了一些有價值的博客。
博客結構爲:先列出作者對於該階段的期望目標,以及各目標完成過程中的筆記(僅記下個人認爲重要的),再附上學習過程中自己的提問(solved & unsolved,天馬行空的提問,歡迎討論)。
本階段目標
任務 | 優先級 | 預計花時間 | 完成狀態 | 遇到問題 | 補充 |
瞭解MXNet中模型的整個inference過程 | 4hour | ||||
MXNet學習資料整理整理 | P0 | 1.5hour | |||
分析VGG案例 | P1 | 2hour | |||
分析SSD案例 | P2 | 3hour |
具體筆記
task1 體會整個inference過程
數據 | 準備數據 | 使用mx.io.ImageRecordIter()來讀取 | |
數據預處理 | |||
網絡 | 預訓練模型導入 |
使用mx.model.load_checkpoint()導入預訓練模型 訓練好的模型參數是用.params文件保存,網絡結構是用.json文件保存
|
|
模型結構修改 |
get_fine_tune_model()函數進行修改
|
||
模型參數初始化 |
mxnet.initializer包用來管理模型參數初始化,例如mxnet.initializer.Xavier 預訓練模型中不修改的層不需要再初始化了 |
||
模型初始化 | mxnet.module.Module | 爲了? | |
訓練 | 學習率變化策略 | 使用mx.lr_scheduler.MultiFactorScheduler類,學習率的改變由epoch和factor決定 | |
訓練超參數 | 初始學習率:learning_rate、梯度下降中的動量參數:momentum、正則項參數:wd、學習率變化策略參數:lr_scheduler | ||
評價函數 | 定義在~/incubator-mxnet/blob/master/python/mxnet/metric.py中,評價函數的基類是mxnet.metric.EvalMetric,可以根據這個類自定義評價函數 | ||
logging記錄 | 下方logging筆記 | ||
開始訓練 |
|
- 關於兩種數據格式
`.rec`文件 | `.lst`和圖像結合的方式 | ||
pro | con | pro | con |
比較穩定,移植到別的電腦上也能復現 | 佔空間(差不多1萬張圖像生成的.rec文件是1G),而且增刪數據不大靈活 | 讀取靈活且不佔空間 |
|
- 關於訓練集和測試集的處理
train和val數據集比較大的區別一方面是val數據集不需要做shuffle操作,另一方面在最後的預處理操作中不需要類似crop或mirror等數據增強操作,但是歸一化操作(mean=True和std=True)在`train`和`val`數據集中要麼都做,要麼都不做,建議都做。另外要提一下最後一個參數aug_list,這個參數的輸入是mx.image.CreateAugmenter()函數,這個函數就是該類中管理數據預處理的函數,可以看到在下面的代碼中添加了輸入圖像尺寸:(3,224,224)、resize操作、crpo操作、mirror操作等等。
processing | train set | val set |
Shuffle | ||
數據增強(crop\mirror等) | ||
歸一化 |
- 關於model.fit
模型訓練的入口就是調用前面初始化得到的model的fit方法。接下來介紹下各參數的含義:train_data和eval_data分別表示訓練數據和測試數據。begin_epoch表示從第幾個epoch開始訓練。num_epoch表示一共要訓練多少個epoch。eval_metric和validation_metric分別表示訓練和測試時候的評價函數。kvstore默認是local。optimizer表示優化方式,默認是'sgd'。`optimizer_params`是優化相關的參數。`arg_params`和`aux_params`這兩個參數默認是None,如果想要用預訓練的模型來初始化,那麼這兩個參數就是預訓練模型的參數。`initializer`是參數初始化的方式。`allow_missing`參數默認是False,如果設置爲True,表示對於`arg_params`和`aux_params`未涉及的層採用`initializer`方式進行初始化。`batch_end_callback`參數是`mx.callback.Speedometer()`函數,該函數的作用是每隔多少個batch顯示一次結果,所以該函數主要有兩個輸入,一個是batch_size,另一個是你指定的間隔多少個batch顯示一次結果,如下代碼中是20。`epoch_end_callback`參數調用的是`mx.callback.do_checkpoint()`函數,該函數的作用是每隔period個epoch保存訓練得到的模型,因此該函數的第一個輸入是保存模型的路徑和名稱,比如下面代碼的`args.save_result+args.save_name`,第二個輸入是每隔幾個epoch保存一次模型,比如下面代碼的2,注意`period`默認值是1,常用默認值。
model.fit(train_data=train,
eval_data=val,
begin_epoch=epoch,
num_epoch=num_epoch,
eval_metric=eval_metric,
validation_metric=val_metric,
kvstore=kv,
optimizer='sgd',
optimizer_params=optimizer_params,
arg_params=arg_params,
aux_params=aux_params,
initializer=initializer,
allow_missing=True,
batch_end_callback=mx.callback.Speedometer(args.batch_size, 20),
epoch_end_callback=mx.callback.do_checkpoint(args.save_result+args.save_name,period=2))
- 關於自定義評價函數
定義:mxnet.metric.EvalMetric這個類沒有辦法直接使用,正確的打開方式是自定義一個繼承該基礎類的類,寫好評價標準後在訓練時調用這個類。
使用:無論是自己寫的還是官方提供的評價函數,都是通過mxnet.metric.CompositeEvalMetric()類的add方法來添加
from my_metric import *
eval_metric = mx.metric.CompositeEvalMetric()
eval_metric.add(Accuracy()) # 自定義的
eval_metric.add(['CrossEntropy']) # 官方的
task2 MXNet學習資料整理
task3 分析MXNet的VGG項目
項目地址:
task4 分析MXNet的SSD項目
其他筆記:argparse
argparse這個模塊做命令行選項和參數解析
其他筆記:logging
import logging
logging.info(args) # 開始訓練模型的時候打印出args中的參數信息
logger = logging.getLogger() #創建了一個Logger記錄器
logger.setLevel(logging.INFO) #設置日誌級別,logging.INFO,表示代碼正常運行時候的日誌
formatter = logging.Formatter('%(asctime)s - %(message)s')
hdlr = logging.FileHandler(args.save_result+ '/train.log') #將日誌保存在指定目錄下(args.save_result)
hdlr.setFormatter(formatter) #設置日誌的格式
logger.addHandler(hdlr) #將設置好的Handler添加到Logger對象中
console = logging.StreamHandler() #在終端輸出信息
console.setFormatter(formatter)
logger.addHandler(console)
學習過程問題記錄
本階段感想
初學者剛接觸MXNet的感受就是:網上教程和資料非常多!github\csdn博客和官網都有很多東西,但有點亂不清楚按照什麼順序來,目前對gluon和symbol還是很暈。所以我先將資料進行整理,再選出一套理論知識和代碼相結合的資料供自己學習,後續如果有疑問還能再查漏補缺。