Tensorflow 2.0 學習(chapter 7)

對列表生成式和dict生成式的使用
imdb = keras.datasets.imdb
word_index = imdb.get_word_index()
word_index = {k:(v+3) for k,v in word_index.items()}
reverse_word_index = {v:k for k,v in word_index.items()}
pad_sequences
train_data = keras.preprocessing.pad_sequences(
	train_data, # 待填充數據
    value=0, # 用0填充
    padding='post', # 在後面填充
    maxlen=max_length
)

train_data應該是list<list<number>>類型的數據,不等長數組組成的數組

Embedding層
keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length)

相當於對one-hot變量降維。輸入層本來是batch_size×maxlen的數據,寫成batch_size×maxlen×vocab_size的獨熱形式,再降維到batch_size×maxlen×embedding_dim。

GlobalAveragePooling
keras.layers.GlobalAveragePooling1D()

在最後一個維度上取平均。得到batch_size×embedding_dim

SimpleRNN
single_rnn_model = keras.models.Sequential([
    keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
    keras.layers.SimpleRNN(units=64, return_sequences=False),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])

Emebedding返回的是batch_size×embedding_dim×maxlen大小的矩陣,SimpleRNN裏面有64個節點,

embedding_dim這個維度和64個節點連接,就像全連接層中embedding_dim個節點和64個節點連接一樣。maxlen這個維度的每個元素逐個輸入進RNN中,並且只保留最後一次的結果,維度會變成1。所以最終維度變成batch_size×64×1。

雙向RNN
model = keras.models.Sequential([
    keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
    keras.layers.Bidirectional(
        keras.layers.SimpleRNN(units=32, return_sequences=True)),
    keras.layers.Bidirectional(
        keras.layers.SimpleRNN(units=32, return_sequences=False)),
...
])

雙向RNN。好像會創建兩層RNN,兩層RNN都向外輸出。

return_sequences=True會把maxlen這個維度上的每次的結果都保存下來,

所以第一個Bidrectional的輸出大小是batch_size×maxlen×64,第二個輸出大小是batch_size×64

tf.random.categorical
# in
tf.random.categorical(tf.math.log([[0.1, 0.9], [0.2, 0.8], [0.3, 0.7]]), 20)

# out
<tf.Tensor: id=53, shape=(3, 20), dtype=int64, numpy=
array([[1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]],
      dtype=int64)>

參數 logits——對數概率分佈,num_samples——抽樣次數

從len(logits)個概率分佈中隨機抽樣num_samples次。比如上面是從3個分佈中抽樣20次。

保存與載入模型
output_dir = './text_generation_checkpoints'
if not os.path.exists(output_dir): os.mkdir(output_dir)
checkpoint_prefix = os.path.join(output_dir, "ckpt_{epoch}")
checkpoint_callback = keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_prefix,
    save_weights_only=True  # 只保存參數的值(不保存模型)
)
epochs = 100
history = model.fit(seq_dataset, epochs=epochs, callbacks=[checkpoint_callback])

保存checkpoint, 可以直接把{epoch}包含在字符串內,weights是參數的值。

model2 = keras.models.Sequential ...
model2.load_weights(tf.train.latest_checkpoint(output_dir)) # 載入參數值
model2.build(tf.TensorShape([1, None])) # None 是變長序列, 需要重新定義模型的輸入

之前用的是tf.keras.models.Model.compile, 在load模型時需要用build載入tf.keras.layers.Layer.build(input_shape)。

expand_dims 和 squeeze
input_eval = tf.expand_dims(input_eval, axis=0)  # 爲 tensor 添加一個維度1
predictions = tf.squeeze(input_eval, 0) # 去掉第dim=1的0個維度

把input_eval由n維變成1×n維,在變回n維

LSTM

用法跟SimpleRNN一樣

model = keras.models.Sequential([
    keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
    keras.layers.Bidirectional(keras.layers.LSTM(units=32, return_sequences=True)),
    keras.layers.Bidirectional(keras.layers.LSTM(units=32, return_sequences=False)),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章