0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

言語処理100本ノック(2020)-82: 確率的勾配降下法による学習(keras)

Posted at

言語処理100本ノック 2020 (Rev2)「第9章: RNN, CNN」82本目「確率的勾配降下法による学習」記録です。前回(81本目)ノックから、大差ありません。訓練・評価するだけです。100Epoch訓練して、テストデータセットに対してLoss0.56、正答率84%まで行きました。まぁまぁではないでしょうか。
記事「まとめ: 言語処理100本ノックで学べることと成果」言語処理100本ノック 2015についてはまとめていますが、追加で差分の言語処理100本ノック 2020 (Rev2)についても更新します。

参考リンク

リンク 備考
82_確率的勾配降下法による学習.ipynb 回答プログラムのGitHubリンク
言語処理100本ノック 2020 第9章: RNN, CNN (PyTorchだけど)解き方の参考
【言語処理100本ノック 2020】第9章: RNN, CNN (PyTorchだけど)解き方の参考
まとめ: 言語処理100本ノックで学べることと成果 言語処理100本ノックまとめ記事

環境

後々GPUを使わないと厳しいので、Google Colaboratory使いました。Pythonやそのパッケージでより新しいバージョンありますが、新機能使っていないので、プリインストールされているものをそのまま使っています。

種類 バージョン 内容
Python 3.7.12 Google Colaboratoryのバージョン
google 2.0.3 Google Driveのマウントに使用
tensorflow 2.7.0 ディープラーニングの主要処理
nltk 3.2.5 Tokenの辞書作成に使用
pandas 1.1.5 行列に関する処理に使用

第8章: ニューラルネット

学習内容

深層学習フレームワークを用い,再帰型ニューラルネットワーク(RNN)や畳み込みニューラルネットワーク(CNN)を実装します.

82. 確率的勾配降下法による学習

確率的勾配降下法(SGD: Stochastic Gradient Descent)を用いて,問題81で構築したモデルを学習せよ.訓練データ上の損失と正解率,評価データ上の損失と正解率を表示しながらモデルを学習し,適当な基準(例えば10エポックなど)で終了させよ.

回答

回答結果

まとめるとこんな精度です。

データセット Loss 正答率
訓練 0.1618 94.73%
検証 0.6502 82.11%
評価 0.5557 83.76%

訓練後のテストデータセットの結果です。100Epochで訓練しています。

結果
42/42 [==============================] - 0s 8ms/step - loss: 0.5557 - acc: 0.8376
[0.5556892156600952, 0.83757483959198]

参考までに訓練時の最後(100Epoch目)の結果です。GPU使わずに訓練して、約14分かかっています。訓練のLossは100Epoch目まで下がっていますが、検証のLossがだいたい80Epoch目くらいから下げ止まりになっているのでEarly Stoppingすれば、もう少し精度が良くなるかもしれません。また、RNN(GRU)にDropOutも入れておけばよかったかもしれません(デフォルトでDropoutの値がゼロ)。

結果
Epoch 1/100
334/334 [==============================] - 14s 28ms/step - loss: 1.2010 - acc: 0.4574 - val_loss: 1.1561 - val_acc: 0.4731
Epoch 2/100
334/334 [==============================] - 8s 24ms/step - loss: 1.1497 - acc: 0.4863 - val_loss: 1.1481 - val_acc: 0.4850

中略

Epoch 99/100
334/334 [==============================] - 8s 24ms/step - loss: 0.1686 - acc: 0.9443 - val_loss: 0.6509 - val_acc: 0.8286
Epoch 100/100
334/334 [==============================] - 8s 24ms/step - loss: 0.1618 - acc: 0.9473 - val_loss: 0.6502 - val_acc: 0.8211

回答プログラム 82_確率的勾配降下法による学習.ipynb

GitHubには確認用コードも含めていますが、ここには必要なものだけ載せています。

import nltk
import pandas as pd
import tensorflow as tf
from google.colab import drive

drive.mount('/content/drive')

BASE_PATH = '/content/drive/MyDrive/ColabNotebooks/ML/NLP100_2020/06.MachineLearning/'
max_len = 0
vocabulary = []


def read_dataset(type_):
    global max_len
    global vocabulary
    df = pd.read_table(BASE_PATH+type_+'.feature.txt')
    df.info()
    sr_title = df['title'].str.split().explode()
    max_len_ = df['title'].map(lambda x: len(x.split())).max()
    if max_len < max_len_:
        max_len = max_len_
    if len(vocabulary) == 0:
        vocabulary = [k for k, v in nltk.FreqDist(sr_title).items() if v > 1]
    else:
        vocabulary.extend([k for k, v in nltk.FreqDist(sr_title).items() if v > 1])
    y = df['category'].replace({'b':0, 't':1, 'e':2, 'm':3})
    return df['title'], tf.keras.utils.to_categorical(y, dtype='int32')  # 4値分類なので訓練・検証・テスト共通でone-hot化


X_train, y_train = read_dataset('train')
X_valid, y_valid = read_dataset('valid')
X_test, y_test = read_dataset('test') # あまりこだわらずにテストデータセットも追加

# setで重複削除し、タプル形式に設定
tup_voc = tuple(set(vocabulary))

print(f'vocabulary size before removing duplicates: {len(vocabulary)}')
print(f'vocabulary size after removing duplicates: {len(tup_voc)}')
print(f'sample vocabulary: {tup_voc[:10]}')
print(f'max length is {max_len}')

vectorize_layer = tf.keras.layers.TextVectorization(
 output_mode='int',
 vocabulary=tup_voc,
 output_sequence_length=max_len)

print(f'sample vocabulary: {vectorize_layer.get_vocabulary()[:10]}')

model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(1,), dtype=tf.string))
model.add(vectorize_layer)
model.add(tf.keras.layers.Embedding(vectorize_layer.vocabulary_size(), 300, mask_zero=True))
model.add(tf.keras.layers.GRU(50))
model.add(tf.keras.layers.Dense(4, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])
model.summary()

model.fit(X_train, y_train, epochs=100, validation_data=(X_valid, y_valid))

回答解説

全体的にあまり変更点ないです。

ラベル

ラベルをto_categoriacal関数使ってOne-Hot化しています。それに伴い、関数から返す変数をXyの2つにしています。

def read_dataset(type_):
    global max_len
    global vocabulary
    df = pd.read_table(BASE_PATH+type_+'.feature.txt')
    df.info()
    sr_title = df['title'].str.split().explode()
    max_len_ = df['title'].map(lambda x: len(x.split())).max()
    if max_len < max_len_:
        max_len = max_len_
    if len(vocabulary) == 0:
        vocabulary = [k for k, v in nltk.FreqDist(sr_title).items() if v > 1]
    else:
        vocabulary.extend([k for k, v in nltk.FreqDist(sr_title).items() if v > 1])
    y = df['category'].replace({'b':0, 't':1, 'e':2, 'm':3})
    return df['title'], tf.keras.utils.to_categorical(y, dtype='int32')  # 4値分類なので訓練・検証・テスト共通でone-hot化

メトリックス追加

メトリックスにAccuracyを追加しています。

model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])

訓練

fit関数で100Epoch訓練をまわしています。

model.fit(X_train, y_train, epochs=100, validation_data=(X_valid, y_valid))

評価

最後にテストデートセットを使って評価。混合行列表示等まですればいいのかもしれませんが、していません。

model.evaluate(X_test, y_test)
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?