RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same - 解决方法
您遇到的错误是由于模型和输入数据之间的数据类型不匹配导致的。为了解决这个问题,请将模型和输入数据都转换为相同的数据类型。
以下是修改后的代码:
import torch
from net import simpleconv
from torchvision import transforms, datasets
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
from tensorboardX import SummaryWriter
import time
import os
def train(train_loader, model, criterion, optimizer, device, len_train, batch_size):
num_loss = 0.0
num_corrects = 0.0
model.train()
for i, (data, target) in enumerate(train_loader):
data = data.to(device)
target = target.to(device)
optimizer.zero_grad()
outputs = model(data)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
num_corrects += torch.sum(preds == target).item()
num_loss = num_loss + loss.item()
train_loss = num_loss / (len_train // batch_size + 1)
train_acc = num_corrects / len_train
return train_loss, train_acc
def val(val_loader, model, criterion, device, len_val, batch_size):
num_loss = 0.0
num_corrects = 0.0
model.eval()
with torch.no_grad():
for i, (data, target) in enumerate(val_loader):
data = data.to(device)
target = target.to(device)
outputs = model(data)
_, preds = torch.max(outputs.data, 1)
loss = criterion(outputs, target)
num_corrects += torch.sum(preds == target).item()
num_loss = num_loss + loss.item()
val_loss = num_loss / (len_val // batch_size + 1)
val_acc = num_corrects / len_val
return val_loss, val_acc
batch_size = 100
nclass = 13
num_epochs = 364
data_dir = './testimage'
if torch.cuda.is_available():
device = torch.device('cuda')
else:
device = torch.device('cpu')
model = simpleconv(nclass).to(device)
# 在模型定义中添加dropout层
model.conv1 = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Dropout(p=0.5).to(device) # 添加dropout层,并将其转换为相同的数据类型
)
model.conv2 = nn.Sequential(
nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Dropout(p=0.5).to(device) # 添加dropout层,并将其转换为相同的数据类型
)
train_transforms = transforms.Compose([
transforms.Resize((64, 64)),
transforms.RandomResizedCrop(48),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])
val_transforms = transforms.Compose([
transforms.Resize((64, 64)),
transforms.CenterCrop(48),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])
train_datasets = datasets.ImageFolder(os.path.join(data_dir, 'train'), train_transforms)
val_datasets = datasets.ImageFolder(os.path.join(data_dir, 'test'), val_transforms)
len_train = len(train_datasets)
len_val = len(val_datasets)
train_loaders = torch.utils.data.DataLoader(
dataset=train_datasets,
batch_size=batch_size,
shuffle=True,
num_workers=0
)
val_loaders = torch.utils.data.DataLoader(
dataset=val_datasets,
batch_size=batch_size,
shuffle=True,
num_workers=0
)
criterion = nn.CrossEntropyLoss()
optimizer_ft = optim.SGD(model.parameters(), lr=0.1, momentum=0.8)
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=200, gamma=0.1)
writer = SummaryWriter('runs')
best_acc = 0.0
for epoch in range(num_epochs):
start = time.time()
train_loss, train_acc = train(train_loaders, model, criterion, optimizer_ft, device, len_train, batch_size)
exp_lr_scheduler.step()
val_loss, val_acc = val(val_loaders, model, criterion, device, len_val, batch_size)
if val_acc > best_acc:
best_acc = val_acc
torch.save(model.state_dict(), './best.pth')
writer.add_scalar('trainloss', train_loss, epoch)
writer.add_scalar('trainacc', train_acc, epoch)
writer.add_scalar('valloss', val_loss, epoch)
writer.add_scalar('valacc', val_acc, epoch)
end = time.time()
print('[{}/{}]: train_loss:{:.3f}, train_acc:{:.3f},eval_loss:{:.3f}, eval_acc:{:.3f}, time:{:.3f}'.format(epoch+1,num_epochs,train_loss,train_acc,val_loss,val_acc,end-start))
writer.close()
在这个修改后的代码中,我们将dropout层转换为与模型和输入数据相同的数据类型(在这种情况下是cuda)。这样就解决了不匹配的数据类型问题。同时,我还修改了设备的指定方式,使用了torch.device来指定设备,以便更好地处理GPU设备。
这样,模型中就添加了dropout层,并在训练和验证过程中起作用。同时,模型参数和输入数据都将具有相同的数据类型,避免了类型不匹配的错误。
原文地址: https://www.cveoy.top/t/topic/RVB 著作权归作者所有。请勿转载和采集!