

Pytorchで画像の10クラス分類を行いたく、コード自体はエラーなく実行できるのですが、何エポック繰り返しても学習が進まず、LossもAccuracyも0.000のまま変わりません。  
（実行すると、100エポック回った段階でも  
`EPOCH: 100, Train [Loss: 0.000, Accuracy: 0.000]`  
と出てしまう状況です。）

クラス数の指定が間違っているのかなとも考え調整も試したのですが解決しませんでした。

`for epoch in range(n_epochs):`  
より前のコードは信頼性のある資料から引っ張ってきたコードですが、それ以降のコードが少しあやふやな知識で実装しているところもあり、ドキュメントも確認したのですが間違い個所が分からず、ご教示をいただければ嬉しいですm(__)m

[code]

    import math
    from collections import OrderedDict
    import os
    import numpy as np
    import torch
    import torch.nn as nn
    import torchvision.transforms as transforms
    from PIL import Image
    
    
    def read_img(root, filedir, transform=None):
        # Data loading
        with open(filedir, 'r') as f:
            lines = f.readlines()  
        output = []    
        for line in lines:
            linesplit = line.split('\n')[0].split(' ')
            addr = linesplit[0]
            target = torch.Tensor([float(linesplit[1])])
            img = Image.open(os.path.join(root, addr)).convert('RGB')
    
            if transform is not None:
                img = transform(img)
            
            output.append([img, target])
        return output
    
    def bn_relu(inplanes):
        return nn.Sequential(nn.BatchNorm2d(inplanes), nn.ReLU(inplace=True))
    
    
    def bn_relu_pool(inplanes, kernel_size=3, stride=2):
        return nn.Sequential(
            nn.BatchNorm2d(inplanes), nn.ReLU(
                inplace=True), nn.MaxPool2d(
                kernel_size=kernel_size, stride=stride))
    
    
    class AlexNet(nn.Module):
        def __init__(self, num_classes=1):
            super(AlexNet, self).__init__()
            self.conv1 = nn.Conv2d(3, 96, kernel_size=11, stride=4, bias=False)
            self.relu_pool1 = bn_relu_pool(inplanes=96)
            self.conv2 = nn.Conv2d(
                in_channels=96,
                out_channels=192,
                kernel_size=5,
                padding=2,
                groups=2,
                bias=False)
            self.relu_pool2 = bn_relu_pool(inplanes=192)
            self.conv3 = nn.Conv2d(
                in_channels=192,
                out_channels=384,
                kernel_size=3,
                padding=1,
                groups=2,
                bias=False)
            self.relu3 = bn_relu(inplanes=384)
            self.conv4 = nn.Conv2d(
                in_channels=384,
                out_channels=384,
                kernel_size=3,
                padding=1,
                groups=2,
                bias=False)
            self.relu4 = bn_relu(inplanes=384)
            self.conv5 = nn.Conv2d(
                in_channels=384,
                out_channels=256,
                kernel_size=3,
                padding=1,
                groups=2,
                bias=False)
            self.relu_pool5 = bn_relu_pool(inplanes=256)
            # classifier
            self.conv6 = nn.Conv2d(256, 256, kernel_size=5, groups=2, bias=False)
            self.relu6 = bn_relu(inplanes=256)
            self.conv7 = nn.Conv2d(256, num_classes, kernel_size=1, bias=False)
    
        def forward(self, x):
            x = self.conv1(x)
            x = self.relu_pool1(x)
            x = self.conv2(x)
            x = self.relu_pool2(x)
            x = self.conv3(x)
            x = self.relu3(x)
            x = self.conv4(x)
            x = self.relu4(x)
            x = self.conv5(x)
            x = self.relu_pool5(x)
            x = self.conv6(x)
            x = self.relu6(x)
            x = self.conv7(x)
            x = x.view(x.size(0), -1)
            return x
    
    
    net = AlexNet().cuda()
    
    import torch.optim as optim
    
    batch_size = 64
    n_epochs = 200
    lr = 0.02
    device = torch.device("cuda")
    
    optimizer = optim.SGD(net.parameters(), lr=lr)
    net.train()
    
    # loading data...
    root = './data/Images'
    traindir = './data/train.txt'
    transform = transforms.Compose([
            transforms.Resize(256),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),])  
    train_dataset = read_img(root, traindir, transform=transform)
    
    dataloader_train = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=batch_size,
        shuffle=True
    )
    
    for epoch in range(n_epochs):
        losses_train = []
    
        net.train()
        n_train = 0
        acc_train = 0
        for x, t in dataloader_train:
            n_train += t.size()[0]
            net.zero_grad()
            x = x.to(device)
            t_hot = torch.eye(10)[np.round(t).long()]
            t_hot = t_hot.to(device)
            y = net.forward(x)
            loss = -(t_hot*torch.log_softmax(y, dim=-1)).sum(axis=1).mean()
            loss.backward()
            optimizer.step()
            pred = y.argmax(1)
            acc_train += (pred.to("cpu") == t).float().sum().item()
            losses_train.append(loss.tolist())
    
        print('EPOCH: {}, Train [Loss: {:.3f}, Accuracy: {:.3f}]'.format(
            epoch,
            np.mean(losses_train),
            acc_train/n_train,
            
        ))
    
[/code]


CC BY-SA 4.0
2022-11-14T11:17:35.310
92226
2022-12-27T15:01:11.007
55396
question
python pytorch
Pytorchで学習が進みません（画像の多クラス分類）


> `class AlexNet(nn.Module):` のコンストラクタの定義で `num_classes=1` となっているので `net =
> AlexNet(10).cuda()` とする

について，以下の条件での確認ですが学習が進むようになりました。

(1) 画像データは CIFAR-10 を使用  
(2) GPU(CUDA) ではなく GPU(MPS) を使用  
（環境: macOS13.1(M1), Python 3.10.8, torch 1.13.1）

オリジナルからの (1), (2) の対応を含む修正箇所と出力を下記に示します。

[code]

    # import torchvision.transforms as transforms
    from torchvision import datasets, transforms
    
    # ...
    
    # net = AlexNet().cuda()
    device = torch.device("mps")
    net = AlexNet(10).to(device)
    
    # ...
    
    # device = torch.device("cuda")
    
    # ...
    
    # train_dataset = read_img(root, traindir, transform=transform)
    train_dataset = datasets.CIFAR10(root="./data_cifar10", train=True,
                                     download=True, transform=transform)
    
[/code]

[code]

    EPOCH: 0, Train [Loss: 1.237, Accuracy: 0.560]
    EPOCH: 1, Train [Loss: 0.835, Accuracy: 0.711]
    EPOCH: 2, Train [Loss: 0.651, Accuracy: 0.775]
    EPOCH: 3, Train [Loss: 0.519, Accuracy: 0.822]
    EPOCH: 4, Train [Loss: 0.411, Accuracy: 0.861]
    EPOCH: 5, Train [Loss: 0.313, Accuracy: 0.897]
    EPOCH: 6, Train [Loss: 0.232, Accuracy: 0.926]
    EPOCH: 7, Train [Loss: 0.159, Accuracy: 0.952]
    EPOCH: 8, Train [Loss: 0.109, Accuracy: 0.971]
    EPOCH: 9, Train [Loss: 0.066, Accuracy: 0.985]
    
[/code]


CC BY-SA 4.0
2022-12-27T15:01:11.007
93051
2022-12-27T15:01:11.007
54588
92226
answer