遇到的错误可能是由于以下原因之一导致的:
为了解决这个问题,可以尝试以下一些方法:
target
的数据类型是Int
,而不是Long
。cross_entropy_loss
要求目标变量的数据类型是Long
。target = target.cuda(non_blocking=True)
改为target = target.long().cuda(non_blocking=True)
,将target = target.cuda()
改为target = target.long().cuda()
。def train(train_loader, model, criterion, optimizer):
model.train()
train_loss = 0.0
for i, (input, target) in enumerate(train_loader):
input = input.cuda(non_blocking=True)
target = target.long().cuda(non_blocking=True) # 修改了这里,原来是 target = target.cuda(non_blocking=True)
# 因为交叉熵损失函数要求目标变量的数据类型是Long,而不是Int
output = model(input)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if i % 20 == 0:
print(loss.item())
train_loss += loss.item()
return train_loss/len(train_loader)
def validate(val_loader, model, criterion):
model.eval()
val_acc = 0.0
with torch.no_grad():
for i, (input, target) in enumerate(val_loader):
input = input.cuda()
target = target.long().cuda() # 修改了这里,原来是 target = target.cuda()
# 因为交叉熵损失函数要求目标变量的数据类型是Long,而不是Int
# compute output
output = model(input)
loss = criterion(output, target)
val_acc += (output.argmax(1) == target).sum().item()
return val_acc / len(val_loader.dataset)
for _ in range(3):
train_loss = train(train_loader, model, criterion, optimizer)
val_acc = validate(val_loader, model, criterion)
train_acc = validate(train_loader, model, criterion)
print(train_loss, train_acc, val_acc)
思路二:
criterion
是一个交叉熵损失函数,它需要的target
参数是一个长整型(LongTensor
)的张量,而不是一个整型(IntTensor
)的张量。RuntimeError: "nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Int'
的异常,这意味着PyTorch没有实现对整型张量进行交叉熵损失计算的CUDA内核函数。.long()
方法,将target
转换为长整型,然后再传给criterion
。这样就可以避免运行时错误,并正确地计算损失函数。def train(train_loader, model, criterion, optimizer):
model.train()
train_loss = 0.0
for i, (input, target) in enumerate(train_loader):
input = input.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
output = model(input)
# 修改前的代码是:loss = criterion(output, target)
# 修改的原因是:criterion需要的target参数是一个长整型张量,而不是一个整型张量
loss = criterion(output, target.long()) # 转换成长整型
optimizer.zero_grad()
loss.backward()
optimizer.step()
if i % 20 == 0:
print(loss.item())
train_loss += loss.item()
return train_loss/len(train_loader)
def validate(val_loader, model, criterion):
model.eval()
val_acc = 0.0
with torch.no_grad():
for i, (input, target) in enumerate(val_loader):
input = input.cuda()
target = target.cuda()
# compute output
output = model(input)
# 修改前的代码是:loss = criterion(output, target)
# 修改的原因是:criterion需要的target参数是一个长整型张量,而不是一个整型张量
loss = criterion(output, target.long()) # 转换成长整型
val_acc += (output.argmax(1) == target).sum().item()
return val_acc / len(val_loader.dataset)
for _ in range(3):
train_loss = train(train_loader, model, criterion, optimizer)
val_acc = validate(val_loader, model, criterion)
train_acc = validate(train_loader, model, criterion)
print(train_loss, train_acc, val_acc)
思路一:
def predict(test_loader, model, criterion):
model.eval()
val_acc = 0.0
test_pred = []
with torch.no_grad():
for i, (input, target) in enumerate(test_loader):
input = input.cuda()
target = target.cuda()
output = model(input)
test_pred.append(output.data.cpu().numpy())
return np.vstack(test_pred)
pred = None
for _ in range(10):
if pred is None:
pred = predict(test_loader, model, criterion)
else:
pred += predict(test_loader, model, criterion)
submit = pd.DataFrame(
{
'uuid': [int(x.split('\\')[-1][:-4]) for x in test_path],
# 修改原因:将反斜杠替换为正斜杠,以适应Windows系统的路径分隔符
# 原代码: 'uuid': [int(x.split('/')[-1][:-4]) for x in test_path],
'label': pred.argmax(1)
})
submit['label'] = submit['label'].map({1:'NC', 0: 'MCI'})
submit = submit.sort_values(by='uuid')
submit.to_csv('submit2.csv', index=None)
思路二:
os.path.basename 来获取文件名,而不是用
x.split(‘/’)[-1][:-4]。这样可以避免在不同的操作系统下出现路径分隔符不一致的问题。
import os
def predict(test_loader, model, criterion):
model.eval()
val_acc = 0.0
test_pred = []
with torch.no_grad():
for i, (input, target) in enumerate(test_loader):
input = input.cuda()
target = target.cuda()
output = model(input)
test_pred.append(output.data.cpu().numpy())
return np.vstack(test_pred)
pred = None
for _ in range(10):
if pred is None:
pred = predict(test_loader, model, criterion)
else:
pred += predict(test_loader, model, criterion)
submit = pd.DataFrame(
{
# 使用 os.path.basename 来获取文件名
'uuid': [int(os.path.basename(x)[:-4]) for x in test_path],
'label': pred.argmax(1)
})
submit['label'] = submit['label'].map({1:'NC', 0: 'MCI'})
submit = submit.sort_values(by='uuid')
submit.to_csv('submit2.csv', index=None)