通过深度学习框架来实现线性回归模型
1.生成数据集
#导入包 import numpy as np import torch from torch.utils import data#torch.utils.data中含有处理数据的模块 from d2l import torch as d2l #真实值 true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = d2l.synthetic_data(true_w, true_b, 1000)
通过人工合成的数据集synthetic_data来生成真实的features(训练数据特征),lables(标签)
2.读取数据
调用框架中现有的API来读取数据
将features和labels作为API的参数传递,通过数据迭代器指定batch_size
is_train:是否希望数据迭代器对象在每个迭代周期内打乱数据
def load_array(data_arrays,batch_size,is_train=True): '''构造一个pytorch数据迭代器''' dataset=data.TensorDataset(*data_arrays) #将features,labels以list的形式传入TensorDataset,即传入x,y.*data_arrays就是存储x,y的表 return data.DataLoader(dataset,batch_size,shuffle=is_train)#调用data.DataLoader,将dataset中合成的数据集每次随机(shuffle)选取batch_size(10个)数据 batch_size=10 #每次小批量更新的数据个数 data_iter=load_array((features,lables),batch_size)#数据生成器 next(iter(data_iter))#将data_iter用iter()函数转为迭代器,再使用next()函数从迭代器中获取数据
注释:
1)pytorch中的TensorDataset和DataLoader:
#首先导入包
from torch.utils.data import TensorDataset
import torch
from torch.utils.data import DataLoader
#具体作用
TensorDataset:用来对tensor进行打包,当中的参数必须是tensor。该类通过每一个tensor的第一个维度进行索引
DataLoader(dataset,batch_size,shuffle=True):用来包装所使用的数据,每次返回一组batch_size个样本和标签进行训练
#TensorDataset&&DataLoader应用 import torch from torch.utils.data import TensorDataset from torch.utils.data import DataLoader a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9]]) b = torch.tensor([11, 22, 33, 44, 55, 66]) #TensorDataset对tensor打包 dataset = TensorDataset(a, b) for x, y in dataset: print(x, y) #DataLoader进行数据封装 loader = DataLoader(dataset, batch_size=3, shuffle=True)#数据迭代器 for id, data in enumerate(loader):# 使用enumerate()方法遍历数据,将列表、元组、字符串的数据给定索引,具有映射的效果 x_data, label = data print('batch:{0},x_data:{1}, label:{2}'.format(id, x_data, label))
enumerate:返回值有两个:一个是序号,也就是在这里的batch地址,一个是数据database
‘{}’.format():用来收集其后的位置参数和关键字段参数,并用他们的值填充字符串中的占位符。通常format()函数配合print()函数达到强格式化的输出能力
2)iter() & next()
iter():用来生成迭代器
iter(object[, sentinel]):
object -- 支持迭代的集合对象。
sentinel -- 如果传递了第二个参数,则参数 object 必须是一个可调用的对象(如,函数),此时,iter 创建了一个迭代器对象,每次调用这个迭代器对象的__next__()方法时,都会调用 object。
next():用来返回迭代器的下一个项目,通常与生成迭代的iter()一起使用。
next(iterable[, default])
iterable – 可迭代对象
default – 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。总结:
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
3. 定义模型
from torch import nn#nn是神经网络的缩写 net = nn.Sequential(nn.Linear(2,1))#Sequential是Linear的容器,Linear(2,1):输入维度是2,输出维度是1
torch.nn.Linear(in_features,out_features,bias=True):n_features指的是输入的二维张量的大小,out_features指的是输出的二维张量的大小
Sequential函数:自动的把所有的神经元按照传入构造器的顺序依次连接起来
4.初始化参数模型
深度学习框架有预定义的方法来初始化参数,指定每个权重参数从均值为0、标准差为0.01的正态分布中随机取样,偏执参数初始化为0
net[0].weight.data.normal_(0, 0.01)#.weight.data:权重的值 net[0].bias.data.fill_(0)#.bisa.data:偏差的值
.normal_(0,0.01):用均值为0,标准差为0.01来代替权重data的值
.fill_(0):用0来替换掉偏差data的值
相当与我们手动实现w,b的值
5. 定义损失函数
loss = nn.MSELoss()
MESLoss类:用来计算均方误差,MES=
6.定义优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
torch.optim:实现各种优化算法的库
SGD是optim中的随机梯度下降算法
torch.optim.SGD(params, lr=lr):params是待优化参数的iterable(w,b的迭代),lr是学习率
7.训练
num_epochs = 3 for epoch in range(num_epochs): for X, y in data_iter:#x为真实值,y为预测值,进行损失函数计算 l = loss(net(X) ,y) trainer.zero_grad()#梯度清零 l.backward()#反向传播 trainer.step()#.step()模型更新 l = loss(net(features), labels) print(f'epoch {epoch + 1}, loss {l:f}')#loss{l:f}:输出l,f表示浮点型(输出小数点后六位)
trainer是一种训练器
w = net[0].weight.data print('w的估计误差:', true_w - w.reshape(true_w.shape)) b = net[0].bias.data print('b的估计误差:', true_b - b)