##はじめに
この記事の対象者は「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=20
→max_epochs=30
に増やし
て学習し、テストデータで検証したところ
結果は、正解率:**約91.5%**という結果が得られました!
これで目標の90%を超えることができました!
##おわりに
画像処理のクラス分類の精度をあげるには、
ネットワークの中間層のout_channnelのようなノード数を調整を行ったり
optimizer(最適化手法)を色々と変えてみるのも
有効なのだと理解しました。
今後、別の課題を処理する場合は
データに合わせて違う調整をする必要があると思いますが、
ある程度人間側の経験に基づいて行うことになるのかな
とも思いました。