十六、深入了解pytorch网络构建思路(从面向对象理解神经网络构建的封装、继承、多态)

以一个神经网络构建、前向计算、反向传播、和对验证集进行预测验证代码入手,理解每一步书写思路和过程。

一、神经网络构建

首先,先看一下第十二节中已经写过的深学习代码,以其中一维卷积神经网络构建为例

下面是对这段代码我自己的理解:

网络搭建

  1. 首先构造一个需要的神经网络类Net,让Net继承父类nn.Module中的方法,并且对其初始化和前向计算函数进行重写。

  1. 然后重写初始化函数,这个初始化函数不需要任何参数。Net()就可以初始化网络模型。

  1. 然后使用super()方法,重写父类中的__new__方法,即使用单例模式,首先在父类__new__方法中申请一片构造类的内存空间,然后返回一个引用给__init__方法,接下来就可以进行初始化了。

  1. 然后接下来在初始化方法里,增加类属性,如下面的self.conv1 = nn.Conv1d()就是为类里增加类属性,所以其实这里类属性只是调用了pytorch中已经写好的块或者类如第一个属性是一个类,这个类是一个一维卷积神经网络层,这个nn.Conv1d类中有前向传播的计算的类方法等。即初始化一个类(或者这里可以叫一个神经网络块,因为可以将这个块放在另一个大网络模型中)。其中类的属性是一个类、类本身也是一个类,我们构造的这个包含很多用类作为类属性的类,也可以作为另一个构造类的属性。

  1. 所以在初始化类属性时候,书写顺序其实无所谓,因为前向计算方法会定义函数先使用哪个层进行计算,顺序书写是为了我们看代码的方便性。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=1)
        self.pool1 = nn.MaxPool1d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1)
        self.pool2 = nn.MaxPool1d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(32 * 140, 256)
        self.fc2 = nn.Linear(256, 64)
        self.fc3 = nn.Linear(64, 6)
    def forward(self, x):
        #将张量x的维度从(a,b)变成(a,1,b)。即在第二个维度上增加一个维度,使得原本的每个元素变为一个包含一个元素的张量。
        x = x.unsqueeze(1)
        x = self.conv1(x)
        x = nn.functional.relu(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = nn.functional.relu(x)
        x = self.pool2(x)
        x = x.view(-1, 32 * 140)
        x = self.fc1(x)
        x = nn.functional.relu(x)
        x = self.fc2(x)
        x = nn.functional.relu(x)
        x = self.fc3(x)
        return x

二、前向计算

  1. forward函数,是一个我们定义的类的方法,这个方法需要一个张量x作为参数,然后就像函数一样,顺序执行,先将x传入self.conv1、然后调用relu函数,依次使用各个层的方法。

  1. 类似于sequential块中添加初始化属性。

三、反向传播和训练模型

首先需要定义损失函数和优化器

net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)
#模型训练
for epoch in range(50):
    running_loss = 0.0
    inputs=train_X
    labels = train_Y
    optimizer.zero_grad()
    outputs = net(inputs)
    loss = criterion(outputs, train_Y)
    loss.backward()
    optimizer.step()
    running_loss += loss.item()
    if(epoch%10==0):
        print("第",epoch,"轮训练")  

然后定义训练轮次,每轮都需要进行损失清零、关于传播的inputs的梯度清零。然后将inputs作为net

模型输入,进行前向计算,然后计算反向传播的损失,最后通过优化函数对模型内部计算参数的更新,即反向传播。

使用模型验证或者预测

将测试的数据传入训练好的模型,进行预测前向计算。

_, predicted = torch.max(outputs.data, 1)这个的作用是,将输出数据的值给到value,然后将标签值传给predicted,1代表维度是1。

#模型预测
with torch.no_grad():
    inputs=test_X
    outputs = net(inputs)
    _, predicted = torch.max(outputs.data, 1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小常在学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值