multi task训练torch_Multi-task Learning的三个小知识
本文譯自Deep Multi-Task Learning – 3 Lessons Learned by Zohar Komarovsky
在過去幾年里,Multi-Task Learning (MTL)廣泛用于解決多個(gè)Taboola(公司名)的業(yè)務(wù)問題。在這些業(yè)務(wù)問題中, 人們使用一組相同的特征以及深度學(xué)習(xí)模型來解決MTL相關(guān)問題。在這里簡單分享一下我們做MTL時(shí)學(xué)習(xí)到的一些小知識(shí)。
小知識(shí)第一條: 整合損失函數(shù)
MTL模型中的第一個(gè)挑戰(zhàn): 如何為multiple tasks定義一個(gè)統(tǒng)一的損失函數(shù)?
最簡單的辦法,我們可以整合不同tasks的loss function,然后簡單求和。這種方法存在一些不足,比如當(dāng)模型收斂時(shí),有一些task的表現(xiàn)比較好,而另外一些task的表現(xiàn)卻慘不忍睹。其背后的原因是不同的損失函數(shù)具有不同的尺度,某些損失函數(shù)的尺度較大,從而影響了尺度較小的損失函數(shù)發(fā)揮作用。這個(gè)問題的解決方案是把多任務(wù)損失函數(shù)“簡單求和”替換為“加權(quán)求和”。加權(quán)可以使得每個(gè)損失函數(shù)的尺度一致,但也帶來了新的問題:加權(quán)的超參難以確定。
幸運(yùn)的是,有一篇論文《Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics》通過“不確定性(uncertainty)”來調(diào)整損失函數(shù)中的加權(quán)超參,使得每個(gè)任務(wù)中的損失函數(shù)具有相似的尺度。該算法的keras版本實(shí)現(xiàn),詳見github。
小知識(shí)第二條:調(diào)整學(xué)習(xí)率 learning rate
在神經(jīng)網(wǎng)絡(luò)的參數(shù)中,learning rate是一個(gè)非常重要的參數(shù)。在實(shí)踐過程中,我們發(fā)現(xiàn)某一個(gè)learnig rate=0.001能夠把任務(wù)A學(xué)習(xí)好,而另外一個(gè)learning rate=0.1能夠把任務(wù)B學(xué)好。選擇較大的learning rate會(huì)導(dǎo)致某個(gè)任務(wù)上出現(xiàn)dying relu;而較小的learning rate會(huì)使得某些任務(wù)上模型收斂速度過慢。怎么解決這個(gè)問題呢?對于不同的task,我們可以采用不同的learning rate。這聽上去很復(fù)雜,其實(shí)非常簡單。通常來說,訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)的tensorflow代碼如下:
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)其中AdamOptimizer定義了梯度下降的方式,minimize則計(jì)算梯度并最小化損失函數(shù)。我們可以通過自定義一個(gè)minimize函數(shù)來對某個(gè)任務(wù)的變量設(shè)置合適的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在單任務(wù)的神經(jīng)網(wǎng)絡(luò)上效果也是很好的。
小知識(shí)第三條:任務(wù)A的評(píng)估作為其他任務(wù)的特征
當(dāng)我們構(gòu)建了一個(gè)MTL的神經(jīng)網(wǎng)絡(luò)時(shí),該模型對于任務(wù)A的估計(jì)可以作為任務(wù)B的一個(gè)特征。在前向傳播時(shí),這個(gè)過程非常簡單,因?yàn)槟P蛯τ贏的估計(jì)就是一個(gè)tensor,可以簡單的將這個(gè)tensor作為另一個(gè)任務(wù)的輸入。但是后向傳播時(shí),存在著一些不同。因?yàn)槲覀儾幌M蝿?wù)B的梯度傳給任務(wù)A。幸運(yùn)的是,Tensorflow提供了一個(gè)API tf.stop_gradient。當(dāng)計(jì)算梯度時(shí),可以將某些tensor看成是constant常數(shù),而非變量,從而使得其值不受梯度影響。代碼如下:
all_gradients = tf.gradients(loss, all_variables, stop_gradients=stop_tensors)再次值得一提的是,這個(gè)trick不僅僅可以在MTL的任務(wù)中使用,在很多其他任務(wù)中也都發(fā)揮著作用。比如,當(dāng)訓(xùn)練一個(gè)GAN模型時(shí),我們不需要將梯度后向傳播到對抗樣本的生成過程中。
感謝閱讀,希望本文對您有所幫助! 謝謝!
如果覺得文章對您有幫助,可以關(guān)注本人的微信公眾號(hào):機(jī)器學(xué)習(xí)小知識(shí)
總結(jié)
以上是生活随笔為你收集整理的multi task训练torch_Multi-task Learning的三个小知识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 河南省大学排名一览表(哪些大学值得报考)
- 下一篇: 小米手机2价格(小米手机价格大全2022