pytorch知识点学习
此文章建议了解numpy、matplotlib相关知识.
一.线性模型
代码:
import numpy as np
import matplotlib.pyplot as plt
from numpy import * #此处表示将numpy的所有功能引入
#建立数据集
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
#计算函数 y = k*x
def forward(x):
return x*w
#损失函数
def loss(x,y):
y_pre = forward(x) #y_pred表示计算出来的值,y表示实际值
return (y_pre - y)*(y_pre - y)
w_list = []
Mse_list = [] #建立两个空列表用于之后画图
for w in np.arange(0.0,4.1,0.1):#范围从0到4.0,以0.1为步长
print('w = ',w)
l_sum = 0
for x_val,y_val in zip(x_data,y_data):
y_pre_val = forward(x_val)
loss_val = loss(x_val,y_val)
l_sum += loss_val #累加以后用于求Mse(平均平方误差)
print('\t',x_val,y_val,y_pre_val,loss_val)
print('Mse = ',l_sum/3)
w_list.append(w)
Mse_list.append(l_sum/3)
plt.plot(w_list,Mse_list)
plt.ylabel('loss')
plt.xlabel('w')
plt.show()
二.梯度下降
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
w = 1.0 #预测值,之后会根据计算调整
Eporch_list = []
cost_list = []
#建立数据集
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
#计算函数
def forward(x):
return x*w
#cost函数
def cost(xs,ys):
cost = 0
for x,y in zip(xs,ys):
y_pred = forward(x)
cost+=(y_pred-y)**2
return cost/len(xs)
#cost对权重求导函数
def gradient(xs,ys):
grad = 0
for x,y in zip(xs,ys):
grad += 2*x*(x*w-y)
return grad/len(xs)
for epoch in range(100):
cost_val = cost(x_data,y_data)
grad_val = gradient(x_data,y_data)
w -= 0.01*grad_val
print('Epoch:',epoch,'w = ',w,'lose=',cost_val)
Eporch_list.append(eporch)
cost_list.append(cost_val)
plt.plot(Eporch_list,cost_list)
plt.xlabel('eporch')
plt.ylabel('cost_val')
plt.show()
因为cost对w的求导表示上升方向,所以给个负号表示下降。
三.随机梯度下降
因为用上述方法,常遇到“鞍点”这类问题,对结果照成影响,所以使用随机梯度下降克服此类问题。因为单个点,容易受到随机噪声的推动。
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
w = 1.0
Eporch_list = []
lost_list = []
#建立数据集
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
#计算函数
def forward(x):
return x*w
#lost函数
def lost(x,y):
y_pred = forward(x)
return (y_pred-y)**2
#lost对权重求导函数
def gradient(x,y):
return 2*x*(x*w-y)
for epoch in range(100):
for x,y in zip(x_data,y_data):
grad = gradient(x,y)
w = w-0.01*grad
print('\tgrad',x,y,grad)
l = lost(x,y)
Eporch_list.append(epoch)
lost_list.append(l)
plt.plot(Eporch_list,lost_list)
plt.xlabel('eporch')
plt.ylabel('lost_val')
plt.show()
四.反向传播
import numpy as np
import matplotlib.pyplot as plt
import torch
from numpy import *
w = torch.Tensor([1.0])
w.requires_grad = True #开启计算梯度
Eporch_list = []
lost_list = []
#建立数据集
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
#计算函数
def forward(x):
return x*w #此时x、w的数据类型都为tensor
#lost函数
def lost(x,y):
y_pred = forward(x)
return (y_pred-y)**2
#lost对权重求导函数
def gradient(x,y):
return 2*x*(x*w-y)
for epoch in range(100):
for x,y in zip(x_data,y_data):
l = lost(x,y)
l.backward() #反向将计算链上所有的梯度都求出来,并存到w里
print('\tgrad:',x,y,w.grad.item())
w.data = w.data-0.01*w.grad.data
Eporch_list.append(epoch)
lost_list.append(l.item())
w.grad.data.zero_() #将存储的梯度清零
plt.plot(Eporch_list,lost_list)
plt.xlabel('w')
plt.ylabel('lost_val')
plt.show()
注意,此时x、y、w等数据都是tensor类型,都是张量。 此时,如果想要像线性模型那样计算Mse,则累加类型为l.item(),因为l此时为张量,累加起来耗费内存极大。