我正在阅读火炬文件,我有几个关于引入的神经网络的问题。该文档定义了以下网络:
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像素乘32)?
第一个卷积将六个内核应用于图像,每个内核都是3x3。这意味着,如果输入通道为32x32,则六个输出通道都具有维度30x30 ( 3x3内核网格会使您失去2个像素的宽度和高度)。第二个卷积应用了更多的内核,因此现在有16个维度为28x28的输出通道(同样,3x3内核网格会使你失去2个像素的宽度和高度)。现在,我希望下一层中有16x28x28节点,因为16个输出通道中的每一个都有28x28像素。不知何故,这是不正确的,下一层包含16x6x6节点。为什么这是真的?
问题2:第二卷积层从六个输入通道到16个输出通道。这是怎么做的?
在第一个卷积层,我们从一个输入通道到六个输入通道,这对我来说是有意义的。您只需将六个内核应用于单个输入通道,即可到达六个输出通道。从6个输入通道到16个输出通道对我来说没有多大意义。不同的内核是如何应用的?您是否将两个核应用于前五个输入通道以到达十个输出通道,而将六个内核应用于最后一个输入通道,从而使总数达到16个输出通道?还是神经网络学会了使用x核,并将它们应用于它认为最合适的输入通道?
发布于 2019-09-07 11:52:34
我现在可以自己回答这些问题了。
问题1:为了了解为什么需要32x32图像这个神经网络工作,需要考虑以下几点:
层1:首先是,卷积是用3x3内核实现的。由于图像的维数为32x32,这将导致网格为30x30。接下来,最大池被应用到网格中,2x2内核和2的跨距导致了一个维度为15x15的网格。
第2层:首先,卷积与3x3内核一起应用于15x15网格,从而形成13x13网格。接下来,使用2x2内核和2的跨步应用max池,从而形成一个维度为6x6的网格。我们得到的是6x6网格,而不是7x7网格,因为默认情况下使用的是地板函数,而不是ceil函数。
由于第二层的卷积有16个输出通道,第一个线性层需要16x6x6节点!我们看到所需的输入确实是一个32x32映像。
问题2:通过对每个输入通道应用六个不同的内核并对结果进行求和,创建了每个输出通道。这在文档中得到了解释。
https://stackoverflow.com/questions/57822568
复制相似问题