使用 Pytorch 进行深度学习:理解神经网络示例

Posted

技术标签:

【中文标题】使用 Pytorch 进行深度学习:理解神经网络示例【英文标题】:Deep learning with Pytorch: understanding the neural network example 【发布时间】:2020-01-09 08:45:05 【问题描述】:

我正在阅读Pytorch documentation,我对所介绍的神经网络有几个问题。该文档定义了以下网络:

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

    class Net(nn.Module):

        def __init__(self):
            super(Net, self).__init__()
            # 1 input image channel, 6 output channels, 3x3 square convolution
            # kernel
            self.conv1 = nn.Conv2d(1, 6, 3)
            self.conv2 = nn.Conv2d(6, 16, 3)
            # an affine operation: y = Wx + b
            self.fc1 = nn.Linear(16 * 6 * 6, 120)  # 6*6 from image dimension
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)

        def forward(self, x):
            # Max pooling over a (2, 2) window
            x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
            # If the size is a square you can only specify a single number
            x = F.max_pool2d(F.relu(self.conv2(x)), 2)
            x = x.view(-1, self.num_flat_features(x))
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x

        def num_flat_features(self, x):
            size = x.size()[1:]  # all dimensions except the batch dimension
            num_features = 1
            for s in size:
                num_features *= s
            return num_features

稍后,声明如下:

让我们尝试一个随机的 32x32 输入。注意:这个网络(LeNet)的预期输入大小是 32x32。要在 MNIST 数据集上使用此网络,请将数据集中的图像大小调整为 32x32。

问题 1: 为什么图像需要为 32x32(我假设这意味着 32 x 32 像素)?

第一个卷积将六个内核应用于图像,每个内核都是 3x3。这意味着如果输入通道为 32x32,则六个输出通道的尺寸均为 30x30(3x3 内核网格会让您在宽度和高度上损失 2 个像素)。第二个卷积应用了更多的内核,因此现在有 16 个尺寸为 28x28 的输出通道(同样,3x3 内核网格会使您在宽度和高度上损失 2 个像素)。现在我希望下一层有 16x28x28 个节点,因为 16 个输出通道中的每一个都有 28x28 像素。不知何故,这是不正确的,下一层包含 16x6x6 节点。为什么这是真的?

问题 2: 第二个卷积层从六个输入通道到十六个输出通道。这是怎么做到的?

在第一个卷积层中,我们从一个输入通道变为六个输入通道,这对我来说很有意义。您只需将六个内核应用于单个输入通道即可达到六个输出通道。从六个输入通道到十六个输出通道对我来说意义不大。不同的内核是如何应用的?您是否对前五个输入通道应用两个内核以得到十个输出通道,然后对最后一个输入通道应用六个内核,这样总共有十六个输出通道?或者神经网络是否学会了自己使用 x 个内核并将它们应用于它认为最合适的输入通道?

【问题讨论】:

【参考方案1】:

我现在可以自己回答这些问题了。

问题 1:要了解为什么需要 32x32 图像才能使该神经网络正常工作,请考虑以下几点:

第 1 层: 首先,使用 3x3 内核应用卷积。由于图像的尺寸为 32x32,这将产生 30x30 的网格。接下来,将最大池化应用于网格,使用 2x2 内核和 2 步长,生成尺寸为 15x15 的网格。

第 2 层: 首先,使用 3x3 内核对 15x15 网格应用卷积,得到 13x13 网格。接下来,使用 2x2 内核和 2 步长应用最大池化,从而生成尺寸为 6x6 的网格。我们得到一个 6x6 网格而不是 7x7 网格,因为默认情况下使用 floor 函数而不是 ceil 函数。

由于第 2 层的卷积有 16 个输出通道,所以第一个线性层需要 16x6x6 个节点!我们看到所需的输入确实是 32x32 图像。

问题 2: 每个输出通道都是通过对每个输入通道应用六个不同的内核并对结果求和来创建的。这在documentation 中有解释。

【讨论】:

以上是关于使用 Pytorch 进行深度学习:理解神经网络示例的主要内容,如果未能解决你的问题,请参考以下文章

神经网络学习小记录70——Pytorch 使用Google Colab进行深度学习

《PyTorch深度学习实践8》——卷积神经网络(Convolution Neural Network)

PyTorch 深度学习实战 |用 TensorFlow 训练神经网络

PyTorch:10分钟让你了解深度学习领域新流行的框架

PyTorch v1.1.0文档研习60分钟快速上手

PyTorch深度学习实战 | 搭建卷积神经网络进行图像分类与图像风格迁移