2
0

More than 1 year has passed since last update.

【Python初学者】画像処理クラス分類の精度・正解率(accuracy)を向上するには。【FashionMNIST】

Posted at

はじめに

この記事の対象者は「python初学者」「機械学習初学者」です。
つまり私です。

今回の例

今回は「FashionMNIST」のデータセットを用いて学習し
テストデータに対するクラス分類の正解率 90% 以上を目指します。

以下のように準備しました。

①訓練データ

torchvision.datasets.FashionMNIST(
    root="datasets", train=True, transform=transform, download=True
)

②テストデータ

torchvision.datasets.FashionMNIST(
    root="datasets", train=False, transform=transform, download=True
)

テストデータはtrain=Falseとしています。

画像処理のネットワーク構築(改善前)

class Net(pl.LightningModule):

    def __init__(self):
        super().__init__()

        self.conv = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, padding=1)
        self.bn = nn.BatchNorm2d(3)
        self.fc = nn.Linear(14*14*3, 10)


    def forward(self, x):
        h = self.conv(x)
        h = F.relu(h)
        h = self.bn(h)
        h = F.max_pool2d(h, kernel_size=2, stride=2)
        h = h.view(-1, 14*14*3)
        h = self.fc(h)
        return h


    def training_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('train_loss', loss, on_step=True, on_epoch=True, prog_bar=True)
        self.log('train_acc', accuracy(y.softmax(dim=-1), t), on_step=True, on_epoch=True, prog_bar=True)
        return loss


    def validation_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('val_loss', loss, on_step=False, on_epoch=True)
        self.log('val_acc', accuracy(y.softmax(dim=-1), t), on_step=False, on_epoch=True)
        return loss


    def test_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('test_loss', loss, on_step=False, on_epoch=True)
        self.log('test_acc', accuracy(y.softmax(dim=-1), t), on_step=False, on_epoch=True)
        return loss


    def configure_optimizers(self):
        optimizer = torch.optim.SGD(self.parameters(), lr=0.01)
        return optimizer

以上をmax_epochs=20で学習し
テストデータで検証したところ

結果は、正解率:約85%でした。
まだまだでした。

画像処理のネットワーク構築(★改善後)

(#★は改善したところ)

class Net(pl.LightningModule):

    def __init__(self):
        super().__init__()
                          
        self.conv = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=1)                                    #★out_channel=3→32に!
        self.bn = nn.BatchNorm2d(32)      #★3→32に!
        self.fc1 = nn.Linear(14*14*32, 300)  #★中間層を作る!!!
        self.fc2 = nn.Linear(300, 10)


    def forward(self, x):
        h = self.conv(x)
        h = self.bn(h)
        h = F.relu(h)   #★位置をself.bn(h)と上下入れ替え
        h = F.max_pool2d(h, kernel_size=2, stride=2)
        h = h.view(-1, 14*14*32)
        h = self.fc1(h)  #★中間層
        h = F.relu(h)   #★relu関数を通す!
        h = self.fc2(h)
        return h


    def training_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('train_loss', loss, on_step=True, on_epoch=True, prog_bar=True)
        self.log('train_acc', accuracy(y.softmax(dim=-1), t), on_step=True, on_epoch=True, prog_bar=True)
        return loss


    def validation_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('val_loss', loss, on_step=False, on_epoch=True)
        self.log('val_acc', accuracy(y.softmax(dim=-1), t), on_step=False, on_epoch=True)
        return loss


    def test_step(self, batch, batch_idx):
        x, t = batch
        y = self(x)
        loss = F.cross_entropy(y, t)
        self.log('test_loss', loss, on_step=False, on_epoch=True)
        self.log('test_acc', accuracy(y.softmax(dim=-1), t), on_step=False, on_epoch=True)
        return loss


    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=0.001) #★SGD→ADM、lrを0.001に!
        return optimizer

以上を
前回max_epochs=20max_epochs=30に増やし
て学習し、テストデータで検証したところ

結果は、正解率:約91.5%という結果が得られました!

これで目標の90%を超えることができました!

おわりに

画像処理のクラス分類の精度をあげるには、
ネットワークの中間層のout_channnelのようなノード数を調整を行ったり
optimizer(最適化手法)を色々と変えてみるのも
有効なのだと理解しました。

今後、別の課題を処理する場合は
データに合わせて違う調整をする必要があると思いますが、
ある程度人間側の経験に基づいて行うことになるのかな
とも思いました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0