Pytorch error: RuntimeError: 1D target tensor expected, multi-target not supported
Pytorch error: RuntimeError: 1D target tensor expected, multi-target not supported
我目前正在研究一个神经元网络,它可以对猫和狗以及除猫狗以外的所有事物进行分类。我的程序有这个:我无法解决的错误:
”文件“/home/johann/Schreibtisch/NN_v0.01/classification.py”,第 146 行,在
火车(纪元)
文件“/home/johann/Schreibtisch/NN_v0.01/classification.py”,第 109 行,在 train 中
损失=标准(出局,目标)
文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/modules/module.py”,第 889 行,在 _call_impl
结果 = self.forward(*输入, **kwargs)
文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/modules/loss.py”,第 1047 行,向前
return F.cross_entropy(输入、目标、权重=self.weight,
文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/functional.py”,第 2693 行,在 cross_entropy
return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/functional.py”,第 2388 行,在 nll_loss 中
ret = torch._C._nn.nll_loss(输入,目标,权重,_Reduction.get_enum(减少),ignore_index)
RuntimeError:预期为 1D 目标张量,不支持多目标
代码:
import os
from torchvision import transforms
from PIL import Image
from os import listdir
import random
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
from tqdm import tqdm
normalize = transforms.Normalize(
mean = [0.485, 0.456, 0.406],
std = [0.229, 0.224, 0.225])
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(256),
transforms.ToTensor(), normalize])
train_data_list = []
target_list = []
train_data = []
waited = False
files = listdir('catsanddogs/train/')
for i in range(len(listdir('catsanddogs/train/'))):
if len(train_data) == 58 and not waited:
waited = True
continue
f = random.choice(files)
files.remove(f)
img = Image.open("catsanddogs/train/" + f)
img_tensor = transform(img)
train_data_list.append(img_tensor)
isSomething = 0
isCat = 1 if 'cat' in f else 0
isDog = 1 if 'dog' in f else 0
if isDog == 0 and isCat == 0:
isSomething = 1
target = [isCat, isDog, isSomething] #, isSomthing
target_list.append(target)
if len(train_data_list) >= 256:
train_data.append((torch.stack(train_data_list), target_list))
train_data_list = []
target_list = []
print('Loaded batch ', len(train_data), 'of ', int(len(listdir('catsanddogs/train/')) / 64))
print('Percentage Done: ', 100 * len(train_data) / int(len(listdir('catsanddogs/train/')) / 64), '%')
if len(train_data) > 2:
break
class Netz(nn.Module):
def __init__(self):
super(Netz, self).__init__()
self.conv1 = nn.Conv2d(3, 6, kernel_size=(5, 5))
self.conv2 = nn.Conv2d(6, 12, kernel_size=(5, 5))
self.conv3 = nn.Conv2d(12, 18, kernel_size=(5, 5))
self.conv4 = nn.Conv2d(18, 24, kernel_size=(5, 5))
self.fc1 = nn.Linear(3456, 1000)
self.fc2 = nn.Linear(1000, 3)
def forward(self, x):
x = self.conv1(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv2(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv3(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv4(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = x.view(-1, 3456)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.softmax(x, dim=1)
model = Netz()
#if os.path.isfile('catdognetz.pt'):
#model = torch.load('catdognetz.pt')
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
def count_parameters(model):
return sum(p.numel() for p in model.parameters() if p.requires_grad)
count_parameters(model)
train_losses = []
train_accu = []
def train(epoch):
print('\nEpoch : %d' % epoch)
model.train()
running_loss = 0
correct = 0
total = 0
for data, target in tqdm(train_data):
target = torch.Tensor(target)
data = Variable(data)
target = Variable(target)
optimizer.zero_grad()
out = model(data)
criterion = nn.CrossEntropyLoss()
loss = criterion(out, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
predicted = out.max(1)
total += target.size(0)
correct += predicted.eq(target).sum().item()
train_loss = running_loss / len(train_data)
accu = 100. * float(correct) / total
train_accu.append(accu)
train_losses.append(train_loss)
print('Train Loss: %.3f | Accuracy: %.3f' % (train_loss, accu))
def test():
model.eval()
file = listdir('catsanddogs/test/')
f = random.choice(file)
img = Image.open('catsanddogs/test/' + f)
img_eval_tensor = transform(img)
img_eval_tensor.unsqueeze_(0)
data = Variable(img_eval_tensor)
out = model(data)
what = "It's a cat"
print(out.data.max(1, keepdim=True)[1].cpu().numpy()[0])
if out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 0:
what = "It's a Dog"
if out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 0 and out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 1:
what = "Neither"
print(what)
img.show()
#x = input('')
epochs = 10
for epoch in range(1, epochs + 1):
train(epoch)
#test()
torch.save(model, 'catdognetz.pt')
plt.plot(train_accu,'-o')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(['Kurve: Training'])
plt.title('Train Accuracy')
plt.show()
plt.plot(train_losses,'-o')
plt.xlabel('epoch')
plt.ylabel('loss bzw. Verlust')
plt.legend(['Kruve : Training'])
plt.title('Train Loss')
plt.show()```
此错误背后的原因是您的目标列表是这样的列表列表:
target = [[1,0,0],[0,1,0],[0,0,1],...]
您应该使用一维张量而不是 one-hot 代码列表,因为 CrossEntropyLoss 不接受 one-hot 编码张量。例如,您可以使用:
target = torch.tensor([0, 1, 2, 2, 1, 0, 0, ...]) # cat = 1, dog=2, something else= 2
您可以通过以下方式自动将目标从 one-hot 编码列表转换为 类 张量:
target = torch.tensor(target)
target= torch.argmax(target ,axis=1)
或者您可以更改算法以创建一维张量而不是列表列表。
你可以阅读更多CrossEntropyLoss的文档here
我目前正在研究一个神经元网络,它可以对猫和狗以及除猫狗以外的所有事物进行分类。我的程序有这个:我无法解决的错误:
”文件“/home/johann/Schreibtisch/NN_v0.01/classification.py”,第 146 行,在 火车(纪元) 文件“/home/johann/Schreibtisch/NN_v0.01/classification.py”,第 109 行,在 train 中 损失=标准(出局,目标) 文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/modules/module.py”,第 889 行,在 _call_impl 结果 = self.forward(*输入, **kwargs) 文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/modules/loss.py”,第 1047 行,向前 return F.cross_entropy(输入、目标、权重=self.weight, 文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/functional.py”,第 2693 行,在 cross_entropy return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction) 文件“/home/johann/.local/lib/python3.8/site-packages/torch/nn/functional.py”,第 2388 行,在 nll_loss 中 ret = torch._C._nn.nll_loss(输入,目标,权重,_Reduction.get_enum(减少),ignore_index) RuntimeError:预期为 1D 目标张量,不支持多目标
代码:
import os
from torchvision import transforms
from PIL import Image
from os import listdir
import random
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
from tqdm import tqdm
normalize = transforms.Normalize(
mean = [0.485, 0.456, 0.406],
std = [0.229, 0.224, 0.225])
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(256),
transforms.ToTensor(), normalize])
train_data_list = []
target_list = []
train_data = []
waited = False
files = listdir('catsanddogs/train/')
for i in range(len(listdir('catsanddogs/train/'))):
if len(train_data) == 58 and not waited:
waited = True
continue
f = random.choice(files)
files.remove(f)
img = Image.open("catsanddogs/train/" + f)
img_tensor = transform(img)
train_data_list.append(img_tensor)
isSomething = 0
isCat = 1 if 'cat' in f else 0
isDog = 1 if 'dog' in f else 0
if isDog == 0 and isCat == 0:
isSomething = 1
target = [isCat, isDog, isSomething] #, isSomthing
target_list.append(target)
if len(train_data_list) >= 256:
train_data.append((torch.stack(train_data_list), target_list))
train_data_list = []
target_list = []
print('Loaded batch ', len(train_data), 'of ', int(len(listdir('catsanddogs/train/')) / 64))
print('Percentage Done: ', 100 * len(train_data) / int(len(listdir('catsanddogs/train/')) / 64), '%')
if len(train_data) > 2:
break
class Netz(nn.Module):
def __init__(self):
super(Netz, self).__init__()
self.conv1 = nn.Conv2d(3, 6, kernel_size=(5, 5))
self.conv2 = nn.Conv2d(6, 12, kernel_size=(5, 5))
self.conv3 = nn.Conv2d(12, 18, kernel_size=(5, 5))
self.conv4 = nn.Conv2d(18, 24, kernel_size=(5, 5))
self.fc1 = nn.Linear(3456, 1000)
self.fc2 = nn.Linear(1000, 3)
def forward(self, x):
x = self.conv1(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv2(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv3(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = self.conv4(x)
x = F.max_pool2d(x, 2)
x = F.relu(x)
x = x.view(-1, 3456)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.softmax(x, dim=1)
model = Netz()
#if os.path.isfile('catdognetz.pt'):
#model = torch.load('catdognetz.pt')
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
def count_parameters(model):
return sum(p.numel() for p in model.parameters() if p.requires_grad)
count_parameters(model)
train_losses = []
train_accu = []
def train(epoch):
print('\nEpoch : %d' % epoch)
model.train()
running_loss = 0
correct = 0
total = 0
for data, target in tqdm(train_data):
target = torch.Tensor(target)
data = Variable(data)
target = Variable(target)
optimizer.zero_grad()
out = model(data)
criterion = nn.CrossEntropyLoss()
loss = criterion(out, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
predicted = out.max(1)
total += target.size(0)
correct += predicted.eq(target).sum().item()
train_loss = running_loss / len(train_data)
accu = 100. * float(correct) / total
train_accu.append(accu)
train_losses.append(train_loss)
print('Train Loss: %.3f | Accuracy: %.3f' % (train_loss, accu))
def test():
model.eval()
file = listdir('catsanddogs/test/')
f = random.choice(file)
img = Image.open('catsanddogs/test/' + f)
img_eval_tensor = transform(img)
img_eval_tensor.unsqueeze_(0)
data = Variable(img_eval_tensor)
out = model(data)
what = "It's a cat"
print(out.data.max(1, keepdim=True)[1].cpu().numpy()[0])
if out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 0:
what = "It's a Dog"
if out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 0 and out.data.max(1, keepdim=True)[1].cpu().numpy()[0] != 1:
what = "Neither"
print(what)
img.show()
#x = input('')
epochs = 10
for epoch in range(1, epochs + 1):
train(epoch)
#test()
torch.save(model, 'catdognetz.pt')
plt.plot(train_accu,'-o')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(['Kurve: Training'])
plt.title('Train Accuracy')
plt.show()
plt.plot(train_losses,'-o')
plt.xlabel('epoch')
plt.ylabel('loss bzw. Verlust')
plt.legend(['Kruve : Training'])
plt.title('Train Loss')
plt.show()```
此错误背后的原因是您的目标列表是这样的列表列表:
target = [[1,0,0],[0,1,0],[0,0,1],...]
您应该使用一维张量而不是 one-hot 代码列表,因为 CrossEntropyLoss 不接受 one-hot 编码张量。例如,您可以使用:
target = torch.tensor([0, 1, 2, 2, 1, 0, 0, ...]) # cat = 1, dog=2, something else= 2
您可以通过以下方式自动将目标从 one-hot 编码列表转换为 类 张量:
target = torch.tensor(target)
target= torch.argmax(target ,axis=1)
或者您可以更改算法以创建一维张量而不是列表列表。
你可以阅读更多CrossEntropyLoss的文档here