引用的必要的库及虚拟环境:
python版本:3.9
虚拟环境anaconda创建的虚拟环境
必要的库:
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l #这本书作者建立的库,存放了一些简单的打包好的函数
from torch.utils.data import Dataset
from torch import nn
完整的代码:
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
from torch.utils.data import Dataset
from torch import nn
true_w=torch.tensor([2,-3.4])
true_b=4.2
#赋值给特征值和标签
features,lables=d2l.synthetic_data(true_w,true_b,1000)
def load_array(data_arrays,batch_size,is_train=True):
#将特征值和标签转化为张量
dataset=data.TensorDataset(*data_arrays)
#转化成数据集
return data.DataLoader(dataset,batch_size,shuffle=True)
batch_size=10
data_iter=load_array((features,lables),batch_size)
net=nn.Sequential(nn.Linear(2,1))
net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0)
#定义损失函数
loss=nn.MSELoss()
trainer=torch.optim.SGD(net.parameters(),lr=0.03)
#训练过程
num_epoch=3
for epoch in range(num_epoch):
for X,y in data_iter:
l=loss(net(X),y)
trainer.zero_grad()
l.backward()
trainer.step()
l=loss(net(features),lables)
print(f'epoch:{epoch+1},loss:{l:f}')
w=net[0].weight.data
print(w)
b=net[0].bias.data
print(b)
代码解析:
true_w=torch.tensor([2,-3.4])
true_b=4.2
#赋值给特征值和标签
features,lables=d2l.synthetic_data(true_w,true_b,1000)
第一行定义了真实的w和b的数值,这个数值是我们要验证的结果,既,模型预测的结果越接近这个值我们的模型效果越好。
d2l.synthrtic_data(参量a,参量b,总生成数据个数)
def synthic_data(w,b,num_examples):
"生成y=wx+b+噪声"
X=torch.normal(0,1,(num_examples,len(w))
#括号内部的数是normal里的size参数,第一个表示行数,第二个表示列数
#含义是生成num_size行维度是w的长度的参数
y=torch.matmul(X,w)+b
y+=torch.normal(0,0.1,y.shape)#添加噪声,模拟传入模型的真实的数据
return X,y.reshape((-1,1))#将y转化为列向量,方便后续计算
实例化数据集:
batch_size=10
data_iter=load_array((features,lables),batch_size)
#将具体的数据传入函数得到可供训练的实例化数据集data_iter
定义线性回归模型并且赋予w和b的初始值:
net=nn.Sequential(nn.Linear(2,1))
net[0].weight.data.normal_(0,0.01)#用随机生成的正态分布更新权重w
net[0].bias.data.fill_(0)#用0去赋值线性回归的偏置b
进行训练:
loss=nn.MSELoss()#损失函数,差平方
trainer=torch.optim.SGD(net.parameters(),lr=0.03)#采用随机梯度下降更新参数,学习率0.03
#训练过程
num_epoch=3#跑三次
for epoch in range(num_epoch):
for X,y in data_iter:
l=loss(net(X),y)#获取损失
trainer.zero_grad()#清零梯度
l.backward()#反向传播,计算每个参量的梯度
trainer.step()#更新参数,优化器trainer调用,得到新的w',b'
l=loss(net(features),lables)#一轮训练后端损失,越小越好
print(f'epoch:{epoch+1},loss:{l:f}')
结果校验:
w=net[0].weight.data
print(w)
b=net[0].bias.data
print(b)
用来和真实的w和b进行比较越接近说明效果越好。在此学习率下三次就可以很好的收敛了。