本周是深度學(xué)習(xí)實(shí)驗(yàn)課的最后一次課,讓我們回顧一下在這個(gè)學(xué)期中大家都學(xué)習(xí)到了哪些內(nèi)容烁巫。在前面的課程中我們首先了解了神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)赖舟,如何去搭建神經(jīng)網(wǎng)絡(luò),怎樣去訓(xùn)練神經(jīng)網(wǎng)絡(luò)喉脖,以及神經(jīng)網(wǎng)絡(luò)的優(yōu)化椰苟、微調(diào)。緊接著我們又學(xué)習(xí)了深度學(xué)習(xí)領(lǐng)域當(dāng)前比較流行的幾個(gè)大方向树叽,例如分類舆蝴、語義分割、目標(biāo)檢測(cè)题诵、對(duì)抗神經(jīng)網(wǎng)絡(luò)洁仗、自然語言處理等等。接下來的內(nèi)容是對(duì)我們所學(xué)的知識(shí)的一個(gè)總結(jié)和升華性锭。
1.神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)內(nèi)容
1.框架
當(dāng)前訓(xùn)練神經(jīng)網(wǎng)絡(luò)的框架有許多赠潦,例如tensorflow, caffe, pytorch等等,由于pytorch上手簡(jiǎn)單草冈,使用方便她奥,所以本門課程選擇的框架是pytorch.
2.神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)單元
在pytorch框架中,神經(jīng)網(wǎng)絡(luò)的最基本的單元是張量(tensor), 由于框架本身已經(jīng)實(shí)現(xiàn)了反向傳播的機(jī)制怎棱,所以我們?cè)诖罱ňW(wǎng)絡(luò)的過程中只需將大部分精力放在正向傳播上哩俭,不太需要關(guān)心反向傳播(梯度消失,梯度爆炸問題除外)拳恋。
3.如何去搭建一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)
import torch
import torch.nn as nn
import torch.optim as optim
class Net(nn.Module):
def __init__(self, *args):
self.layer1 = nn.Conv2d(3,64,kernel_size=3, stride=1,padding=0, bias=True)
self.avg_pool = nn.AvgPool2d(4)
self.layer2 = nn.Linear(64,10)
def forward(self, x):
out = self.layer1(x)
out = out.view(x.size(0), -1)
out = self.layer2(out)
return out
4.如何去訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)
LR = 0.01
BATCH_SIZE = 32
EPOCH = 10
net = Net()
optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9, weight_decay=5e-4)
criterion = nn.CrossEntropyLoss()
for i in range(EPOCH):
for data in enumerate(dataloader):
x, y = data
x, y = x.cuda(), y.cuda()
# 模型預(yù)測(cè)結(jié)果
y_hat = net(x)
# 計(jì)算loss值
loss = criterion(y, y_hat)
# 清空優(yōu)化器凡资,必須在反向傳播前進(jìn)行
optimizer.zero_grad()
# 反向傳播
loss[0].backward()
# 更新網(wǎng)絡(luò)參數(shù)
optimizer.step()
'''
這部分根據(jù)個(gè)人需求添加自己的代碼,可以實(shí)現(xiàn)打印當(dāng)前epoch的loss值谬运,
在訓(xùn)練集上的準(zhǔn)確率隙赁,在驗(yàn)證集上的準(zhǔn)確率垦藏,繪圖等等操作
'''
在以上訓(xùn)練過程中,值得大家注意的是:
建議大家同時(shí)打印出模型在訓(xùn)練集和測(cè)試集上的準(zhǔn)確率伞访,有些同學(xué)只關(guān)注在測(cè)試集上的準(zhǔn)確率膝藕,忽略了在訓(xùn)練集上的準(zhǔn)確率,導(dǎo)致可能出現(xiàn)一種情況咐扭,在測(cè)試集上的準(zhǔn)確率不夠理想芭挽,就懷疑是模型或者是其他什么地方出了問題。這個(gè)時(shí)候我們應(yīng)該看看在訓(xùn)練集上的準(zhǔn)確率如何蝗肪,如果模型在訓(xùn)練集上表現(xiàn)的結(jié)果都不是很好袜爪,說明模型根本就沒有訓(xùn)練好,又怎么能期望它能夠在測(cè)試集上表現(xiàn)得好呢薛闪?這個(gè)時(shí)候我們首先應(yīng)該想辦法讓模型在訓(xùn)練集的準(zhǔn)確率達(dá)到99%以上(分類網(wǎng)絡(luò)一般都可以達(dá)到近乎100%)辛馆。這是初學(xué)者很容易犯的一個(gè)低級(jí)錯(cuò)誤,希望能夠引起大家的重視豁延。
5.模型訓(xùn)練的基本技巧
- 設(shè)置隨機(jī)種子昙篙,確保可以復(fù)現(xiàn)結(jié)果
- k折交叉驗(yàn)證诱咏,驗(yàn)證模型的泛化能力
- 數(shù)據(jù)預(yù)處理中的均值和方差的設(shè)置(目前有兩種較常用的做法苔可,一種是使用pretrain_model數(shù)據(jù)集的均值和方差,一種是使用自己數(shù)據(jù)集的均值和方差袋狞,哪種效果更好焚辅,實(shí)踐出真知)
- 數(shù)據(jù)增強(qiáng),關(guān)于transforms里面眾多函數(shù)的使用苟鸯,也是根據(jù)數(shù)據(jù)集而定同蜻,建議大家多多嘗試,
- 模型的初始化早处,如果使用的模型提供了pretrain_model建議大家充分利用湾蔓,可以加速收斂,如果想重新訓(xùn)練就要考慮torch.nn.init里面的眾多初始化方法
- 模型修改砌梆,根據(jù)自己的需求結(jié)合理論知識(shí)修改網(wǎng)絡(luò)默责,這部分內(nèi)容需要大家進(jìn)行多次實(shí)驗(yàn),找到適合自己數(shù)據(jù)集的較好的模型
- 優(yōu)化器么库,一般來說分類網(wǎng)絡(luò)我們常用sgd和adam兩種優(yōu)化器傻丝,沒有絕對(duì)的定論哪種更好。sgd的缺點(diǎn)是收斂可能要慢一些诉儒,如果調(diào)整得當(dāng)可以得到比較好的結(jié)果,adam收斂速度快一些亏掀,但是結(jié)果可能略遜于sgd
- batch_size忱反,較大的batch_size才能充分發(fā)揮網(wǎng)絡(luò)中bn層的作用泛释,但是消耗的gpu資源也越多
- learning_rate,學(xué)習(xí)率是網(wǎng)絡(luò)訓(xùn)練過程中至關(guān)重要的參數(shù),面對(duì)不同的batch_size温算,不同的優(yōu)化方式怜校,不同的數(shù)據(jù)集其最合適的值都是不確定的,我們無法僅憑經(jīng)驗(yàn)來準(zhǔn)確地得出lr值注竿,能做的就是多做實(shí)驗(yàn)(可以參考的做法:觀察訓(xùn)練過程中l(wèi)oss值和accuracy值茄茁,如果兩者都上升到一定高度后趨于平緩,這個(gè)時(shí)候可以考慮調(diào)低lr巩割,經(jīng)過多次實(shí)驗(yàn)后裙顽,大致可得出lr在何時(shí)可能需要衰減)
- lr與bs的關(guān)系,一般越大的bs使用越大的lr宣谈,因?yàn)樵酱蟮腷s意味著我們學(xué)習(xí)的時(shí)候愈犹,收斂方向的confidence越大,我們前進(jìn)的方向更加堅(jiān)定闻丑,而較小的bs則顯得比較雜亂漩怎,無規(guī)律性,因此bs較小的時(shí)候需要小的學(xué)習(xí)率保證不至于出錯(cuò)
- 模型保存嗦嗡,模型的保存分為兩種勋锤,一種是保存整個(gè)模型,另一種是保存模型的參數(shù)侥祭,一般建議保存模型的參數(shù)怪得,因?yàn)槟P偷膮?shù)更便于我們靈活地去加載(比如之前提到的只加載部分模型參數(shù)),另外卑硫,模型的參數(shù)實(shí)際上是以字典的形式保存下來的徒恋。
以上內(nèi)容基本上在14周課件中都有實(shí)現(xiàn)
6.訓(xùn)練的高級(jí)技巧
- 過擬合,過擬合典型的表現(xiàn)為訓(xùn)練集損失遠(yuǎn)遠(yuǎn)小于驗(yàn)證集損失欢伏,而欠擬合則表現(xiàn)為訓(xùn)練集損失大于驗(yàn)證集損失入挣,記住是遠(yuǎn)遠(yuǎn)大于,而不是說訓(xùn)練集損失稍微大于驗(yàn)證集損失就判斷為過擬合硝拧。舉個(gè)例子径筏,如果遇到訓(xùn)練集損失為0.8,驗(yàn)證集損失為2.0障陶,則可以判斷為過擬合
- dropout滋恬,dropout可以減輕過擬合現(xiàn)象,但請(qǐng)不要無腦使用抱究,dropout一般適合全連接層部分恢氯,而卷積層由于參數(shù)不是很多,所以不太需要dropout,加上的話對(duì)模型的泛化能力沒有太大影響勋拟。
- 難例挖掘勋磕,在深度學(xué)習(xí)任務(wù)中,我們可能會(huì)遇到一些比較’棘手‘的數(shù)據(jù)敢靡,這些數(shù)據(jù)相比較于其他數(shù)據(jù)更難識(shí)別挂滓,他們稱為hard-negative。我們先使用初始的正負(fù)樣本訓(xùn)練分類器啸胧,然后再用訓(xùn)練出的分類器對(duì)樣本進(jìn)行分類赶站,把其中負(fù)樣本錯(cuò)誤分類的那些樣本(hard-negative)放入負(fù)樣本集合,再繼續(xù)訓(xùn)練分類器纺念,如此反復(fù)贝椿,直到達(dá)到到停止條件(比如分類器性能不再提升)
- 嘗試過擬合一個(gè)小數(shù)據(jù)集,關(guān)閉正則化柠辞、隨機(jī)失活团秽、數(shù)據(jù)擴(kuò)充,使用訓(xùn)練集的一小部分叭首,讓神經(jīng)網(wǎng)絡(luò)訓(xùn)練幾個(gè)周期习勤。確保出現(xiàn)零損失,如果沒有焙格,那么很可能什么地方出錯(cuò)了(經(jīng)典的小trick)
一個(gè)很具體的問題
第12次作業(yè)图毕,數(shù)據(jù)預(yù)處理和decoder輸出內(nèi)容轉(zhuǎn)換成文本的過程
網(wǎng)絡(luò)輸出是詞向量,通過查詢字典(embedding)可以轉(zhuǎn)換成對(duì)應(yīng)的index(整數(shù))眷唉,再查詢預(yù)先定義的index和詞的對(duì)應(yīng)關(guān)系予颤,可以找到原始對(duì)應(yīng)的單詞