pytorch学习笔记【3,前馈神经网络】

这次课我们介绍如何使用深度学习框架pytorch实现简单的前馈神经网络。前馈神经网络和逻辑回归的区别在于,前馈神经网络的深度较于逻辑回归来说是更大的。相当于将好几个逻辑回归模型叠罗汉一样的堆叠起来,之后形成了前馈神经网络。

具体代码实现如下:

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

首先也是先导入对应的包。

batch_size = 64
learning_rate = 1e-2
num_epochs = 50
use_gpu = torch.cuda.is_available()

之后定义对应的参数:batch_size表示一次进入前馈神经网络的图片数目,learning_rate表示学习率,num_epochs表示数据集中的数据需要循环多少次,use_gpu表示能否使用gpu对网络进行加速处理。

# 下载训练集 MNIST 手写数字训练集
train_dataset = datasets.FashionMNIST(
    root='../datasets', train=True, transform=transforms.ToTensor(), download=True)

test_dataset = datasets.FashionMNIST(
    root='../datasets', train=False, transform=transforms.ToTensor())

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

之后我们下载数据集中的数据,并且将数据集中的数据转换为张量。之后我们设计训练数据和测试数据的迭代器,用于对数据的迭代。

# 定义简单的前馈神经网络
class neuralNetwork(nn.Module):
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super(neuralNetwork, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Linear(in_dim, n_hidden_1),
            nn.ReLU(True))
        self.layer2 = nn.Sequential(
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True))
        self.layer3 = nn.Sequential(
            nn.Linear(n_hidden_2, out_dim),
            nn.ReLU(True))

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        return x

model = neuralNetwork(28 * 28, 300, 100, 10)
if use_gpu:
    model = model.cuda()

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

之后我们定义模型以及损失函数和更新函数:

定义模型:模型neuralNetwork也是继承了基类nn.Module,因此我们需要定义两个方法,一个是__init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim)用于初始化模型,其中这个方法的参数分别表示(输入维度,经过第一层网络的维度,经过第二层网络的维度,输出维度)。之后每一层都是全连接层,每一层的损失函数都是ReLU函数。另一个方法是forward(self, x),用来表示前向传播。

之后我们使用model = neuralNetwork(28 * 28, 300, 100, 10)语句去初始化这个网络模型,其中网络的输入是28*28的图片,经过第一层的输出是300,第二层的输出是100,最终的输出是10。如果当前gpu可用的话,我们便把模型放置在gpu上用于加速,如果当前gpu是不可用的话,我们便将模型放置在cpu上。

最后我们定义损失函数以及更新函数。

for epoch in range(num_epochs):
    print('*' * 10)
    print(f'epoch {epoch+1}')
    running_loss = 0.0
    running_acc = 0.0
    for i, data in enumerate(train_loader, 1):
        img, label = data
        img = img.view(img.size(0), -1)
        if use_gpu:
            img = img.cuda()
            label = label.cuda()
        # 向前传播
        out = model(img)
        loss = criterion(out, label)
        running_loss += loss.item()
        _, pred = torch.max(out, 1)
        running_acc += (pred == label).float().mean()
        # 向后传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if i % 300 == 0:
            print(f'[{epoch+1}/{num_epochs}] Loss: {running_loss/i:.6f}, Acc: {running_acc/i:.6f}')
    print(f'Finish {epoch+1} epoch, Loss: {running_loss/i:.6f}, Acc: {running_acc/i:.6f}')

之后我们训练这个模型,定义参数running_loss表示损失多少,定义参数running_acc表示准确率多少。之后我们将数据进行整合,如果当前gpu是可用的话,我们将其放置在gpu上,如果当前gpu是不可用的话,我们将其放置在cpu上。之后前向传播用于得到输出以及计算损失,反向传播用于计算梯度和更新参数。

每隔300个数据的时候,我们将数据的损失以及准确率输出,方便我们即时的了解网络。

model.eval()
    eval_loss = 0.
    eval_acc = 0.
    for data in test_loader:
        img, label = data
        img = img.view(img.size(0), -1)
        if use_gpu:
            img = img.cuda()
            label = label.cuda()
        with torch.no_grad():
            out = model(img)
            loss = criterion(out, label)
        eval_loss += loss.item()
        _, pred = torch.max(out, 1)
        eval_acc += (pred == label).float().mean()
    print(f'Test Loss: {eval_loss/len(test_loader):.6f}, Acc: {eval_acc/len(test_loader):.6f}\n')

之后我们在测试集中测试该网络,同时将测试结果进行输出。

# 保存模型
torch.save(model.state_dict(), './neural_network.pth')

最后保存模型以备下次使用。

    原文作者:魏思齐
    原文地址: https://zhuanlan.zhihu.com/p/81084385
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞