# ESUN玉山2021夏季賽 - 繁體中文手寫影像辨識 [- T-Brain 玉山人工智慧挑戰賽2021夏季賽](https://tbrain.trendmicro.com.tw/Competitions/Details/14) 在比賽截止前2個禮拜才參賽 一人用google colab(pytorch) 訓練模型 難免有點倉促 還有許多改進空間可以再努力! :::info **隊名:ownjohn** **最後成績: 25/468 (前5%)** **macro average f1 score: 94%** ::: ## 作法紀錄 ### 競賽介紹 - goal: 屬分類題目,將已切割的中文手寫字圖片 分到正確的類別 - class: 訓練資料共800類(約7w張) 但測試時會出現非訓練資料的字集,需將他分到"**isnull**"類 所以預測結果會是==801==類 ### 資料集 #### training data dic.txt ![](https://i.imgur.com/hKCS8K3.png =x200) 800個字(label) #### 模型訓練資料.tar 共68804張圖片,800個字(cls) - 檔名格式: ``` 864_蔣.jpg 49604_群.jpg 10699_聰.jpg 20854_科.jpg 25140_人.jpg ``` - 圖: ![](https://i.imgur.com/kvIin8D.png =x300) - 觀察: 圖片w,h不固定, 筆跡顏色不同, 沒置中對齊, 切割後不完整, 一圖多字 會有一些雜格線, 躺著的字也可能會出現, 有許多誤標, 有非手寫的印刷字 ![](https://i.imgur.com/DjbIlYE.png =x100) - 各類張數分佈:同一類別最多100張 ![](https://i.imgur.com/EPTY0M3.png =x250) --- ### 步驟 **1. 清資料** 很多錯標/一圖多字/切割不完整的字,用人工方式盡量清理 每個class皆按張數切成`train:vali:test = 7:2:1` **2. 使用resnet18架構 (224x224)** 當作初版baseline **3. 調整訓練參數及threshold** -learning rate -調整分到"isnull"的threshold ``` ### ex: 此模型的threshold設為0.35較適當 ### (若prob<0.35的就分到"isnull") "./model/0617_224_best.pth" 0.1: 0.930 0.2: 0.936 0.25: 0.94308 0.3: 0.94308 0.35: 0.94359 ------v 0.4: 0.941 0.5: 0.938 0.6: 0.930 0.7: 0.915 ``` **4. 驗證結果** 測試在自己的test data **5. 後續有做的調整** - **增加data augmentation** 隨機微幅 旋轉(-20~20度)/形變/色彩(亮度,對比,飽和)/裁剪 ![](https://i.imgur.com/IgtnyFm.png =250x) - **嘗試其他 input size** 用colab訓練 有的訓練時間會太長 inputsize太大的模型 inference時會超時 - **嘗試其他模型架構** resnet50, vgg, InceptionResNetV2, ... - **pesudo labeling** prob 夠高的 instance 貼到離他類別最近的class上 - **持續加新資料**(來自每日比賽的test data) 清理並加入finetune ### training 結果 - 分兩版 dataset - data(v0): 原始資料,尚未清理 - data(v1): 清理過一些的原始資料(v0),加上清理過的day1 day2資料, 當作新版的train data - log ![](https://i.imgur.com/Fr57mXa.png) - accuracy ![](https://i.imgur.com/sGtVi0N.png =300x) - 訓練時間: resnet18, 224x224, 25 epoch --> 329m(5hr) resnet18, 100x100, 25 epoch --> 150m(2.5hr) resnet50, 100x100, 25 epoch --> 179m(3hr) ## future work 有些小技巧來自得獎隊伍 ### 1. 蒐集更多data #### 清理原始資料 很多組花許多人力在清理資料上 多人分工標資料 且 同一張會多人確認 #### 生成更多資料 800類以內/以外的 皆可增加數量 有些隊伍將擴增類別至4k類 - 外部資料集: 大多簡體字集 [CASIA](http://www.nlpr.ia.ac.cn/databases/handwriting/Home.html) [AI-FREE-Team繁體中文手寫資料集](https://github.com/AI-FREE-Team/Traditional-Chinese-Handwriting-Dataset) [KMNIST](http://codh.rois.ac.jp/kmnist/) [GitHub: kirosc/chinese-calligraphy-dataset](https://github.com/kirosc/chinese-calligraphy-dataset/) - 自己人工手寫 - 利用現成電腦字型 - GAN生成 - 生成轉換:用cycleGAN生成新資料(v100 train 12小時) 再調色調讓他跟玉山場景很像 或 合成到多種現成底圖上 - 風格轉換:starGANv2 >第一名隊伍是採用 1:3 官方:合成 ### 2. 資料前處理 #### 色調 - 調成此場景:黃色背景貼藍色的字 - 全轉灰階 #### 加 模糊/雜訊 紅格線 雜點 #### 改變圖片切法 有的圖片旁邊有很大空白,可以研究新切法 或 前面多接detection >第一名隊伍是採用64x128的大小, 其他大多為128x128, 224x224的方形 ### 3. 模型架構 - 多試幾種架構 做k-fold 最後做==ensemble== - 許多隊伍使用 ==Efficientnet==系列 其他還有 inception v3, [HCCR](https://github.com/pavlo-melnyk/offline-HCCR) - 第三名隊伍很特別用==arcface== 套用人臉辨識模型arcface的架構(適合資料少類別多) isnull: 距離每個中心點都不近的 `embedding 190x256 --> ArcMarginProduct 256x num_cls` ### 4. 其他 #### "isnull"類的規則調整 - 可==切分成更多小類== 最後再合併成"isnull"類 加入常用字讓模型學會辨識沒有出現在比賽中的字,還有信心太低的也當作isnull - 可對每一類設定==不同的threshold==,降低誤判成isnull的部份 - isnull是否要自成一類? ## 結語 感謝玉山銀行與T-Brain用心的舉辦此競賽 賽後交流會也是非常精心規劃的 技術長親自參與對談,可見玉山對技術交流活動的重視! gather打造的各個活動區域,讓大家能自由的與其他參賽者交流學習 也展現了玉山各個單位與技術成果,收穫滿滿! ![](https://i.imgur.com/uxrZwke.png =x250) ![](https://i.imgur.com/0Cn4OVN.png =x250)