Pytorch|卷积操作需要四维数据但是输入却只有二维问题探讨

环境

python 3.6
pytorch 1.0.0
torchvision 0.2.1

问题描述

在用pytorch实现简单的手写数字识别项目时遇到了这个错误,这里记录一下。报错的内容如下,这句话的意思就是需要一个四维的向量,但是输入的却是二维的。

Expected 4-dimensional input for 4-dimensional weight [10, 1, 3, 3], but got 2-dimensional input of size [100, 784] instead

下面第12行是报错的语句:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, 3, padding = 1)
        self.conv2 = nn.Conv2d(10, 20, 3, padding  = 1)
        self.pool = nn.MaxPool2d(2, 2)
        self.relu = nn.ReLU()
        self.fc1 = nn.Linear(15680,1000)
        self.fc2 = nn.Linear(1000, 10)
        
    def forward(self, x):
        out = self.conv1(x)  # 报错
        out = self.conv2(out)
        out = self.fc1(out)
        out = self.relu(out)
        out = self.fc2(out)
        return out

下面第4行是输入数据的定义:

train_dataset = dsets.MNIST(root = './data', train = True, transform = transforms.ToTensor(), download = True)
train_loader = torch.utils.data.DataLoader(dataset = train_dataset, batch_size = batch_size, shuffle = True)
for i, (images, labels) in enumerate(train_loader):
    images = Variable(images.view(-1, 28 * 28)) # 这一行是输入数据
    labels = Variable(labels)
    # ......

思考

该行是一个卷积操作,输出Net对象,得到conv1操作的具体参数:

Net(
  (conv1): Conv2d(1, 10, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (conv2): Conv2d(10, 20, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (relu): ReLU()
  (fc1): Linear(in_features=15680, out_features=1000, bias=True)
  (fc2): Linear(in_features=1000, out_features=10, bias=True)
)

经过相关资料查询,知道报错信息中出现的[10, 1, 3, 3]指卷积输出通道数量、输入通道数量、卷积核宽度、卷积核高度。
输入图片数据的形状已经被我改变了,从28*28的二维矩阵变成了大小为784的一维向量,所以才会出现这个错误。

解决方法

因此,输入的图片数据也需要是一个四维的张量,所以将输入数据的定义一行改成

images = Variable(images.view(100, 1, 28, 28))

或者去掉view()方法,如:

images = Variable(images)

需要特别说明的是,在查找类似问题的时候,大家都只说明要怎么做,却没有说出这是为什么。根据我的理解,第一种方法显示定义了输入数据的维数:四维,第一维“100”意为一批的数量(batch),第二维“1”意为输入通道数,第三维“28”和第四维“28”分别意为输入图片数据的宽与高。第二种方法,并没有显示定义,所以系统会自动读取图片的宽、高,还有定义的卷积的输入通道数,并设置相应的batch。

这里面遇到的是二维卷积,如果是一维卷积,那么输入数据应该是三维的,第一维表示batch,第二维表示输入通道数,第三维表示数据长度;如果是三维卷积,那么输入数据应该五维的,第一维、第二维含义不变,后面表示数据。

你可能感兴趣的:(pytorch,python,深度学习,pytorch)