● TensorFlow2 (tf.keras)でニューラルネットワークを構築
# ① import
import tensorflow as tf
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.datasets import mnist
import os
from matplotlib import pyplot as plt
batch_size = 128
epochs = 30
# ②データの取得
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# データの前処理
x_train, x_test = x_train / 255.0, x_test / 255.0
# ③モデルの構築 (Sequential法)
model = tf.keras.models.Sequential([
Flatten(),
Dense(120, activation='relu'),
Dropout(0.2), # 過学習防止
Dense(10, activation='softmax')
])
# # ③モデルの構築 (class法 ※PyTorchに似た書き方)
# class MnistMode(tf.keras.Model):
# def __init__(self):
# super().__init__()
# self.flatten = Flatten()
# self.d1 = Dense(120, activation="relu")
# self.dropout = Dropout(0.2)
# self.d2 = Dense(10, activation="softmax")
#
# def call(self, x, training=False):
# x = self.flatten(x)
# x = self.d1(x)
# if training: # 予測時には適用しない
# x = self.dropout(x, training=training)
# x = self.d2(x)
# return x
#
#
# model = MnistMode()
# ④モデルのコンパイル
model.compile(optimizer=Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
checkpoint_save_path = "./checkpoint/mnist.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
print('-------------重みロード-----------------')
model.load_weights(checkpoint_save_path)
# 訓練中にチェックポイントを保存します。
# (再び訓練を行うことなくモデルを使用することができます)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True)
# ⑤モデルの学習
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,
validation_data=(x_test, y_test),
callbacks=[cp_callback])
# ⑥モデルの構造の表示
model.summary()
# ---------- 学習過程(accuracyとloss)をプロット ----------
plt.figure(figsize=(10, 5))
metrics = ['loss', 'accuracy']
for i in range(len(metrics)):
metric = metrics[i]
plt.subplot(1, 2, i + 1)
plt.plot(history.history[metric], label='Training ' + metric)
plt.plot(history.history['val_' + metric], label='Validation ' + metric)
plt.title(metric)
plt.legend()
plt.show()
● PyTorchでニューラルネットワークを構築
# ① import
import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
from matplotlib import pyplot as plt
batch_size = 128
epochs = 30
torch.manual_seed(20)
# ②データの取得、データの前処理
train_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('mnist_data', train=True, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(
(0.5,), (0.5,))
])),
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('mnist_data/', train=False, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(
(0.5,), (0.5,))
])),
batch_size=batch_size, shuffle=False)
# ③モデルの構築
class MnistMode(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(1 * 28 * 28, 120)
self.fc2 = nn.Linear(120, 10)
def forward(self, x):
x = x.view(-1, 1 * 28 * 28)
x = F.relu(self.fc1(x))
if self.training:
x = F.dropout(x, 0.2, training=self.training)
x = self.fc2(x)
return x
device = "cuda" if torch.cuda.is_available() else "cpu"
model = MnistMode().to(device)
# ④ 損失関数、最適化手法
loss_func = nn.CrossEntropyLoss().to(device) # softmax処理含み
optimizer = optim.Adam(model.parameters(), lr=0.0001)
# ⑤モデルの学習
history = {'loss': [], 'val_loss': [], 'accuracy': [], 'val_accuracy': []}
train_loader_len = len(train_loader)
for epoch in range(epochs):
total_train_loss = 0
total_train_acc = 0
model.train() # 学習モードに (training->True)
print('----- Epoch {}/{} ------'.format(epoch + 1, epochs))
for batch_idx, (x, y) in enumerate(train_loader):
x = x.to(device)
y = y.to(device)
out = model(x)
loss = loss_func(out, y)
total_train_loss += loss.item()
optimizer.zero_grad()
loss.backward()
optimizer.step()
pred_train = out.argmax(dim=1)
correct = (pred_train == y).sum().item() / x.shape[0]
total_train_acc += correct
if (batch_idx + 1) % 50 == 0:
print('{:6}/{} loss: {:.5f} accuracy: {:.5f}'.format(batch_idx + 1, train_loader_len,
loss.item(), correct))
cnt = len(train_loader)
history['loss'].append(total_train_loss / cnt)
history['accuracy'].append(total_train_acc / cnt)
total_val_loss = 0
total_val_acc = 0
model.eval() # 推論モードに (training->False)
with torch.no_grad():
for x, y in test_loader:
x = x.to(device)
y = y.to(device)
x = x.view(-1, 1 * 28 * 28)
out = model(x)
loss = loss_func(out, y)
pred = out.argmax(dim=1)
correct = (pred == y).sum().item()
total_val_loss += loss.item()
total_val_acc += correct
history['val_loss'].append(total_val_loss / len(test_loader))
history['val_accuracy'].append(total_val_acc / len(test_loader.dataset))
format_str = 'Epoch {}/{} loss: {:.5f} - accuracy: {:.5f} - val_loss: {:.5f} - val_accuracy: {:.5f}'
print(format_str.format(epoch + 1, epochs,
history['loss'][-1], history['accuracy'][-1],
history['val_loss'][-1], history['val_accuracy'][-1]))
# ⑥モデルの構造の表示
print(model)
# ---------- 学習過程(lossとaccuracy)をプロット ----------
plt.figure(figsize=(10, 5))
metrics = ['loss', 'accuracy']
for i in range(len(metrics)):
metric = metrics[i]
plt.subplot(1, 2, i + 1)
plt.plot(history[metric], label='Training ' + metric)
plt.plot(history['val_' + metric], label='Validation ' + metric)
plt.title(metric)
plt.legend()
plt.show()