MXNet學習筆記——1 inference全過程

寫在前面

本系列博客記錄了作者上手MXNet的全過程。作者在接觸MXNet之前主要使用keras,和一點tensorflow,因此在上手MXNet之前有一點deep learning的項目基礎。主要參考資料爲MXNet官方教程,也閱讀了一些有價值的博客。

博客結構爲:先列出作者對於該階段的期望目標,以及各目標完成過程中的筆記(僅記下個人認爲重要的),再附上學習過程中自己的提問(solved & unsolved,天馬行空的提問,歡迎討論)。


本階段目標

任務 優先級 預計花時間 完成狀態 遇到問題 補充
瞭解MXNet中模型的整個inference過程   4hour \checkmark    
MXNet學習資料整理整理 P0 1.5hour \checkmark    
分析VGG案例 P1 2hour      
分析SSD案例 P2 3hour      

具體筆記

task1 體會整個inference過程

數據 準備數據 使用mx.io.ImageRecordIter()來讀取  
數據預處理    
網絡 預訓練模型導入

使用mx.model.load_checkpoint()導入預訓練模型

訓練好的模型參數是用.params文件保存,網絡結構是用.json文件保存

sym, arg_params, aux_params = mx.model.load_checkpoint('resnet-50', epoch)
#輸出sym是網絡結構,arg_params和aux_params是預訓練模型的參數信息
 
模型結構修改

get_fine_tune_model()函數進行修改

 

def get_fine_tune_model(sym, num_classes, layer_name):
    all_layers = sym.get_internals() # 獲取所有層信息
    net = all_layers[layer_name+'_output']
    net = mx.symbol.FullyConnected(data=net, num_hidden=num_classes, name='fc')# 給截取後的結構末尾加上一層
    net = mx.symbol.SoftmaxOutput(data=net, name='softmax')
    return net
new_sym = get_fine_tune_model(sym, args.num_classes, 'flatten'

 

 
模型參數初始化

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筆記  
開始訓練

model.fit

 

 
  • 關於兩種數據格式
`.rec`文件 `.lst`和圖像結合的方式
pro con pro con
比較穩定,移植到別的電腦上也能復現 佔空間(差不多1萬張圖像生成的.rec文件是1G),而且增刪數據不大靈活 讀取靈活且不佔空間
  • 如果圖像格式不符合要求的話容易出錯
  • 如果列表中的某些圖像路徑對應的圖像被刪除,就會出錯
  • 如果你不是從固態硬盤上讀取圖像的話,速度會很慢
  • 關於訓練集和測試集的處理

trainval數據集比較大的區別一方面是val數據集不需要做shuffle操作,另一方面在最後的預處理操作中不需要類似cropmirror等數據增強操作,但是歸一化操作(mean=True和std=True)在`train`和`val`數據集中要麼都做,要麼都不做,建議都做。另外要提一下最後一個參數aug_list,這個參數的輸入是mx.image.CreateAugmenter()函數,這個函數就是該類中管理數據預處理的函數,可以看到在下面的代碼中添加了輸入圖像尺寸:(3,224,224)、resize操作、crpo操作、mirror操作等等。

processing train set val set
Shuffle \checkmark \times
數據增強(crop\mirror等) \checkmark \times
歸一化 \checkmark \checkmark
  • 關於model.fit

模型訓練的入口就是調用前面初始化得到的modelfit方法。接下來介紹下各參數的含義:train_dataeval_data分別表示訓練數據和測試數據。begin_epoch表示從第幾個epoch開始訓練。num_epoch表示一共要訓練多少個epoch。eval_metricvalidation_metric分別表示訓練和測試時候的評價函數。kvstore默認是localoptimizer表示優化方式,默認是'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還是很暈。所以我先將資料進行整理,再選出一套理論知識和代碼相結合的資料供自己學習,後續如果有疑問還能再查漏補缺。

參考資料

  1. dive into deep learning,基於Apache MXNet對深度學習算法進行實現,內容詳實,代碼實現;中文版《動手學深度學習》
  2. MXNet官方教程中文翻譯版本
  3. github資料,教程、模型以及預訓練weight
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章