# Catastrophic Forgetting & Life-long learning ## Catastrophic Forgetting 遇到的問題:學一個任務後,Fine-tune在第二個任務上,再回去驗證第一個任務,發現做得很差 最暴力的解法:Multi-task -> 把所有 Task 的資料都倒在一起,用所有資料來 train 但非常沒有效率!只要拿到新資料就要重來,等於是學生要學新知識就把一生看過所有書再看一遍 Storage 和 Computation 的限制! ## Life-long learning(LLL) 希望可以在不複習舊資料的情況下,一個 Model 可以解多個曾經學過的任務 希望不要每次有新任務,就要去重看所有以前的資料才學起來 可以把 Multi-task 資料倒在一起的效果當作 Upper Bound,想辦法逼近那樣的效果 ### 評估 Life-long learning 能力 ![image](https://hackmd.io/_uploads/SkIPntseR.png) 建立表格,三個評斷標準: * Accuracy:Train 完 Task T 後,Test on all tasks 的平均 * Backward transfer:Train 完 Task T 後,Test on 前面的 Task 的 Accuracy 減掉剛 train 該 Task 時的 Acc(通常是負的) * forward transfer:在還沒 Train 過某個任務,到底對沒學過的任務學到什麼程度? ## 方法:Selective Synaptic Plasticity(選擇突觸可塑性) 基本概念:有一些參數對原本的任務特別重要,就盡量不要變 ![image](https://hackmd.io/_uploads/HJYoecsx0.png) 簡單來講,如果參數更新方直接偏向 Task 2 Loss 低的地方,有可能就不適合 Task 1 但如果可以限制更新方向,走到對於 Task 1 和 Task 2 都低的地方,可能就可以防止遺忘 實作:給每個參數一個保鏢(guard)$b_i$,並定義新的 Loss: ![image](https://hackmd.io/_uploads/HkyjMqje0.png) 如果 $b_i$ 越大,參數越不能隨意移動(動了 Loss 就會變大) 相反的,如果 $b_i$ 越小,參數就比較不會受到限制 而 $b_i$ 是人給定的,但是該如何給 $b_i$ 是比較好的呢? ### 訂定 $b_i$ 的算法 * Elastic Weight Consolidation(EWC 彈性權重合併) * Synaptic Intelligence(SI) * Memory Aware Synapses (MAS) * RWalk Extra: 限制 Gradient 方向 instead of 限制參數更新 -> Gradient Episodic Memory (GEM) (需要存少量的舊任務資料來算 Gradient 方向) ### 其他比較不同的做法: * Progressive Neural Network ![image](https://hackmd.io/_uploads/B1erw9oeR.png) 任務增加時,就擴增 Model 來做新任務,不去動已經 Train 好的 該擴增的部分從原本 Model 的 hidden layer 接出來 但 Model 終究會變得太大 * Packnet 先開一個比較大的 Network,每一次任務的訓練只開放一部分的參數來用 ### Memory Replay ![image](https://hackmd.io/_uploads/HyQKOqig0.png) 同時訓練 Generator,可以產生前面任務的資料 後面在訓練新 Task 的時候,同時 Generate 出舊 Task 的資料混在裡面訓練 李宏毅:這個做法其實非常有效 (想法:如果不想另外 train generator 那就乾脆混少量舊資料進去吧) ## Other references 如果新任務的 Classes 比舊任務多怎麼辦: * Learning Without Forgetting(LwF):[Paper](https://arxiv.org/pdf/1904.07734.pdf) * iCaRL(Incremental Classifier and Representation Learning) ### Train 的任務順序 Matters ![image](https://hackmd.io/_uploads/SJZK95oxR.png)