Tensorflow v2
から利用できるTensorflowHub KerasLayerがすごい便利なので紹介。
データが少なくても簡単に自然言語系のタスクを実装できるようになり、Keras利用者にとって KerasLayer
のおかげで TensorflowHub
がもっと組み込みやすくなってます。
そもそもTensorflowHubとは
- 学習済みモデルを利用/公開できるサービス
- https://tfhub.dev/で利用したいモデルを探す
-
pip install tensorflow-hub
とサンプルコードですぐ試せる - 画像関連はもちろん、自然言語で日本語に対応したモデルもある
- 転移学習に利用できる
環境
私はpyenvを使っているので pyenv
で 3.7.1
をインストール。
tensorflow
と tensorflow-hub
もインストールします。
tensorflow
に組み込まれた keras
を利用します。
$ pyenv install 3.7.1
$ pip install tensorflow==2.0.0 tensorflow-hub==0.7.0
簡単なnnlmを使ってみる
TensorflowHub
からモデルをロードして文章をベクトル化できます。(これは以前と同じ)
このベクトルを自作のモデルなどに転移学習する事もできます。
import tensorflow_hub as hub
embed = hub.load('https://tfhub.dev/google/nnlm-ja-dim128-with-normalization/2')
embed(['ネコ'])
<tf.Tensor: id=182, shape=(1, 128), dtype=float32, numpy=
array([[-0.10296704, 0.01587082, 0.0573468 , 0.059175 , -0.03958198,
-0.08217786, -0.14779228, -0.24691384, -0.07068112, -0.11670566,
-0.08285586, -0.01857655, -0.04645912, -0.05692579, 0.0815312 ,
-0.07908769, -0.05466406, -0.02179208, 0.10979927, -0.05734158,
-0.06557054, 0.07709339, 0.12023042, 0.00258559, -0.07060173,
0.10960913, -0.08923677, 0.06238426, 0.08451481, 0.14662118,
-0.03688983, 0.10679894, 0.01809704, -0.08754648, 0.0429281 ,
0.11621989, 0.11202757, 0.05788481, 0.00816733, 0.009843 ,
0.05847297, -0.0869061 , -0.12621959, 0.04002178, 0.12822641,
0.07994641, -0.00221055, -0.19458152, -0.02742083, 0.14718114,
0.0555301 , 0.11112078, 0.10370145, 0.08804794, 0.09565531,
0.16998029, 0.05571814, -0.03676133, 0.08836656, -0.02724845,
0.07221054, -0.04380354, -0.09449258, 0.01015431, -0.0904016 ,
0.10437841, 0.0442632 , -0.06275094, -0.00733054, -0.0532412 ,
0.05747321, 0.08354431, 0.14614691, -0.03355311, -0.04487225,
0.018634 , -0.16693713, 0.01418052, -0.1447136 , -0.02863057,
0.11374816, -0.02529281, -0.15476134, 0.00983464, 0.11917529,
0.08267409, 0.01913127, 0.07049622, -0.08751827, 0.00729084,
-0.03081291, 0.03002417, -0.03669447, -0.10596528, 0.045755 ,
-0.07780168, 0.03002104, 0.12458465, 0.01451691, 0.01804689,
0.03775274, -0.05732382, 0.06064591, 0.07148866, -0.16499299,
0.21076469, 0.0302352 , 0.08122093, -0.15884502, 0.06737471,
0.0686043 , 0.02858042, -0.067475 , -0.08131913, 0.03652628,
0.0554016 , -0.13050069, -0.01471644, 0.13639897, -0.1885046 ,
-0.16372472, -0.03479837, 0.02419067, 0.02371116, 0.02106602,
0.10979195, 0.01713384, -0.01521267]], dtype=float32)>
KerasLayerを使ってkerasに組み込んでみる
KerasLayer
に対応したモデルだと hub.KerasLayer
でkerasに組み込めるレイヤとしてロードできます。
オリジナルのKerasレイヤーを作成するを見て実装する必要がなくなりました。
import tensorflow as tf
from tensorflow import keras
hub_layer = hub.KerasLayer(
'https://tfhub.dev/google/nnlm-ja-dim128-with-normalization/2',
output_shape=[128],
input_shape=[],
dtype=tf.string,
)
model = keras.Sequential()
model.add(hub_layer)
model.add(keras.layers.Dense(64, activation='relu'))
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
keras_layer (KerasLayer) (None, 128) 117568128
_________________________________________________________________
dense (Dense) (None, 64) 8256
_________________________________________________________________
dense_1 (Dense) (None, 16) 1040
_________________________________________________________________
dense_2 (Dense) (None, 1) 17
=================================================================
Total params: 117,577,441
Trainable params: 9,313
Non-trainable params: 117,568,128
_________________________________________________________________
雑に2値分類で学習してみる
10個とかなり少ないデータセットを用意しました。食べ物と動物を2値分類するタスクです。
雑に50エポック回してみます。
model.compile(
optimizer=keras.optimizers.RMSprop(),
loss='binary_crossentropy',
metrics=['acc'],
)
model.fit(
[
'ピザ', '寿司', 'ステーキ', 'パスタ', 'コーラ',
'イヌ', 'ネコ', 'トラ', 'ゾウ', 'キリン',
],
[
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
],
epochs=50,
)
試してみる
import numpy as np
model.predict(np.array(['ラザニア', 'チキン', '牛', 'ワニ', 'サル']))
array([[0.06712804],
[0.10662787],
[0.6637654 ],
[0.8527697 ],
[0.9033404 ]], dtype=float32)
ラザニアは94%、チキンは90%で食べ物と判定し、
ワニは85%、サルは90%で動物だと判定しています。
動物であり、割と食べ物な牛は66%で動物と、的を得ています。
TensorflowHub
から転移学習しなければこんな少ないデータセットで学習する事など無理ですが、
簡単かつ強力なモデルを作る事ができました。
さいごに
簡単に自然言語系のタスクを実装できる TensorflowHub KerasLayer
を紹介しました。
universal-sentence-encoder-xling-manyを転移学習させて質疑応答できるシステムを作ってますが、それ専用にカスタムモデル作ったり、tensorflow/servingに載せる際にハマった事などいろいろあるのでまた今度紹介しようと思います。