--- title: Hand Posture Recognition with CNN - 以CNN解決手勢辨識問題 tags: Fundamental Deep Learning Assignments 2019, NDHU, CSIE lang: zh_tw --- # Hand Posture Recognition with CNN - 以CNN解決手勢辨識問題 ##### Table of Contents [TOC] [code]: https://github.com/how8570/Hand-Posture-Recognition-with-CNN ## 0x00. Before Start - 在開始之前 - 環境建置 參考自 [林鈺錦大大分享的環境配置](https://hackmd.io/@abc1236762/HJAozs9pB) 以及我自行需要的套件 ```shell conda create -n deeplearn --strict-channel-priority python=3.6 tensorflow-gpu=1.14 keras numpy=1.16 pydot opencv jupyter pylint autopep8 matplotlab pillow scikit-learn ``` - [完整原始碼][code] > 這次我們用上了熟悉的 keras 套件完成 CNN 分類辨識問題。在這次的實作中要求,是利用 CNN 分辨出三種不同的手勢。 >[name=how8570] ## 0x01. Problem Descriptions - 問題解釋 - 本次的作業來自 **東華大學2019年度的深度學習導論** 的課堂作業 - [這裡是原題 \[可能需要 東華e學院 帳號才能存取\] ](http://web.csie.ndhu.edu.tw/ccchiang/Data/fdl_assignment2.pdf) - 問題描述: (來自原題)<br>![](https://i.imgur.com/v6kEClS.png) [資料集 \[可能需要 東華e學院 帳號才能存取\]](http://web.csie.ndhu.edu.tw/ccchiang/Data/All_gray_1_32_32.rar) ## 0x02. Solutions - 解決思路 - 由於這次我們很開心的可以使用套件了 ~~所以當然是先 import keras~~ 所以這的最大問題當然是在資料前處理的部分了 - 因為資料要分成測試跟訓練的部分,然後我檢查了一下資料集的數量 ![](https://i.imgur.com/YAjnX29.png) 摁...有點少阿... - 於是為了增加資料量我在處理圖片時增加了 <U>**垂直鏡像**</U> 的處理 實作如下 ```python= def get_train_datas(): train_data = [] train_label = [] for gen_path in itertools.product(path_of_TrainSets, path_of_type, path_of_dataID): path = 'All_gray_1_32_32/' + '/'.join(gen_path) + '/' for img in os.listdir(path): if img.endswith('jpg'): path += img train_data.append(mpimg.imread(path)) # 垂直鏡射增加資料集 train_data.append(mpimg.imread(path)[:,::-1]) if gen_path[1] in ('0000', '0001', '0002'): train_label.append(0) train_label.append(0) # 別忘了一次是生兩張圖 label 也要加兩次 elif gen_path[1] in ('0003', '0004', '0005'): train_label.append(1) train_label.append(1) elif gen_path[1] in ('0006', '0007', '0008'): train_label.append(2) train_label.append(2) return np.array(train_data), np.array(train_label) ``` - 模型設計部分 ![](https://i.imgur.com/g3yRtKd.png) 我以兩層捲積 (Conv2D) 連上三層的全連接層 (Dense) 的架構建置該模型,並在其中插入池化 (Maxpooling) 以期望更良好的抓取特徵,插入丟棄層 (Dropout) 以避免過度學習 (Overfitting)。 - 其他細節請參考 [完整原始碼](code) ## 0x03 Result - 實現成果 - 雖然在我寫作業之前,同寢室的同學一直跟我嚷嚷著他的 **訓練成果是 1** ,如此誇張之高。雖然第一時間覺得是 Overfitting,但讓我心裡備感壓力。 - 而在最初還沒有增加資料時時做辨識率大概只有 83%~85% ,讓我直懷疑我以前在修其他課程所學到的經驗是不是有些出入? - 於是我就去向其他人請教他們的 code 怎麼樣的一回事,發現大部分的同學好像都誤會於老師的題目要求 (或是是我誤會?) - 他們在使用 fit 函數時,將 validation_data 的參數置入 (test_data, vali_label) 範例:`model.fit(x, y, validation_data=(test_data, vali_label), ...)` 這也意味著這些測試資料並不是被用來測試的。 上方的意思如果用比喻來說的話,那就是: - 1.我們訓練 小明 考數學 目標考到100分 2.給了小明考古題 (有題目/有答案) 3.考另一個題庫出的小考 (小考內容是類似的題目,但不曾出現在考古題中),並告訴小明,這題你寫對了還是寫錯了。 4.重複3.直到設定的次數 - 但是這過程中其實已經讓小明 **類似利用試錯法** 的方式 **得知這些題庫小考題目解法**,及意味著 **如果有辦法訓練到 1.0,通常是 Overfitting**。( [issue 連結](https://github.com/keras-team/keras/issues/1753) 有提到相關內容) - 這樣可能導致我們在訓練模型時選出過度符合這些資料集(訓練+測試)的模型 - 關於我理解的 test_data 的使用方式 - 我們應該是把 train_data 分成 train_feature 與 vali_features 兩個部分。訓練完模型後再使用 test_data 這份全新的考題來校驗我們的 model 的準確率 - 而我使用這個方式來核對我的模型正確率如下: 左邊是 loss 右邊是 正確率 ![](https://i.imgur.com/DMx3czZ.png) - 雖然數字看起來低了不少,但我認為這才是 **真正有意義的正確率** ,不是唬爛的數字 - 詳情疑問可以參考這邊 - [issue (多數支持放心在 validation_data 使用 test data)](https://github.com/keras-team/keras/issues/1753) - [簡書上的內容 (支持不應該使用)](https://www.jianshu.com/p/0c7af5fbcf72) - 圖片的部分 ![](https://i.imgur.com/He91Cet.png ) ## 0x04 Summary - 後計與總結 - 在嘗試鏡像原始資料集時,原本預期可能效果沒有這麼好,畢竟右手拇指會在左邊,手整個方向會不一樣。沒想到卻還是提升了不少準確率,可見對於 model 的特徵抽取來說,拇指在哪似乎不是這麼重要 ~~,可以把它切了~~。 - 雖然這次的作業好像砲火猛烈 XD ,但我覺得好像真的是大家誤會了題目的意思。 ## 0x05 Tools and Reference - 工具與參考項目 - Tools - IDE: [Visual Studio Code](https://code.visualstudio.com/) - Git Remote repository: [GitHub](https://github.com/) - Reference - lecture slide - [Wikipedia](https://www.wikipedia.org/) - [keras 中文 doc](https://keras.io/zh/) - [簡書](https://www.jianshu.com/) > [name=how8570] > [time=Thu, Dec 19, 2019 3:37 AM] <style> span.hidden-xs:after { content: ' × NDHU AI' !important; } </style>