线性回归原理:
在一堆散点中 xi yi,拟合出一个函数使其离所有点最近
目标函数:y = w1x + w0
误差函数:MSE(均方误差) L(w1,w0)= Σ(yi - y)^2
优化方法:梯度下降,autograd,反向传播,优化公式,进行更新
公式更新:wt+1 = wt-dL/dwt *δ
乘积的意义:将梯度乘以学习率,得到的结果是参数更新的大小。如果梯度较大,乘以一个较小的学习率可以使参数更新的幅度减小,保持在一个合理的范围内。这样,我们可以沿着损失函数下降最快的方向移动,同时避免更新步长过大导致跳过最优解。所以,乘以一个很小的数(学习率)可以控制参数更新的幅度,确保梯度下降算法朝着最小化损失函数的方向稳定地进行。
import matplotlib.pyplot as plt import torch import matplotlib.pyplot as pit # 点对 x = torch.tensor([1.4,5,11,16,21]) y = torch.tensor([14.4,29.6,62,85.5,113.4]) # 绘制散点图 plt.scatter(x.numpy(),y.numpy()) plt.show() def produce_x(x): x0 = torch.ones(x.numpy().size) X = torch.stack((x,x0),dim=1) return X X = produce_x(x) print(X) inputs = X target = y w = torch.rand(2,requires_grad=True) print(w) def train(epoch = 100,lr = 0.01,num = 100000): for epoch in range(epoch): output = inputs.mv(w) loss = (output - target).pow(2).sum()/num loss.backward() w.data -= lr * w.grad # 清空w的梯度,不然会累加 w.grad.zero_() if epoch%80 == 0: draw(output,loss) return w,loss def draw(output,loss): if CUDA: output = output.cpu() # 清空画布 plt.cla() plt.scatter(x.numpy(), y.numpy()) plt.plot(x.numpy(),output.data.numpy(),'r-',lw=5) plt.text(0.5,0,'loss=%s'%(loss.item()),fontdict={'size':20,'color':'red'}) plt.pause(0.005) # 训练 # w,loss = train(10000,lr=0.0001) # print("loss:",loss.item()) # print("weights:",w.data) # 上述我们使用的是produce_X来初始化五个预设值 # 我们可以用它来生成许多数据并初始化 x = torch.linspace(-3,3,100000) X = produce_x(x) y = x +1.2*torch.rand(x.size()) w = torch.rand(2) plt.scatter(x.numpy(),y.numpy(),s=0.001) plt.show() # cuda加速 CUDA = 1 if CUDA: inputs = X.cuda() target = y.cuda() w = w.cuda() w.requires_grad = True else: inputs = X target = y w = w w.requires_grad = True num1 = target.numel() w,loss = train(10000,lr=0.0001,num=num1) print("loss:",loss.item()) print("weights:",w.data)
下面的实现我们用pytorch的库来实现
import matplotlib.pyplot as plt
import torch
from torch import nn,optim
from time import perf_counter
# 增加一个维度100000行1列
x = torch.unsqueeze(torch.linspace(-3,3,100000),dim=1)
y = x + 1.2*torch.rand(x.size())
def draw(output,loss):
if CUDA:
output = output.cpu()
# 清空画布
plt.cla()
plt.scatter(x.numpy(), y.numpy())
plt.plot(x.numpy(),output.data.numpy(),'r-',lw=5)
plt.text(0.5,0,'loss=%s'%(loss.item()),fontdict={'size':20,'color':'red'})
plt.pause(0.005)
class LR(nn.Module):
def __init__(self):
super(LR,self).__init__()
self.linear = nn.Linear(1,1)
def forward(self,x):
out = self.linear(x)
return out
CUDA = torch.cuda.is_available()
if CUDA:
LR_model = LR().cuda()
inputs = x.cuda()
target = y.cuda()
else:
LR_model = LR()
inputs = x
target = y
criterion = nn.MSELoss()
optimizer = optim.SGD(LR_model.parameters(),lr=1e-4)
def Train(model,criterion,optimizer,epochs):
for epochs in range(epochs):
output = model(inputs)
loss = criterion(output,target)
optimizer.zero_grad()
loss.backward()
optimizer.step() #权重更新
if epochs % 80 == 0:
draw(output,loss)
return model,loss
START = perf_counter()
LR_model,loss = Train(LR_model,criterion,optimizer,10000)
FINISH = perf_counter()
time = FINISH - START
print("time:%s" % time)
print("loss:",loss.item())
print("weights:",list(LR_model.parameters()))