Python PyTorch3:神经网络、回归计算

1. 神经网络的结构

全连接(FC)网络结构是最基本的神经网络结构,每一个节点与上一层中的所有节点相连接。

BP神经网络由输入层、隐藏层和输出层组成。输入层和输出层的节点数取决于问题需要的输出和输出变量的个数,隐藏层节点数需要由开发者进行调试。

在神经网络中,只有数据非线性分离时才需要隐藏层。对于一般的数据集,1~2层隐藏层已经足够了。

隐藏层中的神经元数量由开发者调试获得。在隐藏层中使用太少的神经元将导致欠拟合。相反,使用过多的神经元可能会导致过拟合等问题。选择合适的隐藏层神经元数量至关重要。通常情况下,对所有隐藏层使用相同数量的神经元。与在每一层中添加更多的神经元相比,添加层数将获得更大的性能提升。因此,不要在一个隐藏层中加入过多的神经元。

Python PyTorch3:神经网络、回归计算_第1张图片

2. 线性回归

PyTorch中使用torch.nn创建一个神经网络。自定义的神经网络继承nn.Module类。nn.Module包含神经层。在神经网络类的init构造函数中定义网络结构,forward(input)可以用来返回output输出结果。

import numpy as np
import matplotlib.pyplot as plt
from torch import nn, optim
from torch.autograd import Variable
import torch

# 创建线性函数+噪声
x_data = np.random.rand(100)
noise = np.random.normal(0, 0.01, x_data.shape)
y_data = x_data * 0.1 + 0.2 + noise

# PyTorch需要传入2维数据
x_data = x_data.reshape(-1, 1)
y_data = y_data.reshape(-1, 1)

# 把numpy数据变成tensor
x_data = torch.FloatTensor(x_data)
y_data = torch.FloatTensor(y_data)
# 将tensor转为pytorch的变量 数据的输入
inputs = Variable(x_data)
# 将tensor转为pytorch的变量 数据的目标值 输出
target = Variable(y_data)


# 构建神经网络模型
# 类名可以随便取,需要继承torch.nn.Module类
class LinearRegression(nn.Module):
    # 初始化方法,定义网络结构
    # 一般把网络中具有可学习参数的层放在__init__()中
    def __init__(self):
        # 初始化nn.Module父类
        super(LinearRegression, self).__init__()
        # 全连接层
        # 输入1个神经元(x),输出1个神经元(y)
        self.fc = nn.Linear(1, 1)

    # 定义网络计算
    def forward(self, x):
        # 将x传入全连接层做计算
        out = self.fc(x)
        return out


# 定义模型
model = LinearRegression()
# 定义代价函数
mse_loss = nn.MSELoss()
# 定义优化器 lr学习率
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 循环模型参数的名称和数值,包括权值和偏置值
for name, parameters in model.named_parameters():
    print('name:{}, param:{}'.format(name, parameters))

# 训练循环1001次
for i in range(1001):
    out = model(inputs)
    # 计算loss
    loss = mse_loss(out, target)
    # 梯度清0
    optimizer.zero_grad()
    # 计算梯度
    loss.backward()
    # 修改权值
    optimizer.step()
    if i % 200 == 0:
        print(i, loss.item())

# 将inputs传给模型得到预测值
y_pred = model(inputs)
plt.scatter(x_data, y_data)
plt.plot(x_data, y_pred.data.numpy(), 'r-', lw=3)
plt.show()

输出:

name:fc.weight, param:Parameter containing:
tensor([[0.4561]], requires_grad=True)
name:fc.bias, param:Parameter containing:
tensor([0.7357], requires_grad=True)
0 0.5190306901931763
200 9.697255882201716e-05
400 9.521372703602538e-05
600 9.520256571704522e-05
800 9.520251478534192e-05
1000 9.520247840555385e-05

Python PyTorch3:神经网络、回归计算_第2张图片

3. 非线性回归

import numpy as np
import matplotlib.pyplot as plt
from torch import nn, optim
from torch.autograd import Variable
import torch

# 创建非线性函数+噪声
x_data = np.linspace(-2, 2, 200)
noise = np.random.normal(0, 0.2, x_data.shape)
y_data = np.square(x_data) + noise

x_data = x_data.reshape(-1, 1)
y_data = y_data.reshape(-1, 1)

# 把numpy数据变成tensor
x_data = torch.FloatTensor(x_data)
y_data = torch.FloatTensor(y_data)
inputs = Variable(x_data)
target = Variable(y_data)


# 构建神经网络模型
# 一般把网络中具有可学习参数的层放在__init__()中
class LinearRegression(nn.Module):
    # 定义网络结构
    def __init__(self):
        # 初始化nn.Module
        super(LinearRegression, self).__init__()
        # 非线性回归需要加隐藏层
        # 输入1个神经元,输出10个神经元
        self.fc1 = nn.Linear(1, 10)
        # 非线性回归需要加入隐藏层,隐藏层的意义就是把输入数据的特征,抽象到另一个维度空间,来展现其更抽象化的特征,这些特征能更好的进行线性划分。
        # 在隐藏层中加入tanh激活函数
        self.tanh = nn.Tanh()
        # 输入10个神经元,输出1个神经元
        self.fc2 = nn.Linear(10, 1)

    # 定义网络计算
    def forward(self, x):
        x = self.fc1(x)
        x = self.tanh(x)
        x = self.fc2(x)
        return x


# 定义模型
model = LinearRegression()
# 定义代价函数
mse_loss = nn.MSELoss()
# 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.3)

for name, parameters in model.named_parameters():
    print('name:{}, param:{}'.format(name, parameters))

for i in range(2001):
    out = model(inputs)
    # 计算loss
    loss = mse_loss(out, target)
    # 梯度清0
    optimizer.zero_grad()
    # 计算梯度
    loss.backward()
    # 修改权值
    optimizer.step()
    if i % 200 == 0:
        print(i, loss.item())

y_pred = model(inputs)
plt.scatter(x_data, y_data)
plt.plot(x_data, y_pred.data.numpy(), 'r-', lw=3)
plt.show()

输出:

name:fc1.weight, param:Parameter containing:
tensor([[-0.5076],
        [-0.2512],
        [ 0.3506],
        [-0.3037],
        [ 0.9912],
        [ 0.3866],
        [ 0.1229],
        [ 0.2591],
        [ 0.3712],
        [ 0.8306]], requires_grad=True)
name:fc1.bias, param:Parameter containing:
tensor([-0.0394,  0.7240, -0.5776,  0.7237, -0.0722, -0.7205,  0.9501, -0.1061,
         0.2135, -0.9476], requires_grad=True)
name:fc2.weight, param:Parameter containing:
tensor([[-0.0502, -0.1002,  0.2274, -0.2604,  0.2435,  0.3001,  0.0657, -0.0459,
         -0.2467, -0.2012]], requires_grad=True)
name:fc2.bias, param:Parameter containing:
tensor([0.2703], requires_grad=True)
0 3.604307174682617
200 0.07464659959077835
400 0.09846562147140503
600 0.08561816811561584
800 0.0697840079665184
1000 0.058194875717163086
1200 0.05261123552918434
1400 0.0494537353515625
1600 0.04836893081665039
1800 0.048560041934251785
2000 0.04887966811656952 

Python PyTorch3:神经网络、回归计算_第3张图片

你可能感兴趣的:(Python,python,深度学习,pytorch)