Pytorch:五、用pytorch實(shí)現(xiàn)線性回歸


所含內(nèi)容如下:

  1. 如何構(gòu)造神經(jīng)網(wǎng)絡(luò)模型;
  2. 如何構(gòu)造損失函數(shù);
  3. 如何構(gòu)造優(yōu)化器,如sgd(隨機(jī)梯度下降);

用pytorch寫(xiě)的模型彈性不錯(cuò),可以擴(kuò)展為神經(jīng)網(wǎng)絡(luò);
總體步驟

第二步就是設(shè)計(jì)一個(gè)計(jì)算y^ 的模型;第三步是通過(guò)pytorch的接口來(lái)計(jì)算損失;第四步就是瘋狂前向傳播(算損失),后向傳播(算梯度),更新

在pytorch中,可計(jì)算的圖是在mini-batch中,所以X和Y是3*1的張量。如下圖所示:

注意,最后算出來(lái)的loss一定要是個(gè)標(biāo)量,因此要對(duì)loss的張量進(jìn)行求和,并根據(jù)情況決定是否要求均值:

Linear類使用說(shuō)明

這里分別接受了輸入/出特征的維數(shù)/特征數(shù)(指的是輸入/出的值的個(gè)數(shù)),偏執(zhí)量;

輸入多個(gè)常數(shù)參數(shù)可以通過(guò)* args來(lái)進(jìn)行調(diào)用,不用一個(gè)個(gè)輸入到括號(hào)里了;



變量參數(shù)可以通過(guò)* kwargs來(lái)進(jìn)行調(diào)用;


import torch

#1. 準(zhǔn)備數(shù)據(jù)
#將x和y都寫(xiě)成了3*1的向量
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[2.0],[4.0],[6.0]])

#2.設(shè)計(jì)模型
#需要構(gòu)造一個(gè)計(jì)算圖,pytorch可以自動(dòng)求得梯度
#構(gòu)造模型所使用的都是下面這樣的模板
#我們使用的模型都要繼承torch.nn.Module,其中包含了許多基本方法
class LinearModel(torch.nn.Module):
    #至少要實(shí)現(xiàn)下面這兩個(gè)函數(shù)
    def __init__(self):
        super(LinearModel, self).__init__()
        #通過(guò)nn.Linear類來(lái)構(gòu)造一個(gè)權(quán)重和偏執(zhí)都為1的張量
        self.linear = torch.nn.Linear(1, 1)
        
    def forward(self, x):
        y_pred = self.linear(x)
        return y_pred
    #運(yùn)用Module所構(gòu)建的模型可以用其自帶的backward函數(shù)來(lái)根據(jù)計(jì)算圖進(jìn)行逆向傳播
    
model = LinearModel()

#3. 計(jì)算損失并進(jìn)行優(yōu)化
criterion = torch.nn.MESLoss(size_average=False)

optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
包中自帶的算平均loss的函數(shù)

reduce用來(lái)確定是否要進(jìn)行降維?不過(guò)一般不會(huì)用就是了

優(yōu)化器

優(yōu)化器不會(huì)構(gòu)成計(jì)算圖。第一個(gè)參數(shù)是權(quán)重,model.parameters()來(lái)檢查其成員中是否有對(duì)應(yīng)的權(quán)重值,有的話就加到訓(xùn)練的集合中去;第二個(gè)參數(shù)就是學(xué)習(xí)率,一般都是取個(gè)固定值;

import torch

#1. 準(zhǔn)備數(shù)據(jù)
#將x和y都寫(xiě)成了3*1的向量
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[2.0],[4.0],[6.0]])

#2.設(shè)計(jì)模型
#需要構(gòu)造一個(gè)計(jì)算圖,pytorch可以自動(dòng)求得梯度
#構(gòu)造模型所使用的都是下面這樣的模板
#我們使用的模型都要繼承torch.nn.Module,其中包含了許多基本方法
class LinearModel(torch.nn.Module):
    #至少要實(shí)現(xiàn)下面這兩個(gè)函數(shù)
    def __init__(self):
        super(LinearModel, self).__init__()
        #通過(guò)nn.Linear類來(lái)構(gòu)造一個(gè)權(quán)重和偏執(zhí)都為1的張量
        self.linear = torch.nn.Linear(1, 1)
        
    def forward(self, x):
        y_pred = self.linear(x)
        return y_pred
    #運(yùn)用Module所構(gòu)建的模型可以用其自帶的backward函數(shù)來(lái)根據(jù)計(jì)算圖進(jìn)行逆向傳播
    
model = LinearModel()

#3. 計(jì)算損失并進(jìn)行優(yōu)化
criterion = torch.nn.MSELoss(size_average=False)
#優(yōu)化器對(duì)象知道要對(duì)哪些參數(shù)做優(yōu)化
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

#4.訓(xùn)練過(guò)程
for epoch in range(100):
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    #雖然loss是個(gè)對(duì)象,但是在打印時(shí)會(huì)自動(dòng)調(diào)用str方法轉(zhuǎn)化為輸出字符
    print(epoch, loss)
    
    #記得要進(jìn)行梯度歸零
    optimizer.zero_grad()
    loss.backward()
    #用step函數(shù)進(jìn)行更新,會(huì)根據(jù)所有參數(shù)中其所包含的梯度以及學(xué)習(xí)率來(lái)自動(dòng)更新
    optimizer.step()
    #其實(shí)就是:1.算y^;2. 算loss; 3. 進(jìn)行反推;4. 進(jìn)行更新
    #1和2其實(shí)就是前饋更新操作
    
#輸出權(quán)重和偏執(zhí)
print("w = ",model.linear.weight.item())
print("b = ",model.linear.bias.item())

#測(cè)試模型
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print("y_pred = ", y_test.data)


可以看到:100次迭代后的損失值還是挺大的,但是在進(jìn)行了1000次之后的損失值很小了。此時(shí)的w十分接近2,b也很靠近0,預(yù)測(cè)結(jié)果y也十分靠近8,說(shuō)明效果很好;

因此,想要訓(xùn)練結(jié)果更加好,可以通過(guò)增加訓(xùn)練次數(shù)來(lái)達(dá)到。但是這一操作也是有風(fēng)險(xiǎn)的:會(huì)出現(xiàn)過(guò)擬合的狀況;

代碼的整體步驟

Pytorch的優(yōu)化器們:

附個(gè)官方,去那里看看這些都是干啥的:
Learning PyTorch with Examples — PyTorch Tutorials 1.13.0+cu117 documentation

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容