言語処理100本ノック 2020 (Rev2)の「第8章: ニューラルネット」の79本目「多層ニューラルネットワーク」記録です。ようやくニューラルネットワークとしては一般的なものとなってきました。今までやったバイアスを使わないなど、むしろそんなオプションを知らなかったです。74本目に85%程度だった正解率から5%ほどあがり、90%の大台に達しています。
記事「まとめ: 言語処理100本ノックで学べることと成果」に言語処理100本ノック 2015についてはまとめていますが、追加で差分の言語処理100本ノック 2020 (Rev2)についても更新します。
参考リンク
リンク | 備考 |
---|---|
79_多層ニューラルネットワーク.ipynb | 回答プログラムのGitHubリンク |
言語処理100本ノック 2020 第8章: ニューラルネット | (PyTorchだけど)解き方の参考 |
【言語処理100本ノック 2020】第8章: ニューラルネット | (PyTorchだけど)解き方の参考 |
まとめ: 言語処理100本ノックで学べることと成果 | 言語処理100本ノックまとめ記事 |
環境
後々GPUを使わないと厳しいので、Goolge Colaboratory使いました。Pythonやそのパッケージでより新しいバージョンありますが、新機能使っていないので、プリインストールされているものをそのまま使っています。
種類 | バージョン | 内容 |
---|---|---|
Python | 3.7.12 | Google Colaboratoryのバージョン |
2.0.3 | Google Driveのマウントに使用 | |
tensorflow | 2.6.0 | ディープラーニングの主要処理 |
第8章: ニューラルネット
学習内容
深層学習フレームワークの使い方を学び,ニューラルネットワークに基づくカテゴリ分類を実装します.
ノック内容
第6章で取り組んだニュース記事のカテゴリ分類を題材として,ニューラルネットワークでカテゴリ分類モデルを実装する.なお,この章ではPyTorch, TensorFlow, Chainerなどの機械学習プラットフォームを活用せよ.
79. 多層ニューラルネットワーク
問題78のコードを改変し,バイアス項の導入や多層化など,ニューラルネットワークの形状を変更しながら,高性能なカテゴリ分類器を構築せよ.
回答
回答結果
evaluate
関数の結果、90.2%(+5.4%)の正答率、損失も0.27(-0.19)と大幅に精度向上しています。もっと上昇する余地もあるのでしょうが、時間が惜しいので先に進みます。
42/42 [==============================] - 1s 4ms/step - loss: 0.2675 - acc: 0.9019
[0.26749172806739807, 0.9019461274147034]
回答プログラム 79_多層ニューラルネットワーク.ipynb
GitHubには確認用コードも含めていますが、ここには必要なものだけ載せています。
import tensorflow as tf
from google.colab import drive
drive.mount('/content/drive')
LOG_DIR = './logs'
# Check if GPU is available
tf.config.list_physical_devices('GPU')
def _parse_function(example_proto):
# 特徴の記述
feature_description = {
'title': tf.io.FixedLenFeature([], tf.string),
'category': tf.io.FixedLenFeature([], tf.string)}
# 上記の記述を使って入力の tf.Example を処理
features = tf.io.parse_single_example(example_proto, feature_description)
X = tf.io.decode_raw(features['title'], tf.float32)
y = tf.io.decode_raw(features['category'], tf.int32)
return X, y
BASE_PATH = '/content/drive/MyDrive/ColabNotebooks/ML/NLP100_2020/08.NeuralNetworks/'
def get_dataset(file_name):
ds_raw = tf.data.TFRecordDataset(BASE_PATH+file_name+'.tfrecord')
#shuffleはここを見て理解。データ件数取る方法がわからず、1000件に設定
#https://qiita.com/exy81/items/d1388f6f02a11c8f1d7e
return ds_raw.map(_parse_function).shuffle(1000).batch(32)
train_ds = get_dataset('train')
valid_ds = get_dataset('valid')
test_ds = get_dataset('test')
model = tf.keras.Sequential(
[tf.keras.layers.Dense(64, activation='relu', input_dim=300), # , use_bias=False, kernel_initializer='random_uniform'
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(4, activation='softmax'),
])
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])
callbacks = []
callbacks.append(tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR))
model.fit(train_ds,
epochs=100,
validation_data=valid_ds,
callbacks=callbacks)
model.evaluate(test_ds)
回答解説
モデル
変更したモデル部分です。以下の点を変更。
- 密結合のレイヤを追加
- ドロップアウトのレイヤを追加(率は根拠なく設定)
- 出力層にバイアス項を追加(
use_bias=False
をなくす) - 出力層の重みの初期化をなくす(
kernel_initializer='random_uniform'
をなくす):精度に関係するか不明
model = tf.keras.Sequential(
[tf.keras.layers.Dense(64, activation='relu', input_dim=300), # , use_bias=False, kernel_initializer='random_uniform'
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(4, activation='softmax'),
])
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])
model.summary()
summary
関数でモデルを出力した結果です。
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 64) 19264
_________________________________________________________________
dropout (Dropout) (None, 64) 0
_________________________________________________________________
dense_1 (Dense) (None, 4) 260
=================================================================
Total params: 19,524
Trainable params: 19,524
Non-trainable params: 0
_________________________________________________________________
比較のために変更前のモデルです。学習する変数が一気に増えているのがわかります。
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 4) 1200
=================================================================
Total params: 1,200
Trainable params: 1,200
Non-trainable params: 0