亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用PyTorch常見(jiàn)4個(gè)錯(cuò)誤解決示例詳解

 更新時(shí)間:2022年10月14日 11:21:46   作者:ronghuaiyang  
這篇文章主要為大家介紹了使用PyTorch常見(jiàn)4個(gè)錯(cuò)誤解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

導(dǎo)讀

這4個(gè)錯(cuò)誤,我敢說(shuō)大部分人都犯過(guò),希望能給大家一點(diǎn)提醒。

最常見(jiàn)的神經(jīng)網(wǎng)絡(luò)錯(cuò)誤:

1)你沒(méi)有首先嘗試過(guò)擬合單個(gè)batch。

2)你忘了為網(wǎng)絡(luò)設(shè)置train/eval模式。

3)在.backward()之前忘記了.zero_grad()(在pytorch中)。

4)將softmaxed輸出傳遞給了期望原始logits的損失,還有其他嗎???

這篇文章將逐點(diǎn)分析這些錯(cuò)誤是如何在PyTorch代碼示例中體現(xiàn)出來(lái)的。

常見(jiàn)錯(cuò)誤 #1 你沒(méi)有首先嘗試過(guò)擬合單個(gè)batch

Andrej說(shuō)我們應(yīng)該過(guò)擬合單個(gè)batch。為什么?好吧,當(dāng)你過(guò)擬合了單個(gè)batch —— 你實(shí)際上是在確保模型在工作。我不想在一個(gè)巨大的數(shù)據(jù)集上浪費(fèi)了幾個(gè)小時(shí)的訓(xùn)練時(shí)間,只是為了發(fā)現(xiàn)因?yàn)橐粋€(gè)小錯(cuò)誤,它只有50%的準(zhǔn)確性。當(dāng)你的模型完全記住輸入時(shí),你會(huì)得到的結(jié)果是對(duì)其最佳表現(xiàn)的很好的預(yù)測(cè)。

可能最佳表現(xiàn)為零,因?yàn)樵趫?zhí)行過(guò)程中拋出了一個(gè)異常。但這沒(méi)關(guān)系,因?yàn)槲覀兒芸炀湍馨l(fā)現(xiàn)問(wèn)題并解決它??偨Y(jié)一下,為什么你應(yīng)該從數(shù)據(jù)集的一個(gè)小子集開(kāi)始過(guò)擬合:

  • 發(fā)現(xiàn)bug
  • 估計(jì)最佳的可能損失和準(zhǔn)確率
  • 快速迭代

在PyTorch數(shù)據(jù)集中,你通常在dataloader上迭代。你的第一個(gè)嘗試可能是索引train_loader。

# TypeError: 'DataLoader' object does not support indexing
first_batch = train_loader[0]

你會(huì)立即看到一個(gè)錯(cuò)誤,因?yàn)镈ataLoaders希望支持網(wǎng)絡(luò)流和其他不需要索引的場(chǎng)景。所以沒(méi)有__getitem__方法,這導(dǎo)致了[0]操作失敗,然后你會(huì)嘗試將其轉(zhuǎn)換為list,這樣就可以支持索引。

# slow, wasteful
first_batch = list(train_loader)[0]

但這意味著你要評(píng)估整個(gè)數(shù)據(jù)集這會(huì)消耗你的時(shí)間和內(nèi)存。那么我們還能?chē)L試什么呢?

在Python for循環(huán)中,當(dāng)你輸入如下:

for item in iterable:
    do_stuff(item)

你有效地得到了這個(gè):

iterator = iter(iterable)
try:
    while True:
        item = next(iterator)
        do_stuff(item)
except StopIteration:
    pass

調(diào)用“iter”函數(shù)來(lái)創(chuàng)建迭代器,然后在循環(huán)中多次調(diào)用該函數(shù)的“next”來(lái)獲取下一個(gè)條目。直到我們完成時(shí),StopIteration被觸發(fā)。在這個(gè)循環(huán)中,我們只需要調(diào)用next, next, next… 。為了模擬這種行為但只獲取第一項(xiàng),我們可以使用這個(gè):

first = next(iter(iterable))

我們調(diào)用“iter”來(lái)獲得迭代器,但我們只調(diào)用“next”函數(shù)一次。注意,為了清楚起見(jiàn),我將下一個(gè)結(jié)果分配到一個(gè)名為“first”的變量中。我把這叫做“next-iter” trick。在下面的代碼中,你可以看到完整的train data loader的例子:

for batch_idx, (data, target) in enumerate(train_loader):
    # training code here<br>

下面是如何修改這個(gè)循環(huán)來(lái)使用 first-iter trick :

first_batch = next(iter(train_loader))
for batch_idx, (data, target) in enumerate([first_batch] * 50):
    # training code here

你可以看到我將“first_batch”乘以了50次,以確保我會(huì)過(guò)擬合。

常見(jiàn)錯(cuò)誤 #2: 忘記為網(wǎng)絡(luò)設(shè)置 train/eval 模式

為什么PyTorch關(guān)注我們是訓(xùn)練還是評(píng)估模型?最大的原因是dropout。這項(xiàng)技術(shù)在訓(xùn)練中隨機(jī)去除神經(jīng)元。

想象一下,如果右邊的紅色神經(jīng)元是唯一促成正確結(jié)果的神經(jīng)元。一旦我們移除紅色神經(jīng)元,它就迫使其他神經(jīng)元訓(xùn)練和學(xué)習(xí)如何在沒(méi)有紅色的情況下保持準(zhǔn)確。這種drop-out提高了最終測(cè)試的性能 —— 但它對(duì)訓(xùn)練期間的性能產(chǎn)生了負(fù)面影響,因?yàn)榫W(wǎng)絡(luò)是不全的。在運(yùn)行腳本并查看MissingLink dashobard的準(zhǔn)確性時(shí),請(qǐng)記住這一點(diǎn)。

在這個(gè)特定的例子中,似乎每50次迭代就會(huì)降低準(zhǔn)確度。

如果我們檢查一下代碼 —— 我們看到確實(shí)在train函數(shù)中設(shè)置了訓(xùn)練模式。

def train(model, optimizer, epoch, train_loader, validation_loader):
    model.train() # ????????????
    for batch_idx, (data, target) in experiment.batch_loop(iterable=train_loader):
        data, target = Variable(data), Variable(target)
        # Inference
        output = model(data)
        loss_t = F.nll_loss(output, target)
        # The iconic grad-back-step trio
        optimizer.zero_grad()
        loss_t.backward()
        optimizer.step()
        if batch_idx % args.log_interval == 0:
            train_loss = loss_t.item()
            train_accuracy = get_correct_count(output, target) * 100.0 / len(target)
            experiment.add_metric(LOSS_METRIC, train_loss)
            experiment.add_metric(ACC_METRIC, train_accuracy)
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx, len(train_loader),
                100. * batch_idx / len(train_loader), train_loss))
            with experiment.validation():
                val_loss, val_accuracy = test(model, validation_loader) # ????????????
                experiment.add_metric(LOSS_METRIC, val_loss)
                experiment.add_metric(ACC_METRIC, val_accuracy)

這個(gè)問(wèn)題不太容易注意到,在循環(huán)中我們調(diào)用了test函數(shù)。

def test(model, test_loader):
    model.eval()
    # ...

在test函數(shù)內(nèi)部,我們將模式設(shè)置為eval!這意味著,如果我們?cè)谟?xùn)練過(guò)程中調(diào)用了test函數(shù),我們就會(huì)進(jìn)eval模式,直到下一次train函數(shù)被調(diào)用。這就導(dǎo)致了每一個(gè)epoch中只有一個(gè)batch使用了drop-out ,這就導(dǎo)致了我們看到的性能下降。

修復(fù)很簡(jiǎn)單 —— 我們將model.train() 向下移動(dòng)一行,讓如訓(xùn)練循環(huán)中。理想的模式設(shè)置是盡可能接近推理步驟,以避免忘記設(shè)置它。修正后,我們的訓(xùn)練過(guò)程看起來(lái)更合理,沒(méi)有中間的峰值出現(xiàn)。請(qǐng)注意,由于使用了drop-out ,訓(xùn)練準(zhǔn)確性會(huì)低于驗(yàn)證準(zhǔn)確性。

常用的錯(cuò)誤 #3: 忘記在.backward()之前進(jìn)行.zero_grad()

當(dāng)在 “loss”張量上調(diào)用 “backward” 時(shí),你是在告訴PyTorch從loss往回走,并計(jì)算每個(gè)權(quán)重對(duì)損失的影響有多少,也就是這是計(jì)算圖中每個(gè)節(jié)點(diǎn)的梯度。使用這個(gè)梯度,我們可以最優(yōu)地更新權(quán)值。

這是它在PyTorch代碼中的樣子。最后的“step”方法將根據(jù)“backward”步驟的結(jié)果更新權(quán)重。從這段代碼中可能不明顯的是,如果我們一直在很多個(gè)batch上這么做,梯度會(huì)爆炸,我們使用的step將不斷變大。

output = model(input) # forward-pass
loss_fn.backward()    # backward-pass
optimizer.step()      # update weights by an ever growing gradient ????????????

為了避免step變得太大,我們使用 zero_grad 方法。

output = model(input) # forward-pass
optimizer.zero_grad() # reset gradient ????
loss_fn.backward()    # backward-pass
optimizer.step()      # update weights using a reasonably sized gradient ????

這可能感覺(jué)有點(diǎn)過(guò)于明顯,但它確實(shí)賦予了對(duì)梯度的精確控制。有一種方法可以確保你沒(méi)有搞混,那就是把這三個(gè)函數(shù)放在一起:

zero_grad

backward

step

在我們的代碼例子中,在完全不使用zero_grad的情況下。神經(jīng)網(wǎng)絡(luò)開(kāi)始變得更好,因?yàn)樗诟倪M(jìn),但梯度最終會(huì)爆炸,所有的更新變得越來(lái)越垃圾,直到網(wǎng)絡(luò)最終變得無(wú)用。

調(diào)用backward之后再做zero_grad。什么也沒(méi)有發(fā)生,因?yàn)槲覀儾恋袅颂荻?,所以?quán)重沒(méi)有更新。剩下的唯一有變化的是dropout。

我認(rèn)為在每次step方法被調(diào)用時(shí)自動(dòng)重置梯度是有意義的。

backward的時(shí)候不使用zero_grad的一個(gè)原因是,如果你每次調(diào)用step() 時(shí)都要多次調(diào)用backward,例如,如果你每個(gè)batch只能將一個(gè)樣本放入內(nèi)存中,那么一個(gè)梯度會(huì)噪聲太大,你想要在每個(gè)step中聚合幾個(gè)batch的梯度。另一個(gè)原因可能是在計(jì)算圖的不同部分調(diào)用backward —— 但在這種情況下,你也可以把損失加起來(lái),然后在總和上調(diào)用backward。

常見(jiàn)錯(cuò)誤 #4: 你把做完softmax的結(jié)果送到了需要原始logits的損失函數(shù)中

logits是最后一個(gè)全連接層的激活值。softmax也是同樣的激活值,但是經(jīng)過(guò)了標(biāo)準(zhǔn)化。logits值,你可以看到有些是正的,一些是負(fù)的。而log_softmax之后的值,全是負(fù)值。如果看柱狀圖的話(huà),可以看到分布式一樣的,唯一的差別就是尺度,但就是這個(gè)細(xì)微的差別,導(dǎo)致最后的數(shù)學(xué)計(jì)算完全不一樣了。但是為什么這是一個(gè)常見(jiàn)的錯(cuò)誤呢?在PyTorch的官方MNIST例子中,查看forward 方法,在最后你可以看到最后一個(gè)全連接層self.fc2,然后就是log_softmax

但是當(dāng)你查看官方的PyTorch resnet或者AlexNet模型的時(shí)候,你會(huì)發(fā)現(xiàn)這些模型在最后并沒(méi)有softmax層,最后得到就是全連接的輸出,就是logits。

這兩個(gè)的差別在文檔中沒(méi)有說(shuō)的很清楚。如果你查看nll_loss函數(shù),并沒(méi)有提得輸入是logits還是softmax,你的唯一希望是在示例代碼中發(fā)現(xiàn)nll_loss使用了log_softmax作為輸入。

以上就是使用PyTorch常見(jiàn)4個(gè)錯(cuò)誤示例詳解的詳細(xì)內(nèi)容,更多關(guān)于PyTorch常見(jiàn)4個(gè)錯(cuò)誤解決的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于Tensorflow使用CPU而不用GPU問(wèn)題的解決

    基于Tensorflow使用CPU而不用GPU問(wèn)題的解決

    今天小編就為大家分享一篇基于Tensorflow使用CPU而不用GPU問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • 使用Python開(kāi)發(fā)游戲運(yùn)行腳本成功調(diào)用大漠插件

    使用Python開(kāi)發(fā)游戲運(yùn)行腳本成功調(diào)用大漠插件

    閑來(lái)無(wú)事,想通過(guò)python來(lái)實(shí)現(xiàn)一些簡(jiǎn)單的游戲輔助腳本,而游戲輔助腳本的主要原理就是通過(guò)程序來(lái)查找游戲程序窗口,模擬實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊和鍵盤(pán)按鍵等事件來(lái)實(shí)現(xiàn)游戲輔助的,對(duì)Python開(kāi)發(fā)游戲運(yùn)行腳本相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • Python日期時(shí)間對(duì)象轉(zhuǎn)換為字符串的實(shí)例

    Python日期時(shí)間對(duì)象轉(zhuǎn)換為字符串的實(shí)例

    今天小編就為大家分享一篇Python日期時(shí)間對(duì)象轉(zhuǎn)換為字符串的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • sklearn和keras的數(shù)據(jù)切分與交叉驗(yàn)證的實(shí)例詳解

    sklearn和keras的數(shù)據(jù)切分與交叉驗(yàn)證的實(shí)例詳解

    這篇文章主要介紹了sklearn和keras的數(shù)據(jù)切分與交叉驗(yàn)證的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • 如何使用?Python?Pandas?更新行和列

    如何使用?Python?Pandas?更新行和列

    這篇文章主要介紹了使用?Python?Pandas?更新行和列的方法,在整篇文章中,我們將使用我們現(xiàn)在要?jiǎng)?chuàng)建的數(shù)據(jù)框,這將使大家了解更新數(shù)據(jù)操作,在此之后,大家可以將這些方法應(yīng)用于自己的數(shù)據(jù),需要的朋友可以參考下
    2023-03-03
  • Python進(jìn)階學(xué)習(xí)之特殊方法實(shí)例詳析

    Python進(jìn)階學(xué)習(xí)之特殊方法實(shí)例詳析

    一般說(shuō)來(lái),特殊的方法都被用來(lái)模仿某個(gè)行為。下面這篇文章主要給大家介紹了關(guān)于Python進(jìn)階學(xué)習(xí)之特殊方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起看看吧。
    2017-12-12
  • 利用Python實(shí)現(xiàn)Windows定時(shí)關(guān)機(jī)功能

    利用Python實(shí)現(xiàn)Windows定時(shí)關(guān)機(jī)功能

    是最初的幾個(gè)爬蟲(chóng),讓我認(rèn)識(shí)了Python這個(gè)新朋友,雖然才剛認(rèn)識(shí)了幾天,但感覺(jué)有種莫名的默契感。下面通過(guò)這篇文章給大家介紹Python實(shí)現(xiàn)Windows定時(shí)關(guān)機(jī)功能,需要的朋友可以參考下
    2017-03-03
  • python 實(shí)現(xiàn)自動(dòng)遠(yuǎn)程登陸scp文件實(shí)例代碼

    python 實(shí)現(xiàn)自動(dòng)遠(yuǎn)程登陸scp文件實(shí)例代碼

    這篇文章主要介紹了python 實(shí)現(xiàn)自動(dòng)遠(yuǎn)程登陸scp文件實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Python的Django框架中URLconf相關(guān)的一些技巧整理

    Python的Django框架中URLconf相關(guān)的一些技巧整理

    這篇文章主要介紹了Python的Django框架中URLconf相關(guān)的一些技巧整理,包括視圖配置和debug的示例等,需要的朋友可以參考下
    2015-07-07
  • python同步兩個(gè)文件夾下的內(nèi)容

    python同步兩個(gè)文件夾下的內(nèi)容

    這篇文章主要為大家詳細(xì)介紹了python同步兩個(gè)文件夾下的內(nèi)容,包括子文件夾,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論