tfdsとかっていう、わりと使い勝手の悪い子

tensorflow_dataset 略して tfds ね。

これはtf.data.Datasetを元にして色々とtorch.Textみたいに出来るってやつなんだけど...

自然言語処理、もといテキスト処理に付いてはtorch.Textの方がよっぽど使い勝手が良いわ。

まあ、tensorflowはtensorflowで統一したほうが見通しが良いから、使うんだけどね。

やるのはこの2つ。

1.tfds.features.text.SubwordTextEncoder

2.tf.data.Dataset

1については、これは文章のリストからsentensepieceを使うやつね。

tokenizer = tfds.features.text.SubwordTextEncoder.build_form_corpus(corpus_generator , target_vocab_size)

target_vocab_size は 8000 ~ 32000 あれば十分だそうだから 213 ~ 215と言ったところね。

そうそう、tenorflow の tutorial で tfds.load() した data について、iterationして .numpy() としているわね。

これはただbyte型のデータに戻しているだけだから、自作のデータがあれば、それをそのままリストに変換してcorpus_generatorに入れれば大丈夫よ。

そのときにはstr型のまま,byte型に直さなくてもいいわ。

tokenizer = tfds.features.text.SubwordTextEncoder.load_from_file('path/to/tokenizer')
example = '今日はいい天気だね。一緒に遊びに行こうよ!'
print(tokenizer.encode(example))
#[126, 111, 7134, 132, 1, 169, 3048, 622, 11, 4]
print(tokenizer.decode(tokenizer.encode(example)))
#今日はいい天気だね。一緒に遊びに行こうよ!

2についてはdatasetを作るのに、tf.data.Dataset.from_tensor_slicesを使うわ。

dataset = tf.data.Dataset.from_tensor_slices(({'src': source_lines, 'tgt': target_lines}))

ここで、辞書からDatasetを作るには2重括弧の中に辞書を入れる必要があることに気をつけてね。

中身は勝手にtf.stringに変換されるから良いけど...でも、id化がmapを使ってそのまま変換というのが出来ないのよね。

こういったところが使い勝手が悪いのよ。

paddingした、データを用意する方法は2つ。

datasetに変換する前にid化とpaddingをするのか、変換した後でするかの2つよ。

1.dataset変換前にやる方法

#CONSTANTS
PAD = 0
SOS = tokenizer.vocab_size + 1
EOS = tokenizer.vocab_size + 2

#id化とpaddingね。
senteces = []
for sentence in train_data:
    sentenceの処理
    sentence = [SOS] + tokenizer.encode(sentence) + [EOS]
    sentences.append(sentence)
processed_sentences = tf.keras.preprocessing.sequence.pad_sequences(
                sentences, maxlen=MAX_LEN, padding='post')

#datasetの処理ね。
#questions, answers は上の処理をそれぞれに対して行えばいいわ。
dataset = tf.data.Dataset.from_tensor_slices((questions, answers))
dataset = dataset.cache()
dataset = dataset.shuffle(BUFFER_SIZE)
dataset = dataset.batch(BATCH_SIZE)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

#後はモデルに入れればいいわ
model.fit(dataset, epochs=EPOCHS)

#でも、もしfrom_tensor_slicesに辞書を入れたときは別よ

dataset = tf.data.Dataset.from_tensor_slices(({
    'inputs': questions}, {'outputs': answers}))

def model(args):
    inputs = tf.keras.Input(..., name='inputs')
    ...
    outputs = tf.keras.layers....(..., name='outputs')
   return tf.keras.Model(inputs=[inputs], outputs=outputs)
#ちゃんと名前にdataを合わせてね。

2.Dataset変換後にやる方法

dataset = tf.data.Dataset.from_tensor_slices((questions, answers))

def encode(src, tgt):
    return ([SOS] + tokenizer.encode(src) + [EOS], [SOS] + tokenizer.encode(tgt) + [EOS]
    
def tf_encode(src, tgt):
    result_src, result_tgt = tf.py_function(encode, (src, tgt) , tf.int64)
    result_src.set_shape([None])
    result_tgt.set_shape([None])
    return result_src, result_tgt

dataset = datset.map(tf_encode)
dataの処理
dataset = dataset.chche()
dataset = dataset.shuffle(BUFFER_SIZE)
#ここがpadding化のところね
dataset = dataset.padded_batch(BATCH_SIZE)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

まあ、どっちでも良いわね。