# # 线性回归的从零开始实现 # In[6]: get_ipython().run_line_magic(‘matplotlib‘, ‘inline‘) import torch from IPython import display from matplotlib import pyplot as plt import numpy as np import random # ## 生成数据集 # In[7]: num_inputs = 2 num_examples = 1000 true_w = [2, -3.4] true_b = 4.2 features = torch.randn(num_examples, num_inputs, dtype=torch.float32) labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float32) # In[8]: print(features[0], labels[0]) # In[9]: def use_svg_display(): # 用矢量图显示 display.set_matplotlib_formats(‘svg‘) def set_figsize(figsize=(3.5, 2.5)): use_svg_display() # 设置图的尺寸 plt.rcParams[‘figure.figsize‘] = figsize # # 在../d2lzh_pytorch里面添加上面两个函数后就可以这样导入 # import sys # sys.path.append("..") # from d2lzh_pytorch import * set_figsize() plt.scatter(features[:, 1].numpy(), labels.numpy(), 1); # ## 读取数据 # In[10]: # 本函数已保存在d2lzh包中方便以后使用 def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples)) random.shuffle(indices) # 样本的读取顺序是随机的 for i in range(0, num_examples, batch_size): j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) # 最后一次可能不足一个batch yield features.index_select(0, j), labels.index_select(0, j) # In[11]: batch_size = 10 for X, y in data_iter(batch_size, features, labels): print(X, y) break # ## 初始化模型参数 # In[12]: w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32) b = torch.zeros(1, dtype=torch.float32) # In[13]: w.requires_grad_(requires_grad=True) b.requires_grad_(requires_grad=True) # ## 定义模型 # In[14]: def linreg(X, w, b): # 本函数已保存在d2lzh_pytorch包中方便以后使用 return torch.mm(X, w) + b # ## 定义损失函数 # In[15]: def squared_loss(y_hat, y): # 本函数已保存在d2lzh_pytorch包中方便以后使用 # 注意这里返回的是向量, 另外, pytorch里的MSELoss并没有除以 2 return (y_hat - y.view(y_hat.size())) ** 2 / 2 # ## 定义优化算法 # In[16]: def sgd(params, lr, batch_size): # 本函数已保存在d2lzh_pytorch包中方便以后使用 for param in params: param.data -= lr * param.grad / batch_size # 注意这里更改param时用的param.data # ## 训练模型 # In[17]: lr = 0.03 num_epochs = 3 net = linreg loss = squared_loss for epoch in range(num_epochs): # 训练模型一共需要num_epochs个迭代周期 # 在每一个迭代周期中,会使用训练数据集中所有样本一次(假设样本数能够被批量大小整除)。X # 和y分别是小批量样本的特征和标签 for X, y in data_iter(batch_size, features, labels): l = loss(net(X, w, b), y).sum() # l是有关小批量X和y的损失 l.backward() # 小批量的损失对模型参数求梯度 sgd([w, b], lr, batch_size) # 使用小批量随机梯度下降迭代模型参数 # 不要忘了梯度清零 w.grad.data.zero_() b.grad.data.zero_() train_l = loss(net(features, w, b), labels) print(‘epoch %d, loss %f‘ % (epoch + 1, train_l.mean().item())) # In[18]: print(true_w, ‘\n‘, w) print(true_b, ‘\n‘, b) # # 线性回归的简洁实现 # ## 生成数据集 # In[19]: num_inputs = 2 num_examples = 1000 true_w = [2, -3.4] true_b = 4.2 features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float) labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float) # ## 读取数据 # In[20]: import torch.utils.data as Data batch_size = 10 # 将训练数据的特征和标签组合 dataset = Data.TensorDataset(features, labels) # 随机读取小批量 data_iter = Data.DataLoader(dataset, batch_size, shuffle=True) # In[21]: for X, y in data_iter: print(X, y) break # ## 定义模型 # In[24]: from torch import nn # In[25]: class LinearNet(nn.Module): def __init__(self, n_feature): super(LinearNet, self).__init__() self.linear = nn.Linear(n_feature, 1) # forward 定义前向传播 def forward(self, x): y = self.linear(x) return y net = LinearNet(num_inputs) print(net) # 使用print可以打印出网络的结构 # In[26]: # 写法一 net = nn.Sequential( nn.Linear(num_inputs, 1) # 此处还可以传入其他层 ) # 写法二 net = nn.Sequential() net.add_module(‘linear‘, nn.Linear(num_inputs, 1)) # net.add_module ...... # 写法三 from collections import OrderedDict net = nn.Sequential(OrderedDict([ (‘linear‘, nn.Linear(num_inputs, 1)) # ...... ])) print(net) print(net[0]) # In[27]: for param in net.parameters(): print(param) # ## 初始化模型参数 # In[28]: from torch.nn import init init.normal_(net[0].weight, mean=0, std=0.01) init.constant_(net[0].bias, val=0) # 也可以直接修改bias的data: net[0].bias.data.fill_(0) # ## 定义损失函数 # In[29]: loss = nn.MSELoss() # ## 定义优化算法 # In[30]: import torch.optim as optim optimizer = optim.SGD(net.parameters(), lr=0.03) print(optimizer) # ## 训练模型 # In[31]: 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() # 梯度清零,等价于net.zero_grad() l.backward() optimizer.step() print(‘epoch %d, loss: %f‘ % (epoch, l.item())) # In[32]: dense = net[0] print(true_w, dense.weight) print(true_b, dense.bias)
原文:https://www.cnblogs.com/deeplearning-man/p/12309439.html