上一篇博客说了如何拟合一条直线y=wx+b,今天我们现在使用PyTorch进行相同的曲线拟合
拟合y= x*x -2x +3 + 0.1(-1到1的随机值) 曲线
给定x范围(0,3)
生成数据
import numpy as np
import matplotlib.pyplot as plt
import torch as t
from torch.autograd import Variable as var
def get_data(x,w,b,d): # w * x * x + b * x + d
c,r = x.shape
y = (w * x * x + b*x + d)+ (0.1*(2*np.random.rand(c,r)-1)) # 加入随机噪点
return(y)
xs = np.arange(0,3,0.01).reshape(-1,1) # 创建的二维 NumPy 数组。这个数组包含了从 0 到 3(不包括3)的等差数列,步长为 0.01
ys = get_data(xs,1,-2,3)
xs = var(t.Tensor(xs))
ys = var(t.Tensor(ys))
plt.plot(xs, ys)
plt.show()
生成数据后我们来看一下分布情况吧
这就按照等差数列,步长0.01生成的点集图了,接下来
搭建网络
class Fit_model(t.nn.Module):
def __init__(self):
super(Fit_model,self).__init__() # 调用父类torch.nn.Module的初始化方法,这是创建PyTorch模型时的标准做法
self.linear1 = t.nn.Linear(1,16) # 定义第一个线性层(也称为全连接层),它将输入数据的特征数量从1个扩展到16个
self.relu = t.nn.ReLU() # 定义一个ReLU激活函数,用于增加模型的非线性
self.linear2 = t.nn.Linear(16,1)
self.criterion = t.nn.MSELoss() # 定义损失函数为均方误差损失(MSE),这是回归任务中常用的损失函数
self.opt = t.optim.SGD(self.parameters(),lr=0.01) # 定义优化器为随机梯度下降(SGD),并设置学习率为0.01。
# self.parameters()会返回模型中所有可训练的参数
def forward(self, input):
y = self.linear1(input)
y = self.relu(y)
y = self.linear2(y)
return y
model = Fit_model()
for e in range(20000):
y_pre = model(xs)
loss = model.criterion(y_pre, ys)
if (e % 100 == 0):
print(e, loss.data)
# Zero gradients
model.opt.zero_grad()
# perform backward pass
loss.backward()
# update weights
model.opt.step()
# 显示预测的结果
ys_pre = model(xs)
plt.title("curve")
plt.plot(xs.data.numpy(),ys.data.numpy())
# plt.plot(xs.data.numpy(),ys_pre.data.numpy())
plt.plot(xs.data.numpy(), ys_pre.data.numpy(), color='blue', label="ys_pre")
plt.legend("ys","ys_pre")
plt.show()
这里的话小编训练了2w轮实际上从训练以后的loss反馈来看训练1w左右效果就很好了
上面的方法是固定轮数训练如果想要Loss达到某个标准,可以把训练部分改为如下代码即可
epoch = 1
# 使用while循环进行训练
while epoch:
# 假设 model 的 forward 方法返回预测值
y_pre = model(xs)
# 计算损失
loss = model.criterion(y_pre, ys)
# 如果损失小于50,则跳出循环
if loss.item() < 1:
print(f"Epoch {epoch}: Loss is less than 50, stopping training.")
break
# 每100个epoch打印一次损失
if (epoch % 100 == 0):
print(f"Epoch {epoch}, Loss: {loss.item()}")
# Zero gradients
model.opt.zero_grad()
# perform backward pass
loss.backward()
# update weights
model.opt.step()
epoch +=1