喀戎

导航

3.3 线性回归的简洁实现

  1 3.3 线性回归的简洁实现
  2 import torch
  3 from torch import nn
  4 import numpy as np
  5 torch.manual_seed(1)
  6 
  7 print(torch.__version__)
  8 torch.set_default_tensor_type('torch.FloatTensor')
  9 
 10 # 1 生成数据集
 11 num_inputs = 2         # 输入个数(特征数)
 12 num_examples = 1000    # 训练数据集样本数
 13 true_w = [2, -3.4]     # 真实权重
 14 true_b = 4.2           # 偏差
 15 
 16 # features:训练数据特征;labels:标签
 17 features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype= torch.float)
 18 labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b            # y = Xw + b + e
 19 labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)
 20 
 21 # Passage 2 读取数据
 22 import torch.utils.data as Data
 23 
 24 batch_size = 10
 25 
 26 # 将训练数据的特征和标签组合
 27 dataset = Data.TensorDataset(features, labels)
 28 
 29 # 把dataset放入DataLoader,随机读取小批量
 30 data_iter = Data.DataLoader(
 31     dataset=dataset,      # torch TensorDataset format
 32     batch_size=batch_size,      # mini batch size
 33     shuffle=True,               # 要不要打乱数据 (打乱比较好)
 34     # num_workers=Passage 2,              # 多线程来读数据
 35 )
 36 
 37 # 读取并打印第一个小批量数据样本
 38 for X, y in data_iter:
 39     print(X, '\n', y)
 40     break
 41 
 42 # Passage 3 定义模型
 43 # 导入torch.nn模块(neural networks,神经网络)
 44 # nn的核心数据结构为Module,抽象概念,既可以表示神经网络中的某个层,也可以表示一个包含很多层的神经网络
 45 # 常见做法:继承nn.Module,撰写自己的网络/层
 46 # 一个nn.Module实例应该包含一些层以及返回输出的向前传播方法
 47 class LinearNet(nn.Module):
 48     def __init__(self, n_feature):
 49         super(LinearNet, self).__init__()
 50         self.linear = nn.Linear(n_feature, 1)
 51     # forward 定义向前传播
 52     def forward(self, x):
 53         y = self.linear(x)
 54         return y
 55 
 56 net = LinearNet(num_inputs)
 57 print(net)     # 打印出网络的结构
 58 
 59 # nn.Sequential
 60 # Sequential是一个有序的容器,网络层将按照传入Sequential的顺序依次被添加到计算图中
 61 # 写法一:
 62 net = nn.Sequential(
 63     nn.Linear(num_inputs, 1)
 64     # 此处还可以传入其他层
 65 )
 66 
 67 # 写法二:
 68 net = nn.Sequential()
 69 net.add_module('linear', nn.Linear(num_inputs, 1))
 70 # net.add_module......
 71 
 72 # 写法三:
 73 from collections import OrderedDict
 74 net = nn.Sequential(OrderedDict([
 75     ('linear', nn.Linear(num_inputs, 1))
 76     #......
 77 ]))
 78 
 79 print(net)
 80 print(net[0])
 81 
 82 # 通过net.parameters()来查看模型所有的可学习参数,将返回一个生成器
 83 for param in net.parameters():
 84     print(param)
 85 
 86 # 作为一个单层神经网络,线性回归输出层中的神经元和输入层中各个输入完全连接;因此,线性回归的输出层又叫全连接层
 87 # 注意:torch.nn仅支持输入一个batch的样本不支持单个样本输入,如果只有单个样本,可使用input.unsqueeze(0)来添加一维
 88 
 89 # 4 初始化模型参数,例如线性回归中的权重和偏差
 90 # 通过init.normal_将权重参数每个元素初始化为随机采样于均值为0,标注差为0.01的正态分布,偏差会初始化为零
 91 from torch.nn import init
 92 
 93 init.normal_(net[0].weight, mean=0, std=0.01)
 94 init.constant_(net[0].bias, val=0.0)
 95 # 可以直接修改bias的data: net[0].bias.data.fill_(0)
 96 
 97 for param in net.parameters():
 98     print(param)
 99 
100 # 5 定义损失函数
101 # 损失函数可看作是一种特殊的层
102 loss = nn.MSELoss()   # 使用均方误差
103 
104 # 6 定义优化算法
105 # torch.optim模块提供了很多常用的优化算法,例如:SGD,Adam和RMSProp等
106 # 创建一个用于优化net所有参数的优化器实例,并指定学习率为0.03的小批量随机梯度下降(SGD)为优化算法
107 import torch.optim as optim
108 
109 optimizer = optim.SGD(net.parameters(), lr=0.03)
110 print(optimizer)
111 
112 # 还可以为不同子网络设置不同的学习率,在finetune时经常用到
113 # optimizer = optim.SGD([
114 #     # 如果对某个参数不指定学习率,就使用最外层的默认学习率
115 #     {'params': net.subnet1.parameters()},   # lr=0.01
116 #     {'params': net.subnet2.parameters(), 'lr': 0.01}
117 # ], lr=0.03)
118 
119 # 调整学习率
120 # 法一:修改optimizer.param.groups中对应的学习率
121 # 法二(推荐):新建优化器,由于optimizer十分轻量级,构建开销很小,故而可以构建新的optimizer
122 # 但是后者对于使用动量的优化器(如Adam),会丢失动等状态信息,可能会造成损失函数的收敛出现震荡等情况
123 # for param_group in optimizer.param_groups:
124 #     param_group['lr'] *= 0.1    # 学习率为之前的0.1倍
125 
126 # 7 训练模型
127 num_epochs = 3
128 for epoch in range(1, num_epochs + 1):
129     for X, y in data_iter:
130         output = net(X)
131         l = loss(output, y.view(-1, 1))
132         optimizer.zero_grad() # 梯度清零,等价于net.zero_grad()
133         l.backward()
134         optimizer.step()
135     print('epoch %d, loss: %f' % (epoch, l.item()))
136 
137 dense = net[0]
138 print(true_w, dense.weight.data)
139 print(true_b, dense.bias.data)

 

posted on 2021-03-12 17:13  Estrellay  阅读(54)  评论(0编辑  收藏  举报