深層学習(ディープラーニング)手法を用いて自然言語処理してみたいです。
このような要望にお応えします。
今回は自然言語処理タスクの文書分類にフォーカスします。
PythonライブラリKerasを使用します。
Kerasは、ニューラルネットワークモデルの構築をサポートしてくれます。
このライブラリを用いて、文書分類モデルの構築と評価を行います。
分析対象は、Tensorflowに組み込まれているIMDB datasetを使用します。
文書分類モデルは、入力層にEmbedding層を用いたNN(Neural Network)を使用します。
また、Embedding層のパラメータを一から学習する方法とGloVeの単語埋め込み情報を組み込んで学習するモデルを構築します。
Pythonの実行環境は、Anacondaをベースにjupyter notebookを利用しました。
Anacondaでの開発環境については、下記の記事にまとめています。
今回使用するライブラリのバージョンは以下になります。
- python 3.6.9
- tensorflow 2.2.0
- Keras 2.3.1
文書分類をはじめていきます。手順は、大きく以下のようになります。
- 文書データの準備
- モデルの定義
- モデルの学習/評価
文書データの準備
今回使用するIMDBデータセットは、映画のレビューデータです。各レビューに対して否定的レビューと肯定的なレビューといったラベルが付与されています。各レビューの文書情報がすでに前処理済みの状態になっており、出現単語を数値列に変換されたかたちで参照することができます。今回の問題は、与えられたレビュー文書が肯定的なのか、あるいは否定的なのかを分類する2値分類の問題となります。
1 2 3 4 5 6 7 8 9 |
import tensorflow as tf from tensorflow import keras import numpy as np imdb = keras.datasets.imdb num_words=10000 embedding_size = 32 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=num_words) |
num_wordsは、文書に出現した単語のうち、最も頻繁に出現する10000個を保持するためのものです。
このため、稀に出現するのみの単語は破棄されます。
次に以下の処理で数値と単語の対応付け情報を取得します。
1 2 3 4 5 6 7 8 9 |
word_index = imdb.get_word_index() word_index = {k:(v+3) for k, v in word_index.items()} word_index['<PAD>'] = 0 word_index['<START>'] = 1 word_index['UNK'] = 2 word_index['UNUSED'] = 3 revrese_word_index = dict([(value, key) for (key, value) in word_index.items()]) |
ベクトルに変換する方法は、大きく2つあります。
- 文書を単語の出現に応じて0と1のベクトルに変換するone-shot表現で扱う。ただし、この方法では文書に出現しない単語を0として扱うため、無駄な情報を多く含む傾向にあります。
- 文書を表現する配列をパディングにより同一の長さに揃え、文書データ数*パディング長のテンソル(行列)にします。Kerasでは、この処理を簡単に行うことができます。
今回は、文書を表現する配列をパディングにより同一の長さに揃える方法でデータの準備をします。
そのために、pad_sequencesメソッドを使用します。パディング長の長さを500に設定しています。
1 2 3 |
train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=word_index['<PAD>'], padding='post', maxlen=500) test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=word_index['<PAD>'], padding='post', maxlen=500) |
次に学習用データを用いて、モデル学習とパラメータチューニングを行うためにデータを分割します。
1 2 3 4 5 6 |
x_val = train_data[:10000] x_train = train_data[10000:] y_val = train_labels[:10000] y_train = train_labels[10000:] |
これでデータの準備は完了です。
モデルの定義
次は学習モデルを定義していきます。モデルは、NN(Neural Network)を使用します。
モデル構造は、以下のように設定します。
1 2 3 4 5 6 7 8 |
model = keras.Sequential() model.add(keras.layers.Embedding(num_words, embedding_size)) model.add(keras.layers.GlobalAveragePooling1D()) model.add(keras.layers.Dense(embedding_size, activation='relu')) model.add(keras.layers.Dense(1, activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary() |
モデルの構造は、summary()を用いることで確認することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_5 (Embedding) (None, None, 32) 320000 _________________________________________________________________ global_average_pooling1d_5 ( (None, 32) 0 _________________________________________________________________ dense_10 (Dense) (None, 32) 1056 _________________________________________________________________ dense_11 (Dense) (None, 1) 33 ================================================================= Total params: 321,089 Trainable params: 321,089 Non-trainable params: 0 _________________________________________________________________ |
最初のEmbedding層は、ベクトルに変換した文書を受け取り、各単語に対する埋め込みベクトルを返します。
埋め込みベクトルは、モデルの学習の中で獲得します。
この結果、(文書数, シーケンス長, embedding_size)の次元となります。
次は、GlobalAveragePooling1D層です。この層は、各文書データについて、シーケンスの次元方向に平均値を算出し、固定長のベクトルを返します。この層では、Embedding層からの情報を圧縮する役割があります。
GlobalAveragePooling1Dにより、各文書をembedding_size次元のベクトルに変換されます。
次にGlobalAveragePooling1D層からの情報を隠れユニット数16のDense(全結合)層に渡します。
今回は2値分類を行うタスクとなりますので、隠れ層ユニット1、活性化関数sigmoid関数を指定したDense層に渡します。
モデルの学習には、損失関数と最適化関数が必要です。
今回は2値分類タスクで出力は確率となりますので、損失関数としてbinary_crossentropy関数を使用します。binary_crossentropyは、確率分布間の距離を測定することができますので、今回の問題では真の分布と予測分布の距離を近づけることを目指しますのでこちらの損失関数を使用しています。最適化関数はadamを使用します。
1 2 |
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) |
これでモデル定義は完了です。
GloVeの単語埋め込み情報を組み込んで学習するモデルの構成は以下になります。
GloVeの学習済みパラメータを読み出し、embedding_matrixに格納します。
Embedding層のweightsにembedding_matrixを指定することでGloVeの学習済みのパラメータを組み込みます。
GloVeの学習済みパラメータは、こちら(http://nlp.stanford.edu/data/glove.6B.zip)からダウンロードして使用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
embeddings_index = {} with open('glove.6B.100d.txt') as f: for line in f: values = line.split() word = values[0] coefs = np.asarray(values[1:], dtype='float32') embeddings_index[word] = coefs embedding_matrix = np.zeros((len(word_index) + 1, embedding_size)) for word, i in word_index.items(): embedding_vector = embeddings_index.get(word) if embedding_vector is not None: embedding_matrix[i] = embedding_vector model = keras.Sequential() model.add(keras.layers.Embedding(len(word_index) + 1, embedding_size, weights=[embedding_matrix], input_length=max_sequence_size, trainable=True)) model.add(keras.layers.GlobalAveragePooling1D()) model.add(keras.layers.Dense(embedding_size, activation='relu')) model.add(keras.layers.Dense(1, activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary() |
モデルの構造は、summary()を用いることで確認することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_9 (Embedding) (None, 500, 100) 8858900 _________________________________________________________________ global_average_pooling1d_9 ( (None, 100) 0 _________________________________________________________________ dense_18 (Dense) (None, 100) 10100 _________________________________________________________________ dense_19 (Dense) (None, 1) 101 ================================================================= Total params: 8,869,101 Trainable params: 8,869,101 Non-trainable params: 0 _________________________________________________________________ |
これでモデル定義は完了です。
モデルの学習/評価
モデルを学習し、検証用データでモデルを評価してみます。
512個のサンプルからなるミニバッチを用いて各々40エポック、モデルを学習させます。
この結果、x_train, y_trainに格納した学習用の文書データを40回繰り返すことになります。
学習中は検証用データの10000サンプルを用いて、モデルの損失と正解率を確認します。
1 |
model.fit(x_train, y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1) |
[Embedding層に対するGloVe単語埋め込み情報なしモデルの学習]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
Epoch 1/40 30/30 [==============================] - 1s 41ms/step - loss: 0.6921 - accuracy: 0.5359 - val_loss: 0.6902 - val_accuracy: 0.5887 Epoch 2/40 30/30 [==============================] - 1s 39ms/step - loss: 0.6866 - accuracy: 0.6342 - val_loss: 0.6817 - val_accuracy: 0.6513 Epoch 3/40 30/30 [==============================] - 1s 39ms/step - loss: 0.6715 - accuracy: 0.6855 - val_loss: 0.6600 - val_accuracy: 0.6984 Epoch 4/40 30/30 [==============================] - 1s 40ms/step - loss: 0.6397 - accuracy: 0.7554 - val_loss: 0.6212 - val_accuracy: 0.7609 Epoch 5/40 30/30 [==============================] - 1s 39ms/step - loss: 0.5904 - accuracy: 0.7902 - val_loss: 0.5691 - val_accuracy: 0.7974 Epoch 6/40 30/30 [==============================] - 1s 39ms/step - loss: 0.5295 - accuracy: 0.8248 - val_loss: 0.5117 - val_accuracy: 0.8232 Epoch 7/40 30/30 [==============================] - 1s 39ms/step - loss: 0.4671 - accuracy: 0.8471 - val_loss: 0.4575 - val_accuracy: 0.8385 Epoch 8/40 30/30 [==============================] - 1s 39ms/step - loss: 0.4115 - accuracy: 0.8660 - val_loss: 0.4132 - val_accuracy: 0.8500 Epoch 9/40 30/30 [==============================] - 1s 39ms/step - loss: 0.3669 - accuracy: 0.8788 - val_loss: 0.3799 - val_accuracy: 0.8583 Epoch 10/40 30/30 [==============================] - 1s 39ms/step - loss: 0.3313 - accuracy: 0.8887 - val_loss: 0.3556 - val_accuracy: 0.8661 Epoch 11/40 30/30 [==============================] - 1s 40ms/step - loss: 0.3026 - accuracy: 0.8981 - val_loss: 0.3376 - val_accuracy: 0.8712 Epoch 12/40 30/30 [==============================] - 1s 40ms/step - loss: 0.2794 - accuracy: 0.9051 - val_loss: 0.3226 - val_accuracy: 0.8777 Epoch 13/40 30/30 [==============================] - 1s 39ms/step - loss: 0.2602 - accuracy: 0.9125 - val_loss: 0.3127 - val_accuracy: 0.8797 Epoch 14/40 30/30 [==============================] - 1s 39ms/step - loss: 0.2435 - accuracy: 0.9165 - val_loss: 0.3037 - val_accuracy: 0.8816 Epoch 15/40 30/30 [==============================] - 1s 39ms/step - loss: 0.2282 - accuracy: 0.9214 - val_loss: 0.2970 - val_accuracy: 0.8850 Epoch 16/40 30/30 [==============================] - 1s 39ms/step - loss: 0.2146 - accuracy: 0.9283 - val_loss: 0.2929 - val_accuracy: 0.8859 Epoch 17/40 30/30 [==============================] - 1s 40ms/step - loss: 0.2026 - accuracy: 0.9314 - val_loss: 0.2892 - val_accuracy: 0.8874 Epoch 18/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1915 - accuracy: 0.9358 - val_loss: 0.2897 - val_accuracy: 0.8855 Epoch 19/40 30/30 [==============================] - 1s 40ms/step - loss: 0.1827 - accuracy: 0.9410 - val_loss: 0.2889 - val_accuracy: 0.8848 Epoch 20/40 30/30 [==============================] - 1s 40ms/step - loss: 0.1728 - accuracy: 0.9433 - val_loss: 0.2850 - val_accuracy: 0.8886 Epoch 21/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1657 - accuracy: 0.9455 - val_loss: 0.2828 - val_accuracy: 0.8911 Epoch 22/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1564 - accuracy: 0.9501 - val_loss: 0.2830 - val_accuracy: 0.8918 Epoch 23/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1482 - accuracy: 0.9523 - val_loss: 0.2829 - val_accuracy: 0.8913 Epoch 24/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1423 - accuracy: 0.9550 - val_loss: 0.2841 - val_accuracy: 0.8915 Epoch 25/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1349 - accuracy: 0.9573 - val_loss: 0.2853 - val_accuracy: 0.8909 Epoch 26/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1292 - accuracy: 0.9597 - val_loss: 0.2868 - val_accuracy: 0.8908 Epoch 27/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1231 - accuracy: 0.9631 - val_loss: 0.2892 - val_accuracy: 0.8896 Epoch 28/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1173 - accuracy: 0.9650 - val_loss: 0.2911 - val_accuracy: 0.8919 Epoch 29/40 30/30 [==============================] - 1s 39ms/step - loss: 0.1123 - accuracy: 0.9679 - val_loss: 0.2950 - val_accuracy: 0.8871 Epoch 30/40 30/30 [==============================] - 1s 38ms/step - loss: 0.1077 - accuracy: 0.9693 - val_loss: 0.2965 - val_accuracy: 0.8917 Epoch 31/40 30/30 [==============================] - 1s 40ms/step - loss: 0.1029 - accuracy: 0.9713 - val_loss: 0.3019 - val_accuracy: 0.8891 Epoch 32/40 30/30 [==============================] - 1s 39ms/step - loss: 0.0988 - accuracy: 0.9721 - val_loss: 0.3019 - val_accuracy: 0.8895 Epoch 33/40 30/30 [==============================] - 1s 39ms/step - loss: 0.0944 - accuracy: 0.9752 - val_loss: 0.3085 - val_accuracy: 0.8873 Epoch 34/40 30/30 [==============================] - 1s 39ms/step - loss: 0.0912 - accuracy: 0.9748 - val_loss: 0.3099 - val_accuracy: 0.8890 Epoch 35/40 30/30 [==============================] - 1s 39ms/step - loss: 0.0865 - accuracy: 0.9772 - val_loss: 0.3131 - val_accuracy: 0.8881 Epoch 36/40 30/30 [==============================] - 1s 40ms/step - loss: 0.0826 - accuracy: 0.9792 - val_loss: 0.3164 - val_accuracy: 0.8889 Epoch 37/40 30/30 [==============================] - 1s 40ms/step - loss: 0.0790 - accuracy: 0.9803 - val_loss: 0.3210 - val_accuracy: 0.8880 Epoch 38/40 30/30 [==============================] - 1s 39ms/step - loss: 0.0756 - accuracy: 0.9821 - val_loss: 0.3262 - val_accuracy: 0.8857 Epoch 39/40 30/30 [==============================] - 1s 40ms/step - loss: 0.0728 - accuracy: 0.9820 - val_loss: 0.3308 - val_accuracy: 0.8865 Epoch 40/40 30/30 [==============================] - 1s 40ms/step - loss: 0.0692 - accuracy: 0.9845 - val_loss: 0.3353 - val_accuracy: 0.8847 |
[Embedding層に対するGloVe単語埋め込み情報ありモデルの学習]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
Epoch 1/40 30/30 [==============================] - 6s 191ms/step - loss: 0.6858 - accuracy: 0.5663 - val_loss: 0.6762 - val_accuracy: 0.6306 Epoch 2/40 30/30 [==============================] - 6s 187ms/step - loss: 0.6645 - accuracy: 0.6599 - val_loss: 0.6520 - val_accuracy: 0.6750 Epoch 3/40 30/30 [==============================] - 6s 186ms/step - loss: 0.6315 - accuracy: 0.6983 - val_loss: 0.6143 - val_accuracy: 0.7008 Epoch 4/40 30/30 [==============================] - 6s 187ms/step - loss: 0.5857 - accuracy: 0.7299 - val_loss: 0.5657 - val_accuracy: 0.7454 Epoch 5/40 30/30 [==============================] - 6s 186ms/step - loss: 0.5319 - accuracy: 0.7686 - val_loss: 0.5226 - val_accuracy: 0.7644 Epoch 6/40 30/30 [==============================] - 6s 187ms/step - loss: 0.4755 - accuracy: 0.8083 - val_loss: 0.4626 - val_accuracy: 0.8142 Epoch 7/40 30/30 [==============================] - 6s 187ms/step - loss: 0.4185 - accuracy: 0.8425 - val_loss: 0.4181 - val_accuracy: 0.8368 Epoch 8/40 30/30 [==============================] - 6s 187ms/step - loss: 0.3707 - accuracy: 0.8632 - val_loss: 0.3812 - val_accuracy: 0.8518 Epoch 9/40 30/30 [==============================] - 6s 187ms/step - loss: 0.3332 - accuracy: 0.8759 - val_loss: 0.3552 - val_accuracy: 0.8611 Epoch 10/40 30/30 [==============================] - 6s 186ms/step - loss: 0.3062 - accuracy: 0.8869 - val_loss: 0.3379 - val_accuracy: 0.8674 Epoch 11/40 30/30 [==============================] - 6s 186ms/step - loss: 0.2777 - accuracy: 0.9013 - val_loss: 0.3272 - val_accuracy: 0.8687 Epoch 12/40 30/30 [==============================] - 6s 185ms/step - loss: 0.2584 - accuracy: 0.9067 - val_loss: 0.3133 - val_accuracy: 0.8760 Epoch 13/40 30/30 [==============================] - 6s 187ms/step - loss: 0.2397 - accuracy: 0.9143 - val_loss: 0.3054 - val_accuracy: 0.8788 Epoch 14/40 30/30 [==============================] - 6s 187ms/step - loss: 0.2216 - accuracy: 0.9215 - val_loss: 0.3007 - val_accuracy: 0.8816 Epoch 15/40 30/30 [==============================] - 6s 188ms/step - loss: 0.2093 - accuracy: 0.9249 - val_loss: 0.3012 - val_accuracy: 0.8785 Epoch 16/40 30/30 [==============================] - 6s 186ms/step - loss: 0.1940 - accuracy: 0.9333 - val_loss: 0.2947 - val_accuracy: 0.8844 Epoch 17/40 30/30 [==============================] - 6s 184ms/step - loss: 0.1817 - accuracy: 0.9373 - val_loss: 0.2962 - val_accuracy: 0.8873 Epoch 18/40 30/30 [==============================] - 6s 188ms/step - loss: 0.1723 - accuracy: 0.9410 - val_loss: 0.2913 - val_accuracy: 0.8862 Epoch 19/40 30/30 [==============================] - 6s 189ms/step - loss: 0.1603 - accuracy: 0.9451 - val_loss: 0.2964 - val_accuracy: 0.8835 Epoch 20/40 30/30 [==============================] - 6s 188ms/step - loss: 0.1514 - accuracy: 0.9495 - val_loss: 0.2933 - val_accuracy: 0.8877 Epoch 21/40 30/30 [==============================] - 6s 187ms/step - loss: 0.1421 - accuracy: 0.9547 - val_loss: 0.2964 - val_accuracy: 0.8879 Epoch 22/40 30/30 [==============================] - 6s 187ms/step - loss: 0.1332 - accuracy: 0.9569 - val_loss: 0.2975 - val_accuracy: 0.8881 Epoch 23/40 30/30 [==============================] - 6s 185ms/step - loss: 0.1255 - accuracy: 0.9601 - val_loss: 0.3014 - val_accuracy: 0.8891 Epoch 24/40 30/30 [==============================] - 6s 187ms/step - loss: 0.1205 - accuracy: 0.9618 - val_loss: 0.3076 - val_accuracy: 0.8884 Epoch 25/40 30/30 [==============================] - 6s 187ms/step - loss: 0.1146 - accuracy: 0.9632 - val_loss: 0.3166 - val_accuracy: 0.8847 Epoch 26/40 30/30 [==============================] - 6s 186ms/step - loss: 0.1058 - accuracy: 0.9667 - val_loss: 0.3139 - val_accuracy: 0.8883 Epoch 27/40 30/30 [==============================] - 6s 186ms/step - loss: 0.0987 - accuracy: 0.9703 - val_loss: 0.3198 - val_accuracy: 0.8875 Epoch 28/40 30/30 [==============================] - 6s 203ms/step - loss: 0.0930 - accuracy: 0.9722 - val_loss: 0.3255 - val_accuracy: 0.8873 Epoch 29/40 30/30 [==============================] - 6s 187ms/step - loss: 0.0885 - accuracy: 0.9746 - val_loss: 0.3344 - val_accuracy: 0.8847 Epoch 30/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0836 - accuracy: 0.9750 - val_loss: 0.3386 - val_accuracy: 0.8855 Epoch 31/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0786 - accuracy: 0.9781 - val_loss: 0.3473 - val_accuracy: 0.8847 Epoch 32/40 30/30 [==============================] - 6s 184ms/step - loss: 0.0753 - accuracy: 0.9792 - val_loss: 0.3520 - val_accuracy: 0.8842 Epoch 33/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0694 - accuracy: 0.9817 - val_loss: 0.3609 - val_accuracy: 0.8825 Epoch 34/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0666 - accuracy: 0.9829 - val_loss: 0.3673 - val_accuracy: 0.8830 Epoch 35/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0609 - accuracy: 0.9852 - val_loss: 0.3800 - val_accuracy: 0.8804 Epoch 36/40 30/30 [==============================] - 6s 185ms/step - loss: 0.0598 - accuracy: 0.9858 - val_loss: 0.3844 - val_accuracy: 0.8822 Epoch 37/40 30/30 [==============================] - 6s 186ms/step - loss: 0.0538 - accuracy: 0.9875 - val_loss: 0.3907 - val_accuracy: 0.8820 Epoch 38/40 30/30 [==============================] - 6s 186ms/step - loss: 0.0506 - accuracy: 0.9895 - val_loss: 0.4027 - val_accuracy: 0.8782 Epoch 39/40 30/30 [==============================] - 6s 186ms/step - loss: 0.0491 - accuracy: 0.9888 - val_loss: 0.4058 - val_accuracy: 0.8793 Epoch 40/40 30/30 [==============================] - 6s 186ms/step - loss: 0.0449 - accuracy: 0.9915 - val_loss: 0.4153 - val_accuracy: 0.8795 |
モデルを評価します。評価指標は、損失率、正解率です。
1 |
results = model.evaluate(test_data, test_labels, verbose=2) |
[Embedding層に対するGloVe単語埋め込み情報なしモデルの評価結果]
1 2 |
782/782 - 1s - loss: 0.3633 - accuracy: 0.8715 [0.36330386996269226, 0.8714799880981445] |
[Embedding層に対するGloVe単語埋め込み情報ありモデルの評価結果]
1 2 |
782/782 - 2s - loss: 0.4518 - accuracy: 0.8650 [0.45178553462028503, 0.8649600148200989] |
このように、Kerasを使用すれば比較的簡単にディープラーニングモデルを構築できます。また、モデルの学習/評価も簡単にできます。
今回は、映画レビュー文書の分類を行いましたが、自前の文書を用意して試すこともできますので活用してみてはいかがでしょうか。
ソースコード全体を載せます。
[Embedding層に対するGloVe単語埋め込み情報なしモデル]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import tensorflow as tf from tensorflow import keras import numpy as np imdb = keras.datasets.imdb num_words=10000 embedding_size = 32 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=num_words) word_index = imdb.get_word_index() word_index = {k:(v+3) for k, v in word_index.items()} word_index['<PAD>'] = 0 word_index['<START>'] = 1 word_index['UNK'] = 2 word_index['UNUSED'] = 3 revrese_word_index = dict([(value, key) for (key, value) in word_index.items()]) def decode_text(text): return ' '.join([revrese_word_index.get(i, '?') for i in text]) train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=word_index['<PAD>'], padding='post', maxlen=500) test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=word_index['<PAD>'], padding='post', maxlen=500) x_val = train_data[:10000] x_train = train_data[10000:] y_val = train_labels[:10000] y_train = train_labels[10000:] model = keras.Sequential() model.add(keras.layers.Embedding(num_words, embedding_size)) model.add(keras.layers.GlobalAveragePooling1D()) model.add(keras.layers.Dense(embedding_size, activation='relu')) model.add(keras.layers.Dense(1, activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary() model.fit(x_train, y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1) results = model.evaluate(test_data, test_labels, verbose=2) print(results) |
[Embedding層に対するGloVe単語埋め込み情報ありモデル]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import tensorflow as tf from tensorflow import keras import numpy as np imdb = keras.datasets.imdb num_words=10000 embedding_size = 100 max_sequence_size = 500 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=num_words) word_index = imdb.get_word_index() word_index = {k:(v+3) for k, v in word_index.items()} word_index['<PAD>'] = 0 word_index['<START>'] = 1 word_index['UNK'] = 2 word_index['UNUSED'] = 3 revrese_word_index = dict([(value, key) for (key, value) in word_index.items()]) embeddings_index = {} with open('glove.6B.100d.txt') as f: for line in f: values = line.split() word = values[0] coefs = np.asarray(values[1:], dtype='float32') embeddings_index[word] = coefs embedding_matrix = np.zeros((len(word_index) + 1, embedding_size)) for word, i in word_index.items(): embedding_vector = embeddings_index.get(word) if embedding_vector is not None: embedding_matrix[i] = embedding_vector def decode_text(text): return ' '.join([revrese_word_index.get(i, '?') for i in text]) train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=word_index['<PAD>'], padding='post', maxlen=max_sequence_size) test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=word_index['<PAD>'], padding='post', maxlen=max_sequence_size) x_val = train_data[:10000] x_train = train_data[10000:] y_val = train_labels[:10000] y_train = train_labels[10000:] model = keras.Sequential() model.add(keras.layers.Embedding(len(word_index) + 1, embedding_size, weights=[embedding_matrix], input_length=max_sequence_size, trainable=True)) model.add(keras.layers.GlobalAveragePooling1D()) model.add(keras.layers.Dense(embedding_size, activation='relu')) model.add(keras.layers.Dense(1, activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.summary() model.fit(x_train, y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1) results = model.evaluate(test_data, test_labels, verbose=2) print(results) |