cms仿站十堰seo排名公司
【【Pytorch】學(xué)習記錄分享3——PyTorch 自動微分與線性回歸
- 1. autograd 包,自動微分
- 2. 線性模型回歸演示
- 3. GPU進行模型訓(xùn)練
小結(jié):只需要將前向傳播設(shè)置好,調(diào)用反向傳播接口,即可實現(xiàn)反向傳播的鏈式求導(dǎo)
1. autograd 包,自動微分
自動微分是機器學(xué)習工具包必備的工具,它可以自動計算整個計算圖的微分。
PyTorch內(nèi)建了一個叫做torch.autograd的自動微分引擎,該引擎支持的數(shù)據(jù)類型為:浮點數(shù)Tensor類型 ( half, float, double and bfloat16) 和復(fù)數(shù)Tensor 類型(cfloat, cdouble)
PyTorch中與自動微分相關(guān)的常用的Tensor屬性和函數(shù):
屬性requires_grad:
默認值為False,表明該Tensor不會被自動微分引擎計算微分。設(shè)置為True,表明讓自動微分引擎計算該Tensor的微分
屬性grad:存儲自動微分的計算結(jié)果,即調(diào)用backward()方法后的計算結(jié)果
方法backward(): 計算微分,一般不帶參數(shù),等效于:backward(torch.tensor(1.0))。若backward()方法在DAG的root上調(diào)用,它會依據(jù)鏈式法則自動計算DAG所有枝葉上的微分。
方法no_grad():禁用自動微分上下文管理, 一般用于模型評估或推理計算這些不需要執(zhí)行自動微分計算的地方,以減少內(nèi)存和算力的消耗。另外禁止在模型參數(shù)上自動計算微分,即不允許更新該參數(shù),即所謂的凍結(jié)參數(shù)(frozen parameters)。
zero_grad()方法:PyTorch的微分是自動積累的,需要用zero_grad()方法手動清零
# 模型:z = x@w + b;激活函數(shù):Softmax
x = torch.ones(5) # 輸入張量,shape=(5,)
labels = torch.zeros(3) # 標簽值,shape=(3,)
w = torch.randn(5,3,requires_grad=True) # 模型參數(shù),需要計算微分, shape=(5,3)
b = torch.randn(3, requires_grad=True) # 模型參數(shù),需要計算微分, shape=(3,)
z = x@w + b # 模型前向計算
outputs = torch.nn.functional.softmax(z) # 激活函數(shù)
print("z: ",z)
print("outputs: ",outputs)
loss = torch.nn.functional.binary_cross_entropy(outputs, labels)
# 查看loss函數(shù)的微分計算函數(shù)
print('Gradient function for loss =', loss.grad_fn)
# 調(diào)用loss函數(shù)的backward()方法計算模型參數(shù)的微分
loss.backward()
# 查看模型參數(shù)的微分值
print("w: ",w.grad)
print("b.grad: ",b.grad)
小姐:
方法 | 描述 |
---|---|
.requires_grad 設(shè)置為True | 會開始跟蹤針對 tensor 的所有操作 |
.backward() | 張量的梯度將累積到 .grad 屬性 |
import torchx=torch.rand(1)
b=torch.rand(1,requires_grad=True)
w=torch.rand(1,requires_grad=True)
y = w * x
z = y + bx.requires_grad, w.requires_grad,b.requires_grad,y.requires_grad,z.requires_gradprint("x: ",x, end="\n"),print("b: ",b ,end="\n"),print("w: ",w ,end="\n")
print("y: ",y, end="\n"),print("z: ",z, end="\n")# 反向傳播計算
z.backward(retain_graph=True) #注意:如果不清空,b每一次更新,都會自我累加起來,依次為1 2 3 4 。。。w.grad
b.grad
運行結(jié)果:
反向傳播求導(dǎo)原理:
2. 線性模型回歸演示
import torch
import torch.nn as nn## 線性回歸模型: 本質(zhì)上就是一個不加 激活函數(shù)的 全連接層
class LinearRegressionModel(nn.Module):def __init__(self, input_size, output_size):super(LinearRegressionModel, self).__init__()self.linear = nn.Linear(input_size, output_size)def forward(self, x):out = self.linear(x)return out
input_size = 1
output_size = 1model = LinearRegressionModel(input_size, output_size)
model# 指定號參數(shù)和損失函數(shù)
epochs = 500
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
criterion = nn.MSELoss()# train model
for epoch in range(epochs):epochs+=1#注意 將numpy格式的輸入數(shù)據(jù)轉(zhuǎn)換成 tensorinputs = torch.from_numpy(x_train)labels = torch.from_numpy(y_train)#每次迭代梯度清零optimizer.zero_grad()#前向傳播outputs = model(inputs)#計算損失loss = criterion(outputs, labels)#反向傳播loss.backward()#updates weight and parametersoptimizer.step()if epoch % 50 == 0:print("Epoch: {}, Loss: {}".format(epoch, loss.item()))# predict model test,預(yù)測結(jié)果并且獎結(jié)果轉(zhuǎn)換成np格式
predicted =model(torch.from_numpy(x_train).requires_grad_()).data.numpy()
predicted#model save
torch.save(model.state_dict(),'model.pkl')#model 讀取
model.load_state_dict(torch.load('model.pkl'))
3. GPU進行模型訓(xùn)練
只需要 將模型和數(shù)據(jù)傳入到“cuda”中運行即可,詳細實現(xiàn)見截圖
import torch
import torch.nn as nn
import numpy as np# #構(gòu)建一個回歸方程 y = 2*x+1#構(gòu)建輸如數(shù)據(jù),將輸入numpy格式轉(zhuǎn)成tensor格式
x_values = [i for i in range(11)]
x_train = np.array(x_values,dtype=np.float32)
x_train = x_train.reshape(-1,1)y_values = [2*i + 1 for i in x_values]
y_train = np.array(y_values, dtype=np.float32)
y_train = y_train.reshape(-1,1)## 線性回歸模型: 本質(zhì)上就是一個不加 激活函數(shù)的 全連接層
class LinearRegressionModel(nn.Module):def __init__(self, input_size, output_size):super(LinearRegressionModel, self).__init__()self.linear = nn.Linear(input_size, output_size)def forward(self, x):out = self.linear(x)return outinput_size = 1
output_size = 1model = LinearRegressionModel(input_size, output_size)device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)# 指定號參數(shù)和損失函數(shù)
epochs = 500
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
criterion = nn.MSELoss()# train model
for epoch in range(epochs):epochs+=1#注意 將numpy格式的輸入數(shù)據(jù)轉(zhuǎn)換成 tensorinputs = torch.from_numpy(x_train)labels = torch.from_numpy(y_train)#每次迭代梯度清零optimizer.zero_grad()#前向傳播outputs = model(inputs)#計算損失loss = criterion(outputs, labels)#反向傳播loss.backward()#updates weight and parametersoptimizer.step()if epoch % 50 == 0:print("Epoch: {}, Loss: {}".format(epoch, loss.item()))# predict model test,預(yù)測結(jié)果并且獎結(jié)果轉(zhuǎn)換成np格式
predicted = model(torch.from_numpy(x_train).requires_grad_()).data.numpy()
predicted#model save
torch.save(model.state_dict(),'model.pkl')