神经网络之关系拟合(回归)

【注】由于本人新手入门,花了很长时间几乎对每一行、每一个函数都加入了注释来解释,希望能帮助到和我一样的初学者。

---------------------------------------------------------------------------------------------------------------------------------

拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。因为这条曲线有无数种可能,从而有各种拟合方法。拟合的曲线一般可以用函数表示,根据这个函数的不同有不同的拟合名字。

关系拟合(回归)主要研究神经网络是如何通过简单的形式将一群数据用一条线条来表示. 或者说, 是如何在数据当中找到他们的关系, 然后用神经网络模型来建立一个可以代表他们关系的线条。

接下来直接上代码!

import torch
import torch.nn.functional as F  # 损失函数第三方库
import matplotlib.pyplot as plt

# 获取数据
"""
【注】
1.torch.unsqueeze(input, dim, out=None):
起升维的作用,参数dim表示在哪个地方加一个维度,dim范围在:[-input.dim() - 1, input.dim() + 1]之间,
比如输入input是一维,则dim=0时数据为行方向扩,dim=1时为列方向扩,再大错误

torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) -> 将生成的100个数据(一维)升维到100行1列的二维数据

2. 0.2 * torch.rand(x.size()) -> 模拟noisy
【如果不加noisy,得到的y仅仅是一条x平方的曲线,而不是一些需要拟合的点】
"""
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)  # torch.linspace(-1, 1, 100) -> 在[-1,1]区间生成100个点
y = x.pow(2) + 0.2 * torch.rand(x.size())  # torch.rand(x.size()) -> 随机生成一个与x形状相同的矩阵,取值在(0,1)区间

# 数据可视化(待拟合的散点)
#plt.scatter(x.numpy(), y.numpy(), color="r")
#plt.show(block=True)

"""
【注】这里的前三行代码是“写死的代码”(继承了nn.Module)
"""
class Net(torch.nn.Module):
    # 初始化函数 -> 搭建“层”需要的信息
    #参数:多少个输入,多少个隐藏层神经元,多少个输出
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()

        """
        神经元之间的传递是线型的,非线性是激励函数实现的
        """
        self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隐藏层(hidden layer),n_feature, n_hidden分别为该层的输入和输出
        self.predict = torch.nn.Linear(n_hidden, n_output)   # 预测层(output layer)【隐藏层的输出是预测层的输入】

    # 前向传递函数 -> 让x流经上面定义的2层
    """
    F.relu(self.hidden(x)):
    self.hidden(x) -> 使用隐藏层加工一下x,x作为输入经过隐藏层,得到输出为n_hidden
    F.relu() -> 用relu激励函数激励n_hidden
    """
    def forward(self, x):

        x = F.relu(self.hidden(x))      # activation function for hidden layer
        x = self.predict(x)             # linear output【输出一般不需要激励函数】
        return x


# 实例化,输入参数
net = Net(n_feature=1, n_hidden=10, n_output=1)     # define the network
# 查看搭建的神经网络
print(net)


# 优化神经网络
"""
net.parameters() -> 神经网络所有(可训练)参数
lr -> 学习率(学习率越高,学习的越快但是效果不好) 【学习率一般小于1】
"""
optimizer = torch.optim.SGD(net.parameters(), lr=0.3)  #SGD:随机梯度下降

# 定义损失函数
"""
损失函数输入是一个输入的pair(对): (output, target),然后计算出一个数值来评估output和target之间的差距大小;
其中output代表的是神经网络评估出来的输出值,target代表(有监督训练的,真实的)标签
torch.nn中有若干个不同的损失函数可供使用,
比如nn.MSELoss就是通过计算均方损失来评估输入和目标值之间从差距【越小越好】
【注】用torch.nn.MSELoss()处理回归问题
"""
# 实例化损失函数
loss_func = torch.nn.MSELoss()


"""
plt.ion()与plt.ioff() -> 画动态图
【注】plt.show()要放在ply.ioff()之后
"""
plt.ion()   # something about plotting

# 训练神经网络(训练100步)
for t in range(100):
    prediction = net(x)     # 输入x到神经网络并且基于x预测输出

    loss = loss_func(prediction, y)     # must be (1. nn output, 2. target)【输出值和目标值(预测值和真实值)】

    # 优化步骤
    # 1.将所有参数的梯度降为0 -> 为了优化神经网络的参数(net.parameters())
    optimizer.zero_grad()
    # 2.反向传播 -> 计算出神经网络中的每一个结点的梯度
    loss.backward()
    # 3.用optimizer以学习率0.3优化梯度,更新神经网络参数
    optimizer.step()

    # 神经网络训练过程可视化
    # 每学习5步就打印一次
    if t % 5 == 0:
        # plot and show learning process
        plt.cla()  # 清空当前图形的当前活动轴,其他轴不受影响
        plt.scatter(x.data.numpy(), y.data.numpy())  # 散点图 -> 因变量是原始的数据
        plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)  # 折线图 -> 因变量是预测的数据
        plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':  'red'})  # 显示图形数值
        plt.pause(0.1)  # 如果当前有活动的图形,在pause函数运行前,图形将会更新并显示,在等待期间事件循环会一直运行,直到暂停时间0.1秒后结束。


plt.ioff()
plt.show(block=True)






你可能感兴趣的:(神经网络,回归,算法,人工智能)