Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
6
Help us understand the problem. What are the problem?