這次與人工智慧學校第八期的學員們一起組隊參與了這個競賽,這篇會分享一下我們這組是怎麼做的
1. 題目說明
- 辨識圖檔中文字內容。
- 所有文字皆須回覆「繁體字」。
- 在正式賽的題目中,若該圖片中文字未存在於主辦單位提供之「training data dic」(800 種類別),請以 string 格式回覆 ”isnull”。
- 訓練資料集中的檔名不一定為該圖片中的正確 label,請參賽者務必做資料清理。
2. 原始資料 (raw data)
玉山提供的手寫資料集總共有 68803 筆資料,這邊取出 25 筆資料給各位看,如 圖一 所示:
可以看到資料相當的雜亂,有以下狀況,這邊取出一些代表性的範例,如 圖二 所示:
- 訓練集檔名不是該圖片的正確 label
- 一張圖片出現一個字以上
- 背景雜亂
- 圖片上為簡體字 (日文漢字居多)
- 字醜到人眼看不出來
3. 資料清洗
我們經由工人智慧 (勞力) 把資料清洗,把訓練資料集分成 3 個資料夾,包含:
- Correct: 放正確的字
- Error: 放 1, 2, 5 的狀況
- Simple: 放 4 的狀況
最後我們拿 Correct 裡的字來訓練。
4. 資料前處理
剛剛還有一個背景雜亂的問題,由於想去除背景只保留字體的部分,所以使用 U-2-NET 來進行文字的前景背景切割。首先需要自己生成訓練集資料,我使用 Single_char_image_generator 來生成訓練集資料,先給他自己挑的一些複雜背景,再把字塞進去,就可以產生訓練資料與對應的 mask
訓練出來的效果還不錯,都可以有效去除背景,如 圖六 所示
再經由一些演算法來將字包覆的更好,並使得圖片是正方形的,這樣丟進模型訓練時就不會讓字體變形,效果如 圖七 所示。
這樣就完成我們的資料前處理了。
4. 分類模型
最後就是丟分類模型來訓練了,主辦單位總共訂出了 800 個類別,在訓練之前由於有資料不平衡的部分,所以使用 Single_char_image_generator 來生成資料,最後將每個類別補成 100 張圖片,如 圖八 所示
在訓練部分,這邊使用 efficientnet B0 來訓練,原本想使用比較新的模型 nfnet,但是 tensorflow 2.5 還沒有收錄進去,我就沒去另外找 repo 來訓練,訓練的結果也相當好,可以達到 0.98 的準確率,如 圖九 所示
而這比賽還有一件比較難處理的地方,就是若圖片的類別不在這 800 個字中的話需要預測為 isnull,這邊採取的作法也是很簡單,若 confidence 低於一個 theshold 的話就判斷成 isnull。
總結
總體來說,這個競賽還是滿好玩的,謝謝人工智慧學校第八期的學員們邀請我一起參加這個比賽,雖然最後因為 isnull 處理的太過粗糙而導致最後效果沒有很好,感覺是可以加一些常用字進去一起訓練,如果是那 800 個字以外的再判斷成 isnull 效果應該會好上許多,另外由於時間關係,日文漢字的部分沒有額外處理,原本是想說將常見的日文漢字 (用 Single_char_image_generator 生成日文漢字資料集) 也丟進來訓練,最後再轉換成繁體字也是個不錯的做法。