---
# System prepended metadata

title: ESUN玉山2021夏季賽 - 繁體中文手寫影像辨識

---

# 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)
