本篇文章主要講解本身的圖像數據如何在TnesorFlow上訓練,主要從數據準備、訓練模型、驗證準確率和導出模型並對圖片分類。重點以下:node
原理
對於新手來講,在本身的數據集上訓練一個模型時,最簡單的方法是在ImageNet的模型上進行微調。什麼是微調呢?以VGG16爲例,它的結構爲5部分卷積層共13層(conv1 ~ conv5)和3層的全鏈接層(fc6 ~ fc8),一共16層,所以被稱爲VGG16。
若是將VGG16的結構用於一個新的數據集,就要去掉最後一層的全鏈接層,由於最後一層全鏈接層的輸入是前一層的特徵,輸出的是1000類的機率,正好對應了ImageNet中的1000個類別,可是在這裏,咱們的類別只有6種,因此要去掉最後一層全鏈接層,採用一個更符合數據類別的全鏈接層。
這時,網絡參數的初始化值就不是隨機生成的了,而是利用VGG16在ImageNet上已經訓練好的參數做爲訓練的初始值。由於ImageNet訓練集上的VGG16已經包含了大量有用的卷積過濾器,使用已存在的參數不久節約時間,也有助於提升分類器的性能。python
訓練範圍
在載入參數後,咱們能夠指定訓練層數範圍,訓練層數可選範圍以下:git
只訓練fc8這一層,保持其餘層的參數不變,將VGG16做爲一個特徵提取器,用fc7層提起的特徵作Softmax分類,這樣作有利提升訓練速度,可是性能不是最佳的;github
訓練全部參數,對網絡中的全部參數都進行訓練,性能得以提升,深度模型得以充分發揮,可是速度太慢;web
訓練部分參數,固定淺層參數不變,訓練深層參數。shell
以上這三種方法就是神經網絡的微調,經過微調能夠將神經網絡經過以有模型應用到本身的數據集上。數據庫
python data_convert.py -t pic/ --train-shards 2 --validation-shards 2 --num-threads 2 --dataset-name satellite
解釋一下上面參數的含義:瀏覽器
參數 | 含義 |
---|---|
-t pic/ | 指定要轉換的數據所在的文件夾,這個文件夾下必須有一個訓練目錄和一個驗證目錄,而且每一個目錄按類別存放圖片數據 |
–train-shards 2 | 將訓練數據集分爲兩塊,也就是說轉換完格式後訓練數據集將會是兩個tfrecord格式的文件【注2】 |
–validation-shards 2 | 將驗證數據集分爲兩塊 |
–num-threads 2 | 採用兩個線程生產數據【注3】 |
–dataset-name:satellite | 給轉換後的數據集起一個名字 |
運行命令後,pic文件夾下會出現五個新的數據文件,以 satellite_train_ 開頭的訓練據文件和以 satellite_validation_ 開頭的驗證數據文件,而且還包含一個label.txt文件,表示圖片的標籤數字到真實類別字符串的映射順序。例如tfrecod中圖片標籤爲0,就表明類別爲label.txt中的第一行類別。網絡
注1:
文件下載地址:下載文件svg
注2:
若是訓練數據集較大,則能夠將訓練數據集劃分爲多個數據塊
注3:
線程數量必須能整除train-shars和validation-shards,這樣才能抱枕每一個線程中數據塊的數量相等
git clone ht仁ps://github.corn/tensorflow/models.git
,我所提供的下載地址中也有Slim源碼。將 Slim 文件夾複製到根目錄下便可。代碼結構以下:文件名/文件夾名 | 說明 |
---|---|
datasets/ | 訓練時須要用到的數據庫,訓練本身的數據時必須在這裏進行定義本身的數據庫 |
nets/ | 經常使用的網絡結構 |
preprocessing/ | 針對不一樣網絡定義了不一樣的預處理數據的方法 |
scripts/ | 訓練示例腳本 |
train_image_classificer.py | 訓練模型入口 |
eval_image_classificer.py | 驗證模型性能入口 |
download_and_convert_data.py | 下載並轉換數據及各式入口 |
# 數據的文件名 _FILE_PATTERN = 'satellite_%s_*.tfrecord' # 訓練集和驗證集的數量 SPLITS_TO_SIZE = {'train':4800,'validation':1200} # 數據集中圖片的類別數目 _NUM_CLASSES = 6
# 設定圖片格式 'image/format' : tf.FixedLenFeature((),tf.string,default_value = 'jpg')
from datasets import cifar10 from datasets import flowers from datasets import imagenet from datasets import mnist # 將satellite模塊添加進來 from datasets import satellite # satellite 數據庫加入進來 datasets_map = { 'cifar10':cifar10, 'flowers':flowers, 'imagenet':imagenet, 'mnist':mnist, 'satellite':satellite }
準備訓練文件夾
在slim文件夾下新建 satellite 目錄、satellite/data(訓練和驗證數據文件夾)、satellite/train_dir(保存訓練日誌和模型文件夾)、satellite/pretrained。建立完目錄後須要完成如下工做:
將轉換好格式的數據(包括label.txt)複製 satellite/data 文件夾
下載Inception V3模型,下載地址是:下載地址,解壓後,將inception_v3.ckpt文件複製到 satellite/pretrained
訓練程序
在slim文件夾下啓動命令行,輸入以下命令開始訓練(代碼須要在TensorFlow GPU版本上運行):
python train_image_classifier.py --train_dir=satellite/train_dir --dataset_name=satellite --dataset_split_name=train --dataset_dir=satellite/data --model_name=inception_v3 --checkpoint_path=satellite/pretrained/inception_v3.ckpt --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits --trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits --max_number_of_steps=100000 --batch_size=32 --learning_rate=0.001 --learning_rate_decay_type=fixed --save_interval_secs=300 --save_summaries_secs=2 --log_every_n_steps=10 --optimizer=rmsprop --weight_decay=0.00004
解釋一下上面參數的含義:
參數 | 說明 |
---|---|
–trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits | 指定模型微調變量的範圍。這裏指設定表示只對 InceptionV3/Logits 和 InceptionV3/AuxLogits 兩個變量微調,也就是對fc8進行微調,若是不設置此參數,將會對全部參數進行訓練。 |
–train_dir=satellite/train_dir | 在 satellite/train_dir 目錄下保存日誌和模型文件(heckpoint) |
–dataset_name=satellite、–datasets_split_name=train | 指定訓練數據集 |
–dataset_dir=satellite/data | 訓練數據集保存的位置 |
–model_name=inception_v3 | 使用的模型名稱 |
–checkpoint_path=satellite/pretrained/inception_v3.ckpt | 預訓練模型保存的位置 |
–checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits | 恢復預訓練模型時不回覆這兩層,由於這兩層模型對應着ImageNet數據集的1000類,與當前數據集不符,因此不要恢復他 |
–max_number_of_steps 100000 | 最大執行步數 |
–batch_size=32 | 每步的batch數量 |
–learning_rate=0.001 | 學習率 |
–learning_rate_decay_type=fixed | 學習率是否降低,此處固定學習率 |
–save_interval_secs=300 | 每隔300秒保存一次模型,保存到train_dir目錄下 |
–save_summaries_secs=2 | 每隔2秒保存一第二天志 |
–log_every_n_steps=10 | 每隔10步在屏幕上打印出訓練信息 |
–optimizer=rmsprop | 指定優化器 |
–weight_decay=0.00004 | 設定weight_decay,即模型中全部參數的二次正則化超參數 |
注4:
開始訓練時,若是訓練文件夾(satellite/train_dir)裏沒有保存的模型,就會自動加載 checkpoint_path 中的預訓練模型,而後程序會把初始模型保存在train_dir中,命名爲 model.ckpt-0,0表示第0步。以後每隔300秒就會保存一次模型,因爲模型較大,因此只會保留最新的5個模型。若是中斷程序運行後再次運行,會首先檢查train_dir文件夾中是否存在模型,若是存在則接着存在的模型開始訓練。
python eval_image_classifier.py --checkpoint_path=satellite/train_dir --eval_dir=statellite/eval_dir --dataset_name=satellite --dataset_split_name=validation --dataset_dir=satellite/data --model_name=inception_v3
下面來解釋一下參數
參數 | 說明 |
---|---|
–checkpoint_path=satellite/train_dir | 參數能夠接收目錄路徑或者文件路徑。若是是一個目錄路徑,則會查找這個目錄下最新的模型 |
–eval_dir=satellite/eval_dir | 執行結果日誌的保存目錄 |
–dataset_dir=satellite/data | 驗證數據集保存位置 |
–model_name=inception_v3 | 使用的模型 |
執行後會打印出以下內容:
eval/Accuracy[0.51] eval/Recall_5[0.973333336]
Accuracy表示模型的分類準確率,Recall_5表示前5次的準確率
tensorboard --logdir satellite/train_dir
在TensorBoard中能夠查看損失變化曲線,損失變化曲線有助於調整參數。若是損失曲線比動較大,沒法收斂,就有可能時學習率過大,適當減少學習率就好了。
如今作以下操做:
tensorboard --logdir satellite/train_dir
瀏覽器打開TensorBoard就能夠看到狂歌模型的損失曲線,上方的爲只訓練末端的損失數,下方爲訓練全部層的損失函數。看損失函數能夠看出訓練全部層比只訓練末端要好。
模型訓練完以後,將會進行部署。這裏提供了兩個文件 freeze_graph.py 和 classify_image_inception_v3.py 前者用於導出識別模型,後者用於識別單張圖片。在slim文件夾下執行以下命令:
python export_inference_graph.py --alsologtostderr --model_name=inception_v3 --output_file=satellite/inception_v3_inf_graph.pb --dataset_name satellite
命令執行後,會在satellite文件夾下生成一個 inception_v3_inf_graph.pb 文件,可是這個文件不包含訓練得到的模型參數,須要將cheeckpoint中的模型參數保存進來,方法是使用freeze_graph.py:
python freeze_graph.py --input_graph slim/satellite/inception_v3export_inference_graph.pb --input_checkpoint slim/satellite/train_dir/model.ckpt-5271 --input_binary true --output_node_names InceptionV3/Predictions/Reshape_1 --output_graph slim/satellite/frozen_graph.pb
這裏講解一下參數:
參數 | 說明 |
---|---|
–input_graph slim/satellite/inception_v3_inf_graph.pb | 使用的網絡結構文件(前一步已經導出) |
–input_checkpoint slim/satellite/train_dir/model.ckpt-5271 | 指定載入到網絡結構中的checkpoint參數 |
–input_binary true | 使用網絡結構文件是二進制仍是文本形式 |
–output_node_names InceptionV3/Predictions/Reshape_1 | 是Inception V3最後的輸出層 |
–output_graph slim/satellite/frozen_graph.pb | 導出模型的文件 |
下面開始對圖片進行識別。命令行執行腳本 classify_image_inception_v3.py ,運行以下命令:
python classify_image_inception_v3.py --model_path slim/statellite/frozen_graph.pb --label_path data_preoare/pic/label.txt --image_file test_image.jpg
講解參數:
參數 | 說明 |
---|---|
–model_path slim/statellite/frozen_graph.pb | 導入訓練好的模型 |
–label_path data_preoare/pic/label.txt | 將–model_path輸出的結果轉換爲對應的名稱 |
–image_file test_image.jpg | 要識別的圖片 |
執行完參數後,將輸出每種類別的機率。
首先簡要介紹了微調神經網絡的基本原理,接着詳細介紹瞭如何使用 TensorFlow Slim 微調預訓練模型,包括數據準備、定義新的 datasets 文件、訓練、 驗證 、 導出模型井測試單張圖片等。