Pytorch从0到1之前向神经网络——(4)

开篇

这次我们来用pytorch实现一个自己的前向神经网络。与其说是神经网络不如就把它当成一个感知机理解,并没有达到deep-learning层面的神经网络,这是由简单的连接层和激活层组成,为后面介绍deep-learning领域的基础神经网络热热身。开始吧。

搭建前向神经网络

引入库

import torch
import torchvision
import torch.nn as nn
import torchvision.transforms as transforms

设备的配置

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

这里我们都默认大家有cuda,就算没有cuda就用cpu来跑模型。
参数的定义

input_size = 784
hidden_size = 500
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001

参数包括输入数据的尺寸、隐藏层输出的尺寸、数据类别数、训练轮数、批数、学习率
准备数据(下载数据)
我们仍然使用经典的MNIST数据集。

train_dataset = torchvision.datasets.MNIST(root = '../../data',
                                           train=True,
                                           transforms = transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root = '../../data',
                                          train = False,
                                          transforms = transforms.ToTensor())~

数据的加载

train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
                                           batch_size = batch_size,
                                           shuffle = True)
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
                                          batch_size = batch_size,
                                          shuffle = False)
~

搭建一个全连接神经网络,有一个隐藏层

# 我们自己的神经网络class,应该继承nn.Module,成为它的子类
class NeuralNet(nn.Module):
    def __init__(self,input_size,hidden_size,num_classes):
        # Pytorch类的编写必有这条语句
        super(NeuralNet, self).__init__()
        self.fc1 = nn.Linear(input_size,hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size,num_classes)
    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        return out~

利用搭建好的网络定义一个模型

model = NeuralNet(input_size,hidden_size,num_classes).to(device)~

定义损失函数以及优化器

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(),lr=learning_rate)~

上次我们已经说了,Logistic回归之所以重要是因为他的内部一些细节我们以后要经常用到。例如logistic回归可以做分类问题,因为sigmoid函数可以将最后的输出限制在0-1之间.而且它的损失函数也是我们未来在神经网络中要用到的(分类基本都会用)。
优化器我们选Adam优化器(一些梯度下降的内部原理希望大家掌握,有一些偏的就算了,在这里推荐几种,比如动量梯度下降,RMsprop,SGD,批量梯度下降,牛顿梯度下降,拟牛顿梯度下降以及坐标梯度下降,其他的例如Adagrad,AdaDelta之类的没有必要,想了解也可以了解一下)
训练模型

total_step = len(train_loader)
for epoch in range(num_epochs):
    for i,(images,labels) in enumerate(train_loader):
      
        # -1表示batch_size
        images = images.reshape(-1,28 * 28).to(device)
        labels = labels.to(device)

        # 前向传播
        outputs = model(images)
        loss = criterion(outputs,labels)

        # 反向传播及优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if (i + 1) % 100 == 0:
            print('Epoch [{}/{}],Step [{}/{}],Loss:{:.4f}'
                  .format(epoch+1,num_epochs,i+1,total_step,loss.item()))~

测试模型

#测试阶段不用计算梯度
with torch.no_grad():
    correct = 0
    total = 0
    for images,labels in test_loader:
        images = images.reshape(-1,28*28).to(device)
        labels = labels.to(device)
        outputs = model(images)
        _,predicted = torch.max(outputs.data,1)
        total += labels.size(0)
        # tensor.item()是取出张量中的元素值
        correct += (predicted == labels).sum().item()
    print('Accuracy of the network on the 10000 test images: {} %'.format(100 * correct / total))~

保存模型

torch.save(model.state_dict(), 'model.ckpt')~

总结

这次的内容虽然比较简单,那是因为我们用的是框架啊兄弟们。框架内部都帮我们写好了所有函数了,我们只需要拿来用就好了。相信任何一个对深度学习机器学习感兴趣的朋友都不想被冠以调包侠的称号。可是这么好的东西我们为什么不拿来用呢?一定要一个梯度下降就用30-40行代码去解决的人才不是调包侠嘛?我觉得我们一定要清楚内部原理的基础上再用这些东西才能更加得心应手。所以调包不是问题,但一定要搞懂内部算法的细节。各位加油!
下次我们说ConvNet。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值