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)
まあ、どっちでも良いわね。