【发布时间】:2018-04-09 08:40:54
【问题描述】:
我正在尝试使用 Reber Grammar 输入(暂时未嵌入)来理解 RNN(不是特定的)。您可以在this link 上找到 jupyter 笔记本(请忽略降价,因为我在第一个带有输出的版本上失败了,而且它不是最新的 :))。
对于每个时间步,我提供训练的输入和预期输出(因此它是一个多对多模型)。
-
输入/输出是“OneHotEncoded”(基于字符串“BTSXPVE”),例如
- B 是 [1, 0, 0, 0, 0, 0, 0]
- V 为 [0, 0, 0, 0, 0, 1, 0]
-
对于时间步长,我有长度未知的字符串(此处未编码以使其更清晰),例如:
- BPVVE
- BPVPXVPXVPXVVE
所以我决定将它们填充到 20 个时间步长。
- 对于批次,我有空。我生成了 2048 个用于训练的编码字符串和 256 个用于测试的字符串。
所以我的输入张量是 (2048, 20, 7)。我的输出张量也是 (2048, 20, 7),因为对于每个时间步,我都想得到预测。
所以我训练了 3 个多对多模型(简单 RNN、GRU 和 LSTM),如下面的代码。
model = Sequential()
model.add(LSTM(units=7, input_shape=(maxlen, 7), return_sequences=True))
model.compile(loss='mse',
optimizer='Nadam',
metrics=['mean_squared_error'])
history = model.fit(X_train, y_train, validation_data=(X_test, y_test),
epochs=1500, batch_size=1024)
正如预期的那样,对于每个时间步,我都有可能获得一个特定的值,例如(经过一些清理之后):
B 预测 [0, 0.622, 0, 0, 0.401, 0, 0](60% 有 T 或 40% 有 P)
这是正确的根据图生成一个词
现在,我想使用此模型生成字符串(因此是一对多模型),但我不知道如何保留该模型并将其用作生成器。
我以为只输入 B 的输入(填充到 20 个时间步),得到结果,将 B 与输出的最佳索引连接起来,将其填充到 20 个时间步,将需要的输入提供给 NN 等等.但我很确定这不是我们应该这样做的方式:s
此外,我尝试输入'B'和'T'来检查输出的概率是多少(应该是S或X)但我得到了:
X = np.array([[[1,0,0,0,0,0,0], [0,1,0,0,0,0,0]]]) # [[[B, P]]]
X = sequence.pad_sequences(X, maxlen=20)
print(model.predict(X)[0])
[0, 0.106, 0.587, 0.1, 0, 0.171, 0.007]
我的理解是预测 T(10%)、S(60%)、X(10%)、V (18%),但在 BT 之后,我应该在 X 上获得更多百分比,而在 V 上几乎没有/T(因为 T 之后的 V 和 T 只能在 B/P 之后)。就像我的模型没有考虑 n-1 个时间步长一样。所以也许我的模型是错误的:(
非常感谢您的支持,
【问题讨论】:
-
你用什么作为
Y?是不是X挪了一步? -
没错,我将它移动了 1 步并添加“E”作为最终输出(以保持相同的大小)
-
关于模型的精度,可能对于理解这些序列来说太小了。添加更多层,例如,您可以有一个(或多个)具有更多单元的第一层,然后是具有 7 个单元的最后一层。
-
我会尝试,但我对结果有疑问,因为 NN “创建”熵。我有一个二进制输入并得到一个“概率”作为输出。如果我将它提供给另一层,我猜它会从这种噪音中产生噪音,但我会尝试用于学习目的
-
我的意思是具有两层或多层的单个模型。这使模型“更聪明”(学习时间更长,但学得更好)。拥有太多层或单元可能会使您的模型过于智能(它可以记住训练数据,但无法理解测试数据 - 这称为过度拟合)。
标签: neural-network keras recurrent-neural-network