python - 如何重塑数据以修复“RuntimeError:内核大小不能大于实际输入大小”
问题描述
我尝试在具有以下维度的数据上训练 LeNet 神经网络:
torch.Size([64, 1, 128, 12]), target shape torch.Size([64])
这是LeNet
(仅用于学习目的)的手动实现:
# import the necessary packages
from torch.nn import Module
from torch.nn import Conv2d
from torch.nn import Linear
from torch.nn import MaxPool2d
from torch.nn import ReLU
from torch.nn import LogSoftmax
from torch import flatten
class LeNet(Module):
def __init__(self, numChannels, classes):
# call the parent constructor
super(LeNet, self).__init__()
# initialize first set of CONV => RELU => POOL layers
self.conv1 = Conv2d(in_channels=numChannels, out_channels=20,
kernel_size=(5, 5))
self.relu1 = ReLU()
self.maxpool1 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))
# initialize second set of CONV => RELU => POOL layers
self.conv2 = Conv2d(in_channels=20, out_channels=50,
kernel_size=(5, 5))
self.relu2 = ReLU()
self.maxpool2 = MaxPool2d(kernel_size=(2, 2), stride=(2, 2))
# initialize first (and only) set of FC => RELU layers
self.fc1 = Linear(in_features=800, out_features=500)
self.relu3 = ReLU()
# initialize our softmax classifier
self.fc2 = Linear(in_features=500, out_features=classes)
self.logSoftmax = LogSoftmax(dim=1)
def forward(self, x):
# pass the input through our first set of CONV => RELU =>
# POOL layers
x = self.conv1(x)
x = self.relu1(x)
x = self.maxpool1(x)
# pass the output from the previous layer through the second
# set of CONV => RELU => POOL layers
x = self.conv2(x)
x = self.relu2(x)
x = self.maxpool2(x)
# flatten the output from the previous layer and pass it
# through our only set of FC => RELU layers
x = flatten(x, 1)
x = self.fc1(x)
x = self.relu3(x)
# pass the output to our softmax classifier to get our output
# predictions
x = self.fc2(x)
output = self.logSoftmax(x)
# return the output predictions
return output
当我运行训练脚本时,我收到以下错误:
RuntimeError:计算的每个通道的填充输入大小:(62 x 4)。内核大小:(5 x 5)。内核大小不能大于实际输入大小
根据我的理解,内核大小应该4,4
适合我的数据尺寸。我试图在 LeNet 卷积层中将内核大小从 更改5,5
为。4,4
但后来我得到了一堆与其他层相关的其他维度错误。我花了一些时间一一解决它们,但每次我都遇到新错误。
这是训练脚本的片段:
model = LeNet(numChannels=1,classes=2).to(device)
opt = Adam(model.parameters(), lr=INIT_LR)
lossFn = nn.NLLLoss()
# loop over our epochs
for e in range(0, EPOCHS):
# set the model in training mode
model.train()
# initialize the total training and validation loss
totalTrainLoss = 0
totalValLoss = 0
# initialize the number of correct predictions in the training
# and validation step
trainCorrect = 0
valCorrect = 0
# loop over the training set
for (x, y) in trainDataLoader:
# send the input to the device
(x, y) = (x.to(device), y.to(device))
# perform a forward pass and calculate the training loss
pred = model(x)
loss = lossFn(pred, y)
# zero out the gradients, perform the backpropagation step,
# and update the weights
opt.zero_grad()
loss.backward()
opt.step()
# add the loss to the total training loss so far and
# calculate the number of correct predictions
totalTrainLoss += loss
trainCorrect += (pred.argmax(1) == y).type(torch.float).sum().item()
如何通过重塑输入数据来修复这个错误,以便我可以使用 LeNet 的原始架构?
解决方案
推荐阅读
- ios - 如何处理 Raygun 中断 - 启动后应用程序崩溃
- c# - 如何统一这两种方法
- jmeter - 在 RHEL 8 机器上使用 JMeter 中的 OS 采样器执行文件
- android - 如何在 xamarin 中连接 sqlite
- openssl - 如何针对静态 OpenSSL 库编译应用程序?
- javascript - 在哪里添加用于更新字段的 mongodb 代码
- javascript - 滚动到窗口顶部时元素切换可见性
- .net - 使用 AirPrint 驱动程序 C# .Net 5 MacOS 打印到打印机
- php - 将 /n 添加到 Wordpress (ACF) 中的文本
- c++ - C++ 错误:“QueryFullProcessImageNameA”未在此范围内声明