本章节直接使用pytorch的Module模块进行处理
数据获取
为了便于分析,我们使用y = 5x+6模拟生成一些数据
import torch as tt
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
num_inputs = 1#特征个数,这里是验证一元线性回归,因此只有一个
num_examples = 2000#样本数量
true_w = 5
true_b = 6
features = tt.from_numpy(np.random.normal(0,1,(num_examples, num_inputs)))
labels = true_w * features[:,0] + true_b
features.shape , labels.shape
(torch.Size([2000, 1]), torch.Size([2000]))
增加一些噪声数据表示干扰数据
labels +=tt.from_numpy(np.random.normal(0,1, size = labels.size()))
plt.plot([-3, 3],[true_w*-3 + true_b,true_w*3 + true_b])#实际直线
plt.scatter(features[:,0].numpy(), labels.numpy(),1, c='#ff0000')#待预测点
使用torch data方式
import torch.utils.data as Data
batch_size = 10
# 将训练数据的特征和标签组合
dataset = Data.TensorDataset(features, labels)
# 随机读取小批量数据
data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)
for X, y in data_iter:
print(X, y)
break
tensor([[ 0.8268],
[-0.3417],
[ 1.0532],
[-0.7464],
[ 0.2127],
[ 1.5058],
[-1.8164],
[ 0.3935],
[-1.7147],
[ 0.4632]], dtype=torch.float64) tensor([10.1198, 0.1464, 12.5457, 3.1294, 5.1193, 13.0932, -1.6789, 8.5371,
-3.2574, 7.9574], dtype=torch.float64)
定义模型
import torch.nn as nn
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可以打印
for param in net.parameters():
print(param)
LinearNet(
(linear): Linear(in_features=1, out_features=1, bias=True)
)
Parameter containing:
tensor([[0.3936]], requires_grad=True)
Parameter containing:
tensor([-0.7839], requires_grad=True)
初始化模型参数
from torch.nn import init
init.normal_(net.linear.weight, mean = 0, std = 0.01 )
init.constant_(net.linear.bias, val = 0)
Parameter containing:
tensor([0.], requires_grad=True)
print(net) # 使⽤用print可以打印
for param in net.parameters():
print(param)
LinearNet(
(linear): Linear(in_features=1, out_features=1, bias=True)
)
Parameter containing:
tensor([[0.0089]], requires_grad=True)
Parameter containing:
tensor([0.], requires_grad=True)
优化算法
import torch.optim as optim
optimizer = optim.SGD(net.parameters(),lr = 0.03)
optimizer
SGD (
Parameter Group 0
dampening: 0
lr: 0.03
momentum: 0
nesterov: False
weight_decay: 0
)
optimizer.param_groups
[{'params': [Parameter containing:
tensor([[0.0089]], requires_grad=True),
Parameter containing:
tensor([0.], requires_grad=True)],
'lr': 0.03,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
训练模型
num_epochs = 3
loss = nn.MSELoss()
for epoch in range(1, num_epochs+1):
for x, y in data_iter:
output = net(x.float())#模型输出
l = loss(output.float(), y.view(-1,1).float())#计算损失指
net.zero_grad()#梯度清零
l.backward()#反向传播
optimizer.step()#更新权重参数
print('--------------epoch {}, loss {}'.format(epoch, l))
for param in net.parameters():
print(param)
--------------epoch 1, loss 1.6837152242660522
Parameter containing:
tensor([[5.0119]], requires_grad=True)
Parameter containing:
tensor([5.9765], requires_grad=True)
--------------epoch 2, loss 0.9597989320755005
Parameter containing:
tensor([[4.9659]], requires_grad=True)
Parameter containing:
tensor([5.9982], requires_grad=True)
--------------epoch 3, loss 1.4597216844558716
Parameter containing:
tensor([[4.9286]], requires_grad=True)
Parameter containing:
tensor([6.0770], requires_grad=True)
如上所示,训练3个epochs既可以达到真实的精度了