Pythonで機械学習 手書き数字認識 学習処理Part(11)

colaboratory

はじめに

こんにちわ、swim-loverです。 Pythonで機械学習の一つである手書き数字認識を実装しています。Pythonを始めたばかりですが、「使いながら覚える」をコンセプトに勉強しています。 第10回は、機会学習で使う損失関数の二乗和誤差、交差エントロピー誤差について実装しました。今回も、参考図書にしたがって、学びを進めます。

参考図書

今回、機械学習の参考書籍として、”斎藤康毅著 ゼロから作るDeep Learning オライリージャパン 2016年9月”を使用しました。

ミニバッチ学習

MNISTの学習用データの数は、60,000個ありました。

import torch;
import torchvision
import matplotlib.pyplot as plt
import numpy
from torch.utils.data import DataLoader

train_set = torchvision.datasets.MNIST(root='./data',train=True,download=True)
train_data = DataLoader(train_set,batch_size=None,shuffle=False)
print(train_set)
Dataset MNIST
    Number of datapoints: 60000
    Root location: ./data
    Split: Train

入力層から隠れ層、出力層の計算と第10回の損失関数の計算を60,000回繰り返して、誤差Eが求まりますが、結構大量のデータ数です。仮に1データに1分かかるとしたら、1000時間、41日かかります。1回だけの計算ならまだ良いですが、層の数を変えたり、活性化関数を変えて再度学習することが想定されます。

そこで、全データを使って学習するのではなく、一定数のデータをランダムに選び出し、学習する方法がとられています。これをミニバッチ学習と呼んでいます。(選び出したデータをミニバッチと呼ぶ)

そういえば、第8回のPytorchのDataLoder関数にbatch_sizeの引数が存在していました。batch_sizeに100を指定すれば、60000データから100データを抜き出すことになります。

さらに、shuffle=Trueを指定することで。60000データの中からランダムに100データのミニバッチデータを作成することになります。いつも同じデータを100個取り出して学習してもダメですよね。

DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
           batch_sampler=None, num_workers=0, collate_fn=None,
           pin_memory=False, drop_last=False, timeout=0,
           worker_init_fn=None, *, prefetch_factor=2,
           persistent_workers=False)

torch.utils.data — PyTorch 2.2 documentation

今回もColabで、実際にコード動かしてみます。

import torch;
import torchvision
from torchvision import transforms as transforms
import matplotlib.pyplot as plt
import numpy
from torch.utils.data import DataLoader
train_set = torchvision.datasets.MNIST(root='./data',train=True,transform=transforms.ToTensor(),download=True)
print(train_set)
train_data = DataLoader(train_set,batch_size=100,shuffle=True)

tmp = train_data.__iter__()
#first data
imgs, labels = tmp.next()
print(imgs.size())
print(labels.size())

出力結果になります。

Dataset MNIST
    Number of datapoints: 60000
    Root location: ./data
    Split: Train
    StandardTransform
Transform: ToTensor()
torch.Size([100, 1, 28, 28])
torch.Size([100])

torch.Size([100, 1, 28, 28]) のところは読みずらいですが、以下の例のように、ゼロデータで確認してみると、

a = torch.zeros([2, 1,28,28])
print(a)
print(a.size())

28×28のゼロデータの塊が二つできていることから、 torch.Size([100, 1, 28, 28]) は、100個分の手書き数字画像データ100個分のミニバッチが取得できていることがわかります。

tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]])
torch.Size([2, 1, 28, 28])

まとめ

今回、ミニバッチデータの取得についてPytorchを使って実装してみました。

引き続き、ニューラルネットワークの学習について学んでいきたいと思います。

コメント

タイトルとURLをコピーしました