国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

李沐《動(dòng)手學(xué)深度學(xué)習(xí)》深度學(xué)習(xí)計(jì)算

這篇具有很好參考價(jià)值的文章主要介紹了李沐《動(dòng)手學(xué)深度學(xué)習(xí)》深度學(xué)習(xí)計(jì)算。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

系列文章

李沐《動(dòng)手學(xué)深度學(xué)習(xí)》預(yù)備知識(shí) 張量操作及數(shù)據(jù)處理
李沐《動(dòng)手學(xué)深度學(xué)習(xí)》預(yù)備知識(shí) 線性代數(shù)及微積分
李沐《動(dòng)手學(xué)深度學(xué)習(xí)》線性神經(jīng)網(wǎng)絡(luò) 線性回歸
李沐《動(dòng)手學(xué)深度學(xué)習(xí)》線性神經(jīng)網(wǎng)絡(luò) softmax回歸
李沐《動(dòng)手學(xué)深度學(xué)習(xí)》多層感知機(jī) 模型概念和代碼實(shí)現(xiàn)
李沐《動(dòng)手學(xué)深度學(xué)習(xí)》多層感知機(jī) 深度學(xué)習(xí)相關(guān)概念


教材:李沐《動(dòng)手學(xué)深度學(xué)習(xí)》

一、層和塊

(一)塊的概念

塊(block):可以描述單個(gè)層、由多個(gè)層組成的組件或整個(gè)模型本身

  • 使用塊進(jìn)行抽象的一個(gè)好處是可以將一些塊組合成更大的組件, 這一過(guò)程通常是遞歸的;
  • 通過(guò)定義代碼來(lái)按需生成任意復(fù)雜度的塊, 我們可以通過(guò)簡(jiǎn)潔的代碼實(shí)現(xiàn)復(fù)雜的神經(jīng)網(wǎng)絡(luò)。

李沐《動(dòng)手學(xué)深度學(xué)習(xí)》深度學(xué)習(xí)計(jì)算,李沐《動(dòng)手學(xué)深度學(xué)習(xí)》學(xué)習(xí)筆記,深度學(xué)習(xí),人工智能,pytorch,算法

(二)塊的實(shí)現(xiàn)

  1. 從編程的角度來(lái)看,塊由類表示。每個(gè)塊必須提供的基本功能:
    • 將輸入數(shù)據(jù)作為其前向傳播函數(shù)的參數(shù);
    • 通過(guò)前向傳播函數(shù)來(lái)生成輸出;
    • 計(jì)算其輸出關(guān)于輸入的梯度,可通過(guò)其反向傳播函數(shù)進(jìn)行訪問(wèn),通常這是自動(dòng)發(fā)生的;
    • 存儲(chǔ)和訪問(wèn)前向傳播計(jì)算所需的參數(shù);
    • 根據(jù)需要初始化模型參數(shù)。
  2. 層和塊的順序連接由Sequential塊處理:
    • nn.Sequential定義了一種特殊的Module, 即在PyTorch中表示一個(gè)塊的類, 它維護(hù)了一個(gè)由Module組成的有序列表;
    • 通過(guò)net(X)調(diào)用模型來(lái)獲得模型的輸出,這實(shí)際上是net.call(X)的簡(jiǎn)寫。 這個(gè)前向傳播函數(shù)非常簡(jiǎn)單: 它將列表中的每個(gè)塊連接在一起,將每個(gè)塊的輸出作為下一個(gè)塊的輸入。
net = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
X = torch.rand(2, 20)
net(X)
  1. 一個(gè)塊可以由許多層組成;一個(gè)塊可以由許多塊組成。
class NestMLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),
                                 nn.Linear(64, 32), nn.ReLU())
        self.linear = nn.Linear(32, 16)

    def forward(self, X):
        return self.linear(self.net(X))

chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())
chimera(X)

二、參數(shù)管理

具有單隱藏層的多層感知機(jī):

import torch
from torch import nn

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
net(X)

(一)參數(shù)訪問(wèn):用于調(diào)試、診斷和可視化

當(dāng)通過(guò)Sequential類定義模型時(shí),可以通過(guò)索引來(lái)訪問(wèn)模型的任意層。
參數(shù)訪問(wèn)方式一:

print(net[2].state_dict()) #獲得第二個(gè)全連接層的參數(shù) 
print(type(net[2].bias)) #第二個(gè)全連接層偏置的類型
print(net[2].bias) #第二個(gè)全連接層的偏置 (參數(shù)是復(fù)合的對(duì)象,包含值、梯度和額外信息。)
print(net[2].bias.data) #第二個(gè)全連接層偏置的數(shù)值

參數(shù)訪問(wèn)方式二:

net.state_dict()['2.bias'].data

從嵌套塊收集參數(shù)時(shí),也可以像通過(guò)嵌套列表索引一樣訪問(wèn)它們

#獲得第一個(gè)主要的塊中、第二個(gè)子塊的第一層的偏置項(xiàng)。
rgnet[0][1][0].bias.data

(二)參數(shù)初始化(內(nèi)置初始化、自定義初始化)

深度學(xué)習(xí)框架提供默認(rèn)隨機(jī)初始化, 也允許我們創(chuàng)建自定義初始化方法, 滿足我們通過(guò)其他規(guī)則實(shí)現(xiàn)初始化權(quán)重。

  1. 內(nèi)置初始化:PyTorch的nn.init模塊提供了多種預(yù)置初始化方法

調(diào)用內(nèi)置初始化器,將所有權(quán)重參數(shù)初始化為標(biāo)準(zhǔn)差為0.01的高斯隨機(jī)變量,偏置參數(shù)初始化為0:

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, mean=0, std=0.01)
        nn.init.zeros_(m.bias)
net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]

調(diào)用內(nèi)置初始化器,將參數(shù)初始化為1:

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 1)
        nn.init.zeros_(m.bias)
net.apply(init_constant)
net[0].weight.data[0], net[0].bias.data[0]

使用Xavier初始化第一個(gè)神經(jīng)網(wǎng)絡(luò)層,將第三個(gè)神經(jīng)網(wǎng)絡(luò)層初始化為常量值42:

def init_xavier(m):
    if type(m) == nn.Linear:
        nn.init.xavier_uniform_(m.weight)
def init_42(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 42)

net[0].apply(init_xavier)
net[2].apply(init_42)
print(net[0].weight.data[0])
print(net[2].weight.data)
  1. 自定義初始化
    使用以下的分布為任意權(quán)重參數(shù) w w w定義初始化方法:
    w { U ( 5 , 10 ) 可能性?0.25? 0 可能性?0.5 U ( ? 10 , ? 5 ) 可能性?0.25 w \begin{cases} U(5,10) & \text{可能性 0.25 } \\ 0 & \text{可能性 0.5}\\ U(-10,-5) & \text{可能性 0.25} \end{cases} w? ? ??U(5,10)0U(?10,?5)?可能性?0.25?可能性?0.5可能性?0.25?
def my_init(m):
    if type(m) == nn.Linear:
        print("Init", *[(name, param.shape)
                        for name, param in m.named_parameters()][0])
        nn.init.uniform_(m.weight, -10, 10)
        m.weight.data *= m.weight.data.abs() >= 5

net.apply(my_init)
net[0].weight[:2]
  1. 也可以直接設(shè)置參數(shù)值
net[0].weight.data[:] += 1
net[0].weight.data[0, 0] = 42
net[0].weight.data[0]

(三)參數(shù)綁定:在不同模型組件間共享參數(shù)

為了在多個(gè)層間共享參數(shù),可以定義一個(gè)稠密層,然后使用它的參數(shù)來(lái)設(shè)置另一個(gè)層的參數(shù)

  • 第三個(gè)和第五個(gè)神經(jīng)網(wǎng)絡(luò)層的參數(shù)是綁定的,不僅值相等,而且由相同的張量表示;
  • 改變其中一個(gè)參數(shù),另一個(gè)參數(shù)也會(huì)改變;
  • 反向傳播期間第二個(gè)隱藏層 (即第三個(gè)神經(jīng)網(wǎng)絡(luò)層)和第三個(gè)隱藏層(即第五個(gè)神經(jīng)網(wǎng)絡(luò)層)的梯度會(huì)加在一起。
# 我們需要給共享層一個(gè)名稱,以便可以引用它的參數(shù)
shared = nn.Linear(8, 8)
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                    shared, nn.ReLU(),
                    shared, nn.ReLU(),
                    nn.Linear(8, 1))
net(X)
# 檢查參數(shù)是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0, 0] = 100
# 確保它們實(shí)際上是同一個(gè)對(duì)象,而不只是有相同的值
print(net[2].weight.data[0] == net[4].weight.data[0])

三、延后初始化

  • 框架的延后初始化:直到數(shù)據(jù)第一次通過(guò)模型傳遞時(shí),框架才會(huì)動(dòng)態(tài)地推斷出每個(gè)層的大小。

四、自定義層

(一)不帶參數(shù)的層

構(gòu)建一個(gè)CenteredLayer類,要從其輸入中減去均值:

import torch
import torch.nn.functional as F
from torch import nn


class CenteredLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, X):
        return X - X.mean()

(二)帶參數(shù)的層

實(shí)現(xiàn)自定義版本的全連接層:

  • 需要兩個(gè)參數(shù),一個(gè)用于表示權(quán)重,另一個(gè)用于表示偏置項(xiàng);
  • 使用修正線性單元作為激活函數(shù);
  • in_units和units分別表示輸入數(shù)和輸出數(shù)。
class MyLinear(nn.Module):
    def __init__(self, in_units, units):
        super().__init__()
        self.weight = nn.Parameter(torch.randn(in_units, units))
        self.bias = nn.Parameter(torch.randn(units,))
    def forward(self, X):
        linear = torch.matmul(X, self.weight.data) + self.bias.data
        return F.relu(linear)

五、讀寫文件

(一)加載和保存張量

save和load函數(shù)可用于張量對(duì)象的文件讀寫:

import torch
from torch import nn
from torch.nn import functional as F

x = torch.arange(4)
torch.save(x, 'x-file')

x2 = torch.load('x-file')
x2

(二)加載和保存模型參數(shù)

class MLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden = nn.Linear(20, 256)
        self.output = nn.Linear(256, 10)

    def forward(self, x):
        return self.output(F.relu(self.hidden(x)))

net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)

深度學(xué)習(xí)框架提供了內(nèi)置函數(shù)來(lái)保存和加載整個(gè)網(wǎng)絡(luò),但是只會(huì)保存模型的參數(shù)而不是保存整個(gè)模型。 因?yàn)槟P捅旧砜梢园我獯a,所以模型本身難以序列化。 因此,為了恢復(fù)模型,需要用代碼生成架構(gòu), 然后從磁盤加載參數(shù)。

#模型保存
torch.save(net.state_dict(), 'mlp.params')
#用代碼生成架構(gòu)
clone = MLP()
#加載保存好的參數(shù)
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()

六、GPU

(一)計(jì)算設(shè)備

  1. 可以指定用于存儲(chǔ)和計(jì)算的設(shè)備,如CPU和GPU。 默認(rèn)情況下,張量是在內(nèi)存中創(chuàng)建的,然后使用CPU計(jì)算它。

在PyTorch中,CPU和GPU可以用torch.device(‘cpu’) 和torch.device(‘cuda’)表示。 應(yīng)該注意的是,cpu設(shè)備意味著所有物理CPU和內(nèi)存, 這意味著PyTorch的計(jì)算將嘗試使用所有CPU核心。 然而,gpu設(shè)備只代表一個(gè)卡和相應(yīng)的顯存。 如果有多個(gè)GPU,我們使用torch.device(f’cuda:{i}') 來(lái)表示第 i i i 塊GPU(從0開(kāi)始)。 另外,cuda:0和cuda是等價(jià)的。

import torch
from torch import nn

torch.device('cpu'), torch.device('cuda'), torch.device('cuda:1')
  1. 查詢可用GPU的數(shù)量:
torch.cuda.device_count()
  1. 定義函數(shù)try_gpu,如果申請(qǐng)的GPU存在,就返回GPU(i),不存在就使用CPU
def try_gpu(i=0):  
    if torch.cuda.device_count() >= i + 1:
        return torch.device(f'cuda:{i}')
    return torch.device('cpu')
  1. 定義函數(shù)try_all_gpus,返回所有可用的GPU,如果沒(méi)有GPU,則返回[cpu(),]"
def try_all_gpus():  
    devices = [torch.device(f'cuda:{i}')
             for i in range(torch.cuda.device_count())]
    return devices if devices else [torch.device('cpu')]

try_gpu(), try_gpu(10), try_all_gpus()

(二)張量與GPU

  1. 可以查詢張量所在的設(shè)備。 默認(rèn)情況下,張量是在CPU上創(chuàng)建的
x = torch.tensor([1, 2, 3])
x.device
#返回device(type='cpu')
  1. 將張量存儲(chǔ)在GPU上
X = torch.ones(2, 3, device=try_gpu())
X
Y = torch.rand(2, 3, device=try_gpu(1))
Y
  1. 復(fù)制:對(duì)多個(gè)項(xiàng)進(jìn)行操作時(shí)不同項(xiàng)目必須在同一個(gè)設(shè)備上
Z = X.cuda(1)
print(X)
print(Z)
#返回結(jié)果顯示X在cuda0,Z在cuda1

(三)神經(jīng)網(wǎng)絡(luò)與GPU

神經(jīng)網(wǎng)絡(luò)模型可以指定設(shè)備。 下面的代碼將模型參數(shù)放在GPU上。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-814644.html

net = nn.Sequential(nn.Linear(3, 1))
net = net.to(device=try_gpu())

到了這里,關(guān)于李沐《動(dòng)手學(xué)深度學(xué)習(xí)》深度學(xué)習(xí)計(jì)算的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包