前回のMNISTに引き続き、初歩的な機械学習を練習していきます。
前回まで
TensorFlowの環境構築 indie-du.com
MNIST手書き文字分類 indie-du.com
今回
今回はTensorFlow公式チュートリアルの Text classification をベースにしています。
今回使用するコード
今回もいきなり! コード全文です。
import tensorflow as tf from tensorflow import keras # 対象データ全文中の頻出上位10000語に対して処理する vocab_size=10000 # データセットのロード (train_data, train_labels), (test_data, test_labels) = keras.datasets.imdb.load_data(num_words=vocab_size) # データ前処理(バラバラの長さの配列をパディングして同じ長さにする) train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=0, padding='post', maxlen=256) test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=0, padding='post', maxlen=256) # モデルの構築 model = keras.Sequential() model.add(keras.layers.Embedding(vocab_size, 16)) model.add(keras.layers.GlobalAveragePooling1D()) model.add(keras.layers.Dense(16, activation=tf.nn.relu)) model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid)) # モデルのコンパイル model.compile(optimizer=tf.train.AdamOptimizer(), loss='binary_crossentropy', metrics=['accuracy']) # 検証用データの切り出し(テスト用データとは別) x_val = train_data[:10000] partial_x_train = train_data[10000:] y_val = train_labels[:10000] partial_y_train = train_labels[10000:] # 学習の実行 history = model.fit(partial_x_train, partial_y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1) # モデルの評価 results = model.evaluate(test_data, test_labels) print(results)
コードの解説
データセットの準備
今回もTensorFlowにあらかじめ用意されているデータを使います。
Internet Movie Database にある映画レビューのデータ IMAB というものらしいです。
(train_data, train_labels), (test_data, test_labels) = keras.datasets.imdb.load_data(num_words=vocab_size)
データを覗いてみると下のようになっており、単語ではなく数字の配列になっていることがわかります。
print(train_data)
[list([1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]) list([1, 194, 1153, 194, 8255, 78, 228, 5, 6, 1463, 4369, 5012, 134, 26, 4, 715, 8, 118, 1634, 14, 394, 20, 13, 119, 954, 189, 102, 5, 207, 110, 3103, 21, 14, 69, 188, 8, 30, 23, 7, 4, 249, 126, 93, 4, 114, 9, 2300, 1523, 5, 647, 4, 116, 9, 35, 8163, 4, 229, 9, 340, 1322, 4, 118, 9, 4, 130, 4901, 19, 4, 1002, 5, 89, 29, 952, 46, 37, 4, 455, 9, 45, 43, 38, 1543, 1905, 398, 4, 1649, 26, 6853, 5, 163, 11, 3215, 2, 4, 1153, 9, 194, 775, 7, 8255, 2, 349, 2637, 148, 605, 2, 8003, 15, 123, 125, 68, 2, 6853, 15, 349, 165, 4362, 98, 5, 4, 228, 9, 43, 2, 1157, 15, 299, 120, 5, 120, 174, 11, 220, 175, 136, 50, 9, 4373, 228, 8255, 5, 2, 656, 245, 2350, 5, 4, 9837, 131, 152, 491, 18, 2, 32, 7464, 1212, 14, 9, 6, 371, 78, 22, 625, 64, 1382, 9, 8, 168, 145, 23, 4, 1690, 15, 16, 4, 1355, 5, 28, 6, 52, 154, 462, 33, 89, 78, 285, 16, 14 ...
これは文章中の単語を、使用頻度が高いものから順に数字をつけていって、レビュー文章の単語をそれに置き換えて配列にしたものの ようです。
どんな罵詈雑言が含まれているのでしょうねえ、ふふふ。
vocab_size=10000 としてデータをロードしているので、頻出上位10000語が機械学習の対象となります。
データ配列中の最大値が10000以下であるということです。(同数出ている単語もあると思うので、実際は10000よりだいぶ小さいと思います。)
ちなみに文章に戻したい場合は、手順がここに書いてあります。
Text classification with movie reviews | TensorFlow
データの前処理
配列データをさらに前処理します。
それぞれのレビュー内の単語数はもちろんバラバラなので、パディングを入れて全て 同じ長さの配列 にしています。
train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=0, padding='post', maxlen=256) test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=0, padding='post', maxlen=256)
シーケンスの前処理 - Keras Documentation
モデルの定義
さて今回もモデルを定義していきます。
ここはTensorFlow公式サイトからのコピペ。
Word Embedding
モデルの最初の層は Word Embedding という文章解析で有名なもののようで、
単語や文章を ベクトル としてあてはめる手法のようです。
model.add(keras.layers.Embedding(vocab_size, 16))
第一引数が単語数、第二引数が出力の次元数ということで、
まあ出力のイメージが想像もつきませんが 気にスンナ
Embeddingレイヤー - Keras Documentation
Poolingレイヤー
マックスプーリング演算
model.add(keras.layers.GlobalAveragePooling1D())
Poolingレイヤー - Keras Documentation
マックスプーリング演算
残りの層
残り二行は前回と同じですね。
よくある構成なのでしょうか。
model.add(keras.layers.Dense(16, activation=tf.nn.relu)) model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))
今回の出力層はポジティブ or ネガティブのboolなので、引数に1を指定しています。
モデルのコンパイル
モデルの定義が終わったら、学習プロセスを指定してコンパイルを実行。
model.compile(optimizer=tf.train.AdamOptimizer(), loss='binary_crossentropy', metrics=['accuracy'])
loss (損失関数) は前回と指定が違うのでわかったら追記。
学習の実行
fit メソッドで学習を実行します。
history = model.fit(partial_x_train, partial_y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1)
注意すべきは validation_data 引数ですかね。
学習用データの一部を切り出して指定しています。
引数の詳細は以下リンクから。
Sequentialモデル - Keras Documentation
今回はポジティブかネガティブかの二択判定だったので、もっと種類の多い分類をやるとおもしろいかもしれない。