PyTorch创建简单神经网络

导包

导入必要的包

import torch
import torch.nn as nn
import torch.nn.functional as F
from matplotlib import pyplot as plt

创建数据集与预处理

创建训练用的数据集,这里训练目标是预测 y = x^2+1 。

torch.manual_seed(42)  # 设置PyTorch随机数种子,使下面每次神经网络参数随机初始化一致
x_train = torch.linspace(-1, 1, 100)
y_train = x_train * x_train + 1 + torch.rand_like(x_train)*0.1
plt.plot(x_train, y_train, '.')  # 数据集可视化
plt.show()
x_train = x_train.unsqueeze(1)  # 将x转换为2维数据,因为pytorch在前向传播时不接收一维数据
y_train = y_train.unsqueeze(1)  # 为了在计算loss的时候保持y_train和神经网络的输出形状一致

创建网络(方法1)

# 定义一个有一个隐藏层,一个输出层的神经网络
class RegNet1(nn.Module):  # 必须继承nn.Module
    def __init__(self, n_features, n_hidden, n_output):
        super(RegNet1, self).__init__()
        self.hidden = nn.Linear(n_features, n_hidden)  # 隐藏层接收输入层的数据
        self.output = nn.Linear(n_hidden, n_output)  # 输出层接收隐藏层的数据

    # 前向传播过程,必须重写
    def forward(self, x):
        x = self.hidden(x)  # 数据经过隐藏层
        # x = F.sigmoid(x)  # F.sigmoid(x)在当前PyTorch版本中已经不建议使用了
        x = torch.sigmoid(x)  # 数据经过激活函数
        x = self.output(x)  # 数据经过输出层
        return x  # 返会输出层结果
      
net = RegNet1(1, 10, 1)  # 初始化网络对象,输入层每次只输入1个特征,隐藏层10个神经元,输出层1个神经元

创建网络(方法2)

这种方法更加简单直观,不用定义类,直接可以创建和上面一样的网络

net = nn.Sequential(
    nn.Linear(1, 10),
    nn.Sigmoid(),
    nn.Linear(10, 1)
)

训练过程

criterion = torch.nn.MSELoss(reduction='mean')  # 定义损失函数,采用均方误差
optimizer = torch.optim.SGD(net.parameters(), lr=0.3)  # 定义优化器,采用SGD
for i in range(1000):  # 迭代1000次
    y_pre = net(x_train)  # 前向传播
    loss = criterion(y_pre, y_train)  # 计算损失
    optimizer.zero_grad()  # 梯度清零
    loss.backward()  # 反向传播
    optimizer.step()  # 使用优化器更新梯度
    if i % 10 == 0:  # 每迭代10次打印一次loss
        print(loss)

训练结果

# 可视化训练结果
plt.plot(x_train, y_train, '.b')  # 绘制训练集
plt.plot(x_train, y_pre.detach().numpy(), '.r')  # 绘制预测结果
plt.show()
posted @ 2020-11-27 11:33  火锅先生  阅读(352)  评论(0编辑  收藏  举报