输入类型(torch.cuda.FLOTTENSOR)和重量类型(torch.FLOTTENSOR)应相同

2024-09-29 19:28:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在pyTorch上实现ResNet18,但遇到了一些问题。我的代码是:

device = torch.device("cuda:0")

class ResnetBlock(nn.Module):
    def __init__(self, strides, nf, nf0, reps, bn):
        super(ResnetBlock, self).__init__()
        self.adapt = strides == 2
        self.layers = []
        self.relus = []
        self.adapt_layer = nn.Conv2d(nf0, nf, kernel_size=1, stride=strides, padding=0) if self.adapt else None
        for i in range(reps):
            self.layers.append(nn.Sequential(
                nn.Conv2d(nf0, nf, kernel_size=3, stride=strides, padding=1),
                nn.BatchNorm2d(nf, eps=0.001, momentum=0.99),
                nn.ReLU(),
                nn.Conv2d(nf, nf, kernel_size=3, stride=1, padding=1),
                nn.BatchNorm2d(nf, eps=0.001, momentum=0.99)))
            self.relus.append(nn.ReLU())

            strides = 1
            nf0 = nf

    def forward(self, x):
        for i, (layer, relu) in enumerate(zip(self.layers, self.relus)):
            rama = layer(x)
            if self.adapt and i == 0:
                x = self.adapt_layer(x)
            x = x + rama
            x = relu(x)
        return x


class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),
            nn.MaxPool2d(kernel_size=2, stride=2))

        self.blocks = nn.Sequential(
            ResnetBlock(1, 64, 64, 2, bn),
            ResnetBlock(2, 128, 64, 2, bn),
            ResnetBlock(2, 256, 128, 2, bn),
            ResnetBlock(2, 512, 256, 2, bn))
        
        self.fcout = nn.Linear(512, 10)

    def forward(self, x):
        out = self.layer1(x)
        out = self.blocks(out)
        out = out.reshape(out.size(0), -1)
        out = self.fcout(out)
        return out


num_epochs = 50
num_classes = 10
batch_size = 50
learning_rate = 0.00001

trans = transforms.ToTensor()
train_dataset = torchvision.datasets.CIFAR10(root="./dataset_pytorch", train=True, download=True, transform=trans)
test_dataset = torchvision.datasets.CIFAR10(root="./dataset_pytorch", train=False, download=True, transform=trans)

train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)


def weights_init(m):
    if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):
        nn.init.xavier_uniform_(m.weight.data)
        nn.init.zeros_(m.bias.data)

model = ConvNet()
model.apply(weights_init)

model.to(device)

summary(model, (3,32,32))

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, eps=1e-6)

# Train the model
total_step = len(train_loader)
loss_list = []
acc_list = []
acc_list_test = []
for epoch in range(num_epochs):
    total = 0
    correct = 0
    for i, (images, labels) in enumerate(train_loader):
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        # Run the forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss_list.append(loss.item())

        # Backprop and perform Adam optimisation
        loss.backward()
        optimizer.step()

        # Track the accuracy
        total += labels.size(0)
        _, predicted = torch.max(outputs.data, 1)
        correct += (predicted == labels).sum().item()
    acc_list.append(correct / total)

    print("Train")
    print('Epoch [{}/{}], Accuracy: {:.2f}%'
          .format(epoch + 1, num_epochs, (correct / total) * 100))


    total_test = 0
    correct_test = 0
    for i, (images, labels) in enumerate(test_loader):
        images = images.to(device)
        labels = labels.to(device)

        # Run the forward pass
        outputs = model(images)

        # Track the accuracy
        total_test += labels.size(0)
        _, predicted = torch.max(outputs.data, 1)
        correct_test += (predicted == labels).sum().item()
    acc_list_test.append(correct_test / total_test)
    print("Test")
    print('Epoch [{}/{}], Accuracy: {:.2f}%'
          .format(epoch + 1, num_epochs, (correct_test / total_test) * 100))

这很奇怪,因为即使我将模型和数据都移动到了cuda,它也会给我带来那个错误

我想这与我如何定义或使用“ResnetBlock”有关,因为如果我从ConvNet中删除这些块(删除out = self.blocks(out)行),代码就会工作。但我不知道我做错了什么


Tags: testselfsizelabelsmodelinitdevicenn
1条回答
网友
1楼 · 发布于 2024-09-29 19:28:57

问题出在这一行:

model.to(device)

to未到位。它返回转换后的模型。您需要将其更改为:

model = model.to(device)

编辑:另一个问题:PyTorch无法跟踪vanillalist。您需要使用nn.ModuleList。 从

self.layers = []
self.relus = []

self.layers = nn.ModuleList()
self.relus = nn.ModuleList()

相关问题 更多 >

    热门问题