multi task训练torch_Multi-task Learning的三个小知识
本文譯自Deep Multi-Task Learning – 3 Lessons Learned by Zohar Komarovsky
在過去幾年里,Multi-Task Learning (MTL)廣泛用于解決多個Taboola(公司名)的業務問題。在這些業務問題中, 人們使用一組相同的特征以及深度學習模型來解決MTL相關問題。在這里簡單分享一下我們做MTL時學習到的一些小知識。
小知識第一條: 整合損失函數
MTL模型中的第一個挑戰: 如何為multiple tasks定義一個統一的損失函數?
最簡單的辦法,我們可以整合不同tasks的loss function,然后簡單求和。這種方法存在一些不足,比如當模型收斂時,有一些task的表現比較好,而另外一些task的表現卻慘不忍睹。其背后的原因是不同的損失函數具有不同的尺度,某些損失函數的尺度較大,從而影響了尺度較小的損失函數發揮作用。這個問題的解決方案是把多任務損失函數“簡單求和”替換為“加權求和”。加權可以使得每個損失函數的尺度一致,但也帶來了新的問題:加權的超參難以確定。
幸運的是,有一篇論文《Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics》通過“不確定性(uncertainty)”來調整損失函數中的加權超參,使得每個任務中的損失函數具有相似的尺度。該算法的keras版本實現,詳見github。
小知識第二條:調整學習率 learning rate
在神經網絡的參數中,learning rate是一個非常重要的參數。在實踐過程中,我們發現某一個learnig rate=0.001能夠把任務A學習好,而另外一個learning rate=0.1能夠把任務B學好。選擇較大的learning rate會導致某個任務上出現dying relu;而較小的learning rate會使得某些任務上模型收斂速度過慢。怎么解決這個問題呢?對于不同的task,我們可以采用不同的learning rate。這聽上去很復雜,其實非常簡單。通常來說,訓練一個神經網絡的tensorflow代碼如下:
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)其中AdamOptimizer定義了梯度下降的方式,minimize則計算梯度并最小化損失函數。我們可以通過自定義一個minimize函數來對某個任務的變量設置合適的learning rate。
all_variables = shared_vars + a_vars + b_vars all_gradients = tf.gradients(loss, all_variables)shared_subnet_gradients = all_gradients[:len(shared_vars)] a_gradients = all_gradients[len(shared_vars):len(shared_vars + a_vars)] b_gradients = all_gradients[len(shared_vars + a_vars):]shared_subnet_optimizer = tf.train.AdamOptimizer(shared_learning_rate) a_optimizer = tf.train.AdamOptimizer(a_learning_rate) b_optimizer = tf.train.AdamOptimizer(b_learning_rate)train_shared_op = shared_subnet_optimizer.apply_gradients(zip(shared_subnet_gradients, shared_vars)) train_a_op = a_optimizer.apply_gradients(zip(a_gradients, a_vars)) train_b_op = b_optimizer.apply_gradients(zip(b_gradients, b_vars))train_op = tf.group(train_shared_op, train_a_op, train_b_op)值得一提的是,這樣的trick在單任務的神經網絡上效果也是很好的。
小知識第三條:任務A的評估作為其他任務的特征
當我們構建了一個MTL的神經網絡時,該模型對于任務A的估計可以作為任務B的一個特征。在前向傳播時,這個過程非常簡單,因為模型對于A的估計就是一個tensor,可以簡單的將這個tensor作為另一個任務的輸入。但是后向傳播時,存在著一些不同。因為我們不希望任務B的梯度傳給任務A。幸運的是,Tensorflow提供了一個API tf.stop_gradient。當計算梯度時,可以將某些tensor看成是constant常數,而非變量,從而使得其值不受梯度影響。代碼如下:
all_gradients = tf.gradients(loss, all_variables, stop_gradients=stop_tensors)再次值得一提的是,這個trick不僅僅可以在MTL的任務中使用,在很多其他任務中也都發揮著作用。比如,當訓練一個GAN模型時,我們不需要將梯度后向傳播到對抗樣本的生成過程中。
感謝閱讀,希望本文對您有所幫助! 謝謝!
如果覺得文章對您有幫助,可以關注本人的微信公眾號:機器學習小知識
總結
以上是生活随笔為你收集整理的multi task训练torch_Multi-task Learning的三个小知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 河南省大学排名一览表(哪些大学值得报考)
- 下一篇: 3l如何使用_慢阻肺患者如何选购呼吸机和