所含內(nèi)容如下:
- 如何構(gòu)造神經(jīng)網(wǎng)絡(luò)模型;
- 如何構(gòu)造損失函數(shù);
- 如何構(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ù)情況決定是否要求均值:


這里分別接受了輸入/出特征的維數(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)

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

優(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

