Je suis débutant pour Pytorch. J'essayais d'écrire du code CNN faisant référence au tutoriel Pytorch. Ci-dessous est une partie du code, mais il affiche l'erreur "RuntimeError: les données variables doivent être un tenseur, mais la liste est". J'ai essayé de lancer des données d'entrée sur le tenseur, mais cela n'a pas bien fonctionné. Si quelqu'un connaît la solution, aidez-moi s'il vous plaît ...
def read_labels(file):
dic = {}
with open(file) as f:
reader = f
for row in reader:
dic[row.split(",")[0]] = row.split(",")[1].rstrip() #rstrip(): eliminate "\n"
return dic
image_names= os.listdir("./train_mini")
label_dic = read_labels("labels.csv")
names =[]
labels = []
images =[]
for name in image_names[1:]:
images.append(cv2.imread("./train_mini/"+name))
labels.append(label_dic[os.path.splitext(name)[0]])
"""
Data distribution
"""
N = len(images)
N_train = int(N * 0.7)
N_test = int(N*0.2)
X_train, X_tmp, Y_train, Y_tmp = train_test_split(images, labels, train_size=N_train)
X_validation, X_test, Y_validation, Y_test = train_test_split(X_tmp, Y_tmp, test_size=N_test)
"""
Model Definition
"""
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.head = nn.Sequential(
nn.Conv2d(in_channels=1, out_channels=10,
kernel_size=5, stride=1),
nn.MaxPool2d(kernel_size=2),
nn.ReLU(),
nn.Conv2d(10, 20, kernel_size=5),
nn.MaxPool2d(kernel_size=2),
nn.ReLU())
self.tail = nn.Sequential(
nn.Linear(320, 50),
nn.ReLU(),
nn.Linear(50, 10))
def forward(self, x):
x = self.head(x)
x = x.view(-1, 320)
x = self.tail(x)
return F.log_softmax(x)
CNN = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(CNN.parameters(), lr=0.001, momentum=0.9)
"""
Training
"""
batch_size = 50
for Epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i in range(N / batch_size):
#for i, data in enumerate(trainloader, 0):
batch = batch_size * i
# get the inputs
images_batch = X_train[batch:batch + batch_size]
labels_batch = Y_train[batch:batch + batch_size]
# wrap them in Variable
images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = CNN(images_batch)
loss = criterion(outputs, labels_batch)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.data[0]
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(Epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
Et l'erreur se produit ici
# wrap them in Variable
images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)
Si ma supposition est correcte, vous obtenez probablement une erreur dans la ligne suivante.
# wrap them in Variable
images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)
Ça veut dire, images_batch
et/ou labels_batch
sont des listes. Vous pouvez simplement les convertir en tableau numpy, puis les convertir en tenseur comme suit.
# wrap them in Variable
images_batch = torch.from_numpy(numpy.array(images_batch))
labels_batch = torch.from_numpy(numpy.array(labels_batch))
Cela devrait résoudre votre problème.
Modifier : si vous obtenez l'erreur suivante lors de l'exécution de l'extrait de code ci-dessus:
"RuntimeError: impossible de convertir un np.ndarray donné en un tenseur - il a un type non valide. Les seuls types pris en charge sont: double, float, int64, int32 et uint8."
Vous pouvez créer le tableau numpy en donnant un type de données. Par exemple,
images_batch = torch.from_numpy(numpy.array(images_batch, dtype='int32'))
Je suppose images_batch
contient des informations sur les pixels des images, j'ai donc utilisé int32
. Pour plus d'informations, consultez documentation officielle .