Python:最简单的神经网络分类模型(附带详细注释说明)+ 训练结果可视化+ 模型可视化

# 神经网络的搭建--分类任务 #
# PyTorch由4个主要包装组成:
# 1.Torch:类似于Numpy的通用数组库,可以在将张量类型转换为(torch.cuda.TensorFloat)并在GPU上进行计算。
# 2.torch.autograd:用于构建计算图形并自动获取渐变的包
# 3.torch.nn:具有共同层和成本函数的神经网络库
# 4.torch.optim:具有通用优化算法(如SGD,Adam等)的优化包
import torch  # 深度学习库
import matplotlib.pyplot as plt  # 画图用的库函数
import torch.nn.functional as F  # 激励函数都在这
import numpy as np

# x0,x1是数据,y0,y1是标签
n_data = torch.ones(100, 2)  # 数据的基本形态:100*2的二维张量(tensor)
x0 = torch.normal(2 * n_data, 1)  # 样本类型0 x data (tensor), shape=(100, 2), normal() 生成均值=2,标准差=1的正态分布的随机数
y0 = torch.zeros(100)  # 样本类型0 y data (tensor), shape=(100, )
x1 = torch.normal(-2 * n_data, 1)  # 样本类型1 x data (tensor), shape=(100, 1), normal() 生成均值=-2,标准差=1的正态分布的随机数
y1 = torch.ones(100)  # 样本类型1 y data (tensor), shape=(100, )

# 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)
# torch.cat((x0, x1), dim = 0) 按行拼接
# torch.cat((x0, x1), dim = 1) 按列拼接
x = torch.cat((x0, x1), 0).type(torch.FloatTensor)  # FloatTensor = 32-bit floating
y = torch.cat((y0, y1), 0).type(torch.LongTensor)  # LongTensor = 64-bit integer

# x.data.numpy()将张量转换为与其共享底层存储的 n 维 numpy 数组
# c:表示的是色彩或颜色序列,s:表示的是大小,是一个标量或者是一个shape大小为(n,)的数组,cmap:Colormap,标量或者是一个colormap的名字,cmap仅仅当c是一个浮点数数组的时候才使用
# plt.scatter()函数解析(最清晰的解释):https://blog.csdn.net/TeFuirnever/article/details/88944438
plt.figure(1)
plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap='RdYlGn')
plt.show()  # 图形显示


# 建立神经网络
class Net(torch.nn.Module):  # 继承 torch 的 Module,它是所有的神经网络的根父类! 你的神经网络必然要继承
    def __init__(self, n_feature, n_hidden, n_output):  # n_feature=特征数量, n_hidden=隐藏层个数, n_output=类别数量
        super(Net, self).__init__()  # 继承 __init__ 功能
        self.hidden = torch.nn.Linear(n_feature, n_hidden)  # 隐藏层线性输出
        self.out = torch.nn.Linear(n_hidden, n_output)  # 输出层线性输出

    def forward(self, x):  # 正向传播输入值, 神经网络分析出输出值
        x = F.relu(self.hidden(x))  # ReLU激励函数(隐藏层的线性值)
        x = self.out(x)  # 输出值, 但是这个不是预测值, 预测值还需要再另外计算
        return x


net = Net(n_feature=2, n_hidden=10, n_output=2)  # 几个类别就几个 output

# 训练网络
# 算误差的时候, 注意真实值不是one-hot形式的, 而是1D Tensor, (batch,),但是预测值是2D tensor (batch, n_classes)
# torch.optim是实现各种优化算法的包,学习率lr=0.02
# SGD 就是随机梯度下降 opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
# momentum 动量加速,在SGD函数里指定momentum的值即可 opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
# RMSprop 指定参数alpha ,opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
# Adam 参数betas=(0.9, 0.99),opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
# torch.nn.CrossEntropyLoss交叉熵损失函数
optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
loss_func = torch.nn.CrossEntropyLoss()

plt.figure(2)
plt.ion()  # 动态画图窗口
plt.show()
lossAll = []
for t in range(100):  # 训练100次
    out = net(x)  # 喂给 net 训练数据 x, 输出分析值
    loss = loss_func(out, y)  # 计算两者的误差
    lossAll.append(loss.data.numpy())
    optimizer.zero_grad()  # optimizer.zero_grad() 清空过往梯度;
    loss.backward()  # 反向传播,计算当前梯度
    optimizer.step()  # 根据梯度更新网络参数

    # 可视化展示
    if t % 2 == 0:
        plt.cla()  # 清除figure(2)的内容
        # SoftMax:https://blog.csdn.net/weixin_43643082/article/details/134731130
        # F.softmax(input, dim=0)  # 按列SoftMax,列和为1
        # F.softmax(input, dim=1)  # 按行SoftMax,行和为1
        # torch.max(input, dim=0)  # 按列取max
        # torch.max(input, dim=1)  # 按行取max
        prediction = torch.max(F.softmax(out), 1)[1]  # 过了一道 softmax 的激励函数后的最大概率才是预测值
        # np.squeeze()函数可以删除数组形状中的单维度条目,即把shape中为1的维度去掉,但是对非单维的维度不起作用
        pred_y = prediction.data.numpy().squeeze()
        target_y = y.data.numpy()
        plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap='RdYlGn')
        accuracy = sum(pred_y == target_y) / 200.  # 计算准确度
        plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'red'})
        plt.pause(0.1)

plt.ioff()  # 停止画图
plt.show()

lossAll = np.array(lossAll)
plt.figure(3)
plt.plot(range(lossAll.size), lossAll,
         marker='o',     # 标记样式:圆点
         linestyle='-',  # 线条样式:实线
         color='green',  # 线条颜色:蓝色
         linewidth=2,    # 线宽:2
         markersize=10)
plt.title('Loss')
plt.show()


import netron
scripted_model = torch.jit.script(net)  # 保存模型
torch.jit.save(scripted_model, '.net.pth')
netron.start('.net.pth')  # 可视化

Python:最简单的神经网络分类模型(附带详细注释说明)+ 训练结果可视化+ 模型可视化_第1张图片

https://blog.csdn.net/qq_37333048/article/details/110479438

你可能感兴趣的:(python编程,监督学习系列,python,神经网络,分类)