V1n*_*3nt 8 padding sequence lstm keras recurrent-neural-network
我有一个关于Keras中LSTM序列长度不同的问题.我将大小为200的批次和可变长度序列(= x)与序列中每个对象(=> [200,x,100])的100个特征传递到LSTM:
LSTM(100, return_sequences=True, stateful=True, input_shape=(None, 100), batch_input_shape=(200, None, 100))
Run Code Online (Sandbox Code Playgroud)
我将模型拟合到以下随机创建的矩阵中:
x_train = np.random.random((1000, 50, 100))
x_train_2 = np.random.random((1000, 10,100))
Run Code Online (Sandbox Code Playgroud)
据我所知,LSTM(和Keras实现)正确,x应该指LSTM单元的数量.对于每个LSTM单元,必须学习状态和三个矩阵(用于单元的输入,状态和输出).如何在不填充最大值的情况下将不同的序列长度传递到LSTM中.指定长度,就像我一样?代码正在运行,但它实际上不应该(在我的理解中).甚至可以在之后传递另一个序列长度为60的x_train_3,但是不应该有额外的10个单元格的状态和矩阵.
顺便说一句,我使用Keras版本1.0.8和Tensorflow GPU 0.9.
这是我的示例代码:
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
from keras import backend as K
with K.get_session():
# create model
model = Sequential()
model.add(LSTM(100, return_sequences=True, stateful=True, input_shape=(None, 100),
batch_input_shape=(200, None, 100)))
model.add(LSTM(100))
model.add(Dense(2, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# Generate dummy training data
x_train = np.random.random((1000, 50, 100))
x_train_2 = np.random.random((1000, 10, 100))
y_train = np.random.random((1000, 2))
y_train_2 = np.random.random((1000, 2))
# Generate dummy validation data
x_val = np.random.random((200, 50, 100))
y_val = np.random.random((200, 2))
# fit and eval models
model.fit(x_train, y_train, batch_size=200, nb_epoch=1, shuffle=False, validation_data=(x_val, y_val), verbose=1)
model.fit(x_train_2, y_train_2, batch_size=200, nb_epoch=1, shuffle=False, validation_data=(x_val, y_val), verbose=1)
score = model.evaluate(x_val, y_val, batch_size=200, verbose=1)
Run Code Online (Sandbox Code Playgroud)
Dan*_*ler 10
第一:似乎你不需要stateful=True和batch_input.这些用于当您想要在部分中划分非常长的序列时,并且在没有模型认为序列已经结束的情况下单独训练每个部分.
使用有状态层时,必须在确定某个批处理是长序列的最后一部分时手动重置/擦除状态/内存.
你好像在处理整个序列.不需要有状态.
填充不是严格必要的,但似乎您可以使用填充+屏蔽来忽略其他步骤.如果您不想使用填充,则可以将数据分成较小的批次,每批次具有不同的序列长度.请参阅:stackoverflow.com/questions/46144191
序列长度(时间步长)不会改变细胞/单位数或重量.可以使用不同的长度进行训练.无法更改的维度是要素数量.
输入尺寸:
输入维度是(NumberOfSequences, Length, Features).
输入形状和单元数之间绝对没有关系.它只携带步数或递归,这是Length维度.
细胞:
LSTM层中的单元在密集层中表现得像"单元".
细胞不是一个步骤.单元格只是"并行"操作的数量.每组单元一起执行循环操作和步骤.
正如@ Yu-Yang在评论中注意到的那样,细胞之间有对话.但是他们是通过步骤继承的同一个实体的想法仍然有效.
你在图片看到这些小模块,如这不是细胞,它们的步骤.
可变长度:
也就是说,序列的长度不会影响LSTM层中的所有参数(矩阵)数量.它只会影响步骤数.
对于长序列,层内固定数量的矩阵将重新计算更多次,对于短序列将重新计算更少次数.但在所有情况下,它都是一个获得更新的矩阵,并被传递到下一步.
序列长度仅改变更新次数.
图层定义:
单元格的数量可以是任意数量,它只会定义多少并行的迷你大脑将一起工作(这意味着一个或多或少强大的网络,以及或多或少的输出功能).
LSTM(units=78)
#will work perfectly well, and will output 78 "features".
#although it will be less intelligent than one with 100 units, outputting 100 features.
Run Code Online (Sandbox Code Playgroud)
有一个独特的权重矩阵和一个独特的状态/记忆矩阵,可以继续传递到下一步.这些矩阵在每个步骤中都只是"更新",但每个步骤都没有一个矩阵.
每个框"A"是使用和更新相同组矩阵(状态,权重,......)的步骤.
没有4个单元,但是一个和相同的单元执行4次更新,每次输入更新一次.
每个X1,X2,...是长度维度中序列的一个切片.
较长的序列将比较短的序列重用和更新矩阵更多次.但它仍然是一个细胞.
细胞数确实影响基质的大小,但不依赖于序列长度.所有细胞都将并行工作,并在它们之间进行一些对话.
在您的模型中,您可以像这样创建LSTM图层:
model.add(LSTM(anyNumber, return_sequences=True, input_shape=(None, 100)))
model.add(LSTM(anyOtherNumber))
Run Code Online (Sandbox Code Playgroud)
通过使用None在input_shape这样,你已经告诉你的模型,它接受任何长度的序列.
你所要做的就是训练.你的培训代码还可以.唯一不允许的是在里面创建一个不同长度的批次.因此,正如您所做的那样,为每个长度创建一个批次并训练每个批次.
| 归档时间: |
|
| 查看次数: |
4257 次 |
| 最近记录: |