キカガク(KIKAGAKU)で「ニューラルネットワークの実装(回帰)」を学ぶで練習問題が出ていたので、解いてみた。
練習問題
上記の結果のように、平均ニ乗誤差 (MSE) が検証データに対して約 73となっており、誤差を二乗しているとしても少し予測誤差が大きいことがわかります。この原因を考え、対策をうち、平均ニ乗誤差が小さくなるようなモデルを考えてみましょう。ヒント
- Batch Normalization をいれる
- エポック数を増やす
- 最適化手法 (optimizer) を変更する
- データセットを可視化し、必要な特徴量を選択する or 増やす
試行錯誤することで、実際の動作などの理解が深まるのでぜひ取り組りくんでください。
回答例
モデル変更前の MSE は次のとおり。
[62.691704245174634, 6.1231995]
なぜか、73
よりよくなっている。
Batch Normalization をいれると、MSE は次のような結果になった。
[36.493252174527036,
4.8187714]
改善前と比べて 58% 改善した。
変更箇所はソースコード 42 行目から 47 行目までを参照。
エポック数を 30 から 60 に増やすと、MSE は次のような結果になった。
[27.27410544601141, 3.981625]
改善前と比べて 43%
改善した。
変更箇所はソースコード 62 行目を参照。
optimaizer を adam から sgd に変更すると、MSE は次のような結果になった。
[40.223956089393766,
4.9830503]
前回までと比べると悪化したので、optimaizer は adam の方が適しているといえる。
変更箇所はソースコード 50 行目を参照。
ちなみに RMSprop
に変更すると、MSE は次のような結果になった。
[26.024830537683822, 3.8633108]
特徴量を 13 から 12に減らすと、MSE は次のような結果になった。
[20.303845349480124,
3.5017285]
改善前と比べて 32% 改善した。
今回は、4つ目の変数 CHAS を減らした。
CHAS | チャールズ川によるダミー変数 (1: 川の周辺, 0: それ以外) |
変更箇所はソースコード 11 行目から 20 行目までを参照。
目的関数
評価関数
ソースコード
import numpy as np | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
import tensorflow as tf | |
from tensorflow.keras import models, layers | |
# データセットの準備 | |
dataset = tf.keras.datasets.boston_housing | |
train, test = dataset.load_data() | |
# 特徴量の選択 | |
d = train[0] | |
f = d.T | |
d = np.vstack((f[0:3], f[4:14])) | |
train_0 = d.T | |
d = test[0] | |
f = d.T | |
d = np.vstack((f[0:3], f[4:14])) | |
test_0 = d.T | |
# 学習用データセット | |
x_train = np.array(train_0, np.float32) | |
t_train = np.array(train[1], np.int32) | |
# テスト用データセット | |
x_test = np.array(test_0, np.float32) | |
t_test = np.array(test[1], np.uint32) | |
# モデルの定義 | |
import os, random | |
def reset_seed(seed=0): | |
os.environ['PYTHONHASHSEED'] = '0' | |
random.seed(seed) | |
np.random.seed(seed) | |
tf.random.set_seed(seed) | |
# シードの固定 | |
reset_seed(0) | |
# モデルの構築 | |
model = tf.keras.models.Sequential([ | |
tf.keras.layers.BatchNormalization(input_shape=(12,)), | |
tf.keras.layers.Dense(32, activation='relu'), | |
tf.keras.layers.Dense(1) | |
]) | |
# モデルのコンパイル | |
model.compile(optimizer='RMSprop', | |
loss='mse', | |
metrics=['mae']) | |
# モデル構造の確認 | |
model.summary() | |
# モデル構造の可視化 | |
tf.keras.utils.plot_model(model) | |
# モデルの学習 | |
history = model.fit(x_train, t_train, | |
epochs=60, | |
batch_size=32, | |
validation_data=(x_test, t_test)) | |
# 学習済みモデルの評価 | |
score = model.evaluate(x_test, t_test) | |
print(score) | |
# 結果の可視化 | |
result = pd.DataFrame(history.history) | |
# 目的関数の可視化 | |
result[['loss', 'val_loss']].plot() | |
plt.show() | |
# 評価指標の可視化 | |
result[['mae', 'val_mae']].plot(); | |
plt.show() |