LoginSignup
22
7

More than 3 years have passed since last update.

Tensorflow v2とTensorflowHub KerasLayerを使った最小の労力で自然言語処理

Last updated at Posted at 2019-12-04

Tensorflow v2 から利用できるTensorflowHub KerasLayerがすごい便利なので紹介。

データが少なくても簡単に自然言語系のタスクを実装できるようになり、Keras利用者にとって KerasLayer のおかげで TensorflowHub がもっと組み込みやすくなってます。

そもそもTensorflowHubとは

  • 学習済みモデルを利用/公開できるサービス
  • https://tfhub.dev/で利用したいモデルを探す
  • pip install tensorflow-hub とサンプルコードですぐ試せる
  • 画像関連はもちろん、自然言語で日本語に対応したモデルもある
  • 転移学習に利用できる

環境

私はpyenvを使っているので pyenv3.7.1 をインストール。

tensorflowtensorflow-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に載せる際にハマった事などいろいろあるのでまた今度紹介しようと思います。

22
7
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
22
7