编码器-解码器模型提供了一种使用循环神经网络来解决诸如机器翻译之类的复杂序列到序列预测问题的模式。
在 Keras Python 深度学习库中可以开发编码器-解码器模型,并且 Keras 博客上已经描述了一个使用此模型开发的神经机器翻译系统的示例,并且 Keras 项目随附了示例代码。
该示例可为开发用于您自己的序列到序列预测问题的编码器-解码器 LSTM 模型提供基础。
在本教程中,您将了解如何为 Keras 的序列到序列预测问题开发一个复杂的编码器-解码器循环神经网络。
完成本教程后,您将了解:
- 如何为序列到序列预测在 Keras 中正确定义一个复杂的编码器-解码器模型。
- 如何定义一个人为但可扩展的序列到序列预测问题,您可以使用它来评估编码器-解码器 LSTM 模型。
- 如何在 Keras 中应用编码器-解码器 LSTM 模型来解决可扩展整数序列到序列预测问题。
通过我的新书 《Python 长短期记忆网络》来启动您的项目,其中包含分步教程以及所有示例的Python 源代码文件。
让我们开始吧。
- 2020年1月更新:更新了Keras 2.3和TensorFlow 2.0的API。

如何在Keras中开发用于序列到序列预测的编码器-解码器模型
照片来源:Björn Groß,部分权利保留。
教程概述
本教程分为3个部分;它们是
- Keras 中的编码器-解码器模型
- 可扩展序列到序列问题
- 用于序列预测的编码器-解码器 LSTM
Python 环境
本教程假定您已安装 Python SciPy 环境。您可以将此教程与 Python 2 或 3 结合使用。
您必须安装 Keras(2.0 或更高版本),并使用 TensorFlow 或 Theano 后端。
本教程还假设您已安装 scikit-learn、Pandas、NumPy 和 Matplotlib。
如果您在环境方面需要帮助,请参阅此帖子
Keras 中的编码器-解码器模型
编码器-解码器模型是一种组织循环神经网络以解决序列到序列预测问题的方法。
它最初是为机器翻译问题开发的,尽管它在诸如文本摘要和问答之类的相关序列到序列预测问题上也取得了成功。
该方法涉及两个循环神经网络,一个用于编码源序列,称为编码器,第二个用于将编码后的源序列解码为目标序列,称为解码器。
Keras 深度学习 Python 库提供了一个如何为机器翻译实现编码器-解码器模型的示例(lstm_seq2seq.py),该模型由库的创建者在其文章:“Keras 中序列到序列学习的十分钟入门”中描述。
有关此模型的详细分解,请参阅文章
有关 return_state 的更多信息,这可能对您来说是新知识,请参阅文章
有关使用 Keras Functional API 的更多帮助,请参阅文章
利用该示例中的代码作为起点,我们可以开发一个通用的函数来定义编码器-解码器循环神经网络。下面是这个名为 define_models() 的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 返回训练、推理编码器和推理解码器模型 def define_models(n_input, n_output, n_units): # 定义训练编码器 encoder_inputs = Input(shape=(None, n_input)) encoder = LSTM(n_units, return_state=True) encoder_outputs, state_h, state_c = encoder(encoder_inputs) encoder_states = [state_h, state_c] # 定义训练解码器 decoder_inputs = Input(shape=(None, n_output)) decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True) decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states) decoder_dense = Dense(n_output, activation='softmax') decoder_outputs = decoder_dense(decoder_outputs) model = Model([encoder_inputs, decoder_inputs], decoder_outputs) # 定义推理编码器 encoder_model = Model(encoder_inputs, encoder_states) # 定义推理解码器 decoder_state_input_h = Input(shape=(n_units,)) decoder_state_input_c = Input(shape=(n_units,)) decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c] decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs) decoder_states = [state_h, state_c] decoder_outputs = decoder_dense(decoder_outputs) decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states) # 返回所有模型 return model, encoder_model, decoder_model |
该函数接受 3 个参数,如下所示
- n_input:输入序列的基数,例如每个时间步的特征、单词或字符的数量。
- n_output:输出序列的基数,例如每个时间步的特征、单词或字符的数量。
- n_units:在编码器和解码器模型中创建的单元数,例如 128 或 256。
然后,该函数创建并返回 3 个模型,如下所示
- train:给定源序列、目标序列和移位目标序列即可训练的模型。
- inference_encoder:在为新的源序列进行预测时使用的编码器模型。
- inference_decoder:在为新的源序列进行预测时使用的解码器模型。
模型在给定源序列和目标序列的情况下进行训练,其中模型将源序列和移位目标序列作为输入,并预测整个目标序列。
例如,一个源序列可能是 [1,2,3],目标序列是 [4,5,6]。训练期间模型的输入和输出将是
1 2 3 |
输入 1:['1', '2', '3'] 输入 2:['_', '4', '5'] 输出:['4', '5', '6'] |
该模型旨在在生成新源序列的目标序列时进行递归调用。
源序列被编码,目标序列一次生成一个元素,使用“序列开始”字符(如“_”)来启动过程。因此,在上述情况下,训练期间将发生以下输入-输出对
1 2 3 4 |
t,输入 1,输入 2,输出 1, ['1', '2', '3'], '_', '4' 2, ['1', '2', '3'], '4', '5' 3, ['1', '2', '3'], '5', '6' |
这里可以看到如何使用模型的递归来构建输出序列。
在预测期间,inference_encoder 模型用于对输入序列进行一次编码,该编码返回用于初始化 inference_decoder 模型的状态。从那时起,inference_decoder 模型用于逐步生成预测。
下面名为 predict_sequence() 的函数可以在模型训练后用于在给定源序列的情况下生成目标序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 根据源序列生成目标序列 def predict_sequence(infenc, infdec, source, n_steps, cardinality): # 编码 state = infenc.predict(source) # 序列开始输入 target_seq = array([0.0 for _ in range(cardinality)]).reshape(1, 1, cardinality) # 收集预测结果 output = list() for t in range(n_steps): # 预测下一个字符 yhat, h, c = infdec.predict([target_seq] + state) # 存储预测结果 output.append(yhat[0,0,:]) # 更新状态 state = [h, c] # 更新目标序列 target_seq = yhat return array(output) |
该函数接受 5 个参数,如下所示
- infenc:在为新的源序列进行预测时使用的编码器模型。
- infdec:在为新的源序列进行预测时使用的解码器模型。
- source:编码后的源序列。
- n_steps:目标序列中的时间步数。
- cardinality:输出序列的基数,例如每个时间步的特征、单词或字符的数量。
然后,该函数返回一个包含目标序列的列表。
可扩展序列到序列问题
在本节中,我们定义了一个人为且可扩展的序列到序列预测问题。
源序列是一系列随机生成的整数值,例如 [20, 36, 40, 10, 34, 28],目标序列是输入序列的预定义子集的反向,例如反向顺序的前 3 个元素 [40, 36, 20]。
源序列的长度是可配置的;输入和输出序列的基数以及目标序列的长度也是可配置的。
我们将使用 6 个元素的源序列、50 的基数和 3 个元素的目标序列。
下面是一些更具体的示例。
1 2 3 4 5 |
源序列,目标序列 [13, 28, 18, 7, 9, 5] [18, 28, 13] [29, 44, 38, 15, 26, 22] [38, 44, 29] [27, 40, 31, 29, 32, 1] [31, 40, 27] ... |
鼓励您探索更大、更复杂的变体。请在下面的评论中发布您的发现。
让我们开始定义一个函数来生成随机整数序列。
我们将使用 0 值作为填充或序列开始字符,因此它已被保留,我们不能在源序列中使用它。为了实现这一点,我们将把我们的配置基数加 1,以确保独热编码足够大(例如,值 1 映射到索引 1 中的“1”值)。
例如
1 |
n_features = 50 + 1 |
我们可以使用 randint() Python 函数在 1 和问题基数大小减 1 之间的范围内生成随机整数。下面的 generate_sequence() 生成一个随机整数序列。
1 2 3 |
# 生成一个随机整数序列 def generate_sequence(length, n_unique): return [randint(1, n_unique-1) for _ in range(length)] |
接下来,我们需要根据源序列创建相应的目标序列。
为了简单起见,我们将选择源序列的前 n 个元素作为目标序列并反转它们。
1 2 3 |
# 定义目标序列 target = source[:n_out] target.reverse() |
我们还需要一个向前移位一个时间步的目标序列版本,以便作为到目前为止生成的模拟目标,包括第一个时间步的序列开始值。我们可以直接从目标序列创建它。
1 2 |
# 创建填充的目标输入序列 target_in = [0] + target[:-1] |
现在所有序列都已定义,我们可以对它们进行独热编码,即将其转换为二进制向量序列。我们可以使用 Keras 内置的 to_categorical() 函数来实现。
我们可以将所有这些放入一个名为 get_dataset() 的函数中,该函数将生成一定数量的序列,我们可以用它们来训练模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 为 LSTM 准备数据 def get_dataset(n_in, n_out, cardinality, n_samples): X1, X2, y = list(), list(), list() for _ in range(n_samples): # 生成源序列 source = generate_sequence(n_in, cardinality) # 定义目标序列 target = source[:n_out] target.reverse() # 创建填充的目标输入序列 target_in = [0] + target[:-1] # 编码 src_encoded = to_categorical([source], num_classes=cardinality) tar_encoded = to_categorical([target], num_classes=cardinality) tar2_encoded = to_categorical([target_in], num_classes=cardinality) # 存储 X1.append(src_encoded) X2.append(tar2_encoded) y.append(tar_encoded) return array(X1), array(X2), array(y) |
最后,我们需要能够解码一个 独热编码的序列,使其可以再次被读取。
这对于打印生成的目標序列和轻松比较完整的预测目標序列是否与预期的目標序列匹配都是必需的。one_hot_decode() 函数将解码一个编码序列。
1 2 3 |
# 解码 One-Hot 编码字符串 def one_hot_decode(encoded_seq): return [argmax(vector) for vector in encoded_seq] |
我们可以将所有这些内容整合在一起并测试这些函数。
下面列出了一个完整的实际示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
from random import randint from numpy import array from numpy import argmax 从 keras.utils 导入 to_categorical # 生成一个随机整数序列 def generate_sequence(length, n_unique): return [randint(1, n_unique-1) for _ in range(length)] # 为 LSTM 准备数据 def get_dataset(n_in, n_out, cardinality, n_samples): X1, X2, y = list(), list(), list() for _ in range(n_samples): # 生成源序列 source = generate_sequence(n_in, cardinality) # 定义目标序列 target = source[:n_out] target.reverse() # 创建填充的目标输入序列 target_in = [0] + target[:-1] # 编码 src_encoded = to_categorical([source], num_classes=cardinality) tar_encoded = to_categorical([target], num_classes=cardinality) tar2_encoded = to_categorical([target_in], num_classes=cardinality) # 存储 X1.append(src_encoded) X2.append(tar2_encoded) y.append(tar_encoded) return array(X1), array(X2), array(y) # 解码 One-Hot 编码字符串 def one_hot_decode(encoded_seq): return [argmax(vector) for vector in encoded_seq] # 配置问题 n_features = 50 + 1 n_steps_in = 6 n_steps_out = 3 # 生成单个源序列和目标序列 X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 1) print(X1.shape, X2.shape, y.shape) print('X1=%s, X2=%s, y=%s' % (one_hot_decode(X1[0]), one_hot_decode(X2[0]), one_hot_decode(y[0]))) |
运行示例后,首先会打印生成的数据集的形状,确保用于训练模型的 3D 形状符合我们的预期。
生成的序列随后被解码并打印到屏幕上,这表明源序列和目标序列的准备都符合我们的预期,并且解码操作正在正常工作。
1 2 |
(1, 6, 51) (1, 3, 51) (1, 3, 51) X1=[32, 16, 12, 34, 25, 24], X2=[0, 12, 16], y=[12, 16, 32] |
现在我们可以为这个序列到序列的预测问题开发模型了。
用于序列预测的编码器-解码器 LSTM
在本节中,我们将把第一节中开发的编码器-解码器 LSTM 模型应用于第二节中开发的序列到序列预测问题。
第一步是配置问题。
1 2 3 4 |
# 配置问题 n_features = 50 + 1 n_steps_in = 6 n_steps_out = 3 |
接下来,我们必须定义模型并编译训练模型。
1 2 3 |
# 定义模型 train, infenc, infdec = define_models(n_features, n_features, 128) train.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) |
接下来,我们可以生成一个包含 100,000 个示例的训练数据集并训练模型。
1 2 3 4 5 |
# 生成训练数据集 X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 100000) print(X1.shape,X2.shape,y.shape) # 训练模型 train.fit([X1, X2], y, epochs=1) |
模型训练完成后,我们可以对其进行评估。我们将通过对 100 个源序列进行预测并计算正确预测的目标序列数量来进行评估。我们将使用 numpy 的 `array_equal()` 函数对解码后的序列进行相等性检查。
1 2 3 4 5 6 7 8 |
# 评估 LSTM total, correct = 100, 0 for _ in range(total): X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 1) target = predict_sequence(infenc, infdec, X1, n_steps_out, n_features) if array_equal(one_hot_decode(y[0]), one_hot_decode(target)): correct += 1 print('Accuracy: %.2f%%' % (float(correct)/float(total)*100.0)) |
最后,我们将生成一些预测,并打印解码后的源序列、目标序列和预测目标序列,以了解模型是否按预期工作。
将所有这些元素组合在一起,完整的代码示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
from random import randint from numpy import array from numpy import argmax from numpy import array_equal from keras.utils import to_categorical from keras.models import Model from keras.layers import Input 从 keras.layers 导入 LSTM from keras.layers import Dense # 生成一个随机整数序列 def generate_sequence(length, n_unique): return [randint(1, n_unique-1) for _ in range(length)] # 为 LSTM 准备数据 def get_dataset(n_in, n_out, cardinality, n_samples): X1, X2, y = list(), list(), list() for _ in range(n_samples): # 生成源序列 source = generate_sequence(n_in, cardinality) # 定义填充的目标序列 target = source[:n_out] target.reverse() # 创建填充的目标输入序列 target_in = [0] + target[:-1] # 编码 src_encoded = to_categorical([source], num_classes=cardinality) tar_encoded = to_categorical([target], num_classes=cardinality) tar2_encoded = to_categorical([target_in], num_classes=cardinality) # 存储 X1.append(src_encoded) X2.append(tar2_encoded) y.append(tar_encoded) return array(X1), array(X2), array(y) # 返回训练、推理编码器和推理解码器模型 def define_models(n_input, n_output, n_units): # 定义训练编码器 encoder_inputs = Input(shape=(None, n_input)) encoder = LSTM(n_units, return_state=True) encoder_outputs, state_h, state_c = encoder(encoder_inputs) encoder_states = [state_h, state_c] # 定义训练解码器 decoder_inputs = Input(shape=(None, n_output)) decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True) decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states) decoder_dense = Dense(n_output, activation='softmax') decoder_outputs = decoder_dense(decoder_outputs) model = Model([encoder_inputs, decoder_inputs], decoder_outputs) # 定义推理编码器 encoder_model = Model(encoder_inputs, encoder_states) # 定义推理解码器 decoder_state_input_h = Input(shape=(n_units,)) decoder_state_input_c = Input(shape=(n_units,)) decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c] decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs) decoder_states = [state_h, state_c] decoder_outputs = decoder_dense(decoder_outputs) decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states) # 返回所有模型 return model, encoder_model, decoder_model # 根据源序列生成目标序列 def predict_sequence(infenc, infdec, source, n_steps, cardinality): # 编码 state = infenc.predict(source) # 序列开始输入 target_seq = array([0.0 for _ in range(cardinality)]).reshape(1, 1, cardinality) # 收集预测结果 output = list() for t in range(n_steps): # 预测下一个字符 yhat, h, c = infdec.predict([target_seq] + state) # 存储预测结果 output.append(yhat[0,0,:]) # 更新状态 state = [h, c] # 更新目标序列 target_seq = yhat return array(output) # 解码 One-Hot 编码字符串 def one_hot_decode(encoded_seq): return [argmax(vector) for vector in encoded_seq] # 配置问题 n_features = 50 + 1 n_steps_in = 6 n_steps_out = 3 # 定义模型 train, infenc, infdec = define_models(n_features, n_features, 128) train.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 生成训练数据集 X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 100000) print(X1.shape,X2.shape,y.shape) # 训练模型 train.fit([X1, X2], y, epochs=1) # 评估 LSTM total, correct = 100, 0 for _ in range(total): X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 1) target = predict_sequence(infenc, infdec, X1, n_steps_out, n_features) if array_equal(one_hot_decode(y[0]), one_hot_decode(target)): correct += 1 print('Accuracy: %.2f%%' % (float(correct)/float(total)*100.0)) # 抽查一些例子 for _ in range(10): X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 1) target = predict_sequence(infenc, infdec, X1, n_steps_out, n_features) print('X=%s y=%s, yhat=%s' % (one_hot_decode(X1[0]), one_hot_decode(y[0]), one_hot_decode(target))) |
运行示例后,首先会打印准备好的数据集的形状。
1 |
(100000, 6, 51) (100000, 3, 51) (100000, 3, 51) |
接下来,模型会被拟合。您应该会看到一个进度条,并且在现代多核 CPU 上运行应该不到一分钟。
1 |
100000/100000 [==============================] - 50s - loss: 0.6344 - acc: 0.7968 |
接下来,模型被评估并打印准确率。
注意:由于算法或评估过程的随机性,或者数值精度的差异,您的结果可能有所不同。考虑运行示例几次并比较平均结果。
我们可以看到,模型在新的随机生成示例上达到了 100% 的准确率。
1 |
Accuracy: 100.00% |
最后,生成 10 个新示例并预测目标序列。同样,我们可以看到模型在每种情况下都正确预测了输出序列,并且预期值与源序列的前 3 个元素的反转匹配。
1 2 3 4 5 6 7 8 9 10 |
X=[22, 17, 23, 5, 29, 11] y=[23, 17, 22], yhat=[23, 17, 22] X=[28, 2, 46, 12, 21, 6] y=[46, 2, 28], yhat=[46, 2, 28] X=[12, 20, 45, 28, 18, 42] y=[45, 20, 12], yhat=[45, 20, 12] X=[3, 43, 45, 4, 33, 27] y=[45, 43, 3], yhat=[45, 43, 3] X=[34, 50, 21, 20, 11, 6] y=[21, 50, 34], yhat=[21, 50, 34] X=[47, 42, 14, 2, 31, 6] y=[14, 42, 47], yhat=[14, 42, 47] X=[20, 24, 34, 31, 37, 25] y=[34, 24, 20], yhat=[34, 24, 20] X=[4, 35, 15, 14, 47, 33] y=[15, 35, 4], yhat=[15, 35, 4] X=[20, 28, 21, 39, 5, 25] y=[21, 28, 20], yhat=[21, 28, 20] X=[50, 38, 17, 25, 31, 48] y=[17, 38, 50], yhat=[17, 38, 50] |
现在您有了一个编码器-解码器 LSTM 模型模板,您可以将其应用于您自己的序列到序列预测问题。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
相关文章
- 如何使用 Anaconda 设置用于机器学习和深度学习的 Python 环境
- 如何在 Keras 中为神经机器翻译定义编码器-解码器序列到序列模型
- 理解 Keras 中 LSTM 的 return sequences 和 return states 的区别
- 如何使用 Keras 函数式 API 进行深度学习
Keras 资源
总结
在本教程中,您将学习如何使用 Keras 为序列到序列预测问题开发一个编码器-解码器循环神经网络。
具体来说,你学到了:
- 如何为序列到序列预测在 Keras 中正确定义一个复杂的编码器-解码器模型。
- 如何定义一个人为但可扩展的序列到序列预测问题,您可以使用它来评估编码器-解码器 LSTM 模型。
- 如何在 Keras 中应用编码器-解码器 LSTM 模型来解决可扩展整数序列到序列预测问题。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
这个模型也适用于序列回归吗?例如洗发水销售问题
你可以试试,但通常 LSTM 在自回归问题上表现不佳
https://machinelearning.org.cn/suitability-long-short-term-memory-networks-time-series-forecasting/
你好,这个例子可以用于预测浮点数吗?例如 [0.123,0.234,0.345],目标是 [0.234,0.123]。
是的,你可以在这里看到一个例子
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
嗨,谢谢你的帖子。我是 LSTM 的新手。看起来目标总是源的一部分,我们能用 LSTM 预测目标不是源的子集吗?例如,源是 [0.123,0.234,0.345],目标是 [0.564, 0.923, 0.667]?提前感谢。
是的,你可以。
你好。可以在这个代码中为编码器和解码器使用多层 LSTM 吗?谢谢你的精彩博客。
是的,但我没有例子。对于这种情况,需要一些仔细的重新设计。
你好,也许这次你对多层 LSTM 自编码器有什么想法?
也许这会有所帮助
https://machinelearning.org.cn/lstm-autoencoders/
@Teimour @Dk @jason Brownlee 这里有一个使用 Keras 函数式 API 的多层编码器-解码器的优秀示例。
你能否提供更多关于如何修改以在解码器中拥有多个 LSTM 层的信息?我正在处理类似的事情,并希望为解码器添加层。
我如何提取瓶颈层来提取序列数据中的重要特征?
你可以访问返回的状态来获取上下文向量,但这并不能帮助你理解哪些输入特征是相关的/重要的。
谢谢你,Jason!
不客气。
感谢 Jason 的精彩教程!
不过我遇到一个问题:我尝试按原样执行您的代码(复制粘贴),但它报错了
使用 TensorFlow 后端。
回溯(最近一次调用)
File “C:\Users\User\Documents\pystuff\keras_auto.py”, line 91, in
train, infenc, infdec = define_models(n_features, n_features, 128)
File “C:\Users\User\Documents\pystuff\keras_auto.py”, line 40, in define_models
encoder = LSTM(n_units, return_state=True)
File “C:\Users\User\Anaconda3\envs\py35\lib\site-packages\keras\legacy\interfaces.py”, line 88, in wrapper
return func(*args, **kwargs)
File “C:\Users\User\Anaconda3\envs\py35\lib\site-packages\keras\layers\recurrent.py”, line 949, in __init__
super(LSTM, self).__init__(**kwargs)
File C:\Users\User\Anaconda3\envs\py35\lib\site-packages\keras\layers\recurrent.py”, line 191, in __init__
super(Recurrent, self).__init__(**kwargs)
File “C:\Users\User\Anaconda3\envs\py35\lib\site-packages\keras\engine\topology.py”, line 281, in __init__
raise TypeError(‘Keyword argument not understood:’, kwarg)
TypeError: (‘Keyword argument not understood:’, ‘return_state’)
我使用的是 anaconda 环境 (python 3.5.3)。可能出了什么问题?
也许请确认您安装了最新版本的 Keras 和 TensorFlow。
我遇到了同样的问题,更新了 Keras(到 2.1.2 版本)和 TensorFlow(到 1.4.0 版本)。上面的问题解决了。但是,我现在看到 X1、X2 和 y 的形状是 ((100000, 1, 6, 51), (100000, 1, 3, 51), (100000, 1, 3, 51)) 而不是 ((100000, 6, 51), (100000, 3, 51), (100000, 3, 51))。这可能是为什么?
我不确定,也许与 Keras 中最近的 API 更改有关?
这是我解决问题的方法。
在代码顶部,包含此行(在任何 ‘from numpy import’ 语句之前)
import numpy as np
将 get_dataset() 函数更改为以下内容:
注意,我们返回的不是 array(X1), array(X2), array(y),而是经过 squeeze(移除一个维度)的数组。我们移除第 1 轴是因为它的形状不符合我们的需要。
现在输出是符合预期的了(尽管我的准确率是 98%,而不是 100%)。
感谢分享。
也许请确认您已将 Keras 更新到 2.1.2,它修复了 to_categorical() 的 bug?
是的,我们必须重塑模型,然后一切都会正常工作。
(n_in, cardinality) 是什么?
我在使用用户定义变量时遇到困难。对于随机数,参数的输入和输入形状应该是什么?
看这里
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
我移除了 to_categorical 中的参数 [ ]。我认为是因为 target 等参数已经是数组了,所以不需要括号。
说得有理。
我遇到了同样的问题,你的评论帮我解决了!谢谢!
由于我也遇到了同样的问题,我认为更简单的解决方案是只使用
to_categorical(source, num_classes=cardinality)
而不是
to_categorical([source], num_classes=cardinality).shape
这三个列表。
我也必须这样做才能获得正确格式的数据。还有一个函数 tensorflow.one_hot,我更喜欢它而不是 to_categorical。它们做同样的事情。
嗨,Jason!
编码器-解码器网络是否适用于时间序列分类?
根据我的经验,与 MLP 相比,LSTM 在自回归方面并不有效。
有关更多详细信息,请参阅此帖子。
https://machinelearning.org.cn/suitability-long-short-term-memory-networks-time-series-forecasting/
对于以后的人来说,您不需要使用 squeeze,
让我们试试
from
src_encoded = to_categorical([source], num_classes=cardinality)
tar_encoded = to_categorical([target], num_classes=cardinality)
tar2_encoded = to_categorical([target_in], num_classes=cardinality)
推广到
src_encoded = to_categorical(source, num_classes=cardinality)
tar_encoded = to_categorical(target, num_classes=cardinality)
tar2_encoded = to_categorical(target_in, num_classes=cardinality)
谢谢。
感谢 Jason 为 machinelearningmastery.com 撰写博客。我看了很多博客。
我有一个查询——
在我的数据集中——
列数为 5 (输入),
输出数为 3(要预测的特征),并且
行数为 34079。
那么如何在你的代码中设置这些参数——
n_features = 34079
n_steps_in = 5
n_steps_out = 3
# 生成训练数据集
X1, X2, y = get_dataset(n_steps_in, n_steps_out, n_features, 1)
print(X1.shape,X2.shape,y.shape)
我收到了一个类似这样的错误——–>>>您的会话在使用完所有可用内存后崩溃。查看运行时日志。我使用了14GB内存。请根据您的代码建议我如何设置参数……提前感谢。
听起来您可能需要减小数据集大小或使用内存更多的机器?
Jason,感谢您的回复,
但我认为,我可能没有正确地将参数保存在变量中。
在我的数据集中——
列数为 5 (输入),
输出数为 3(要预测的特征),并且
行数为 34079。
那么如何将它们放入您的变量中——
n_features = ???
n_steps_in = 5
n_steps_out = 3
sample = ???
谢谢
哦,我明白了,这将帮助您将问题映射到样本、时间步、特征的术语上。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
这有帮助吗?
嗨,Jason,
运行get_dataset函数时,它会在Arrays X1, X2, y中返回一个额外的行。
(1,1,6,51) (1,1,3,51)(1,1,3,51).
这导致numpy.array(),在X1, X2, y是具有正确大小的列表之前。
(1,6,51) (1,3,51)(1,3,51).
看起来array()命令添加了一个额外的维度。您能帮我解决这个问题吗?
如何训练keras,它必须识别大写字母和小写字母是相同的
请为此建议任何策略。
首先要清楚地定义您的问题。
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
您能否提供一个关于我们输入seq2seq模型的输入是词嵌入,输出也是词嵌入的教程?我发现看到最后有一个Dense层很令人沮丧,这是阻碍一个完全的seq2seq模型,其输入和输出都是词嵌入的原因。
为什么我们要在输出层使用词嵌入?
如果输入是嵌入,我们希望输出也是嵌入(自动编码器)。想象一下输入=类别(猫,狗,青蛙,鲸鱼,人类)。这些动物非常不同,所以我们用嵌入来表示。与其使用5个OHE的密集输出,如果使用嵌入作为输出,那么假设,特别是如果输入和输出的权重是共享的,我们可以用它来训练网络,并让它关于每个类别的确切含义有更多的细节……而不是使用像交叉熵这样的东西。
好的。
有这样的教程了吗?听起来很有趣。
我还没有写过,我仍然不理解/看不到这种方法的优点。很高兴能被证明是错误的。
嗨,Jason,
我正在尝试在编码器和解码器的输入处使用嵌入层,并且像您在上面的代码中所提到的那样使用密集层。
稍后在预测函数调用中,当我给target_seq提供3D输入时,它会抛出维度错误:检查输入时出错:预期Decoder_input具有2个维度,但得到了形状为(1, 1, 341)的数组,这里341是我的原始特征维度,已被嵌入层压缩到32。
您能就哪个环节出了问题给我一些建议吗?
我无法调试您的更改,抱歉。或许可以将您的代码和错误发布到Stack Overflow上?
谢谢Jason。我只是想了解在解码器输入和解码器输出具有不同维度的情况下,您的预测函数(target_seq)的形状会如何?
您能指导一下吗?
我不太确定,我认为您需要进行实验。
你好!在将dropout和recurrent_dropout作为LSTM参数添加到最后一个完整代码示例的第40行时,其余部分保持不变,代码就出错。那么在这种情况下我该如何添加dropout呢?谢谢!
我在这里提供了dropout与LSTM一起使用的实例。
https://machinelearning.org.cn/use-dropout-lstm-networks-time-series-forecasting/
Jason您好!感谢您为在这里提供编码器解码器实现所付出的巨大努力。正如Dinter所提到的,当添加dropout时,代码在训练阶段可以正常运行,但在预测期间会给出以下错误。
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor ‘lstm_1/keras_learning_phase’ with dtype bool
[[Node: lstm_1/keras_learning_phase = Placeholder[dtype=DT_BOOL, shape=, _device=”/job:localhost/replica:0/task:0/cpu:0″]()]]
如何在此特定实现中解决此问题?
[注意:您关于dropout的实例对我来说是有效的,但不同之处在于您在那里是逐层添加到顺序模型中的,这与此编码器解码器示例不同]
很抱歉听到这个消息,也许这是一个bug?您能否在小型独立网络上重现此故障?
当我尝试使用您提供的示例中的完全相同的网络,并在define_models函数的第10行和第15行添加dropout=0.0时,程序可以运行,但对于其他dropout值,它会出错。另外,更改网络的大小,例如,单元数量为5、10、20也会出现相同的错误。
有什么关于添加dropout的想法吗?
第5行:encoder = LSTM(n_units, return_state=True,dropout=0.0)
第10行:decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True,dropout=0.0)
请看这个教程
https://machinelearning.org.cn/use-dropout-lstm-networks-time-series-forecasting/
嗨,Jason,
指定模型输入之间的区别是什么
Model( [decoder_inputs] + decoder_states_inputs,….)
和这个
Model([decoder_inputs,decoder_states_inputs],…)
第一种版本是将decoder_states_inputs数组的元素添加到decoder_inputs的相应元素吗?
Jason您好,感谢您分享这个教程。我只对您定义模型时感到困惑。这是这一行
train, infenc, infdec = define_models(n_features, n_features, 128)
为什么在这种情况下n_features同时用于n_input和n_output,而不是n_input等于6且n_output等于3?
我期待尽快收到您的回复。
谢谢
好问题,因为模型每次调用只处理一个时间步,所以我们手动遍历输入/输出时间步。
Jason您好,我和上面的疑问一样。您能再解释一下吗?抱歉,我没听懂您的回复。
我想看到隐藏状态向量。因为有96个训练样本,所以会有96个这样的向量(每个向量的长度为4)。
我在LSTM中添加了“return_sequences=True”
model = Sequential()
model.add( LSTM(4, input_shape=(1, look_back), return_sequences=True ) )
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=20, batch_size=20, verbose=2)
但是,我收到了错误
回溯(最近一次调用)
File “”, line 1, in
File “E:\ProgramData\Anaconda3\lib\site-packages\keras\models.py”, line 965, in fit
validation_steps=validation_steps)
File “E:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py”, line 1593, in fit
batch_size=batch_size)
File “E:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py”, line 1430, in _standardize_user_data
exception_prefix=’target’)
File “E:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py”, line 110, in _standardize_input_data
‘形状为 ’ + str(data_shape))
ValueError: Error when checking target: expected dense_24 to have 3 dimensions, but got array with shape (94, 1)
如何让这个模型工作,以及如何查看每个输入样本的隐藏状态(应该有96个隐藏状态)?
谢谢你。
Return sequences 不返回隐藏状态,而是返回每个时间步的输出。
这篇文章可能会让您更清楚地了解输出和隐藏状态。
https://machinelearning.org.cn/return-sequences-and-return-states-for-lstms-in-keras/
嗨,Jason,
我喜欢您的博文。我有一些基于这篇博文的代码,但我总是收到这个错误消息。我的密集层有问题。您能指出是什么问题吗?这里units是300,tokens_per_sentence是25。
一个错误消息
ValueError: Error when checking target: expected dense_layer_b to have 2 dimensions, but got array with shape (1, 25, 300)
这是部分代码
也许数据与模型不匹配,您可以更改其中一个。
我很想帮忙,但我不能为您调试代码,抱歉。
你好。所以我想我需要为lstm_a和lstm_b都设置‘return_sequences’为True。
亲爱的 Jason,
您认为此算法适用于天气预测吗?例如,将输入整数变量作为露点、湿度和温度,以降雨量作为输出?
仅用于演示目的。
实际上,天气预报是使用物理模型模拟进行的,并且比小型机器学习模型更准确。
你好,Jason。
我想问您,如何使用此模型处理浮点数?您的训练数据看起来像这样
[[
[0,0,0,0,1,0,0]
[0,0,1,0,0,1,0]
[0,1,0,0,0,0,0]]
.
.
.
]]
我需要类似这样的东西
[[
[0.12354,0.9854,5875, 0.0659]
[0.12354,0.9854,5875, 0.0659]
[0.12354,0.9854,5875, 0.0659]
[0.12354,0.9854,5875, 0.0659]
]]
当我用浮点数运行您的模型时,网络无法学习。我应该使用不同的损失函数吗?
谢谢你
损失函数与输出有关,如果您有一个实值输出,请考虑使用mse或mae损失函数。
如何在编码器-解码器架构中添加双向层?
直接在编码器或解码器上使用它。
以下是如何在Keras中做到这一点。
https://machinelearning.org.cn/develop-bidirectional-lstm-sequence-classification-python-keras/
您好。
我想将您的模型与词嵌入一起使用。我受到 https://blog.keras.org.cn/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html -> features -> word-level model 的启发
我将句子中的词解码为整数。我的输入是包含15个词的句子列表。 [[1,5,7,5,6,4,5, 10,15,12,11,10,8,1,2], […], [….], …]
我的模型看起来像
encoder_inputs = Input(shape=(None,))
x = Embedding(num_encoder_tokens, latent_dim)(encoder_inputs)
x, state_h, state_c = LSTM(latent_dim, return_state=True)(x)
encoder_states = [state_h, state_c]
# 设置解码器,使用
encoder_states
作为初始状态。decoder_inputs = Input(shape=(None,))
x = Embedding(num_decoder_tokens, latent_dim)(decoder_inputs)
x = LSTM(latent_dim, return_sequences=True)(x, initial_state=encoder_states)
decoder_outputs = Dense(num_decoder_tokens, activation=’softmax’)(x)
# 定义将
#
encoder_input_data
&decoder_input_data
转换为decoder_target_data
的模型model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
当我尝试训练模型时,我收到这个错误:expected dense_1 to have 3 dimensions, but got array with shape (10, 15)。您能帮帮我吗?
谢谢你
你好,
我也遇到了同样的问题。你能解决你的问题吗?
嗨,
我正在尝试使用Keras – LSTM来解决seq2seq问题。预测的输出单词与使用数据集构建的词汇表中出现频率最高的单词匹配。不确定是什么原因。训练完成后,在尝试为给定输入序列进行预测时,模型会预测相同的输出,而与输入序列无关。我还为编码器和解码器使用了单独的嵌入层。
您能告诉我可能的原因吗?
问题在此处进行了详细说明。
https://stackoverflow.com/questions/49638685/keras-seq2seq-model-predicting-same-output-for-all-test-inputs
谢谢。
这表明模型没有学会这个问题。
这里有一系列您可以尝试的想法。
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨,Jason,
在您当前的设置中,您将如何添加预训练的嵌入矩阵,例如glove?
这里有一些加载词嵌入的例子。
https://machinelearning.org.cn/use-word-embedding-layers-deep-learning-keras/
你好,
您能帮我解决我的问题吗?我认为很多所需的逻辑都包含在您的代码中,但我对python非常不熟悉。我想根据输入测试序列(seq2seq)来预测数字,所以我的解码器的输出应该是6个数字(1-7)的序列。您可以将其想象为彩票预测。我有一个非常长的数字向量1-7(包含6个数字的序列),所以我不需要生成测试数据。我只需要预测接下来的6个数字,这些数字应该是生成的。1,1,2,2,3 -> 3,4,4,5,5,6
谢谢你
也许这里是您开始使用LSTM的好地方。
https://machinelearning.org.cn/start-here/#lstm
谢谢Jason,这对我很有帮助。您能给我一些关于如何正确初始化和训练具有多个输入序列的网络吗?
它们可以并排。
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
或者完全独立的输入。
https://machinelearning.org.cn/keras-functional-api-deep-learning/
Jason,非常感谢您的教程,它让我入门了。我尝试使用更长的序列,输入是400个数字系列,输出是40个数字。由于索引错误,我在分类方面遇到了问题,而且我不知道如何为基数/n_features设置或获取值。您能给我一些关于这个的思路吗?
我也不清楚这是否是一种分类模型。您能确认一下吗?谢谢。
您可以对分类输入特征进行整数编码或独热编码。这里有一个关于该主题的教程。
https://machinelearning.org.cn/how-to-one-hot-encode-sequence-data-in-python/
这篇博文将清楚地区分分类和回归。
https://machinelearning.org.cn/classification-versus-regression-in-machine-learning/
你好,
谢谢您的这个教程,我在运行您的示例时收到了这个错误
ValueError: Error when checking input: expected input_1 to have 3 dimensions, but got array with shape (100000, 1, 6, 51)
你好!我遇到了同样的问题……您解决了吗?谢谢!
修改这个
src_encoded = to_categorical([source], num_classes=cardinality)[0]
tar_encoded = to_categorical([target], num_classes=cardinality)[0]
tar2_encoded = to_categorical([target_in], num_classes=cardinality)[0]
您尝试过Gary的答案吗?
Jason您好,非常感谢您的教程。是否可以一次性解码多个序列,而不是一次解码一个字符?我的项目的推理耗时太长了,我以为批量处理可能会有帮助。
您可以使用模型的副本并行地为不同的输入进行预测。
你好,我只是想知道为什么当序列已经是数字时还需要使用to_categorical。在我的情况下,我有一系列输入特征(数字)和另一系列输出特征(数字)。我仍然需要使用to_categorical方法吗?
好问题,它会进行数字的独热编码。
https://keras.org.cn/utils/#to_categorical
嗨,Jason,
我正在处理词边界检测问题,其中包含.wav文件的数据库,其中有人说一句,并且每个.wav文件都有对应的.wrd文件,其中包含句子中说的单词以及它们的边界(开始和结束边界)。
我们的任务是识别test .wav文件中的单词边界(也会给出所说的单词)。
我想用序列模型来做这件事。
我尝试过的方法是
我使用librosa模块将.wav文件读取为numpy数组(通过填充使其等于最大尺寸)。
它的输出类似于3333302222213333022221333302222133333(例如,输入为“I am hero”)。
其中(0:单词开始,1:单词结束,2:中间,3:空格)
这意味着我想将这个问题作为监督学习问题来解决,我可以用RNN训练这样的模型吗?
听起来是个很棒的项目。
我对处理音频数据的示例不熟悉,抱歉,我无法给你一些好的即时建议。
也许可以找一些相关的建模问题的代码库来获得灵感?
你好。
我尝试过这个用于单词级聊天机器人的例子。在小数据(5000个句子)上一切都运行良好
当我使用50,000个句子的数据集时,有些地方不对劲。模型的准确率为95%,但当我尝试与该聊天机器人聊天时,响应是随机生成的。聊天机器人能够从数据集中学习句子,但它会随机使用它们来响应用户的提问。
当准确率如此之高时,这是怎么可能的?
谢谢
也许它记住了训练数据?例如,过拟合?
先生,如何创建混淆矩阵,评估并打印此模型的准确率
# 定义输入序列并处理。
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
# 我们丢弃
encoder_outputs
,只保留状态。encoder_states = [state_h, state_c]
# 设置解码器,使用
encoder_states
作为初始状态。decoder_inputs = Input(shape=(None, num_decoder_tokens))
# 我们将解码器设置为返回完整的输出序列,
# 并返回内部状态。我们在训练模型中不使用
# 返回状态,但在推理时会使用它们。
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs,
initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation=’softmax’)
decoder_outputs = decoder_dense(decoder_outputs)
# 定义将
#
encoder_input_data
&decoder_input_data
转换为decoder_target_data
的模型model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
model.compile(optimizer=’rmsprop’, loss=’categorical_crossentropy’, metrics=[‘accuracy’])
model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
batch_size=batch_size,
epochs=epochs,
validation_split=0.2)
model.summary()
这里有关于如何计算混淆矩阵的信息
https://machinelearning.org.cn/confusion-matrix-machine-learning/
嗨,Jason,
感谢您提供的精彩教程,非常有帮助。我有一个简单的问题。是否有任何特定的
原因使用50+1作为n_features?
请指教
+1是为了为“0”值(“无数据”)留出空间。
嗨,Jason,
感谢所有精彩的教程……工作很棒。
我有一个问题,
在时间序列预测中,多变量是否比单变量产生更好的结果。
例如:“北京PM2.5数据集”我们有多个变量,多变量是否会产生更好的结果,还是通过获取单个污染数据进行单变量预测会产生更好的结果。
2- 时间序列预测是使用编码器-解码器还是普通RNN更好。
对于这两个问题,这取决于具体的问题。
嗨Jason,这里看起来是模型的一个时间步。为了在模型中添加更多时间步,我需要改变什么?
# 返回训练、推理编码器和推理解码器模型
def define_models(n_input, n_output, n_units)
# 定义训练编码器
encoder_inputs = Input(shape=(None, n_input))
encoder = LSTM(n_units, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
# 定义训练解码器
decoder_inputs = Input(shape=(None, n_output))
decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(n_output, activation=’softmax’)
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
# 定义推理编码器
encoder_model = Model(encoder_inputs, encoder_states)
# 定义推理解码器
decoder_state_input_h = Input(shape=(n_units,))
decoder_state_input_c = Input(shape=(n_units,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
# 返回所有模型
return model, encoder_model, decoder_model
嗨,Jason,
非常感谢!我想问一个看似愚蠢的问题…在训练模型时,我们将权重存储在训练模型中。推理编码器和解码器是空的吗?在预测阶段,不使用训练模型,那么训练模型的权重是如何用于预测的?
期待您的回复。谢谢!
没有愚蠢的问题!
模型的状态在每个批次结束时被重置。
明白了。非常感谢!
很高兴听到这个消息。
您能否更详细地解释一下。我似乎不明白model.fit与inference_encoder/decoder的关系。谢谢!
(顺便说一句,这篇帖子写得很好)我也需要更多的解释。这是我的不理解之处,实例化了3个模型(训练、推理编码器、推理解码器)。一个模型(训练)被训练并开发了权重,这些权重(希望)能产生准确的预测。
然后另外两个模型用于测试预测能力,但我不知道训练模型的权重是如何解析并分别传递给推理编码器和解码器的。(而且,我怀疑我从根本上缺少一些关于keras基础设施的知识)
我也有同样的问题,想知道train的权重是如何用于infenc的。
好问题。
我建议您回顾一下define_models()函数,您可以看到模型权重在模型之间共享——但每个模型提供了不同的用例。
这篇博文中描述的模型可以用于输入长度可变的情况吗?如何使用。
还有输出长度可变的情况。
是的,它一次处理一个时间步,因此默认支持可变长度。
嗨Jason,如果您有3D形状(样本,时间步,特征)的时间序列数据,并且不能/不想对其进行独热编码,您将如何处理和实现这个模型?提前感谢。
您可以在输入上使用整数编码和嵌入层。
那会是什么样子?之后我能不能只用推理部分来实现?抱歉我的问题可能听起来有点蠢,我正在尝试理解这些主题。
我在这里提供了更多关于准备LSTM数据的信息。
https://machinelearning.org.cn/faq/single-faq/how-do-i-prepare-my-data-for-an-lstm
嗨,Jason,
感谢分享您的代码。我将其用于我自己的问题,并且它有效,但我仍然从远离训练值的值中获得良好的预测结果。我的问题可能是什么?我使用了MSE作为回归损失,我需要不同的损失函数吗?
我有一些关于提高模型技能的建议,或许可以给您一些启发。
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨Jason,非常感谢您的贡献!当我将时间序列数据用于此模型时,是否也可以不使用目标数据中的偏移情况作为y,即:model.fit([input, output], output),那么output = input.reversed(),这是否也有意义?因为我想使用滑动窗口作为输入和输出;然后将输出偏移一个单位在我看来没有意义。
抱歉,我不明白。
也许这篇帖子会让事情更清楚。
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
假设我用形状(1000,20,1)训练,但我想要用(20000,20,1)来预测,那么这将行不通,因为样本数量更大。我该如何调整?
output=list()
for t in range(2)
output_tokens, h, c = decoder_model.predict([target_seqs] + states_values)
output.append(output_tokens[0,0,:])
states_values = [h,c]
target_seq = output_tokens
为什么不行呢?
它显示:索引1000超出轴0的界限,尺寸为1000。
所以第二个轴的长度需要相同。但我预测时使用的数据长度与训练时不同。如何解决这个问题?
也许仔细检查一下你的数据。
仍然不工作Jason,不幸的是,可变序列长度似乎是不可能的?我用一部分数据训练了我的模型,并想在推理中使用所有数据?
我纠正一下:因为我想使用编码器的最后一个状态作为初始状态,所以我在训练数据的开头填充0?
我有两个问题
1-这个例子使用了教师强制,对吗?我试图在没有教师强制的情况下重新实现它,但它失败了。当我将训练模型定义为(您的示例的第49行):model = Model(encoder_inputs,decoder_outputs),它给了我这个错误:RuntimeError:Graph disconnected:cannot obtain value for tensor Tensor(“decoder_inputs:0”,shape=(?,n_units,n_output_features),dtype=float32)at layer “decoder_inputs”。以下先前层已被无问题地访问:[‘encoder_inputs’,‘encoder_LSTM’]
2-您能否更详细地解释一下您如何定义解码器模型?我不明白第52到60行的代码(如下所示)发生了什么?为什么您需要重新定义decoder_outputs?模型是如何定义的?
# 定义推理解码器
decoder_state_input_h = Input(shape=(n_units,))
decoder_state_input_c = Input(shape=(n_units,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
# 返回所有模型
是的。如果性能在没有教师强制的情况下很差,那么就不要在没有教师强制的情况下进行训练。我不明白你为什么要去掉它?!
解码器是一个使用编码器部分的新模型。这有帮助吗?
HI Jason,我查阅了不同的页面,发现seq2seq在没有通过零等数据进行操作的情况下,无法处理可变长度。那么在您的示例中,您只能在推理中使用形状为(100000,timesteps,features)的数据,也就是没有可变长度的数据,这是正确的吗?如果不是,您该如何更改?非常感谢您的回复!
通常,可变长度输入可以被截断或填充,并且可以使用掩码层来忽略填充。
或者,上述模型可以按时间步使用,允许真正的多变量输入。
不错的解释,最后一个问题:我的时间步在所有情况下都将是相同的,只有样本数量会不同。Keras的填充序列只显示时间步的填充,或者我错了?在这种情况下,我需要填充我的样本。
好问题。只有时间步和特征维度是固定的,样本数量可以变化。
Jason,
这些教程非常棒,您对它们的解释做得很好。
仅供参考,为了帮助其他读者,我必须使用tensorflow v1.7才能与Keras 2.2.0一起运行。使用旧版本我初始化模型时出现了一些错误,而使用较新的v1.8版本时出现了一些TF会话错误。
谢谢提示。
你好Jason,您的工作一直很出色。我从您的教程中学到了很多。
我正在尝试一个简单的编码器-解码器模型,遵循您的示例,但遇到了一些问题。
我的问题是词汇量大小,大约是5600,这使得我的独热编码器非常大,并导致我的电脑冻结。您能否给出一个简单的例子,其中我不需要对数据进行独热编码?我知道sparse_categorical_crossentropy,但我很难实现它。也许我的方法是错误的。您的指导将对我帮助很大。
再次感谢您提供如此出色的教程……
也许可以尝试词嵌入?
或者,也许可以尝试在EC2实例上进行训练?
嗨 Jason
为什么我运行您的代码时会得到这种形状((100000, 1, 6, 51),(100000, 1, 3, 51),(100000, 1, 3, 51))……或者我需要重塑还是我没有正确复制?
因为它显示您得到((100000,6, 51),(100000,3, 51),(100000,3, 51))
您的Keras版本是最新的吗?
您是否完全复制了所有代码?
嗨Jason,版本不同,我放了这个
X1 = np.squeeze(array(X1), axis=1)
X2 = np.squeeze(array(X2), axis=1)
y = np.squeeze(array(y), axis=1)
现在没问题了,您所做的叫做多对一编码?在解码的情况下,这叫做一对多吗?
另一个问题是我想删除那些独热编码,我想编码确切的数字并预测确切的数字。
还要删除此选项src_encoded = to_categorical([source], num_classes=cardinality)
但我遇到了很多错误。
我有一些关于在keras中更改回归/分类的建议。
https://machinelearning.org.cn/faq/single-faq/how-can-i-change-a-neural-network-from-regression-to-classification
尝试删除to_categorical参数中的括号,也就是说,尝试使用
to_categorical(source, num_classes=cardinality)而不是
to_categorical([source], num_classes=cardinality)。
+500
令人恼火的是,这个失误没有得到解决。我猜这是有意忽略的,目的是为了增加教程的训练价值🙂
一种教学方法……
我认为API已更改。我需要修复它……
嗨,Jason,
很好的解释,感谢您的分享!我想问一下,在推理预测的行中
for t in range(n_steps)
您也可以使用比n_steps多一个的步数?或者为什么您要用n_steps循环?您只用for t in range(1)也能得到一个结果,对吗?希望您能理解我想弄清楚什么。
抱歉,我不太明白。您能提供更多细节吗?
所以,在您的以下代码中,您正在一个for循环中进行n_steps的预测,n_steps需要是什么?您也可以用1吗?或者您需要n_steps来自数据形状(batch,n_steps,features)作为时间步?因为当您infdec.predict时,模型是一次性接收整个target_seq进行预测,为什么您需要n_steps?
for t in range(n_steps)
# 预测下一个字符
yhat, h, c = infdec.predict([target_seq] + state)
# 存储预测
output.append(yhat[0,0,:])
# 更新状态
state = [h, c]
# 更新目标序列
target_seq = yhat
return array(output)
当然,您可以将其设置为1。
使用1或更高的迭代次数有什么好处?
用于多步预测。
在“def define_models()”中,有三个模型:model,encoder_model,decoder_model,
encoder_model 和 decoder_model 的功能是什么?我能只用“model”进行
预测吗?期待您的回复
您可以在这里了解更多关于架构的信息
https://machinelearning.org.cn/encoder-decoder-long-short-term-memory-networks/
如何使用归一化折扣累计增益(NDCR)来评估模型?
有必要使用NDCR吗,还是可以使用准确率作为性能指标?
NDCR究竟是什么?我从未听说过。
你好,感谢您精彩的描述。为什么您没有使用“rmsprop”优化器?
我发现Adam(RMSProp的扩展)能带来很好的结果。
https://machinelearning.org.cn/adam-optimization-algorithm-for-deep-learning/
你好,
我将嵌入矩阵添加到您的代码中,并收到了与Luke在之前评论中提到的矩阵维度相关的错误。您是否有关于将嵌入矩阵添加到编码器-解码器中的帖子?
我在这里有一些建议
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
嗨,Jason,
我有一个低级问题。为什么您只训练了模型一个“epoch”?选择更高的数字不是更好吗?
因为我们有大量的随机样本。
也许重读一下教程?
谢谢你,Jason。如何保存模型的预测结果以便以后使用?
请看这个教程
https://machinelearning.org.cn/save-load-keras-deep-learning-models/
在您的代码中,我猜应该保存这3个模型(即define_models返回的3个)
train, infenc, infdec = define_models(n_features, n_features, 128)
是的,也许可以尝试使用save()函数分别保存它们。
Jason您好,我正在使用您的代码来解决一个回归问题。我的数据定义与您完全相同,但我想保留整数或浮点数,而不是将其转换为独热向量。
我修改了代码如下:
def define_models(n_input, n_output, n_units)
# 定义训练编码器
encoder_inputs = Input(shape=(None, n_input))
encoder = LSTM(n_units, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
# 定义训练解码器
decoder_inputs = Input(shape=(None, n_output))
decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(n_output, activation='relu')
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
# 定义推理编码器
encoder_model = Model(encoder_inputs, encoder_states)
# 定义推理解码器
decoder_state_input_h = Input(shape=(n_units,))
decoder_state_input_c = Input(shape=(n_units,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
# 返回所有模型
return model, encoder_model, decoder_model
但是模型只能学习预测一个未来时间步,只对一个时间步的预测是正确的。您能提供一些解决方案吗?非常感谢!
我然后这样进行预测:
def predict_sequence(infenc, infdec, source, n_steps)
state = infenc.predict(source)
output = list()
pred=np.array([0]).reshape(1,1,1)
for t in range(n_steps)
yhat, h, c = infdec.predict([pred]+state)
output.append(yhat[0,0,0])
state = [h, c]
pred = yhat
return array(output)
我这里有一些想法
https://machinelearning.org.cn/improve-deep-learning-performance/
你好Khan,我遇到了类似的问题,网络不能预测超过一个时间步。你找到解决方案了吗?
Jason您好,感谢您的精彩系列文章!
在本教程中,我遇到了一些复杂的问题(我是Python新手。我只有一点AI和ML理论知识)。
我的y(目标序列)是X1的一部分。显然,y由X(反向和子集)指定。所以,
1、在训练模型时,您是否使用X1中的y作为输入序列(序列X1(y) => 序列y)?
2、我可以定义y与X1分开(例如不子集,不反向…)吗?
谢谢!
我不确定您的意思。也许这能帮助您定义您的问题
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
嗨,先生
我想从预训练的嵌入中生成序列,详细来说,我有一组嵌入列表及其对应的句子。我想拥有一个模型来根据该嵌入数据生成句子。但我不知道如何开发该模型。
您可以使用类似LSTM的模型来生成文本,但不能单独使用嵌入。
嗨,Jason,
再次感谢您的精彩工作!我是您教程的忠实粉丝!
我正在处理一个水位预测问题。我可以通过天气预报来预测水位,给定天气和历史水位的值。
我尝试了一个简单的LSTM模型,使用重叠序列(时间序列到监督学习),将天气预报和过去的水位作为输入,并输出未来的水位。这效果很好。
看到所有这些Seq2Seq时间序列预测的趋势,我也尝试了一下,方法是编码天气预报并解码为水位(以过去的水位作为解码器输入),希望能获得更好的结果。
但是这个Seq2Seq模型的表现非常糟糕。您有什么想法吗?我是否应该放弃这类模型来解决我的问题?
也许可以尝试改进模型的性能。
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨,Jason,
我读过您关于seq2seq和lstm的几篇博文。我想知道如何将这个编码器-解码器模型与注意力机制结合起来?我的场景有点像翻译。
当然,注意力机制通常可以提高编码器-解码器模型的性能。
Jason您好,我有两个问题:
问题1 – 您如何在神经翻译模型中估计整个序列预测的“置信度”?我认为您可以将每个时间步的单独概率相乘。但我不太确定这是否是正确的方法。另一种方法是将输出序列的概率输入到一个二元分类器(置信/不置信)中,并将其值作为置信度得分。
问题2 – 您如何确保神经翻译模型中的整个序列预测是最优序列?如果您采用贪婪方法,在每个时间步都取最大值,那么最终得到的序列本身可能不是最可能的序列。我听说过束搜索和其他方法。您对最先进的技术有什么了解吗?
您可以通过贪婪搜索预测的概率来获得每个时间步最可能的词,但这并不意味着它是最佳序列。
也许可以研究一下束搜索。
你好Luke,
我正在处理整数序列的相同场景。
在输入序列之前,您需要将序列重塑为3D,最好在小批量中训练模型,因为它会在每次迭代后重置状态,这对基于LSTM的模型非常有效。
希望有所帮助。
为什么不将TimeDistributed应用于解码器,就像在https://machinelearning.org.cn/develop-neural-machine-translation-system-keras/ 中一样?
在这种情况下,我们有一个动态的1步模型 – 例如,它是不需要的。
嗨,Jason!
这个模型可以用来总结句子吗?我正在研究抽象文本摘要,并尝试使用具有注意力机制的编码器-解码器来构建一个。
你能帮帮我吗?
我有很多关于摘要的帖子。
https://machinelearning.org.cn/?s=text+summarization&post_type=post&submit=Search
感谢您出色的教程!!有一件事我不明白,希望您能澄清。
我们训练了一个模型,如下所示:
train, infenc, infdec = define_models(n_features, n_features, 128)
train.compile(optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘acc’])
train.fit([X1, X2], y, epochs=1)
但是,推理编码器/解码器模型(infenc和infdec)似乎仍然未训练。
我不明白“训练模型”中的信息(权重、状态等)是如何、在哪里、何时转移到推理模型中的。
在预测时,您说:
“在预测期间,推理编码器模型用于一次性编码输入序列,并返回用于初始化推理解码器模型的状态。从那时起,推理解码器模型用于逐步生成预测。”
但是推理编码器和推理解码器不是未训练的吗?
权重是训练过的,只是我们有两个相同的权重引用,所以我们可以用它们进行不同的操作(训练/推理)。
嗨,Jason,
是否可以将Batchnormalization应用于上述代码?
当然可以。
以下是一些使用batchnorm的示例,您可以参考:
https://machinelearning.org.cn/how-to-accelerate-learning-of-deep-neural-networks-with-batch-normalization/
嗨,Jason,
由于上述代码不使用Keras Sequential模型,因此不允许直接将Batchnormalization层添加到模型中。
如果我们想在上述代码中应用Bn,您能帮忙吗?
您可以使用函数式API将其添加到模型中。
https://machinelearning.org.cn/keras-functional-api-deep-learning/
Jason,谢谢。您的帖子非常有帮助!
谢谢 Jason!
很高兴它有帮助。
嗨,Jason,
我只是好奇为什么您将“epochs”指定为1。是因为准确率已经达到100%了吗?
如果“epochs”为1时准确率不是100%,我是否应该更改为其他epoch数量以获得更高的准确率?
提前感谢您!
Kyu
并非完全如此,这是因为我们定义了大量的随机样本,它们起到了类似epoch的作用。
您可以使用更少的样本和更多的epoch来实现相同的效果。
嗨,Jason,
一如既往的精彩帖子,我喜欢阅读您的博客。我有一个问题。我可能遗漏了什么,但为什么我们需要将移位后的目标序列作为解码器的输入?还有另一个问题:为什么要移位它?如果您能为我澄清这一点,那将是很好的。提前感谢🙂
祝好,
Tobs
将其转化为监督学习问题,例如,请参阅此
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
嗨,Jason,
您能否帮助我实现基于GRU的自编码器推理模型?
/Ashima
您可以使用本教程中的LSTM自编码器,并将层更改为GRU。
https://machinelearning.org.cn/lstm-autoencoders/
谢谢 Jason
不客气。
嗨,Jason,
非常感谢您的博文及其出色的内容。关于这篇帖子,似乎encoder_outputs没有被使用。为什么我们不使用这个输出?我们可以在它上面放一个自动解码器来重现输入1吗?这有助于网络预测序列吗?
此致
Mostafa
它被使用了——编码器的输出连接到解码器。
Jason您好,我看到encoder_outputs根本没有被使用。将其捕获到变量中有任何目的吗?我只看到状态被传播到解码器。
并不是真的。
Jason您好,感谢您的教程!我想在解码器LSTM层之后添加BatchNormalization和Dropout层。您知道我该如何做吗?
此致,
古奈
要小心在LSTM上使用dropout,请使用特定于LSTM的dropout。
https://machinelearning.org.cn/how-to-reduce-overfitting-with-dropout-regularization-in-keras/
此外,batch norm和dropout可能会相互作用,请小心不要将它们并排使用——请务必进行测试。
嗨,Jason,
非常感谢您精彩的博文。它很棒,我有一个问题。
如果我们有多个相互关联的输入序列,并希望预测结果,该怎么办?
例如,预测天气,我们有多个特征和序列?
您可以拥有并行输入特征或多输入模型。
我在这里展示了如何做到这两点。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
太棒了,非常感谢。
嗨,Jason,
感谢这篇精彩的文章。
我需要问一个您可能认为非常愚蠢的问题。
我有一个整数序列,表示用户xyz访问过的位置,其用户类型为“category1”。我有许多属于某个类别的用户,每个用户都访问过某些位置。
给定某个用户的序列,我想预测该用户接下来会去哪个位置。另外,我想考虑用户类型/类别来预测。
问题是,我们如何将上面的帖子用于所述问题,因为在帖子中,值是以反向顺序预测的。
也许有多种方式来构建问题。我鼓励您集思广益,然后测试几种方法,看看哪种最有效。
这听起来像是一个时间序列分类问题。我认为这里的教程会给您一些想法。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
Jason,在提供免费建议时,请注意代码应能在真实世界的大型数据集上运行。To_categorical 是最糟糕的选择,而且不能优化内存占用。因此,我建议重新编辑这篇帖子,并使用“sparse_softmax_cross_entropy_with_logits”作为“categorical_cross_entropy”的代理。Seq2seq模型通常在大型词汇数据集上进行训练,而您的示例可惜无法运行。您需要去其他地方寻找解决方案。顺便说一句,您的帖子很有启发性。
感谢您的建议。
Jason您好,我正在尝试机器翻译,并正在阅读您的所有文章。
这篇帖子是关于“Keras中用于序列到序列预测的编码器-解码器模型”的实现,其中包含一些精巧的代码。
我看到您还有另一篇帖子,位于:
https://machinelearning.org.cn/develop-neural-machine-translation-system-keras/
和
https://machinelearning.org.cn/encoder-decoder-long-short-term-memory-networks/
该帖子也介绍了用于
序列到序列预测的编码器-解码器LSTM,并附有非常简单的Python代码示例:
model = Sequential()
model.add(LSTM(…, input_shape=(…)))
model.add(RepeatVector(…))
model.add(LSTM(…, return_sequences=True))
model.add(TimeDistributed(Dense(…)))
您能否告诉我这两者之间的确切区别?是后面这5行代码的实现,使用LSTM的方式更好?还是哪一个更好?
我通常教授一种使用自编码器架构的编码器-解码器方法,因为它通常能获得与更高级的编码器-解码器相同或更好的结果。
更多信息在这里
https://machinelearning.org.cn/lstm-autoencoders/
所以这篇帖子里的不是自编码器,而是使用了Teacher Forcing,我们能否在自编码器方法中也使用Teacher Forcing?
正确。
Jason您好,感谢您的教程!
我有一个关于Teacher Forcing的问题。
如果我理解您的例子是正确的,您在这里没有使用任何验证集(是吗?)。
如果我在拟合过程中添加验证分割,模型在验证阶段也会使用Teacher Forcing吗?
这个选择是正确的,还是模型应该在验证期间使用贪婪或束搜索来模拟更真实的性能?
谢谢!
并非完全正确。我使用步进式验证。
您可以在这里了解更多关于Teacher Forcing的信息:
https://machinelearning.org.cn/teacher-forcing-for-recurrent-neural-networks/
嗨,Jason,
我有一些数据块(每个数据块的长度不同,从 700 行到 2000 行),其中包含多元输入(3 个时间序列)和因变量序列。例如,我的第一个数据块有 700 行,包含 3 个输入时间序列和因变量(一个输出)时间序列。我想使用这 3 个输入来预测(生成)因变量序列。
我该怎么做?
提前感谢您!
也许这篇博文会对您有所帮助或给您带来灵感。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
还有这个。
https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/
你好,
这与此处提出的编码器-解码器有什么区别?
https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
在这种情况下,编码是通过 LSTM 的状态完成的,而在链接中只是通过卷积滤波器?
除了复杂性之外,还有什么情况下这种架构会不如另一种架构吗?
这篇博文中的示例符合论文中提供的编码器-解码器定义,并且是动态 RNN 的一个示例。
另一篇博文中的示例是基于自编码器思想的一个更简单的编码器-解码器模型。
我通常推荐后者,因为它在训练和使用方面都更简单。
Jason,
难道不能输入一个序列并也输出一个序列,而不是必须循环推理解码器以获得预测的输出以获得整个预测序列吗?
关于哪种方式更好,有什么想法吗?
我的具体情况是使用这篇博文的方法来预测视频帧。
是的,您可以通过矢量输出或基于 LSTM 自编码器的解码器模型来实现。
编码器架构是否需要与解码器相同,或者我可以在一个中拥有更多的 LSTM 层?
不,它们可以不同。
嗨!
我正在尝试使用几个 GB 的数据来训练我的模型。我的机器内存不足。
我该如何训练批次模型?我想用 10,000 个示例的批次调用 fit 方法,但我不知道如何操作。
你能帮忙吗?
您可以使用数据生成器并逐步将数据加载到内存中供模型使用。
我在博客上提供了一些关于加载大型图像和文本数据集的示例。
https://machinelearning.org.cn/develop-a-deep-learning-caption-generation-model-in-python/
嗨,Jason,
我确信在您的博文中会遇到一些问题,但我想说的是,您涵盖的主题数量之多让我惊叹不已。这篇博文尤其非常有帮助。感谢您的所有工作!
Eli
谢谢 Eli!
很棒的博文,谢谢!
我应该如何考虑何时使用教师强制模型(我认为这篇博文描述的就是这种模型),而不是简单的标准 LSTM 呢?
https://machinelearning.org.cn/encoder-decoder-long-short-term-memory-networks/
谢谢你
尝试几种问题的表达方式,看看哪种适用于您特定的数据集。
嗨,Jason,
首先,我要感谢您出色的网站。到目前为止,它在我的论文写作中帮助了我很多!
我目前正在尝试实现一个带有教师强制的自编码器。由于我的数据是纯连续的,我一直在尝试避免独热编码。但是,我被一个问题卡住了,即我应该如何标记目标序列的开始。我尝试使用一个数字,该数字在源/目标序列使用的数字的范围内或范围之外,但结果很差。无论我输入什么序列,我的网络似乎都会重复相同的输出(只进行微小修改)。也许我在实现中犯了另一个错误,但您是否对如何在不使用独热编码的情况下标记序列“字符”的开始有一些建议?
提前非常感谢。
谢谢。
对于长度可变的输出问题,我使用一个标记来标记序列的开始和结束。例如,图片字幕生成。
https://machinelearning.org.cn/develop-a-deep-learning-caption-generation-model-in-python/
嗨,Jason,
感谢您的快速回复。
我的输出长度是固定的。我的问题更多是关于使用的数据类型。让我尝试重新表述一下:如果序列由连续的(数据类型:double 或 float)数据组成,并且我*不*想对其进行分箱和独热编码,那么是否有标准的方法来标记序列的开始/结束?这种序列的一个例子可以是传感器数据的时序。
感谢您的帮助。
是的,使用超出正常值范围的值,例如 -1 或 -999 等。
我有一个序列问题。每个样本是一个轨迹,包含 200 个按时间顺序排列的点。每个点存在于一个 2D 网格中,其中每个网格单元由一个唯一的整数 ID 表示。例如,一个包含 10 个点的轨迹经过以下网格单元 -> [23, 32, 38, 18, 58, 41, 28, 28, 30, 48]。如何建模这个问题?
我有 8000 个样本,每个样本有一个包含 200 个点的序列,并且只有一个特征(即网格单元号)。如果形状是 (8000,200,1),那么 X 的形状应该是多少,这意味着有 200 个时间步,每个时间步只有一个条目。那么问题将在 get_dataset 中生成偏移序列。
或者另一种方法是使用单个时间步来处理所有样本,例如 (8000,1,200)。用单个时间步来解决序列到序列的问题是否合乎逻辑?
也许这可以帮助您确定形状。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
也许可以尝试几种不同的模型和问题表述方式,看看哪种效果最好。
Jason,您好,我想问一下如何提取 LSTM 每个时间部分返回的状态,例如,我想提取第一个和第二个时间步的输出。
也许可以在感兴趣的层上使用 return_sequences=True,并将该层用作输出层?
使用 return_sequences=True,我想要实现的功能是将两个输出紧密地拼接在一起,后面跟着一个 Dense(1),如何实现这个功能?期待您的答复,谢谢。
抱歉,我没明白。
也许可以尝试将您的问题和代码发布到 stackoverflow?
你好,杰森,
我尝试运行上面的代码,但遇到了以下错误:
ValueError 回溯 (最近一次调用)
in ()
—-> 1 train.fit([X1, X2], y, epochs=1)
2 帧
/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
129 ‘: expected ‘ + names[i] + ‘ to have ‘ +
130 str(len(shape)) + ‘ dimensions, but got array ‘
–> 131 ‘with shape ‘ + str(data_shape))
132 if not check_batch_axis
133 data_shape = data_shape[1:]
ValueError: Error when checking input: expected input_9 to have 3 dimensions, but got array with shape (100000, 1, 6, 51)
您能帮我解决这个问题吗?
很抱歉听到这个消息,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
您好,非常感谢您撰写这篇教程!
我将尝试修改它来预测/填充一个长句子的中间 1/3。
您认为这可能吗?您能给出一些提示吗?
听起来很有趣!
是的,这里关于语言模型的教程会很有帮助。
https://machinelearning.org.cn/start-here/#nlp
嘿 Jason,我想知道。这能否用于标签是单个数字而目标是序列的数据框?
例子
数据框
标签 | 预测
9000 | [5000,8000,9000]
就像一对多一样,但我希望模型根据其标签生成序列。
这用编码器-解码器可能吗?如果不行,您能推荐一个更好的设置吗?
您可以模拟该问题,但一个数字不足以进行序列预测。
看起来编码大量数字会遇到内存错误。列表中的数字超过 100000。
有什么方法可以解决这个问题吗?
在 get_dataset(n_in, n_out, cardinality, n_samples) 中
15 target_in.append(in_target)
16 # 编码
—> 17 src_encoded = to_categorical(source)
18 tar_encoded = to_categorical(target)
19 tar2_encoded = to_categorical(target_in)
~/anaconda3/envs/amazonei_tensorflow_p36/lib/python3.6/site-packages/tensorflow/python/keras/utils/np_utils.py in to_categorical(y, num_classes, dtype)
46 num_classes = np.max(y) + 1
47 n = y.shape[0]
—> 48 categorical = np.zeros((n, num_classes), dtype=dtype)
49 categorical[np.arange(n), y] = 1
50 output_shape = input_shape + (num_classes,)
内存错误
一些想法
– 使用更少的类别。
– 使用具有更多 RAM 的机器
– 使用标签编码而不是独热编码。
更多想法。
https://machinelearning.org.cn/faq/single-faq/how-do-i-handle-a-large-number-of-categories
如何在动态编码器-解码器模型中添加注意力?
非常感谢您的帮助。
也许可以尝试使用 TensorFlow 的注意力层?
再次抱歉打扰您。
您在其他博客中多次使用 Keras 层来构建 seq2seq 模型,例如
model = Sequential()
model.add(LSTM(…, input_shape=(…)))
model.add(RepeatVector(…))
model.add(LSTM(…, return_sequences=True))
model.add(TimeDistributed(Dense(…)))
我对此感到困惑,此 Keras seq2seq 与本博文中的动态模型有何区别?
谢谢!
我通常使用的方法基于 LSTM 自编码器,并且在 Keras 中实现起来要容易得多。
https://machinelearning.org.cn/lstm-autoencoders/
上面的动态 LSTM 更贴近原始论文。
在多种问题上,两种模型的性能似乎都差不多。
非常感谢!
嗨
查看 define_models 函数中的以下代码行:
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(n_output, activation=’softmax’)
为什么不需要 TimeDistributed 包装器?
我期望看到以下内容:
decoder_dense = TimeDistributed(Dense(n_output, activation=’softmax’))
因为我们根据 decoder_outputs(因为 return_sequences=True)将 Dense 层应用于每个给定的时间步。
谢谢
这是一个动态 RNN,每次调用都会进行单步预测。
谢谢,但该代码片段属于训练阶段,而不是推理阶段……所以我们还没有进入预测步骤。
嗨 Jason
非常感谢您能对此进行说明。
谢谢
啊,谜题解开了。
https://stackoverflow.com/questions/47305618/what-is-the-role-of-timedistributed-layer-in-keras/47309453#47309453
谢谢
看起来它为解码器创建输出。
谢谢您的回复。我的英语不太好,所以不太明白您的意思,您能详细说明一下吗?
同时,使用以下代码证明了(自 Keras 2.0 起)Dense 层可以处理 3 维输入:
from keras.layers import Dense, TimeDistributed
来自 keras.models import Sequential
from numpy import arange
batch = 3
steps = 10
features = 16
# 使用 TimeDistributed 的模型
model = Sequential()
model.add(TimeDistributed(Dense(8), input_shape=(steps, features)))
model.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
# 不使用 TimeDistributed 的模型
model2 = Sequential()
model2.add(Dense(8, input_shape=(steps, features)))
model2.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
X = arange(batch * steps * features).reshape(batch, steps, features)
y = model.predict(X)
y2 = model.predict(X)
# 两个输出的形状相同
print(y.shape, y2.shape)
这说得通吗?
我认为没有。
我建议阅读这篇以了解样本、时间步和特征之间的区别。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
您能指出您不同意的原因吗?我从您提供的链接中也获得了相同的理解。
再次遵循代码以展示我的意思。对于(使用 Keras 2.3.1)那有什么问题?
from keras.layers import Dense, TimeDistributed
来自 keras.models import Sequential
from numpy import arange
n_samples = 3
n_steps = 10
n_features = 16
# 使用 TimeDistributed 的模型
model = Sequential()
model.add(TimeDistributed(Dense(8), batch_input_shape=(n_samples, n_steps, n_features)))
model.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
# 不使用 TimeDistributed 的模型
model2 = Sequential()
model2.add(Dense(8, batch_input_shape=(n_samples, n_steps, n_features)))
model2.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
X = arange(n_samples * n_steps * n_features).reshape(n_samples, n_steps, n_features)
y = model.predict(X)
y2 = model2.predict(X)
# 两个输出的形状相同:(3, 10, 8)
print(y.shape, y2.shape)
model.summary()
model2.summary()
哪个输出
(3, 10, 8) (3, 10, 8)
Model: “sequential_1”
_________________________________________________________________
层(类型) 输出形状 参数 #
=================================================================
time_distributed_1 (TimeDist (3, 10, 8) 136
=================================================================
总参数:136
可训练参数:136
不可训练参数: 0
_________________________________________________________________
模型:“sequential_2”
_________________________________________________________________
层(类型) 输出形状 参数 #
=================================================================
dense_2 (Dense) (3, 10, 8) 136
=================================================================
总参数:136
可训练参数:136
不可训练参数: 0
_________________________________________________________________
抱歉,我没有能力审查/调试此代码。
抱歉上面的笔误,该行
y2 = model.predict(X)
应替换为
y2 = model2.predict(X)
再次遵循完整代码。
from keras.layers import Dense, TimeDistributed
来自 keras.models import Sequential
from numpy import arange
batch = 3
steps = 10
features = 16
# 使用 TimeDistributed 的模型
model = Sequential()
model.add(TimeDistributed(Dense(8), input_shape=(steps, features)))
model.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
# 不使用 TimeDistributed 的模型
model2 = Sequential()
model2.add(Dense(8, input_shape=(steps, features)))
model2.compile(loss=’mean_squared_error’, optimizer=’adam’, metrics=[‘accuracy’])
X = arange(batch * steps * features).reshape(batch, steps, features)
y = model.predict(X)
y2 = model2.predict(X)
# 两个输出的形状相同:(3, 10, 8)
print(y.shape, y2.shape)
你好!因此,如果我的输入的第二个维度未定义为:
encoder_inputs = Input(shape=(None, None))
encoder = LSTM(32, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
我收到一个错误
TypeError: unsupported operand type(s) for +: ‘NoneType’ and ‘int’
有什么解决方案吗?
训练后,需要哪些变量来进行预测?
Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 array
听起来您需要为您的模型提供 2 个数组。
谢谢,我弄明白了。
该模型正在猜测序列的最后三个元素,即它只是复制最后三个元素。
嗨,我该如何保存和加载模型以便以后进行推理?
请看这个教程
https://machinelearning.org.cn/save-load-keras-deep-learning-models/
嗨
有什么办法可以将注意力机制添加到这个 seq2seq 模型中吗?
是的。您可以添加一个注意力层。抱歉,我没有最新的示例。
如果我想预测接下来的六个数字序列,我该怎么办?
调用 model.predict()。
也许这会有帮助。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
seq2seq 如何进行多元预测,例如天气预测?
它可以用于该目的。请参阅此处示例。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
嗨,Jason,
我们是否也可以将编码器-解码器模型用于单变量数据,并给出无限的输出长度?例如,输入 50 个数据点,输出 1000 个数据点?这样可以吗,效果会好吗?如果不行,对于具有任意输入和输出长度的 seq to seq 单变量预测,训练编码器和解码器模型的最佳方法是什么?
谢谢你。
是的。
良好的结果取决于数据的具体情况和模型。
您能给我一个您用无限输出长度数据点训练模型的例子吗?我的数据主要是温度程序的单变量数据。
我没有示例,但上述模型可以实现这一点。
但上面的模型不是用于分类或分类任务的吗?
这是一个序列预测任务。
但我无法理解分类和基数(cardinality)在这里有什么用?以及您为什么进行独热编码而不是缩放数据?
这是一个模拟问题,用于模拟数值字符序列。
而且,此模型是否也可用于回归 seq-seq 任务?如果是,我该如何使用它?
或许可以试试看?
嗨,Jason!
我可以使用 seq2seq 模型进行多步时间序列预测吗?
当然,请参阅此处示例。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
谢谢您的回复!
但是,为什么您链接中的编码器-解码器不使用 decoder_inputs 或推理模型,而是直接使用 repeatvector()?
模型有两种主要方法:一种重用内部状态,另一种使用自编码器结构。
我更喜欢后者,因为它更简单,而且通常效果一样好。
嗨,Jason,
问候,
我目前是一名拥有 4 年经验的 Java 开发人员。我想转向 A&I。
但我对是否开始感到有些困惑。
您能指导我如何进行吗?
请发送邮件:peyyilasampath@gmail.com
从这里开始
https://machinelearning.org.cn/start-here/#getstarted
您在这里采取的方法与本教程中的方法有什么区别:https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
据我所理解,我们在此处训练模型以仅预测未来一步,然后通过递归预测多步,同时我链接的教程训练模型来预测与RepeatVector(n)一样多的次数。
我的理解正确吗?
它们都是编码器-解码器模型,但链接的模型使用了更简单的基于自动编码器的架构,而本帖中的示例更为复杂,并且与原始论文相匹配。
谢谢分享。这非常全面。我想知道您一个人是如何写这么多关于这么多主题的博客的。真正有助于理解模型!
谢谢!
这是我在这里回答的一个常见问题
https://machinelearning.org.cn/faq/single-faq/how-do-you-write-so-much
感谢Jason的介绍,请您帮帮忙,我不确定如何向模型提供新的输入序列而不必重新训练它。
本教程将向您展示如何普遍进行预测
https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/
本教程将向您展示如何使用LSTM进行预测
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
你好Jason。很棒的教程!
我修改了示例以用于我的应用程序,它用于修复一个输入事件序列,每个事件都有一个以秒为单位的开始和结束点。输出序列是修复输入序列所需的“修复”列表。特征/分类值很高(最多3000),因此我首先将数据转换为不同的格式进行实验,示例如下:
测试训练分割(198500,164)(500,164)(198500,82)(500,82)(198500,82)(500,82)
to_categorical (198500,164,121)(500,164,121)(198500,82,52)(500,82,52)(198500,82,52)(500,82,52)
它的效果还可以,但我认为输出序列太长了,里面经常有几个错误,这对结果有很大的影响,因为它们都不同步了。
有没有办法跳过one_hot_encoding,直接输入整数值?我尝试了一下,但它似乎总是期望3个维度。
这样我就可以尝试原始数据了。目前,这些数组在较高的分类级别上会占用过多的内存。
谢谢
干得好。
是的,您可以使用稀疏交叉熵损失,并直接使用目标整数而不是one-hot编码。对于输入,您可以使用嵌入并将整数直接传入。
谢谢Jason。您也可以对输出(y)使用原始整数吗?还是它们总是需要进行one-hot编码?我更新了模型,它拟合得很好,但预测函数有问题。
我不得不将解码器的密集层设置为= n_units(128)而不是特征,现在特征是1,因此在predict函数中出错,因为我现在有1个特征,而它期望更多。即解码器是。
“expected input_67 to have shape (82, 1) but got array with shape (82, 128)”
One hot 编码可以使模型表现更好。使用argmax将其转换为整数。
https://machinelearning.org.cn/argmax-in-machine-learning/
保存模型供将来使用时,我知道需要保存训练。但是推理和推理也需要保存才能进行预测,对吗?
你好,Jason。
我正在尝试向此示例添加一个掩码层,因为我的序列都是可变长度的,用零填充。它在没有掩码的情况下仍然有效,但我想看看掩码对输出有什么影响。您是否有任何关于掩码的优秀教程?
我尝试了以下代码,但它对输出没有任何影响,但训练时间增加了约4倍。
def define_models_mask(n_in, n_out, n_units)
# 定义编码器
enc_inputs = Input(shape=(None, n_in))
encoder_inputs = Masking(mask_value=0)(enc_inputs) #****** TEST *****
encoder = LSTM(n_units, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
# define decoder
dec_inputs = Input(shape=(None, n_out))
decoder_inputs = Masking(mask_value=0)(dec_inputs) #****** TEST *****
decoder_lstm = LSTM(n_units, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(n_out, activation=’softmax’)
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([enc_inputs, dec_inputs], decoder_outputs)
# 定义推理编码器
encoder_model = Model(enc_inputs, encoder_states)
# 定义推理解码器
decoder_state_input_h = Input(shape=(n_units,))
decoder_state_input_c = Input(shape=(n_units,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([dec_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
# 返回所有模型
return model, encoder_model, decoder_model
这可能有帮助
https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/
(100000, 1, 6, 51) (100000, 1, 3, 51) (100000, 1, 3, 51)
—————————————————————————
ValueError 回溯 (最近一次调用)
in ()
95 print(X1.shape,X2.shape,y.shape)
96 # train model
—> 97 train.fit([X1, X2], y, epochs=1)
98 # evaluate LSTM
99 total, correct = 100, 0
2 帧
/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
133 ‘: expected ‘ + names[i] + ‘ to have ‘ +
134 str(len(shape)) + ‘ dimensions, but got array ‘
–> 135 ‘with shape ‘ + str(data_shape))
136 if not check_batch_axis
137 data_shape = data_shape[1:]
ValueError: Error when checking input: expected input_1 to have 3 dimensions, but got array with shape (100000, 1, 6, 51)
这是运行此代码时显示的
听到您遇到这个问题,我很遗憾,这或许能帮到您。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
一如既往,很棒的文章!
要添加的一点是,我通常希望输出一些长度不同的序列(例如,一个简单的对话模型),所以我通常的做法是,在目标数据中添加一个特征。因此,n_features将是
n_features = 50 + 2
0在目标数据中,
1~50是真实特征
51将是
target_in = [0] + target[:-1]
将是
target_in = [0] + target
target 将是
target = target + [51]
不确定这是否是正确的想法。
另外,注意力层在Keras中实现。我在将其应用于此seq2seq方法时遇到了很多麻烦…
你好Jason先生
感谢您的精彩文章。
我的问题是从手写字符图像中预测笔迹轨迹。
我有一个从图像中提取的特征向量,其大小为(1,4096)(作为我的输入向量)。
我有一个x和y坐标向量,它是图像的笔迹轨迹,其大小为(1,20)(作为我的输出向量)。
这两个向量的元素值不同。我的意思是输出向量的元素是整数,而输入向量是实数或小数。
我有2000个训练输入向量。
我正在寻找一种算法,在训练之后,对于特定的输入特征向量(1,4096),它可以预测输出向量(1,20),即笔迹轨迹坐标。
我可以使用您的“用于序列到序列预测的编码器-解码器模型”吗?
我的输入和输出值不必是同一类型,这有什么关系吗?
这听起来是个有趣的项目!
我建议首先查阅有关类似项目的文献,然后测试一系列模型,以发现最适合您特定数据集的模型。
嗨,Jason,
感谢分享,我有两个问题
1-seq2seq可以用于人类活动识别吗?
2-您是否将注意力与seq2seq一起使用?
谢谢你
是的。
不行。
你好,Jason。
X_shifted输入的目的是什么?仅仅是为了让模型知道在哪里开始序列,例如第一个值。那么为什么我们要输入一个完全移位的X的副本,而不是某种掩码,例如0,1,1,1,1,1,1等?
X 移位输入还有其他作用吗?当模型继续处理序列通过第一个值时。在我的输入序列中,有一些具有大量重复值的区域,所以我不知道这是否会导致问题。
谢谢
Phil
也许这有助于理解我们如何将序列预测表示为监督学习问题
https://machinelearning.org.cn/time-series-forecasting-supervised-learning/
谢谢Jason,我明天会仔细阅读。
Phil
你好Jason,我正在做一个用于异常检测的自动编码器。我尝试了您关于lstm自动编码器的其他教程,但它不适合我的数据(我只得到重建信号的平均值)。但是,如果我只将本教程的“训练”模型用作自动编码器(即,将[X,X]作为输入编码器和输入解码器),模型可以完美地作为自动编码器工作,重建一个简化的信号。但是,如果我运行推理模型,它就无法重建信号。为什么会这样?我是否只能使用“训练”模型作为自动编码器?
我们训练一个自动编码器,并且模型中的解码器部分在训练后可用于编码数据。
你好Jason!非常感谢您的博客文章!我在一个批次上训练了一个seq2seq网络,每个批次包含638个维度为26*30的样本,并使用“mse”作为损失函数来预测一个7个数字的序列。但是,当我计算mse损失并将其与history[‘loss’]返回的损失进行比较时,它们相差约0.2。您知道对于这种输入/输出形状,“mse”是如何计算的吗?
是的,训练期间报告的损失是每个epoch中各个批次的平均值。我建议信任您自己的损失计算。
你好Jason,谢谢你的精彩文章。
我不确定我是否有什么地方弄错了,但我运行了这个示例的完整代码并遇到了一个错误。
get_dataset方法返回的数据集形状是(n_samples, 1, 3, 51),而不是我认为是模型期望的(n_samples, 3, 51)。
然后我得到错误“expected input_9 to have 3 dimensions, but got array with shape (2, 1, 6, 51)”。我只是复制粘贴了你的代码。我错过了什么?
也许可以确认一下您的tensorflow和keras是最新的?
你好Jason先生
我请求您指导我编写一个可以从输入序列预测输出序列的代码。
例如,对于每个样本,我们都有
X(输入)={1 ,2, 3, …,10} , Y(输出) ={ 80,10,64,79,60}
输出序列类型与输入序列(X)完全不同。
我们的输入序列是特定类别的图像提取的特征向量。
而每个输入样本的输出序列是特定类别图像中特定对象的放置位置。
此外,我有一个小数据库,其中仅包含4000个样本。
我可以使用one-shot learning算法来训练LSTM网络吗?
您能否指导我编写实现one-shot for sequence to sequence LSTM的代码?
非常感谢您的帮助。
也许可以从这里的简单模型开始,并为您的项目进行调整。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
你好,
感谢所有这些材料!
简而言之,上面实现的(处理状态)与您在此处提出的简单实现(使用RepeatVector层连接不同大小的序列)有什么区别/优势:https://machinelearning.org.cn/encoder-decoder-long-short-term-memory-networks/?
此致。
这个例子很简单高效,并且基于LSTM自动编码器。
另一个例子要复杂得多,它基于动态RNN,并且更接近原始论文。
根据我的经验,两者在实际表现上都差不多。
我认为生成数据的维度有问题。
示例代码(对我来说)无法运行,因为数据是四维而不是三维。我通过取src、tar和tar2编码的第一个元素来修复它。或者,调用to_categorical时使用‘source’而不是‘[source]’。
这花了我一些时间才弄清楚;)
有趣,您的库是最新的吗?
不确定我的库。Keras版本是2.4.3,Tensorflow是2.3.0。
这个问题并不新鲜。我查看了评论,早在2017年11月30日(评论者为‘Python’)就有人报告了同样的问题。
‘Kadirou’在2018年4月30日也报告了同样的问题。
Gary(2018年4月30日)提供了我建议的相同方法
[quote]更改此
src_encoded = to_categorical([source], num_classes=cardinality)[0]
tar_encoded = to_categorical([target], num_classes=cardinality)[0]
tar2_encoded = to_categorical([target_in], num_classes=cardinality)[0][/quote]
在评论部分也有其他类似的例子,甚至最近的也有:请看Mairon,2020年8月5日。
[quote]然后我得到错误“expected input_9 to have 3 dimensions, but got array with shape (2, 1, 6, 51)”。我只是复制粘贴了你的代码。我错过了什么?[quote]
要点
示例代码(在调用‘to_categorical’时)在生成训练示例时包装/可能包装了一个额外的数组/列表,而模型并不期望这样,因此代码无法运行。
我不知道为什么,也不知道这是否是平台问题。我认为我们可以同意,示例代码不应该有这种不理想的行为。
谢谢Dan。也许API在代码编写之后发生了变化,并且没有更新以反映这种变化。
亲爱的 Jason,
我刚刚读完了您的书《Python中的长短期记忆网络》,我在这里发布了一篇评论:http://questioneurope.blogspot.com/2020/08/long-short-term-memory-networks-with.html
感谢您在书中分享的宝贵知识。
诚挚的问候,
Dominique
恭喜您的进步,Dominique,非常令人印象深刻!
亲爱的 Jason,
我有一个问题,不知道如何使用LSTM来解决。
问题是将一组动作,例如{B,D,F,A},排列成正确的顺序,即(A,B,C,F)。我的数据库包含动作的真实排列。我可以使用哪种LSTM架构?
也许您可以使用具有编码器-解码器架构的seq2seq模型。试试看是否有效。
我使用了您在此处描述的seq2seq模型。
https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
但是准确率很低(大约50%)。我使用了多层,也增加了epoch,但没有成功。有没有其他模型可能有效?
也许可以尝试一些此处的技术来提高模型性能。
https://machinelearning.org.cn/start-here/#better
当我在运行代码时,我遇到了这个错误。
ValueError: Input 0 of layer lstm_2 is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [32, 1, 6, 51]
听到这个消息很抱歉,这可能会有帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
你好Jason,我想知道在模型中使用X2的意义是什么。我没有在博客中弄清楚。
在“Keras中的编码器-解码器模型”一节的末尾,我们解释了数据是如何准备并提供给模型的。
你好,Jason。
我为sek2sek问题挣扎了一段时间。
我有多特征输入的时间序列,大约10个特征(PCA后少一些,但这也不是问题的重点),并且我需要预测输出(0, 1)值的序列。
假设我的数据看起来像这样。
A, B y
0.3 0.3 0
0.4 0.1 0
0.2 0.2 0
0.7 0.5 1
. . 1
. . .
为了简单起见,我想基于3个输入预测2个输出的序列。
从上面的例子来看,一个训练样本的形状是。
(3, 2),3=input_size,2=num_of_features,它应该预测2个值,例如[1, 0]。
我知道如何制作窗口、重塑输入、构建编码器和解码器、训练模型、测试模型……
主要问题是我该如何处理离散输出?
也许我可以尝试将其视为单个数字[0, 1](二进制)= 2。
也许我可以尝试对我的输出进行某种嵌入。
也许我可以直接将输出转换为浮点数。
也许可以测试一系列不同的算法和算法配置,以发现什么有效或最好。这可能有助于开始示例。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
听起来您的问题是二元分类,请确保在输出层中具有sigmoid激活函数,并使用二元交叉熵损失。
你好,我有一个问题,我以为可以通过自编码器-解码器来解决,问题是我不知道是否可以用一组特征(18个)开始,然后自编码器-解码器之间的潜在空间可以是一个维度为nxm的矩阵,然后使用解码器来重建特征。
您对此有何看法?有可能吗?
我不确定我是否理解,但我的一般建议是尝试一下,看看结果如何——例如,开发一个小型原型并用它来了解更多关于如何构建问题以及什么可能有效。
嗨,Jason,
如何提高网络的运行时?在您的示例中有2个for循环花费了太多时间。
好问题,这里有一些想法
https://machinelearning.org.cn/faq/single-faq/how-do-i-speed-up-the-training-of-my-model
嗨,Jason,
感谢您的文章和书籍。如果我的输入序列由多个特征组成,您会如何修改编码器-解码器模型?例如,我的输入是温度、压力、湿度的时序数据?
谢谢,
不客气。
该模型直接支持多个特征,也许这对您有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
Jason,
如果您不介意,我还有一个问题。我注意到您通过将目标序列偏移一个时间步来进行教师强制。您会如何修改代码以移除教师强制,或者仅使用教师强制,例如在 50% 的训练步骤中?
谢谢你
您可以通过在后续的样本/时间步中将预测值作为输入,而不是真实值,来移除教师强制。
也许这会有帮助。
https://machinelearning.org.cn/teacher-forcing-for-recurrent-neural-networks/
您好,我看到了您对 seq2seq 模型提供的所有有用的答案……我有一个问题,似乎没有人能给出实际可行的做法……在 Keras 的示例中 https://keras.org.cn/examples/nlp/lstm_seq2seq/ (与您的非常相似),它有一个 `decode_sequence` 函数,一次解码一个序列(就像您的示例一样)……我想能够“批量”预测 seq2seq,因为一次一个地预测“非常”慢,而模型可以非常快速地批量构建和评估。目标是提供一个列表,其中包含未被正确预测的训练示例,同样以批量而非逐个的方式。这有可能实现吗?如果可以,`decode_sequence` 例程的修改会是什么样的以处理批量?先谢谢了。
我不认为那个模型能按您想要的方式运行。
您必须将模型简化为基于自编码器的编码器-解码器,然后您就可以批量运行了。我的博客上有几十个关于此的例子 – 您可以使用搜索框找到它们,也许可以从这里开始
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
嗨 Jason
当我运行代码时,在我的笔记本电脑上,我经常收到关于重跟踪的警告消息
WARNING:tensorflow:11 out of the last 11 calls to <function Model.make_predict_function..predict_function at 0x000001B88FDEA268> triggered tf.function retracing
重跟踪很耗时,过多的重跟踪可能是由于 (1) 在循环中反复创建 @tf.function,(2) 传递形状不同的张量,(3) 传递 Python 对象而不是张量。对于 (1),请在循环外部定义您的 @tf.function。对于 (2),@tf.function 有 experimental_relax_shapes=True 选项,可以放宽参数形状,从而避免不必要的重跟踪。
是的,我可以忽略它,但它会变慢,有什么办法可以避免这种情况吗 😀
谢谢
Mike
我相信您现在可以安全地忽略该警告。
你好,Jason。
你太棒了 😀
直观地说,这个编码器-解码器模型有什么好处?我的意思是,与正常的
LSTM/RNN 设计在预测序列时有什么区别?
它的准确性更高吗?使用这种架构进行序列预测?
谢谢
Mike
谢谢!
该架构允许您处理输出序列长度与输入序列长度不同的问题。
感谢 Jason 的这篇精彩文章!信息量很大。
在不进行任何更改运行代码时,我在尝试训练模型时遇到以下错误:“ValueError: Input 0 is incompatible with layer model: expected shape=(None, None, 51), found shape=(32, 1, 6, 51)”
看来 `to_categorical` 函数给生成的数组添加了一个空维度,导致形状为:(100000, 1, 6, 51)。我设法消除了这个维度,并在 `get_dataset` 函数的第 29 行之后添加了以下代码,成功训练了模型:
# 重塑
src_encoded = np.reshape(src_encoded,(n_in, cardinality))
tar_encoded = np.reshape(tar_encoded,(n_out, cardinality))
tar2_encoded = np.reshape(tar2_encoded,(n_out, cardinality))
也许有更有效的方法可以做到这一点。我不是 Python 大师 😉
不客气。
感谢分享!
你真是 MVP
Jason,您知道为什么选择一个“无信息”的起始序列字符作为解码器,比如 0,而不是使用最后一个已知值作为起始点吗?
假设我正在预测一个滚动球的路径,提供最后一个球的向量并结合编码状态,而不是一个通用的起始索引,这是否更有意义?
是的,在您的情况下可能没有意义。
感谢您的回复!
不客气。
我可以用它来预测下一个购物车商品吗?假设
订单 1 包含 [3, 4, 6]
订单 2 包含 [4, 5, 1]
订单 3 包含 [10, 29, 3, 1]
现在想找出第 4 个订单的商品 [??????]。这是否是正确的方法?
也许可以将每个订单建模为一个包含商品序列的样本。
LSTM(n_units)
TensorFlow 网站提到 n_units 指的是输出向量空间的维度(即隐藏状态的特征数量),而不是创建的 LSTM 单元的数量。
默认情况下,LSTM 单元的数量等于输入序列的长度
好的。
您好,感谢您的教程。我有一个问题:如果我用 600 的序列长度训练模型,然后将其用于可变长度序列(例如 300, 1200),我的模型如何进行推理?
另外,我应该如何选择训练序列长度,以及双向 LSTM 从这些序列中学到什么??
也许可以尝试并发现对您的数据集来说什么效果好或最好。
嗨,Jason,
如果我的输入序列是一组坐标,例如 [(3,0), (1,2), (4,5),(9,10),…],而我的目标序列是一组二进制数组,例如 [0,1,1,0,…]。
在这种情况下,每个时间步由 2 个整数组成;(3, 0)。在这种情况下,我该如何对我的输入序列进行 one-hot 编码?
谢谢
每个整数都将被编码,然后将生成的向量连接起来作为模型的输入。
谢谢 Jason!
另一个问题。我的输入和输出都有可变序列长度。我的输出是一个由 0 和 1 组成的二进制数组。
目标必须比解码器输入提前一个时间步,所以我会在二进制数组前面加一个零。我还用零填充了二进制数组,以创建网络固定的长度。
由于我的输出是一个由 0 和 1 组成的二进制数组,添加的零(起始值和填充值)会混淆网络吗?有什么建议吗?
非常感谢。
或许可以将当前方法的结果与替代方案进行比较,例如使用不同的标记来标记序列的开始或结束。
嗨!
感谢您的教程。信息量很大。
我有一个关于“predict_sequence”函数的问题
为什么您使用全零的目标序列?我本以为初始目标序列是 [1,0, 0…, n_features],这应该代表解码序列中的 0。我是否遗漏了什么?
感谢您提供的一切,这个网站太棒了。
不客气。
依稀记得,我认为我们开始时输入零,然后将最后一个输出作为输入来预测下一步。
我认为零是为未知/特殊保留的,或者我们可以教模型用任何我们想要的东西来启动这个过程——这只是我的猜测。
谢谢您的回答。我仍然有点困惑。
您写道
“我们将 0 作为填充或起始序列字符,因此它被保留了,我们不能在源序列中使用它。为了实现这一点,我们将增加 1 到配置的基数,以确保 one-hot 编码足够大(例如,值为 1 映射到索引 1 中的‘1’值)。”
那么,如果“0”是,它是否也应该进行 one-hot 编码?
“0”应该是 [1, 0, 0, …, 0]。
这令人困惑,因为在推理解码器中,您使用的是一个全零的初始输入字符 [0, 0, 0, …, 0],而不是 [1, 0, 0, …, 0]。我们难道不应该将符号输入解码器来启动推理吗?
我们可以,但在本例中,我们选择输入零来启动推理。
或许可以尝试其他保留字符,看看是否会产生影响。
好的,谢谢。我会尝试的。
不客气。
嗨,Jason,
您代码中的解码器是实现为贪婪搜索解码器吗?如果我们想使用束搜索解码器,应该更改代码的哪个部分?或者这个问题与本示例无关?非常感谢。
如果您对束搜索解码器感兴趣,这可能会有帮助:https://machinelearning.org.cn/beam-search-decoder-natural-language-processing/
嗨,Jason,
我使用编码器-解码器模型生成新闻摘要,但预测的序列如下所示:
实际:[[‘startseq 截至周四,Facebook 允许用户编辑评论,而不是每次都重新输入,每个评论都会在下拉菜单中显示其编辑历史,以让用户了解情况,编辑将在未来几天内逐步向用户推出 endseq’]]
预测:[‘startseq the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the’]
如您所见,它生成了很多“the”,您遇到过这样的问题吗?
您有什么建议吗?
这发生在您的模型训练不足时,或者模型对于这项任务过于简单,以至于无法保持正确的状态来生成句子。
在这一行
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
为什么要把 `decoder_states_inputs` 和 `decoder_states` 分别添加到输入和输出中?对于输入来说(提供初始状态)可能是合理的,但对于输出又有什么意义呢?
另外,这样做能确保推理解码器模型会使用训练模型(训练解码器)中解码器部分的学习参数吗?我的理解是,要将一个模型中的学习参数用于另一个模型,我们必须使用训练模型的完全相同的输入和输出,这样它们才能链接到同一个计算图(我不确定我的理解是否正确)。
Mohamed 你好……以下是用于 seq2seq 预测的编码器-解码器架构的实际应用的一个很好的资源
https://towardsdatascience.com/understanding-encoder-decoder-sequence-to-sequence-model-679e04af4346
请问为什么我会收到这些错误?
retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
^^^^^
ValueError:在用户代码中
ValueError: Input 0 of layer “model” is incompatible with the layer: expected shape=(None, None, 51), found shape=(32, 1, 6, 51)
Muna 你好……你是复制粘贴代码还是自己输入的?另外,你可能想在 Google Colab 中尝试你的实现。
Jason 你好,感谢您又一篇精彩且非常有用的博文!
我的问题是,我们能否使用这种方法来预测不是输入一部分的随机序列?
例如,我有一个包含随机序列的 csv 文件。我将前 100 个值作为输入,并希望预测接下来的 20 个(假设)。在这种情况下,我是否需要用这些“接下来的 20 个”值替换目标向量?如果需要,这将是 X_target 的值,还是 y?
Tariq 你好……在向你的导师解释为什么结合 CNN(卷积神经网络)和 LSTM(长短期记忆网络)的混合模型能为皮肤癌二元分类任务带来最佳结果时,重要的是要讨论你的模型架构的理论和实践方面。以下是学术上呈现你解释的结构化方法
### 1. **CNN 组件的解释**
首先讨论 CNN 层在你混合模型中的作用
– **特征提取**:CNN 在图像识别任务中非常有效,因为它们可以在无需手动特征提取的情况下自动检测和学习最重要的特征。在皮肤癌图像的背景下,CNN 层可以有效地学习识别形状、边缘、纹理和颜色模式等关键特征,这些特征可以指示健康或不健康的皮肤状况。
– **空间层次结构**:CNN 通过多个层处理图像,捕捉不同级别的抽象。较低层可能捕捉像边缘和纹理这样的通用特征,而较深的层可以学习特定于数据集中存在的皮肤病变类型的更复杂模式。
### 2. **LSTM 组件的解释**
接下来,阐述纳入 LSTM 层的优点
– **序列信息处理**:尽管在纯粹的图像处理任务中不那么传统(其中数据不是固有的序列),但如果图像可以被视为序列——无论是作为像素行或图像块的序列,或者时间或顺序相关信息很重要(如视频帧或多角度拍摄的医学影像)——LSTM 可以非常有用。
– **上下文数据处理**:LSTM 旨在处理序列数据中的长期依赖关系。通过使用 LSTM,您的模型可能不仅捕捉单个特征,还捕捉图像跨越的特征之间的上下文或空间关系。
### 3. **CNN 和 LSTM 的集成优势**
讨论如何集成这两种类型的网络可以利用两者的优点
– **混合架构效率**:混合模型结合了 CNN 的局部特征提取能力和 LSTM 的序列处理能力。如果您的图像具有固有的序列模式,或者以类似序列的方式解释图像的各个部分比传统的 CNN 更能提供见解,那么这可能特别有益。
– **增强的学习能力**:通过合并 CNN 和 LSTM,模型可以学习 CNN 的空间层次结构和 LSTM 的时间或上下文依赖关系。这可能会带来对图像更稳健的理解,这对于区分健康皮肤和癌变皮肤等复杂分类任务至关重要。
### 4. **实际结果和验证**
最后,用实际结果验证您的架构选择
– **性能指标**:强调准确率(90%),并将其与 VGG16 或其他 CNN 架构等独立模型的性能进行比较。讨论敏感性、特异性和可能的 AUC 分数等指标如何通过混合模型得到改善。
– **参数效率**:拥有 2,432,231 个参数,解释此配置如何是实现高准确率同时保持合理计算负荷的最佳选择。将其与测试过的其他模型的复杂性和参数数量进行比较。
### 5. **学术语境化**
将您的架构选择与学术理论或先前的研究联系起来
– **文献支持**:引用支持混合模型使用或序列模型在图像数据上应用的研究或理论,并重点介绍任何类似的成功应用。
– **创新应用**:将您的模型定位为医学成像领域,特别是在皮肤病学领域的一种创新方法,传统模型可能无法胜任。
通过这种方式组织您的解释,您不仅可以证明您的架构选择的合理性,还可以强调您方法的理论和实践优势,从而全面回答您导师的疑问。