Torch架构图

学习的内容实在torch.nn这个模块下,所以就学习使用封装好的torch.nn模块来实现第一个深度神经网络的正向传播。

数据集设计

数据量 特征数 标签量
500 20 3

神经网络设计

网络层次 神经元个数 所在层激活函数
输入层 20 -
第一层 13 Relu
第二层 8 sigmoid
第三层(输出层) 3 softmax

其中,输入层神经元个数由数据集特征数决定,经过一个三层神经网络,最后输出一个三分类。

代码设计

导包

import torch 
import torch.nn as nn
from torch.nn import functional as F

定义数据集

torch.random.manual_seed(420)
X=torch.rand((500,20),dtype=torch.float32) #X是数据集,一共500行20列,500个样本20个特征
y=torch.randint(low=0,high=3,size=(500,1),dtype=torch.float32) 
#y是标签,从0,1,2三个数值里面选一个,大小是500行1列

 使用随机数种子,随机生成一组数据,便于后续复现过程。

定义神经网络架构

class Model(nn.Module):
    def __init__(self,in_features=10,out_features=2):
        """
        in_features:输入层上的神经元数目
        out_features:输出层上的神经元数目
        """
        super(Model,self).__init__()
        self.linear1 = nn.Linear(in_features,13,bias=True) #隐藏层第一层
        self.linear2 = nn.Linear(13,8,bias=True)#隐藏层第二层
        self.output = nn.Linear(8,out_features,bias=True)#隐藏层第三层,输出层

    def forward(self,x):#神经网络的前向传播
        z1 = self.linear1(x)
        sigma1=torch.relu(z1)
        z2 = self.linear2(sigma1)
        sigma2 = torch.sigmoid(z2)
        z3 = self.output(sigma2)
        sigma3 = F.softmax(z3,dim=1)
        return sigma3

通过定义一个Model类,用它来继承nn.Module类来完成神经网络的架构设计。

定义解释

① __init__是定义类本身,只要这个类被实例化,那一瞬间就会被执行。

super()参数解释:super(请查找目前这个类的父亲,请使用找到的父类来替换目前的类)

super()方法必须调用,否则无法使用使用 PyTorch 的核心功能。

输入层不用写,直接定义两个隐藏层,和最后的输出层,正好三层神经网络。

nn.Linear()参数解释:nn.Linear(两层之间左边输入神经元的个数,两层之间右边接收神经元的个数,是否具有偏置项bias)

nn.Linear()是 PyTorch 的线性层(全连接层),功能是计算y = x·W + bW为权重矩阵,b为偏置项)。

②forward,神经网络的前向传播,定义整个神经网络的前进过程,init被执行完毕后,就可以被调用使用。

数据流动步骤

1.输入X,形状(500,20),传入linear1计算得到z1,从输入层传到了第一层

2.在第一层使用Relu函数对z1进行处理,得到sigma1,其将作为去往下一层的输入

3.sigma1传入linear2计算得到z2,从第一层传到了第二层

4.在第二层使用sigmoid函数对z2进行处理,得到sigma2,将其作为去往下一层的输入

5.sigma2传入output计算得到z3,从第二层传到了输出层

6.在输出层使用softmax函数对ze进行处理,得到sigma3,作为神经网络的总输出

实例化神经网络

input_ = X.shape[1] #特征的数目
output_ = len(y.unique()) #分类的数目

shape[1]获取数据集的列数,即数据集的特征总数

y.unique()获取标签所有不同取值的集合,即三个分类:0,1,2;使用len()方法获取集合总数3。

torch.manual_seed(420)
net = Model(in_features=input_, out_features=output_)

代码执行的一瞬间,net被创建,并且类中的linear层就已经自动定义好了随机的w和b,需要随机数种子方便复现。

#前向传播
net.forward(X)

调用forward()方法,传入X数据集,运行神经网络。

输出结果

输出结果是一个(500,3)形状的矩阵,每一行代表一个样本,每一列代表这个样本所属类别的概率。

加餐

对权重矩阵的理解

输入的数据集是X(500,20),输入到神经网络后,会自动进行一次转置,成(20,500)的结构,此时才可以和线性层上的权重矩阵w进行相乘,获得正确的与下一层神经元对应的结构

第一个线性层的权重矩阵(13,20),对应输入层20个神经元,第一层13个神经元

第二个线性层的权重矩阵(8,13),对应第一层13个神经元,第二层8个神经元

第三个线性层的权重矩阵(3,8),对应第二层8个神经元,输出层3个神经元

正好是相反的,所以权重矩阵才这么个样子

在最后获得(3,500)的结构后,最后输出时会重新进行一次转置,变为(500,3)的结构输出结果

对偏置项的理解

对继承方法的理解

通过使用super函数,神经网络模型从nn.Module那里继承了很多有用的属性和方法。首先, 如果不加super函数,神经网络的向前传播是无法运行的。nn.Module类的定义代码有一千多行,其__init__函数中有许多复杂的内容需要被继承,因此super函数 一定不能漏下。

继承的有用的方法:

​#属性的继承
net.training #是否用于训练
#方法的继承
net.cuda() #网络转移到gpu上运行
net.cpu()  #网络转移到cpu上运行
net.apply() #对__init__中的所有对象(全部层)都执行同样的操作
net.parameters() #一个迭代器,可以通过循环的方式查看里面究竟是什么内容
for param in net.parameters():
    print(param)   #可以查看每一层的权重矩阵,偏置都是什么之类的

总结

再接再厉,冲鸭!

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐