我该如何解决这个问题?输入必须有 3 个维度,得到 4
Posted
技术标签:
【中文标题】我该如何解决这个问题?输入必须有 3 个维度,得到 4【英文标题】:How can I solve this issue? input must have 3 dimensions, got 4 【发布时间】:2021-10-05 09:27:45 【问题描述】:以下是我传递给数据加载器的数据,
train_path='/content/drive/MyDrive/Dataset_manual_pytorch/train'
test_path='/content/drive/MyDrive/Dataset_manual_pytorch/test'
train = torchvision.datasets.ImageFolder(train_path,transform=transformations)
test = torchvision.datasets.ImageFolder(test_path,transform=transformations)
train_loader = torch.utils.data.DataLoader(train, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test, batch_size =32, shuffle=True)
这是我的循环神经网络模型,
hidden_size = 256
sequence_length = 28
num_classes = 2
num_layers = 2
input_size = 32
learning_rate = 0.001
num_epochs = 3
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first = True)
self.fc = nn.Linear(hidden_size*sequence_length, num_classes)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)
#Forward Prop
out,_ = self.rnn(x, h0)
out = out.reshape(out.shape[0], -1)
out = self.fc(out)
return out
model_rnn = RNN(input_size, hidden_size, num_layers, num_classes).to(device)
当我为特定时期和训练数据训练这个模型时,它给了我以下错误;
RuntimeError: input must have 3 dimensions, got 4
数据的形状为:torch.Size([64, 3, 32, 32])
我认为错误是因为我正在输入 4 维数据,其中我也传递了三个通道(RGB),为了解决这个问题,我需要重塑; torch.Size([64, 3, 32, 32]) --> torch.Size([64, 32, 32])) 但我做不到。
培训代码是;
@torch.no_grad()
def Validation_phase(model, val_loader):
model.eval()
for data, labels in val_loader:
out = model(data)
val_loss = F.cross_entropy(out, labels)
val_acc = accuracy(out, labels)
return val_loss.detach(), val_acc
def fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.SGD):
history = []
optimizer = opt_func(model.parameters(), lr)
for epoch in range(epochs):
# Training Phase
model.train()
train_losses = []
train_accuracy = []
for data, labels in train_loader:
#forward
print(data.shape)
out = model(data)
#loss calculate
train_loss = F.cross_entropy(out, labels)
#Accuracy
train_acc = accuracy(out, labels)
train_accuracy.append(train_acc)
train_losses.append(train_loss.item())
#back_propagate
train_loss.backward()
optimizer.step()
optimizer.zero_grad()
train_accuracy = np.mean(torch.stack(train_accuracy).numpy())
train_losses = np.mean(train_losses)
#Validation phase
val_losses, val_accuracy = Validation_phase(model, val_loader)
print("Epoch [], train_loss: :.4f, train_accuracy: :.4f, val_loss: :.4f, val_acc: :.4f".format(
epoch, train_losses*100 , train_accuracy*100 , val_losses.item()*100, val_accuracy.item()*100))
# history.append(result)
# return history
fit(5, 0.001, model_rnn, train_loader, test_loader, torch.optim.Adam)
【问题讨论】:
【参考方案1】:您可以按照下面的代码将 torch.Size([64, 3, 32, 32]) 的大小转换为 torch.size([64, 32, 32]):
x = torch.ones((64, 3, 32, 32))
x = x[:, 0, :, :]
#Check code:
print(x.size())
【讨论】:
所以你要保持红色并扔掉蓝色和绿色?此外,您的x
最终将拥有 3 个轴...
这个方法会影响我的模型。【参考方案2】:
您可以使用 RGB 通道的平均值来获得具有 torch.mean
的单个通道上的图像表示。您可能需要保持平均尺寸,才能正确输入模型:您可以使用 keepdim
选项:
>>> x = torch.rand(64, 3, 32, 32)
>>> z = x.mean(1, keepdim=True)
>>> z.shape
(64, 1, 32, 32)
请记住,有 other ways 进行此操作(RGB 到灰度转换)。
【讨论】:
是的,我可以取所有 3 个通道的平均值,但是这里模型的准确性会受到影响,我可以将所有 RGB 图像转换为灰度,但是这种方法计算量太高,因为我有数百万图像。谢谢 当然会影响你的模型,这会有效的减少你数据中的信息量。确实没有什么神奇的方法可以绕过它。或者,一种常见的方法是对数据进行一次预处理,在您的情况下计算一次灰度并在训练中使用转换后的灰度图像。你怎么看? 我正在使用 OpenCV 将 RGB 转换为灰度,然后再次加载到 Data Loader 以保持批量大小。以上是关于我该如何解决这个问题?输入必须有 3 个维度,得到 4的主要内容,如果未能解决你的问题,请参考以下文章
检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (224, 224, 3) 的数组
检查输入时出错:预期 lstm_input 有 3 个维度,但得到的数组形状为 (4, 1)
RNN - RuntimeError:输入必须有 3 维,得到 2
检查输入时出错:预期 lstm_input 有 3 个维度,但得到了形状为 (160, 1000) 的数组
model.predict() == ValueError:检查输入时出错:预期 flatten_input 有 3 个维度,但得到的数组形状为 (1, 2)