ホーム » TensorFlow 2.0 » TensorFlow 2.0 : Tutorials : データのロードと前処理 :- テキストをロードする

TensorFlow 2.0 : Tutorials : データのロードと前処理 :- テキストをロードする

TensorFlow 2.0 : Beginner Tutorials : データのロードと前処理 :- テキストをロードする (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/06/2019

* 本ページは、TensorFlow org サイトの TF 2.0 – Beginner Tutorials – Load and preprocess data の以下のページを
翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

データのロードと前処理 :- テキストをロードする

このチュートリアルはテキストファイルからのサンプルをロードするために tf.data.TextLineDataset をどのように使用するかのサンプルを提供します。TextLineDataset はテキストファイルからのデータセットを作成するために設計されています、そこでは各サンプルは元のファイルからのテキストの 1 行です。これは主として行ベースの任意のテキストデータ (例えば、詩やエラーログ) のために潜在的に有用です。

このチュートリアルでは、同じワーク Homer’s Illiad の 3 つの異なる英語翻訳を使用します、そしてテキストのシングル行が与えられたとき翻訳者を識別するためにモデルを訓練します。

 

セットアップ

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

import tensorflow_datasets as tfds
import os

3 つの翻訳のテキストは次によります :

このチュートリアルで使用されるテキストファイルは幾つかの典型的な前処理タスクを受けています、殆どは何かを除去しています — ドキュメント・ヘッダとフッタ、行番号、章タイトルです。これらの軽く変換された (= munged) ファイルをローカルにダウンロードします。

DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt']

for name in FILE_NAMES:
  text_dir = tf.keras.utils.get_file(name, origin=DIRECTORY_URL+name)
  
parent_dir = os.path.dirname(text_dir)

parent_dir
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/cowper.txt
819200/815980 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/derby.txt
811008/809730 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/butler.txt
811008/807992 [==============================] - 0s 0us/step

'/home/kbuilder/.keras/datasets'

 

テキストをデータセットにロードする

ファイルを通して反復して、各一つをそれ自身のデータセットにロードします。

各サンプルは個々にラベル付けされる必要がありますので、各一つに labeler 関数を適用するために tf.data.Dataset.map を使用します。これはデータセットの総てのサンプルに渡り反復し、 (example, label) ペアを返します。

def labeler(example, index):
  return example, tf.cast(index, tf.int64)  

labeled_data_sets = []

for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(os.path.join(parent_dir, file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)

これらのラベル付けされたデータセットを単一のデータセットに結合して、そしてそれをシャッフルします。

BUFFER_SIZE = 50000
BATCH_SIZE = 64
TAKE_SIZE = 5000
all_labeled_data = labeled_data_sets[0]
for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)
  
all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)

tf.data.Dataset.take を使用して (example, label) ペアがどのようなものか見るためにプリントすることができます。numpy プロパティは各 Tensor の値を表示します。

for ex in all_labeled_data.take(5):
  print(ex)
(<tf.Tensor: id=74, shape=(), dtype=string, numpy=b'Fulfilling some, in others he shall fail,'>, <tf.Tensor: id=75, shape=(), dtype=int64, numpy=1>)
(<tf.Tensor: id=76, shape=(), dtype=string, numpy=b"Of straight-horn'd oxen, and your flowing cups">, <tf.Tensor: id=77, shape=(), dtype=int64, numpy=1>)
(<tf.Tensor: id=78, shape=(), dtype=string, numpy=b'him by the head, while Patroclus kept fast hold of his feet, and <tf.Tensor: id=79, shape=(), dtype=int64, numpy=2>)
(<tf.Tensor: id=80, shape=(), dtype=string, numpy=b"So thick and dark, about th' Ajaces stirr'd,">, <tf.Tensor: id=81, shape=(), dtype=int64, numpy=1>)
(<tf.Tensor: id=82, shape=(), dtype=string, numpy=b'Then, as the life ebbed out of you, you answered, O knight Patroclus:'>, <tf.Tensor: id=83, shape=(), dtype=int64, numpy=2>)

 

テキスト行を数値としてエンコードする

機械学習モデルは数値上で動作します、単語上ではありませんので、文字列値は数値のリストに変換される必要があります。それを行なうために、各一意の単語を一意の整数にマップします。

 

語彙を構築する

最初に、テキストを個々の一意な単語のコレクションにトークン化して語彙を構築します。TensorFlow と Python の両者でこれを行なう 2, 3 の方法があります。このチュートリアルのためには :

  1. 各サンプルの numpy 値に渡り反復する。
  2. tfds.features.text.Tokenizer を使用してそれをトークンに分割する。
  3. これらのトークンを Python set に集めます、重複を除去するためです。
  4. 後で使用するために語彙のサイズを得ます。
tokenizer = tfds.features.text.Tokenizer()

vocabulary_set = set()
for text_tensor, _ in all_labeled_data:
  some_tokens = tokenizer.tokenize(text_tensor.numpy())
  vocabulary_set.update(some_tokens)

vocab_size = len(vocabulary_set)
vocab_size
17178

 

サンプルをエンコードする

vocabulary_set を tfds.features.text.TokenTextEncoder に渡すことによりエンコーダを作成します。エンコーダの encode メソッドはテキストの文字列を取り整数のリストを返します。

encoder = tfds.features.text.TokenTextEncoder(vocabulary_set)

これを単一行の上で出力がどのようなものか見るために試すことができます。

example_text = next(iter(all_labeled_data))[0].numpy()
print(example_text)
b'Fulfilling some, in others he shall fail,'
encoded_example = encoder.encode(example_text)
print(encoded_example)
[8801, 4457, 10895, 9164, 12881, 7887, 2100]

今はデータセットの上でエンコーダをそれを tf.py_function にラッピングしてそれをデータセットの map メソッドに渡すことにより実行します。

def encode(text_tensor, label):
  encoded_text = encoder.encode(text_tensor.numpy())
  return encoded_text, label

def encode_map_fn(text, label):
  return tf.py_function(encode, inp=[text, label], Tout=(tf.int64, tf.int64))

all_encoded_data = all_labeled_data.map(encode_map_fn)

 

データセットをテストと訓練バッチに分割する

小さいテスト・データセットとより大きな訓練セットを作成するために tf.data.Dataset.taketf.data.Dataset.skip を使用します。

モデルに渡される前に、データセットはバッチ化される必要があります。典型的には、バッチ内部のサンプルは同じサイズと shape である必要があります。しかし、これらのデータセットのサンプルは総てが同じサイズではありません — テキストの各行は単語の異なる数を持っていました。そこでサンプルを同じサイズにパッドするために (batch の代わりに) tf.data.Dataset.padded_batch を使用します。

train_data = all_encoded_data.skip(TAKE_SIZE).shuffle(BUFFER_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE, padded_shapes=([-1],[]))

test_data = all_encoded_data.take(TAKE_SIZE)
test_data = test_data.padded_batch(BATCH_SIZE, padded_shapes=([-1],[]))

今では、test_data と train_data は (example, label) ペアのコレクションではなく、バッチのコレクションです。各バッチは配列として現れる (多くのサンプル, 多くのラベル) のペアです。

例示するために :

sample_text, sample_labels = next(iter(test_data))

sample_text[0], sample_labels[0]
(<tf.Tensor: id=99547, shape=(16,), dtype=int64, numpy=
 array([ 8801,  4457, 10895,  9164, 12881,  7887,  2100,     0,     0,
            0,     0,     0,     0,     0,     0,     0])>,
 <tf.Tensor: id=99551, shape=(), dtype=int64, numpy=1>)

新しいトークン・エンコーディングを導入したので (パディングのために使用されるゼロ)、語彙サイズは 1 つ増えました。

vocab_size += 1

 

モデルを構築する

model = tf.keras.Sequential()

最初の層は整数表現を密ベクトル埋め込みに変換します。より多くの詳細については Word Embeddings チュートリアルを見てください。

model.add(tf.keras.layers.Embedding(vocab_size, 64))

次の層は Long Short-Term Memory 層で、これはモデルに単語をそれらの他の単語とのコンテキストで理解させます。LSTM 上の双方向ラッパーはその前とその後に来たデータポイントとの関係でデータポイントについて学習します。

model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))

最後に一つまたはそれ以上の密結合層のシリーズを持ちます、最後の一つは出力層です。出力層は総てのラベルのための確率を生成します。最も高い確率を持つ一つはサンプルのラベルのモデル予測です。

# One or more dense layers.
# Edit the list in the `for` line to experiment with layer sizes.
for units in [64, 64]:
  model.add(tf.keras.layers.Dense(units, activation='relu'))

# Output layer. The first argument is the number of labels.
model.add(tf.keras.layers.Dense(3, activation='softmax'))

最後に、モデルをコンパイルします。softmax カテゴリー化モデルのためには、損失関数として sparse_categorical_crossentropy を使用します。他の optimizer も試すことができますが、adam は非常に一般的です。

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

 

モデルを訓練する

このデータ上で実行するこのモデルは妥当な結果を生成します (約 83%)。

model.fit(train_data, epochs=3, validation_data=test_data)
Epoch 1/3
697/697 [==============================] - 32s 46ms/step - loss: 0.5213 - accuracy: 0.7403 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 2/3
697/697 [==============================] - 26s 37ms/step - loss: 0.2968 - accuracy: 0.8667 - val_loss: 0.3581 - val_accuracy: 0.8400
Epoch 3/3
697/697 [==============================] - 26s 37ms/step - loss: 0.2214 - accuracy: 0.9019 - val_loss: 0.3703 - val_accuracy: 0.8428

<tensorflow.python.keras.callbacks.History at 0x7efb903020f0>
eval_loss, eval_acc = model.evaluate(test_data)

print('\nEval loss: {:.3f}, Eval accuracy: {:.3f}'.format(eval_loss, eval_acc))
79/79 [==============================] - 3s 40ms/step - loss: 0.3703 - accuracy: 0.8428

Eval loss: 0.370, Eval accuracy: 0.843
 

以上



AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com