pytorch AlexNet在训练时的准确率很低

zbwhf8kr  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(157)

我想用AlexNet对自己的图像数据集进行分类,但在训练过程中,准确率始终在0.14左右,损失几乎没有变化。总共有7个类别,1 / 7正好是0.1429,所以训练似乎没有起到作用,准确率是随机的1 / 7。
AlexNet代码如下

import torch
import torch.nn as nn
# from torchsummary import summary

class AlexNet(nn.Module):
    def __init__(self, nums):
        super(AlexNet, self).__init__()
        
        self.nums = nums
        
        self.conv = nn.Sequential(
            
            nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=0),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2)
        )
        
        # self.avg_pool = nn.AdaptiveAvgPool2d((5, 5))
        
        self.fc = nn.Sequential(
            
            nn.Linear(in_features=6 * 6 * 256, out_features=2048),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            
            nn.Linear(in_features=2048, out_features=2048),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            
            nn.Linear(in_features=2048, out_features=nums)
        )

    def forward(self, x):
        x = self.conv(x)
        
        # x = self.avg_pool(x)
        
        x = x.view(x.size(0), -1)
        # print(x.size())
        x = self.fc(x)
        return x

def alexnet(num_classes):
    return AlexNet(num_classes)

我的训练代码如下

img_transform = transforms.Compose([transforms.Resize((227, 227)), transforms.ToTensor()])
    train_dataset = torchvision.datasets.ImageFolder(root=train_data_filepath, transform=img_transform)
    val_dataset = torchvision.datasets.ImageFolder(root=val_data_filepath, transform=img_transform)
    train_dataloader = DataLoader(train_dataset, batch_size=Batch_Size, shuffle=True)
    val_dataloader = DataLoader(val_dataset, batch_size=Batch_Size, shuffle=True)
network = get_network(net_choice).to(device)

loss_function = torch.nn.CrossEntropyLoss()

optimizer = torch.optim.SGD(network.parameters(), lr=Learning_rate, weight_decay=5e-4)

gc.collect()
torch.cuda.empty_cache()
train_loss, train_accuracy = [], []
val_loss, val_accuracy = [], []
for epoch in range(1, Epoch+1):
    Epoch_start = time.time()
    train_epoch_loss, train_epoch_accuracy = AlexNet_train(
        network, train_dataloader, optimizer, loss_function
        )
    val_epoch_loss, val_epoch_accuracy = AlexNet_Val(
        network, val_dataloader, loss_function
        )
    train_loss.append(train_epoch_loss)
    train_accuracy.append(train_epoch_accuracy)
    val_loss.append(val_epoch_loss)
    val_accuracy.append(val_epoch_accuracy)

我尝试将Learning_rate更改为0.001或0.01或0.0001,并尝试将batch_size从32更改为64或更大,但从未成功

lx0bsm1f

lx0bsm1f1#

看起来梯度消失和爆炸发生是因为没有执行初始化。He (Kaiming) initialization方法可用于可靠地训练模型。
在下面的代码中,初始化方法应用于AlexNet模型。

import torch
import torch.nn as nn

class AlexNet(nn.Module):
    def __init__(self, nums):
        super(AlexNet, self).__init__()
        
        self.nums = nums
        
        self.conv = [   
            nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=0),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2),
            
            nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            
            nn.MaxPool2d(kernel_size=3, stride=2)
        ]
        
        self.fc = [
            nn.Linear(in_features=6 * 6 * 256, out_features=2048),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            
            nn.Linear(in_features=2048, out_features=2048),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            
            nn.Linear(in_features=2048, out_features=nums)
        ]

        for m in self.conv:
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)

        for m in self.fc:
            if isinstance(m, nn.Linear):
                nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)

        self.conv = nn.Sequential(*self.conv)
        self.fc = nn.Sequential(*self.fc)

    def forward(self, x):
        x = self.conv(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

您也可以将动量应用于SGD,使其更好地训练。
重量衰减似乎太大了。

optimizer = torch.optim.SGD(network.parameters(), lr=Learning_rate, weight_decay=1e-4, momentum=0.9)

相关问题