機械学習第8章
MNISTを使った数字認識
問題の定義
MNIST手書き数字データセットを使用する
訓練用に60000枚、検証用に10000枚
PyTorchのライブラリ経由で利用
画像データは縦、横28画素
画素ごとの色の濃淡は0から255までの整数値(pytorchライブラリ経由で取得する場合は0,1の範囲の浮動小数点)
1,28,28の3階テンソルになっている
全結合型ニューラルネットワークの場合入力は1階テンソル形式にする必要がある
→前処理を行い、784要素の1次元配列に展開した形式のデータを入力とする
数字は全部で10種類→分類先のクラスは10個
モデルは、入力784次元、出力10次元の隠れ層ありニューラルネットワーク
Point
ミニバッチ学習法
今回60000枚のデータを扱うため、学習量が膨大になる
どのような単位で1回の学習をするかが重要になり、その解決策がミニバッチ学習法
PyTorchではデータローダーという仕組みを使って簡単にミニバッチ学習法を実行
ReLU関数
x<0では定数0,x>= 0ではy=xの一次元関数
GPU・CPUの理解
PyTorchでは、Kerasと比べてプログラムで常にGPUを意識する必要がある。
1テンソルの変数はデータがCPU・GPU上のどちらにあるのかを属性として持っている
2CPUとGPU間のデータ転送はto関数を使う
32つの変数が両方ともGPU上にある場合、演算はGPUで行われる
4片方がGPU、CPUの場合演算はエラーになる
データ前処理
値の範囲の変更:0,1の範囲を-1,1の範囲にする
次元の変換:1件のデータが1,28,28の3階テンソルを784の一階テンソルにする
実装
1データ準備
データ入手:Dataset
データ加工:Transform
ミニバッチ用データセット生成:DataLoader
データ取得
code:pyton
# ライブラリインポート
import torchvision.datasets as detasets
# ダウンロード先ディレクトリ
data_root = './data'
train_set0 = datasets.MNIST(
root = data_root,
# 訓練データか検証データか
train = True,
# 元データがない時にダウンロードするか
download = True)
読み込んだデータセットであるtrain_set0はpythonのリストとして(入力データ、正解データ)のセットを順に取得できる
データセットの確認
code:python
# データ件数の確認
print(len(train_set_0))
# 最初の要素の取得
image, label = train_set00
# データ型の確認
print(type(image))
print(type(label))
60000件
入力データimage PIL.Image.Image
正解データlabel int
Transformsによるデータ前処理
step1 ToTensorの利用
step2 Normalizeの利用
データを正規化する
0,1の範囲を-1,1に変更する
step3 Lambdaクラスを利用して1次元化
入力変数のshapeを元の1,28,28から784に変更
transformsの定義
code:python
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(0.5,0,5),
transforms.Lambda(lambda x: x.view(-1),
])
データセットの定義
code:python
# 訓練データセット
train_set = datasets.MNIST(root = data_root, train = True, download = True, transform = transform)
# 検証データセット
test_set = datasets.MNIST(root = data_root, train = False, download = True, transform = transform)
データローダーによるミニバッチ用データ生成
code:python
# ライブラリのインポート
from torch.utils.data import DataLoader
# ミニバッチのサイズ指定
batch_size = 500
#訓練用データローダー
train_loader = DaraLoader(train_set, batch_size = batch_size, shuffle = True)
# 検証用データローダー
test_loader = DataLoader(test_set, batch_size = batch_size, shuffle = False)
定義したデータローダーは、for inputs, labels in train_loader: のような形でループを定義して使う
2 モデル定義
入力と出力の次元数の設定と隠れ層のノード数
code:python
n_input = image.shape0
n_output = len(set(list(labels.data.numpy())))
n_hidden = 128
モデルクラスの定義
code:python
class Net(nn.Module):
def __init__(self, n_input, n_output, n_hidden):
super().__init__()
#
self.l1 = nn.Linear(n_input, n_hidden)
self.l2 = nn.Linear(n_hidden, n_output)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
x1 = self.l1(x)
x2 = self.relu(x1)
x3 = self.l2(x2)
return x3
二層目の後に活性化関数がないのは、softmax関数を損失関数がわに含めるから
モデル変数の生成
code:python
# モデルのインスタンス化をしてGPU側に送る
net = Net(n_input, n_output, n_hidden).to(device)
最適化関数定義、損失関数定義
code:python
# 学習率
lr = 0.01
# アルゴリズム: 勾配降下法
optimizer = torch.optim.SGD(net.parameters(), lr=lr)
# 損失関数: 交差エントロピー関数
criterion = nn.CrossEntropyLoss()
3 勾配降下法
予測計算
データロードからデータを取得
code:python
for images, labels in train_loader:
break
学習データのGPUへの転送
code:python
inputs = images.to(device)
labels = labels.to(device)
予測値の計算
code:python
outputs = net(inputs)
損失計算
code:python
loss = criterion(outputs, labels)
繰り返し処理
初期化処理
code:python
lr = 0.01
net = Net(n_input, n_output, n_hidden).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=lr)
num_epochs = 100
繰り返し処理 
code:python
# 繰り返し計算メインループ
for epoch in range(num_epochs):
train_acc, train_loss = 0, 0
val_acc, val_loss = 0, 0
n_train, n_test = 0, 0
# 訓練フェーズ
# GPUへ転送
inputs = inputs.to(device)
labels = labels.to(device)
# 勾配の初期化
optimizer.zero_grad()
# 予測計算
outputs = net(inputs)
# 損失計算
loss = criterion(outputs, labels)
# 勾配計算
loss.backward()
#parameter修正
optimizer.step()
# 予測フェーズ
inputs_test = inputs_test.to(device)
labels_test = labels_test.to(device)
# 予測計算
outputs_test = net(inputs_test)
# 損失計算
loss_test = criterion(outputs_test, labels_test)
# 予測計算
predicted_test = torch.max(outputs_test, 1)1
機械学習1章・2章
機械学習3章
機械学習第6章
機械学習第7章
機械学習第9章
機械学習第10章