概要
このチュートリアルをやってみました
所感などメモしておきます
環境
- macOS 14.0 (m2mac mini pro)
- Python 3.11.6
- tensorflow 2.14.0
インストール
- piepnv install tensorflow
- pipenv install tensorflow-macos
- pipenv install tensorflow-metal
訓練に時間がかかるので GPU を有効にします
使わないと10倍くらい訓練に時間がかかります
サンプルコード
import os
import time
import numpy as np
import tensorflow as tf
path_to_file = tf.keras.utils.get_file(
"shakespeare.txt",
"https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt",
)
text = open(path_to_file, "rb").read().decode(encoding="utf-8")
# 1. 学習データの取得、作成
vocab = sorted(set(text))
char2idx = {u: i for i, u in enumerate(vocab)}
idx2char = np.array(vocab)
text_as_int = np.array([char2idx[c] for c in text])
seq_length = 100
examples_per_epoch = len(text) // (seq_length + 1)
char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)
sequences = char_dataset.batch(seq_length + 1, drop_remainder=True)
def split_input_target(chunk):
input_text = chunk[:-1]
target_text = chunk[1:]
return input_text, target_text
dataset = sequences.map(split_input_target)
# 2, モデルの生成
BATCH_SIZE = 64
BUFFER_SIZE = 10000
dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)
vocab_size = len(vocab)
embedding_dim = 256
rnn_units = 1024
def build_model(vocab_size, embedding_dim, rnn_units, batch_size):
model = tf.keras.Sequential(
[
tf.keras.layers.Embedding(
vocab_size, embedding_dim, batch_input_shape=[batch_size, None]
),
tf.keras.layers.GRU(
rnn_units,
return_sequences=True,
stateful=True,
recurrent_initializer="glorot_uniform",
),
tf.keras.layers.Dense(vocab_size),
]
)
return model
model = build_model(
vocab_size=len(vocab),
embedding_dim=embedding_dim,
rnn_units=rnn_units,
batch_size=BATCH_SIZE,
)
# 3. モデルの訓練
def loss(labels, logits):
return tf.keras.losses.sparse_categorical_crossentropy(
labels, logits, from_logits=True
)
for input_example_batch, target_example_batch in dataset.take(1):
example_batch_predictions = model(input_example_batch)
sampled_indices = tf.random.categorical(example_batch_predictions[0], num_samples=1)
sampled_indices = tf.squeeze(sampled_indices, axis=-1).numpy()
example_batch_loss = loss(target_example_batch, example_batch_predictions)
model.compile(optimizer="adam", loss=loss)
checkpoint_dir = "./training_checkpoints"
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt_{epoch}")
checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_prefix, save_weights_only=True
)
EPOCHS = 10
history = model.fit(
dataset, epochs=EPOCHS, callbacks=[checkpoint_callback]
) # これで訓練するのでこれが時間がかかる
tf.train.latest_checkpoint(checkpoint_dir)
model = build_model(vocab_size, embedding_dim, rnn_units, batch_size=1)
model.load_weights(tf.train.latest_checkpoint(checkpoint_dir)).expect_partial()
model.build(tf.TensorShape([1, None]))
model.summary()
# 4. モデルの評価
def generate_text(model, start_string):
num_generate = 1000
input_eval = [char2idx[s] for s in start_string]
input_eval = tf.expand_dims(input_eval, 0)
text_generated = []
temperature = 1.0
model.reset_states()
for i in range(num_generate):
predictions = model(input_eval)
predictions = tf.squeeze(predictions, 0)
predictions = predictions / temperature
predicted_id = tf.random.categorical(predictions, num_samples=1)[-1, 0].numpy()
input_eval = tf.expand_dims([predicted_id], 0)
text_generated.append(idx2char[predicted_id])
return start_string + "".join(text_generated)
print(generate_text(model, start_string="ROMEO: "))
ちょっと解説
流れとしては
- 学習データの取得、作成
- 学習モデルを作成
- 学習モデルの訓練
- モデルの評価
という感じです
今回のサンプルだと毎回訓練するので評価までに時間がかかります
GPU を使っていれば 1 分ほどで完了します
最後に
他気になった点としては
- 毎回訓練させないで作成したモデルを使う回す方法
- GPU が 10 コアあるが 1 コアしか使っていなかった (並列で学習させると一意性が担保できないから?)
- そもそも keras の使い方や学習のさせ方がわかっていなさすぎる
とりあえず動かすことはできたのでいろいろと試してみたいと思います
0 件のコメント:
コメントを投稿