摘要:本次實踐基於 mobilenetV2 實現貓狗圖像分類,貫穿了數據集獲取及處理、預訓練模型微調及遷移、端側部署及推理等環節和知識點,體會到了 MindSpore 簡單的開發體驗和全場景快速部署的魅力。
- startTime: 2021年1月23日00:43:22
- endTime: 2021年1月23日11:34:44
(包含學習、睡覺、吃飯、爬坑、水文……的時間)
了解MindSpore開源生態
發現一個小秘密。 github 上多三個倉庫,是什么呢?
此處應是 github 過濾的 bug ,實際上mindspore-ai 有 15 個倉庫, 比 gitee 多出來的三個是:mindspore-21-days-tutorials、 mail_templates、 infrastructure
別看這 3 個不起眼的倉庫,在社區建設方面卻大有作為。比如,mindspore-21-days-tutorials 是我們之前參加 21 天實戰營的參考代碼和指導文檔,多么寶貴的學習資料;另外兩個是 MindSpore 的開源基礎建設,其中 infrastructure 包含了用於配置 Mindspore 社區的所有必需 Dockerfile 和 YAML 文件,並借助 Github 的 Action 定時自動同步 Gitee 的代碼到 Github 。
訓練時長截圖
手機識別截圖
學習總結
在學習之前我以為我會了,但真正實踐起來還是磕磕碰碰,所有的代碼似曾相識,都是 26 個字母加一些符號組成,但真正去理解還是發現基本功不夠:一是不知道怎么寫,二是不知道為什么要這么寫。盡管如此,我大概理順了整個實踐流程:訓練貓狗圖像分類模型(雲端) --> 手機端推理及應用 --> 從 “1” 開始 Fine Tune 模型(本地) --> 手機端驗證 ,當然作為學渣,整個操作過程肯定不止一個小時, 深刻體會到“眼睛:學會了,腦子:學廢了!”,因此必須借此帖記錄一下“學廢了”的過程:
目的
本次實踐基於 mobilenetV2 實現貓狗圖像分類,貫穿了數據集獲取及處理、預訓練模型微調及遷移、端側部署及推理等環節和知識點,體會到了 MindSpore 簡單的開發體驗和全場景快速部署的魅力。
項目目錄
MindSporePetClassification ├─ ADB // 支持手機與電腦傳遞文件工具 │ ├─ adb.exe │ ├─ AdbWinApi.dll │ ├─ AdbWinUsbApi.dll │ └─ fastboot.exe ├─ code // Fine tune訓練代碼及數據集 │ ├─ dataset │ │ ├─ PetImages │ │ │ ├─ eval │ │ │ │ ├─ Cat │ │ │ │ └─ Dog │ │ │ ├─ train │ │ │ │ ├─ Cat │ │ │ │ └─ Dog │ │ ├─ MSR-LA - 3467.docx │ │ └─ readme[1].txt │ ├─ src │ │ ├─ __pycache__ │ │ │ ├─ args.cpython-37.pyc │ │ │ ├─ config.cpython-37.pyc │ │ │ ├─ dataset.cpython-37.pyc │ │ │ ├─ lr_generator.cpython-37.pyc │ │ │ ├─ mobilenetV2.cpython-37.pyc │ │ │ ├─ models.cpython-37.pyc │ │ │ └─ utils.cpython-37.pyc │ │ ├─ args.py │ │ ├─ config.py │ │ ├─ dataset.py │ │ ├─ lr_generator.py │ │ ├─ mobilenetV2.py │ │ ├─ models.py │ │ └─ utils.py │ ├─ mobilenetV2.ckpt // 預訓練模型文件 │ ├─ preprocessing_dataset.py // 預先處理數據集腳本 │ └─ train.py // 主訓練腳本 ├─ converter // 轉換工具MindSpore Lite Converter │ ├─ converter_lite.exe │ ├─ libgcc_s_seh-1.dll │ ├─ libglog.dll │ ├─ libmindspore_gvar.dll │ ├─ libssp-0.dll │ ├─ libstdc++-6.dll │ └─ libwinpthread-1.dll └─ kagglecatsanddogs_3367a.zip
依賴安裝
本次實踐依賴opencv-python 和 matplotlib,一個用來處理圖形比如打印圖片和嵌入文字,一個用來將數據集以可視化圖片的形式展現出來。
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
數據預處理
主要刪除一些不符合要求(如非JPEG格式)的圖片並分割 train 和 eval 數據集,默認9:1:
python preprocessing_dataset.py 您的路徑\kagglecatsaData to Dragnddogs_3367a.zip
Fine tune
執行Fine tune腳本train.py,並生成模型文件:
python train.py
此時會彈窗提示6張圖片,這是因為腳本會在正式訓練前從數據集中抽取6張圖片載入當前模型文件,需要手動關閉才能繼續,這是 AI 很傻,全都識別成了 Dog 。
當然,我這邊由於機器的原因,沒少踩坑,這不“出師未捷身先死”,突然的報錯把我整蒙了,將所有num_parallel_workers參數設置為4之后,繼續訓練!
$ python train.py start cache feature! Traceback (most recent call last): File "train.py", line 52, in <module> data, step_size = extract_features(backbone_net, args_opt.dataset_path, config) File "F:\dosomethings\serverless\ModelArts\MIndSpore\MindSporePetClassification\MindSporePetClassification\code\src\dataset.py", line 84, in extract_features train_dataset = create_dataset(dataset_path=os.path.join(dataset_path, "train"), do_train=True, config=config) File "F:\dosomethings\serverless\ModelArts\MIndSpore\MindSporePetClassification\MindSporePetClassification\code\src\dataset.py", line 41, in create_dataset ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) File "C:\Users\huqi\AppData\Local\Programs\Python\Python37\lib\site-packages\mindspore\dataset\engine\validators.py", line 51, in new_method validate_dataset_param_value(nreq_param_int, param_dict, int) File "C:\Users\huqi\AppData\Local\Programs\Python\Python37\lib\site-packages\mindspore\dataset\core\validator_helpers.py", line 352, in validate_dataset_param_value check_num_parallel_workers(param_dict.get(param_name)) File "C:\Users\huqi\AppData\Local\Programs\Python\Python37\lib\site-packages\mindspore\dataset\core\validator_helpers.py", line 340, in check_num_parallel_workers raise ValueError("num_parallel_workers exceeds the boundary between 1 and {}!".format(cpu_count())) ValueError: num_parallel_workers exceeds the boundary between 1 and 4!
這一步耗時就和本地機器的性能有關了,我的粗糧渣渣機大概跑廢了。趁着訓練的空檔,學習了一些代碼。作為新晉調參學徒,我大概知道參數和配置在code\src\args.py和code\src\config.py這兩個文件,而數據的加載在code\src\dataset.py這個文件處理,code\src\mobilenetV2.py定義了模型,code\src\models.py這個文件讀取和保存模型並打印輸出訓練日志。
訓練完成會,又會調用predict_from_net方法來顯示預測的圖片和標簽,這回我們發現 AI 挺棒的,全部識別正確! 當我滿懷信心點擊關閉的時候,以為程序立馬會給我一個mobilenetv2.mindir,結果我又蒙了,返回了一串錯誤日志!!!
early stop! the best epoch is 2 train total cost 4141.2663 s Traceback (most recent call last): File "train.py", line 81, in <module> export_mindir(net, "mobilenetv2") File "F:\dosomethings\serverless\ModelArts\MIndSpore\MindSporePetClassification\MindSporePetClassification\code\src\utils.py", line 93, in export_mindir export(net, Tensor(input_np), file_name=path, file_format='MINDIR') File "C:\Users\huqi\AppData\Local\Programs\Python\Python37\lib\site-packages\mindspore\train\serialization.py", line 535, in export Validator.check_file_name_by_regular(file_name) File "C:\Users\huqi\AppData\Local\Programs\Python\Python37\lib\site-packages\mindspore\_checkparam.py", line 438, in check_file_name_by_regular target, prim_name, reg, flag)) ValueError: 'F:\dosomethings\serverless\ModelArts\MIndSpore\MindSporePetClassification\MindSporePetClassification\code\mobilenetv2.mindir' is illegal, it should be match regular'^[0-9a-zA-Z\_\-\.\/\\]+$' by flags'256'
一開始我以為是文件層級太深了,將文件目錄遷移到盤的根目錄,重來重來!好在不需要再次加載數據集了,不然又得漫長的等待。 滿懷信心結果又被“啪啪啪”打臉,之后群里請教一遍之后,王輝老師建議我把路徑改成文件名再試試,果然立馬奏效~
- path = os.path.abspath(f"{name}.mindir") + path = name
終於如願以償,code\mobilenetv2.mindir她來了!
手機端推理及應用
- 訓練模型轉換
將.mindir模型文件轉換成.ms文件,.ms文件可以導入端側設備並基於MindSpore端側框架訓練。
F:\MindSporePetClassification\converter>call converter_lite --fmk=MINDIR --modelFile=f:\MindSporePetClassification\code\mobilenetv2.mindir --outputFile=pet
我們可以下載 MindSpore 官方提供的 Android APP 源碼: https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/pet_classification
或者直接下載打包好的 APP 安裝到手機: https://download.mindspore.cn/model_zoo/official/lite/apk/pet/petclassification.apk
先體驗下預訓練模型的識別效果:
接着我們把轉換好的模型移動到手機端的/sdcard/PetClassification,這里用到的是 ADB 工具:需要確保手機已開啟開發者模式並打開文件傳輸
F:\MindSporePetClassification\converter>adb push f:\MindSporePetClassification\converter\pet.ms /sdcard/PetClassification * daemon not running; starting now at tcp:5037 * daemon started successfully f:\MindSporePetClassification\converter\pet.ms: 1 file pushed, 0 skipped. 43.4 MB/s (8900552 bytes in 0.196s)
再試試識別效果:
對本次實踐 APP 端代碼感興趣的小伙伴可以直接去閱讀源碼: https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/lite/pet_classification/app/src/main/java/com/mindspore/classificationforpet/widget/MainActivity.java
本文分享自華為雲社區《Copy攻城獅1小時入門AI開發工程師》,原文作者:胡琦。