python tensorflow 2.0 不使用 Keras 搭建简单的 LSTM 网络

Posted

技术标签:

【中文标题】python tensorflow 2.0 不使用 Keras 搭建简单的 LSTM 网络【英文标题】:python tensorflow 2.0 build a simple LSTM network without using Keras 【发布时间】:2020-05-23 17:16:42 【问题描述】:

我正在尝试在不使用 Keras API 的情况下构建 tensorflow LSTM 网络。模型很简单:

    4 个单词索引序列的输入 嵌入输入 100 个暗淡的词向量 通过 LSTM 层 输出 4 个单词序列的密集层

损失函数是序列损失。

我有以下代码:

# input
input_placeholder = tf.placeholder(tf.int32, shape=[config.batch_size, config.num_steps], name='Input')
labels_placeholder = tf.placeholder(tf.int32, shape=[config.batch_size, config.num_steps], name='Target')

# embedding
embedding = tf.get_variable('Embedding', initializer=embedding_matrix, trainable=False)
inputs = tf.nn.embedding_lookup(embedding, input_placeholder)
inputs = [tf.squeeze(x, axis=1) for x in tf.split(inputs, config.num_steps, axis=1)]

# LSTM
initial_state = tf.zeros([config.batch_size, config.hidden_size])
lstm_cell = tf.nn.rnn_cell.LSTMCell(config.hidden_size)
output, _ = tf.keras.layers.RNN(lstm_cell, inputs, dtype=tf.float32, unroll=True)

# loss op
all_ones = tf.ones([config.batch_size, config.num_steps])
cross_entropy = tfa.seq2seq.sequence_loss(output, labels_placeholder, all_ones, vocab_size)
tf.add_to_collection('total_loss', cross_entropy)
loss = tf.add_n(tf.get_collection('total_loss'))

# projection (dense)
proj_U = tf.get_variable('Matrix', [config.hidden_size, vocab_size])
proj_b = tf.get_variable('Bias', [vocab_size])
outputs = [tf.matmul(o, proj_U) + proj_b for o in output]

我现在的问题是在 LSTM 部分:

# tensorflow 1.x
output, _ = tf.contrib.rnn.static_rnn(
        lstm_cell, inputs, dtype = tf.float32, 
        sequence_length = [config.num_steps]*config.batch_size)

我在将其转换为 tensorlow 2 时遇到问题。在上面的代码中,我收到以下错误:

----------------------------------- ---------------------------- TypeError Traceback(最近一次调用 最后)在 ----> 1 个输出,_ = tf.keras.layers.RNN(lstm_cell, inputs, dtype=tf.float32, unroll=True)

TypeError: 无法解压不可迭代的 RNN 对象

【问题讨论】:

【参考方案1】:

以下代码应该适用于 TensorFlow 2.X。

import tensorflow as tf
# input
input_placeholder = tf.compat.v1.placeholder(tf.int32, shape=[config.batch_size, config.num_steps], name='Input')
labels_placeholder = tf.compat.v1.placeholder(tf.int32, shape=[config.batch_size, config.num_steps], name='Target')

# embedding
embedding = tf.compat.v1.get_variable('Embedding', initializer=embedding_matrix, trainable=False)
inputs = tf.nn.embedding_lookup(params=embedding, ids=input_placeholder)
inputs = [tf.squeeze(x, axis=1) for x in tf.split(inputs, config.num_steps, axis=1)]

# LSTM
initial_state = tf.zeros([config.batch_size, config.hidden_size])
lstm_cell = tf.compat.v1.nn.rnn_cell.LSTMCell(config.hidden_size)
output, _ = tf.keras.layers.RNN(lstm_cell, inputs, dtype=tf.float32, unroll=True)

# loss op
all_ones = tf.ones([config.batch_size, config.num_steps])
cross_entropy = tfa.seq2seq.sequence_loss(output, labels_placeholder, all_ones, vocab_size)
tf.compat.v1.add_to_collection('total_loss', cross_entropy)
loss = tf.add_n(tf.compat.v1.get_collection('total_loss'))

# projection (dense)
proj_U = tf.compat.v1.get_variable('Matrix', [config.hidden_size, vocab_size])
proj_b = tf.compat.v1.get_variable('Bias', [vocab_size])
outputs = [tf.matmul(o, proj_U) + proj_b for o in output]

# tensorflow 1.x
output, _ = tf.compat.v1.nn.static_rnn(
        lstm_cell, inputs, dtype = tf.float32, 
        sequence_length = [config.num_steps]*config.batch_size)

【讨论】:

以上是关于python tensorflow 2.0 不使用 Keras 搭建简单的 LSTM 网络的主要内容,如果未能解决你的问题,请参考以下文章

在 Tensorflow 2.0 中使用 GradientTape() 和 jacobian() 时出错

2020新书机器学习概念与PythonJupyter本环境使用Tensorflow 2.0,301页pdf

RuntimeError: `set_session` 在使用 TensorFlow 2.0 时不可用

社区分享 | Spark 玩转 TensorFlow 2.0

Tensorflow 2.0

Keras TensorFlow 2.0 精华资源