框架实现线性回归
创建数据集
创建数据集与之前一样,因为没有数据集,所以需要直接创建数据集。
代码语言:javascript复制#生成数据集
num_inputs = 2 #特征数,数据集的列数
num_examples = 1000 #样本数,数据集的行数
true_w = [2,-3.4] #线性模型的真实权重
true_b = 4.2 #线性模型的真实偏差
featrues = torch.randn(num_examples,num_inputs,dtype = torch.float32)
#使用随机张量函数,生成一个1000行2列的随机张量
labels = true_w[0]*featrues[:,0] true_w[1]*featrues[:,1] true_b
#使用随机张量作为输入生成一组标签
labels = torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)
#为标签加随机噪声,生成随机噪声方法:使用numpy库的random.normal生成一个均值为0,标准差为0.0.1的正态分布,其大小为1行2000个的行向量。
#在这一部分,使用了两种随机矩阵生成的方法,主要区别是第二个为正态分布。且第二种生成的行向量。
读取数据
2020/2/23/19:35
pytorch提供了data包来读取数据。
代码语言:javascript复制import torch.utils.data as Data
#避免重名,换名处理
batch_size = 10 #小批量数设置为10
dataset = Data.TensorDataset(features,labels)
#将features和labels转化为pytorch框架可以识别的数据集类型。
#数据集的类型是TensorDataset。
data_iter = Data.DataLoader(dataset,batch_size,shuffle=True)
#DataLoader,生成一个迭代器,shuffle:是否开启打乱顺序。
Data.DataLoader包含多个参数
参数 | 功能 |
---|---|
dataset | Dataset类型,从其中加载数据 |
batch_size | int类型,每个批量加载多少个数 |
shuffle | bool类型,每个学习周期都打乱顺序 |
num_workers | int类型,加载数据时使用多少子进程。默认值为0. |
collate_fn | 定义如何取样本,可通过定义自己的函数来实现。(太深奥,暂且跳过) |
pin_memory | 锁页内存处理。(太深奥了,暂且跳过) |
drop_last | bool类型,如果有剩余的样本,True表示丢弃;Flase表示不丢弃 |
使用时牢记
- 第一步导入:import torch.utils.data as Data
- 第二步转化类型:数据集 = Data.TensorDataset(样本集1,样本集2)
- 第三步生成迭代器:迭代器 = Data.DataLoader(数据集,加载数)
定义模型
Pytorch提供了大量预定义的层,使用框架时,主要是需要关注使用哪些层来构造模型。
方法一
使用nn.Module搭配forward来撰写网络或层
代码语言:javascript复制class LinearNet(nn.module):
def __init__(self,n_feature):
super(LinearNet,self).__init__()
#类中固有的
self.linear = nn.Linear(n_feature,1)
#定义一个层。
#定义前向传播
def forward(self,x):
y = self.linear(x)
return y
#这一步是打印出网络的结构
net = LinearNet(num_inputs)
print(net)
方法二
使用nn.Sequential来搭建网络,Sequential是一个有序容器,网络层将按照传入容器的顺序依次添加到计算图中。
代码语言:javascript复制#这里只介绍一种方法
net = nn.Sequential(
nn.Linear(num_inputs,1)
#还可以添加其他层
)
#同样的输出方法
print(net)
#输出第一层
print(net[0])
查看模型参数
通过net.parameters(),可查看模型所有的可学习参数(如权重和偏差),注意:net.parameters()是一个生成器,而非一个函数,所以通过for循环来查看。
代码语言:javascript复制for param in net.parameters():
print(param)
初始化模型参数
使用网络前,需要初始化模型参数,如线性回归模型中的权重和偏差。
代码语言:javascript复制#首先导入pytorch中的init模块
from torch.nn import init
#使用init.normal_将第一层的权重参数初始化为均值为0,标准差为0.01的正态分布
init.normal_(net.linear.weight,mean=0,std=0.01) #这种写法对应方法一
init.normal_(net[0].weight,mean=0,std=0.01) #这种写法对应方法二
#使用init.constant_将偏差初始化为0
init.normal_(net.linear.bias,val=0) #这种写法对应方法一
init.constant_(net[0].bias,val=0) #这种写法对应方法二
#net[0]只适用于net是一个容器时
定义损失函数
pytorch提供了各种损失函数,这些损失函数可看作是一种特殊的层,所以这些损失函数实现为nn.Module的子类。
代码语言:javascript复制#本节使用均方差损失作为损失函数
loss = nn.MSELoss()
定义优化算法
pytorch在torch.optim模块中提供了很多优化算法
代码语言:javascript复制#本节使用小批量随机梯度下降算法(SGD)
import torch.optim as optim
optimizer = optim.SGD(net.parameters(),lr=0.03)
#lr,设置学习率为0.03;net.parameters()导入模型的参数
print(optimizer) #输出优化算法的各项参数
扩展内容:
代码语言:javascript复制#为不同网络设置不同学习率
optimizer = optim.SGD([
{'params':net.subnet1.parameters()}, #不设置lr,默认使用最外层的
{'params':net.subnet2.parameters(),lr=0.01}
],lr = 0.03)
代码语言:javascript复制#调整学习率
for param_group in optimizer.param_groups:
param_group['lr']*=0.1 #学习率调整为之前的0.1倍
训练模型
代码语言:javascript复制num_epochs = 3 #学习周期为3
for epoch in range(1,num_epochs 1):
for X,y in data_iter:
output = net(X) #特征值对应的标签
l = loss(output,y.view(-1,1)) #y.view(-1,1)将y转化为一列的形式,行数无要求
optimizer.zero_grad() #同样的梯度需要清零
l.backward() #对损失函数求梯度
optimizer.step()#调用优化函数,计算模型参数
print('epoch %d loss:%f' %(epoch,l.item()))
程序
代码语言:javascript复制#需要导入的库
import torch #张量计算
from IPython import display #嵌入显示图像
from matplotlib import pyplot as plt #绘制图像
import numpy as np #矩阵运算
import random #生成随机数
import torch.utils.data as Data #避免重名,换名处理
from torch.nn import init #导入初始化模块
import torch.nn as nn #导入构建层需要的模块
import torch.optim as optim #导入内置优化算法的模块
#生成数据集
num_inputs = 2 #特征数,数据集的列数
num_examples = 1000 #样本数,数据集的行数
true_w = [2,-3.4] #线性模型的真实权重
true_b = 4.2 #线性模型的真实偏差
featrues = torch.randn(num_examples,num_inputs,dtype = torch.float32)
#使用随机张量函数,生成一个1000行2列的随机张量
labels = true_w[0]*featrues[:,0] true_w[1]*featrues[:,1] true_b
#使用随机张量作为输入生成一组标签
labels = torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)
#为标签加随机噪声,生成随机噪声方法:使用numpy库的random.normal生成一个均值为0,标准差为0.0.1的正态分布,其大小为1行2000个的行向量。
#在这一部分,使用了两种随机矩阵生成的方法,主要区别是第二个为正态分布。且第二种生成的行向量。
batch_size = 10
dataset = Data.TensorDataset(featrues,labels)
data_iter = Data.DataLoader(dataset,batch_size,shuffle=True)
#输出第一组X和y做测试
# for X,y in data_iter:
# print(X,y)
# break
#定义模型
class Linear(nn.Module):
def __init__(self,n_feature):
super(Linear,self).__init__()
self.linear = nn.Linear(n_feature,1)
def forward(self,x):
y = self.linear(x)
return y
net = Linear(num_inputs) #实例化这个类
#参数初始化
init.normal_(net.linear.weight,mean=0,std = 0.01) #初始化权重为均值为0,标准差为0.01正态分布
init.constant_(net.linear.bias,val=0) #初始化偏差为0
#定义损失函数(均方差损失函数)
loss = nn.MSELoss()
#定义优化算法(同样的小批量随机梯度下降算法)
optimizer = optim.SGD(net.parameters(),lr = 0.03)
#训练过程
num_epochs = 3 #学习周期
for epoch in range(1,num_epochs 1):
for X,y in data_iter:
output = net(X)
l = loss(output,y.view(-1,1))
optimizer.zero_grad() #梯度清零
l.backward()
optimizer.step() #计算出优化得到的参数值
print('epoch %d | loss:%f' %(epoch,l.item()))
print(true_w,'n',net.linear.weight)
print(true_b,'n',net.linear.bias)