iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
AI & Data

AI Facial Expression Recognition: Data, Model, Application系列 第 17

[Day 17] 我的資料哪有這麼平衡!第二季 (class weights)

  • 分享至 

  • xImage
  •  

前言

走過了資料分析、演算法選擇後,
我們得知了有些可以改善模型的方向:

  1. 解決資料不平衡(Now)
  2. 學習率的設定(Not yet)
  3. 訓練輪數(Not yet)
  4. 模型深度(Not yet)
  5. 階段式訓練(Not yet)

為了解決資料不平衡的問題,
昨天嘗試過資料增強,
但效果不是很明顯,
今天我將嘗試調整類別權重(class weight)。


類別權重

MSE

現在我們從損失函數(loss function)下手,
以最簡單的Mean Squared Error舉例:
0

我們現在有N筆資料,y^是預測值;y是實際值,
對於每一筆資料i來說,我們去計算預測值和實際值差的平方,
然後取平均值。(為什麼要除以2? 因為導數比較好看 :D)

class-weighted

class-weighted MSE就是在計算第i筆資料時乘以一個權重,
如果這個權重比較大,那這筆資料的loss就會影響整體loss較多。

所以只要對某一個類別的所有資料乘以一個大大的權重(W_c),

就等於這一類別影響整體loss很多。

由於最佳化理論就是在想辦法降低loss,
所以當某一類別佔據大部分的loss時,
最佳化方法降低loss時,就是在特別學習該類別的資料。

你想要哪個類別被特別關注,就把該類別的權重調大就對了!

對於資料量較少的類別(像是罕見疾病),
我們預設模型在學習辨識它們時會有困難(因為給他學的材料不夠多),
所以把資料量少的類別權重提升就對了!


程式碼

在實務上有一個簡單地決定類別權重的方式,
那就是把每一類權重設成該類資料量的倒數。

例如:

類別 資料量 類別權重
A 1 1
B 10 0.1
C 100 0.01

以下是我的實作方式,
如果有更簡單的方式歡迎提出XD

class_sample_size = [np.where(y_train == c)[0].shape[0]
                     for c in range(len(emotions.keys()))]
max_class_size = np.max(class_sample_size)
class_weight = [max_class_size/size for size in class_sample_size]
class_weight = dict(zip(emotions.keys(), class_weight))
# class_weight = 
# {0: 1.8060075093867334, 1: 16.548165137614678, 2: 1.7610446668293873, 3: 1.0, 4: 1.4937888198757765, 5: 2.275307473982971, 6: 1.4531722054380665}

上面做成一個dictionary是因為keras.fit()下參數的時候需要。

hist1 = model.fit(X_train, y_train_oh, validation_data=(X_val, y_val_oh),
                      epochs=epochs, batch_size=batch_size, class_weight=class_weight)

  • 特別說明: training時才會被class_weight影響,validation set的loss計算還是照舊。

實驗結果

訓練出來的模型就叫做EFN_classWeight。
拿來和EFN_base(baseline)做比較:

模型 | 訓練時長(秒) | acc | loss | val_acc | val_loss
------------- | ------------- | ------------- | -------------
EFN_classWeight | 2557 | 0.931 | 0.315 | 0.603 | 1.844
EFN_base | 2004 | 0.952 | 0.139 | 0.617 | 1.905

1. 驗證集準確率

結果準確率居然降低了/images/emoticon/emoticon06.gif
2

2. 驗證集損失函數值

loss果然是降低了!
3

結語

雖然說驗證集準確率降低了,
但不要忘記這是因為我們還沒"訓練完全",
從train_loss和val_loss的趨勢來看: over fitting的現象減緩了,
如果再繼續訓練個10 epochs可能就能在acc上超越EFN_base了!


上一篇
[Day 16] 我的資料哪有這麼平衡!第一季 (data augmentation)
下一篇
[Day 18] 我會把我的over fitting,drop好drop滿
系列文
AI Facial Expression Recognition: Data, Model, Application30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
WeiYuan
iT邦新手 4 級 ‧ 2021-10-02 01:53:55

好實務的問題!

謝謝~

我要留言

立即登入留言