PyTorch 一维 CNN 问题
PyTorch 1D CNN Problems
我在 PyTorch 中实现 1D CNN 时遇到了很多麻烦。这个想法是我们使用 xTrainVar 来预测 yTrainVar,并使用 xTestVar 来预测 yTestVar。时间序列。
这一行:
pred = prod_outputs(train_loader, model)
在这里创建一个问题:
_, predictions = torch.max(scores, 1)
导致此错误:
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
通常我不会转储完整的代码库,但我就是看不到我的错误,所以这里是:
#################################
# Load the libraries
#################################
import torch
import torchvision
import torch.nn.functional as F
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch import optim
from torch import nn
from torch.utils.data import DataLoader
from tqdm import tqdm
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
import numpy as np
import torch.utils.data as data_utils
#################################
# Prepare the data
#################################
xTrainVar = [[8.1,4.1,4.1,4.3], [3.9, 3.8, 3.9, 3.7], [3.8, 3.7, 3.8, 3.8], [3.9, 3.8, 4.1, 4.4]]
yTrainVar = [3.9, 3.8, 3.9, 4.4]
xTestVar = [[8.1,4.1,4.1,4.3], [3.9, 3.8, 3.9, 3.7], [3.8, 3.7, 3.8, 3.8], [3.9, 3.8, 4.1, 4.4],[3.9, 3.8, 4.1, 4.4]]
yTestVar = [3.9, 3.8, 3.9, 4.4, 4.4]
# Convert to Tensors
# Prepare training data
train_data = torch.tensor(np.array(xTrainVar, dtype=np.float32))
train_target = torch.tensor(np.array(yTrainVar, dtype=np.float32))
train_data = train_data.unsqueeze(1) # try to get the right shape [4,1,4]
# Reshape the data to be in line with the other shape
new_shape = (len(yTrainVar), 1, 1) # There used to be another ,1 here
train_target = train_target.view(new_shape)
train_tensor = data_utils.TensorDataset(train_data, train_target)
train_loader = data_utils.DataLoader(dataset=train_tensor, batch_size=32,shuffle=False)
# Prepare test data
test_data = torch.tensor(np.array(xTestVar, dtype=np.float32))
test_target = torch.tensor(np.array(yTestVar, dtype=np.float32))
test_data = test_data.unsqueeze(1) # try to get the right shape [5,1,4]
# Reshape the data to be in line with the other shape
new_shape = (len(yTestVar), 1,1)
test_target = test_target.view(new_shape)
test_tensor = data_utils.TensorDataset(test_data, test_target)
test_loader = data_utils.DataLoader(dataset=test_tensor, batch_size=32)
class NN(nn.Module):
def __init__(self, input_size, num_classes):
super(NN, self).__init__()
self.conv1d = nn.Conv1d(in_channels=1, out_channels=4, kernel_size=4, stride=1, padding=0)
self.relu = nn.ReLU(inplace=True)
self.fc1 = nn.Linear(16,50)
self.fc2 = nn.Linear(50,1).
def forward(self, x):
x = self.conv1d(x)
x = self.relu(x)
x = x.view(-1)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# Set the hyperparameters
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
input_size = 1*4
num_classes = 1
learning_rate = 0.001
batch_size = 64
num_epochs = 1
model = NN(input_size=input_size, num_classes=num_classes).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
#################################
# Train model using training data
#################################
for epoch in range(num_epochs):
# Fit the model to the training data
for batch_idx, (data, targets) in enumerate(tqdm(train_loader)):
# Get data to cuda if possible
data = data.to(device=device)
targets = targets.to(device=device)
# forward
scores = model(data)
loss = criterion(scores, targets)
# backward
optimizer.zero_grad()
loss.backward()
# gradient descent or adam step
optimizer.step()
def prod_outputs(loader, model):
model.eval() # Place the model into evaluation mode.
with torch.no_grad():
for x, y in loader:
x = x.to(device=device)
y = y.to(device=device)
scores = model(x)
_, predictions = scores.max(1)
print(predictions)
model.train() # Return the model to training mode once we are done.
return scores # This used to be predictions
#################################
# Evaluate the model
#################################
# This is where I am up to with the work.
pred = prod_outputs(train_loader, model) # Use train dependent variable (x) to generate predictions of independent variable (y)
pred = pred.numpy()
你需要退一步审视形势:
您有一个 (bs, c, w)
形如 (4, 1, 4)
的输入。因此,单个通道的批量大小为 4
,长度为 4
。通过卷积层,这变成 (bs, 4, 1)
因为内核大小是 (4,)
,每个通道基本上只有一个值。
在应用使整个张量变平的重塑之后,这通常不是一个好主意。因为您实际上是将批处理元素压平在一起。相反,您应该 将它们分开。您可以为此使用 nn.Flatten
。例如,在 __init__
中设置 self.flatten = nn.Flatten()
,然后在正向定义中使用 x = self.flatten(x)
而不是 x = x.view(-1)
。
这就是说,除第一个轴(批次轴)外的扁平化将导致形状为 (4, 4)
的张量。所以,最终你的第一个密集层应该有相应数量的神经元,即 4
。类似于 self.fc1 = nn.Linear(4, 50)
.
不要认为这是理所当然的,我是在解释你的代码中有什么问题,而不是给你一个可以坚持的架构。我为您提供的修改将 运行,不保证它会 train... 这是另一天的问题!
我在 PyTorch 中实现 1D CNN 时遇到了很多麻烦。这个想法是我们使用 xTrainVar 来预测 yTrainVar,并使用 xTestVar 来预测 yTestVar。时间序列。
这一行:
pred = prod_outputs(train_loader, model)
在这里创建一个问题:
_, predictions = torch.max(scores, 1)
导致此错误:
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
通常我不会转储完整的代码库,但我就是看不到我的错误,所以这里是:
#################################
# Load the libraries
#################################
import torch
import torchvision
import torch.nn.functional as F
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch import optim
from torch import nn
from torch.utils.data import DataLoader
from tqdm import tqdm
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
import numpy as np
import torch.utils.data as data_utils
#################################
# Prepare the data
#################################
xTrainVar = [[8.1,4.1,4.1,4.3], [3.9, 3.8, 3.9, 3.7], [3.8, 3.7, 3.8, 3.8], [3.9, 3.8, 4.1, 4.4]]
yTrainVar = [3.9, 3.8, 3.9, 4.4]
xTestVar = [[8.1,4.1,4.1,4.3], [3.9, 3.8, 3.9, 3.7], [3.8, 3.7, 3.8, 3.8], [3.9, 3.8, 4.1, 4.4],[3.9, 3.8, 4.1, 4.4]]
yTestVar = [3.9, 3.8, 3.9, 4.4, 4.4]
# Convert to Tensors
# Prepare training data
train_data = torch.tensor(np.array(xTrainVar, dtype=np.float32))
train_target = torch.tensor(np.array(yTrainVar, dtype=np.float32))
train_data = train_data.unsqueeze(1) # try to get the right shape [4,1,4]
# Reshape the data to be in line with the other shape
new_shape = (len(yTrainVar), 1, 1) # There used to be another ,1 here
train_target = train_target.view(new_shape)
train_tensor = data_utils.TensorDataset(train_data, train_target)
train_loader = data_utils.DataLoader(dataset=train_tensor, batch_size=32,shuffle=False)
# Prepare test data
test_data = torch.tensor(np.array(xTestVar, dtype=np.float32))
test_target = torch.tensor(np.array(yTestVar, dtype=np.float32))
test_data = test_data.unsqueeze(1) # try to get the right shape [5,1,4]
# Reshape the data to be in line with the other shape
new_shape = (len(yTestVar), 1,1)
test_target = test_target.view(new_shape)
test_tensor = data_utils.TensorDataset(test_data, test_target)
test_loader = data_utils.DataLoader(dataset=test_tensor, batch_size=32)
class NN(nn.Module):
def __init__(self, input_size, num_classes):
super(NN, self).__init__()
self.conv1d = nn.Conv1d(in_channels=1, out_channels=4, kernel_size=4, stride=1, padding=0)
self.relu = nn.ReLU(inplace=True)
self.fc1 = nn.Linear(16,50)
self.fc2 = nn.Linear(50,1).
def forward(self, x):
x = self.conv1d(x)
x = self.relu(x)
x = x.view(-1)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# Set the hyperparameters
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
input_size = 1*4
num_classes = 1
learning_rate = 0.001
batch_size = 64
num_epochs = 1
model = NN(input_size=input_size, num_classes=num_classes).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
#################################
# Train model using training data
#################################
for epoch in range(num_epochs):
# Fit the model to the training data
for batch_idx, (data, targets) in enumerate(tqdm(train_loader)):
# Get data to cuda if possible
data = data.to(device=device)
targets = targets.to(device=device)
# forward
scores = model(data)
loss = criterion(scores, targets)
# backward
optimizer.zero_grad()
loss.backward()
# gradient descent or adam step
optimizer.step()
def prod_outputs(loader, model):
model.eval() # Place the model into evaluation mode.
with torch.no_grad():
for x, y in loader:
x = x.to(device=device)
y = y.to(device=device)
scores = model(x)
_, predictions = scores.max(1)
print(predictions)
model.train() # Return the model to training mode once we are done.
return scores # This used to be predictions
#################################
# Evaluate the model
#################################
# This is where I am up to with the work.
pred = prod_outputs(train_loader, model) # Use train dependent variable (x) to generate predictions of independent variable (y)
pred = pred.numpy()
你需要退一步审视形势:
您有一个
(bs, c, w)
形如(4, 1, 4)
的输入。因此,单个通道的批量大小为4
,长度为4
。通过卷积层,这变成(bs, 4, 1)
因为内核大小是(4,)
,每个通道基本上只有一个值。在应用使整个张量变平的重塑之后,这通常不是一个好主意。因为您实际上是将批处理元素压平在一起。相反,您应该 将它们分开。您可以为此使用
nn.Flatten
。例如,在__init__
中设置self.flatten = nn.Flatten()
,然后在正向定义中使用x = self.flatten(x)
而不是x = x.view(-1)
。这就是说,除第一个轴(批次轴)外的扁平化将导致形状为
(4, 4)
的张量。所以,最终你的第一个密集层应该有相应数量的神经元,即4
。类似于self.fc1 = nn.Linear(4, 50)
.
不要认为这是理所当然的,我是在解释你的代码中有什么问题,而不是给你一个可以坚持的架构。我为您提供的修改将 运行,不保证它会 train... 这是另一天的问题!