我在deep Deep Learning with Python的第7章第1节中找到了一段代码,如下所示:
from keras.models import Model
from keras import layers
from keras import Input
text_vocabulary_size = 10000
question_vocabulary_size = 10000
answer_vocabulary_size = 500
# Our text input is a variable-length sequence of integers.
# Note that we can optionally name our inputs!
text_input = Input(shape=(None,), dtype='int32', name='text')
# Which we embed into a sequence of vectors of size 64
embedded_text = layers.Embedding(64, text_vocabulary_size)(text_input)
# Which we encoded in a single vector via a LSTM
encoded_text = layers.LSTM(32)(embedded_text)
# Same process (with different layer instances) for the question
question_input = Input(shape=(None,), dtype='int32', name='question')
embedded_question = layers.Embedding(32, question_vocabulary_size)(question_input)
encoded_question = layers.LSTM(16)(embedded_question)
# We then concatenate the encoded question and encoded text
concatenated = layers.concatenate([encoded_text, encoded_question], axis=-1)
# And we add a softmax classifier on top
answer = layers.Dense(answer_vocabulary_size, activation='softmax')(concatenated)
# At model instantiation, we specify the two inputs and the output:
model = Model([text_input, question_input], answer)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['acc'])
如您所见,此模型的输入没有原始数据的形状信息,那么在嵌入图层后,LSTM的输入或嵌入的输出是一些可变长度序列。
所以我想知道:
附加信息:为了解释lstm_unit是什么(我不知道如何调用它,所以只显示它的图像):
答案 0 :(得分:3)
提供的循环图层继承自基础实现keras.layers.Recurrent
,其中包含选项return_sequences
,默认为False
。这意味着,默认情况下,循环图层将使用可变长度输入,并最终在最后的连续步骤中仅生成图层的输出。
因此,使用None
指定可变长度输入序列维度没有问题。
但是,如果您希望图层返回完整的输出序列,即输入序列的每一步的输出张量,那么您必须进一步处理该输出的可变大小。
你可以通过让下一层进一步接受一个可变大小的输入来解决这个问题,直到你的网络中的问题直到最后你必须从一些可变长度的东西计算一个损失函数,或者计算一些固定长度的表示,然后继续到后面的图层,具体取决于你的模型。
或者你可以通过要求固定长度的序列来做到这一点,可能使用特殊的sentinel值填充序列的末尾,这些值只表示一个空的序列项纯粹用于填充长度。
另外,Embedding
层是一个非常特殊的层,用于处理可变长度输入。对于输入序列的每个标记,输出形状将具有不同的嵌入向量,因此形状具有(批量大小,序列长度,嵌入维度)。由于下一层是LSTM,这没有问题......它也会愉快地使用可变长度序列。
但正如Embedding
上的文档中提到的那样:
input_length: Length of input sequences, when it is constant.
This argument is required if you are going to connect
`Flatten` then `Dense` layers upstream
(without it, the shape of the dense outputs cannot be computed).
如果您想直接从Embedding
转到非可变长度表示,则必须提供固定序列长度作为图层的一部分。
最后,请注意,当您表达LSTM图层的维度时,例如LSTM(32)
,您将描述该图层的输出空间的维度。
# example sequence of input, e.g. batch size is 1.
[
[34],
[27],
...
]
--> # feed into embedding layer
[
[64-d representation of token 34 ...],
[64-d representation of token 27 ...],
...
]
--> # feed into LSTM layer
[32-d output vector of the final sequence step of LSTM]
为了避免批量大小为1的低效率,一种策略是按照每个示例的序列长度对输入训练数据进行排序,然后根据公共序列长度分组,例如使用自定义Keras DataGenerator。
这具有允许大批量的优势,特别是如果您的模型可能需要批量标准化或涉及GPU密集型培训,甚至只是为了批量更新的梯度估计较少的好处。但它仍然允许您处理具有不同批处理长度的输入训练数据集,以用于不同的示例。
更重要的是,它还有一个很大的优势,即您无需管理任何填充以确保输入中的常见序列长度。
答案 1 :(得分:1)
如何处理单位?
单位是完全独立的长度,因此,没有什么特别的做法。
长度仅增加"重复步骤",但是重复步骤一直使用相同的单元格。
单元格数由用户固定和定义:
如何处理变长?
train_on_batch
和predict_on_batch
是最简单的形式。
mask_zero=True
。