LoginSignup
0
0

More than 1 year has passed since last update.

深層学習における基本ニューラルネットワークの構築(メモ)

Posted at

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()

0
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
0
0