使用tensorflow訓練模式識別圖片中的物件(object-detection)
開始前準備:強烈推薦使用 anaconda 來做 python 的環境管理工具,它裡面自帶了很多科學計算的類庫,可以避免很多不必要的問題
顯示卡:我的顯示卡是 gtx960 最多隻能訓練10批次的資料,再多了視訊記憶體就不足了,唉。。
下載圖片
百度,谷歌都行,搜尋一些圖片,下載下來,放在 images
資料夾裡,我這裡用貓跟狗的圖片來訓練,我下載了40張圖,20張貓,20張狗的圖片
標記圖片
下載labelimg工具,下載地址: https://github.com/tzutalin/labelImg
用法見readme裡的介紹,標記好之後,圖片資料夾裡會生成跟圖片數量相等的 xml 檔案
然後在 images
資料夾裡新建兩個資料夾 train
test
訓練跟測試比例按照 4:1 來分一下剛才標記的圖片,這個比例一般是 10:1 的比例,也就是10張訓練圖,1張測試的,我這圖太少,就4:1來分了
注意:圖片分開之後,原圖還要在images資料夾裡留著,也就是說,分圖片的要用複製,不能用剪下,否則後面生成tfrecord檔案的時候會報錯
生成CSV
這一步將上一步標記圖片生成的 xml 收集起來生成一個 csv 檔案
開啟 raccoon_dataset 專案,將裡面的 xml_to_csv.py
檔案複製出來,開啟修改裡面的內容如下:
這時候可以再建立一個資料夾 cat_dog
將 images
資料夾複製進去,然後將 xml_to_csv.py
儲存在 cat_dog
資料夾裡,再在 cat_dog
資料夾裡建立一個 data
的資料夾用來放生成的 csv 檔案
# 將下面這部分 def main(): image_path = os.path.join(os.getcwd(), 'annotations') xml_df = xml_to_csv(image_path) xml_df.to_csv('raccoon_labels.csv', index=None) print('Successfully converted xml to csv.') # 修改成下面這樣 def main(): for directory in ['train', 'test']: image_path = os.path.join(os.getcwd(), 'images/{}'.format(directory)) xml_df = xml_to_csv(image_path) xml_df.to_csv('data/{}_labels.csv'.format(directory), index=None) print('Successfully converted xml to csv.')
開啟一個終端,你可以用cmd,powershell,或者直接在 anaconda 的 navigator 裡啟動一個自己建立好環境的終端,我這裡用的是git bash
conda create -n tf python=3.5 source activate tf python xml_to_csv.py
成功後,終端裡會輸出下面資訊
$ python xml_to_csv.py Successfully converted xml to csv. Successfully converted xml to csv. (tf)
生成tfrecord檔案
還是 raccoon_dataset 專案,將裡面的 generate_tfrecord.py
檔案拷貝到 cat_dog
資料夾下,並修改內容如下
# 將下面內容 # TO-DO replace this with label map def class_text_to_int(row_label): if row_label == 'raccoon': return 1 else: None # 修改成下面這樣 # TO-DO replace this with label map def class_text_to_int(row_label): if row_label == 'cat': return 1 elif row_label == 'dog': return 2 else: None
然後執行下面兩條命令,生成 train.tfrecord
test.tfrecord
兩個檔案,成功的話,終端裡會輸出下面資訊
$ python generate_tfrecord.py --csv_input=data/train_labels.csv--output_path=data/train.record Successfully created the TFRecords: C:\Users\liygh\Desktop\cat_dog\data\train.record (tf) liygh@DESKTOP-DI1356Q MINGW64 ~/Desktop/cat_dog $ python generate_tfrecord.py --csv_input=data/test_labels.csv--output_path=data/test.record Successfully created the TFRecords: C:\Users\liygh\Desktop\cat_dog\data\test.record (tf)
安裝model
下載 tensorflow 組織下的 models 專案 https://github.com/tensorflow/models 不嫌卡的可以 git clone 嫌卡的,直接下載zip包就可以了
下載下來解壓,我這裡放在桌面上了
然後下載一個 protobuf ,下面要用到 protoc 命令,下載地址: https://github.com/protocolbuffers/protobuf/releases 解壓,配置環境變數,這裡就跳過了
在終端裡執行 protoc --version
命令,如果有輸出 版本資訊,就安裝好了
PS: 如果環境變數配置好了,要把終端退了,再重新開啟一下終端,它才會載入剛配置的環境變數,注意要再執行一次 source activate tf
進入tf環境
下面在終端裡進入到 models-master/research
目錄裡執行命令來編譯: protoc object_detection/protos/*.proto --python_out=.
然後新增類庫到 PYTHONPATH 環境變數裡, 還是在 research
目錄下執行 export PYTHONPATH=$PYTHONPATH:
pwd :
pwd /slim
遺憾的是 windows 上這樣還是不行的,還要執行下面兩條命令
- 在
research
目錄下執行python setup.py install
- 在
research/slim
目錄下執行python setup.py build
然後執行python setup.py install
下載訓練的配置檔案
下載檔案 ssd_mobilenet_v1_pets.config 和 下載訓練模式 ssd_mobilenet_v1_coco
其中 ssd_mobilenet_v1_pets.config
地址: https://github.com/tensorflow/models/blob/master/research/object_detection/samples/configs/ssd_mobilenet_v1_pets.config
ssd_mobilenet_v1_coco
地址: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
將下載的 ssd_mobilenet_v1_pets.config
和解壓後的 ssd_mobilenet_v1_coco
都放在前面建立的 cat_dog
資料夾裡
修改 ssd_mobilenet_v1_pets.config
檔案的內容
# 找到 num_classes: 37 # 將其修改成 2 , 我這裡就兩個分類,貓跟狗 # 找到 num_steps: 200000 # 這個是訓練步數,預設給的是20萬步,我這改成 2000 步,你可以根據自己的需求來修改 num_steps: 2000 # 找到 fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt" # 修改為 fine_tune_checkpoint: "ssd_mobilenet_v1_coco_2018_01_28/model.ckpt" # 找到 train_input_reader: { tf_record_input_reader { input_path: "PATH_TO_BE_CONFIGURED/pet_faces_train.record-?????-of-00010" } label_map_path: "PATH_TO_BE_CONFIGURED/pet_label_map.pbtxt" } # 修改為 train_input_reader: { tf_record_input_reader { input_path: "data/train.record" } label_map_path: "data/object-detection.pbtxt" } # 找到 eval_input_reader: { tf_record_input_reader { input_path: "PATH_TO_BE_CONFIGURED/pet_faces_val.record-?????-of-00010" } label_map_path: "PATH_TO_BE_CONFIGURED/pet_label_map.pbtxt" shuffle: false num_readers: 1 } # 修改為 eval_input_reader: { tf_record_input_reader { input_path: "data/test.record" } label_map_path: "data/object-detection.pbtxt" shuffle: false num_readers: 1 }
下面在 data
資料夾下建立 object-detection.pbtxt
檔案, 填上下面內容
item { id: 1 name: 'cat' } item { id: 2 name: 'dog' }
拷貝檔案
將 cat_dog
資料夾下的 data
images
ssd_mobilenet_v1_pets.config
ssd_mobilenet_v1_coco_2018_01_28
都複製到下載的 models 資料夾下 ,具體路徑是 models-master/research/object_detection
下面
然後在 object-detection
資料夾下新建一個資料夾 training
用來存放訓練結果的
開始訓練
執行命令: python legacy/train.py --logtostderr --train_dir=training/ --pipeline_config_path=ssd_mobilenet_v1_pets.config
開始訓練
過程如下, 我的顯示卡是 gtx960 大概是 1.5s/step
識別過程中,可以檢視訓練日誌等資訊,執行命令 tensorboard --logdir=training/
然後瀏覽器執行 http://localhost:6006
就可以查看了
匯出模型工具
執行下面命令將訓練結果匯出一個用來識別圖片的工具,在cat_dog_graph資料夾裡
python export_inference_graph.py \ --input_type image_tensor \ --pipeline_config_path ssd_mobilenet_v1_pets.config \ --trained_checkpoint_prefix training/model.ckpt-2000 \ --output_directory cat_dog_graph
識別圖片
再下載幾張貓狗的圖片,命名為 image{數字}.jpg 放在 object-detection
下的 test_images
資料夾下
在 object-detection
資料夾下執行命令 jupyter notebook
在自動開啟的瀏覽器頁面裡開啟 object_detection_tutorial.ipynb
檔案並進行如下修改
# 找到 MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17' # 修改為 MODEL_NAME = 'cat_dog_graph' # 刪除下面兩行 MODEL_FILE = MODEL_NAME + '.tar.gz' DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/' # 找到 PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt') # 修改為 PATH_TO_LABELS = os.path.join('data', 'object-detection.pbtxt') # 找到 NUM_CLASSES = 90 # 修改為 NUM_CLASSES = 2 # 找到下面內容然後全部註釋掉 opener = urllib.request.URLopener() opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE) tar_file = tarfile.open(MODEL_FILE) for file in tar_file.getmembers(): file_name = os.path.basename(file.name) if 'frozen_inference_graph.pb' in file_name: tar_file.extract(file, os.getcwd()) # 找到 TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ] # 修改為 TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 8) ]
然後在jupyter裡執行這個檔案,等待片刻即可看到識別的效果
參考
- 5GeCQnxYnSSaar2tpku" rel="nofollow,noindex" target="_blank">https://www.youtube.com/watch?v=COlbP62-B-U&list=PLQVvvaa0QuDcNK5GeCQnxYnSSaar2tpku
- https://github.com/tensorflow/models
原文連結: