bounty将在7天后过期。回答此问题可获得+200的声誉奖励。Marek M.正在寻找来自声誉良好来源的答案。
在《使用scikit-learn和Tensorflow的机器学习》一书中,有一段代码片段我无法理解。在那一章之前,他们的模型只是显式地使用层--无论是以顺序方式还是函数方式。但在第16章中,有这样一段代码:
import tensorflow_addons as tfa
encoder_inputs = keras.layers.Input(shape=[None], dtype=np.int32)
decoder_inputs = keras.layers.Input(shape=[None], dtype=np.int32)
sequence_lengths = keras.layers.Input(shape=[], dtype=np.int32)
embeddings = keras.layers.Embedding(vocab_size, embed_size)
encoder_embeddings = embeddings(encoder_inputs)
decoder_embeddings = embeddings(decoder_inputs)
encoder = keras.layers.LSTM(512, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_embeddings)
encoder_state = [state_h, state_c]
sampler = tfa.seq2seq.sampler.TrainingSampler()
decoder_cell = keras.layers.LSTMCell(512)
output_layer = keras.layers.Dense(vocab_size)
decoder = tfa.seq2seq.basic_decoder.BasicDecoder(decoder_cell, sampler,
output_layer=output_layer)
final_outputs, final_state, final_sequence_lengths = decoder(
decoder_embeddings, initial_state=encoder_state,
sequence_length=sequence_lengths)
Y_proba = tf.nn.softmax(final_outputs.rnn_output)
model = keras.models.Model(
inputs=[encoder_inputs, decoder_inputs, sequence_lengths],
outputs=[Y_proba])
然后他用一种标准的方式运行这个模型:
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam")
X = np.random.randint(100, size=10*1000).reshape(1000, 10)
Y = np.random.randint(100, size=15*1000).reshape(1000, 15)
X_decoder = np.c_[np.zeros((1000, 1)), Y[:, :-1]]
seq_lengths = np.full([1000], 15)
history = model.fit([X, X_decoder, seq_lengths], Y, epochs=2)
我很难理解从第7行开始的代码。作者正在创建一个Embedding
层,他立即在encoder_inputs
和decoder_inputs
上调用该层,然后,他对LSTM
层执行基本相同的操作,他在之前创建的encoder_embeddings
上调用该层,并且此操作返回的Tensor在下面的代码中使用。我不知道这些Tensor是如何训练的,看起来他没有使用模型中创建Tensor的层,但是如果是这样,那么嵌入是如何学习的,整个模型是如何收敛的?
1条答案
按热度按时间wtlkbnrh1#
这是Keras Functional API的一个示例。在这种定义模型的风格中,您先编写蓝图,然后再使用它。请将其视为电路布线:当你连接东西时,没有电流通过(电流对应于我们比喻中的数据),稍后,你打开电源,电流通过。
这也是Functional API的工作原理。首先,让我们阅读最后一行:
它说:“嘿,Keras,我需要一个模型,它的输入是
encoder_inputs
、decoder_inputs
和sequence_lengths
,它们最终将产生Y_proba
。它们将如何产生这个输出的细节在上面定义。让我们看看你遇到问题的特定行:第一行是“Keras,给予我一个可以生成嵌入的层”。
embeddings
是一个层对象。接下来的两行是我们讨论过的连接:您可以在数据流过层之前抢先连接层:* 这是Functional API的关键所在 *。因此,第二层表示:“Keras,encoder_inputs
,它是Input
,将连接(并通过)我刚刚创建的Embedding
层,其结果将存储在我称为encoder_embeddings
的变量中。代码的其余部分遵循相同的逻辑:你把电线连接在一起,然后你
compile
你的模型,最后fit
它与数据。