如何在 Keras 中为循环神经网络 (RNN) 使用嵌入层

Posted

技术标签:

【中文标题】如何在 Keras 中为循环神经网络 (RNN) 使用嵌入层【英文标题】:How to use the Embedding Layer for Recurrent Neural Network (RNN) in Keras 【发布时间】:2016-05-07 12:13:03 【问题描述】:

我对神经网络和 Keras 库还很陌生,我想知道如何使用 here 所述的嵌入层将我的输入数据从 2D 张量屏蔽为 RNN 的 3D 张量.

假设我的时间序列数据如下(随着时间的增加):

X_train = [
   [1.0,2.0,3.0,4.0],
   [2.0,5.0,6.0,7.0],
   [3.0,8.0,9.0,10.0],
   [4.0,11.0,12.0,13.0],
   ...
] # with a length of 1000

现在,假设我想为 RNN 提供最后 2 个特征向量,以便预测时间 t+1 的特征向量。

目前(没有嵌入层),我正在自己创建所需的形状为 (nb_samples, timesteps, input_dim) 的 3D 张量(如本例中的here)。

与我的示例相关,最终的 3D 张量将如下所示:

X_train_2 = [
  [[1.0,2.0,3.0,4.0],
   [2.0,5.0,6.0,7.0]],
  [[2.0,5.0,6.0,7.0],
   [3.0,8.0,9.0,10.0]],
  [[3.0,8.0,9.0,10.0],
   [4.0,11.0,12.0,13.0]],
  etc...
]

和Y_train:

Y_train = [
   [3.0,8.0,9.0,10.0],
   [4.0,11.0,12.0,13.0],
   etc...
]

我的模型如下所示(改编为上面的简化示例):

num_of_vectors = 2
vect_dimension = 4

model = Sequential()
model.add(SimpleRNN(hidden_neurons, return_sequences=False, input_shape=(num_of_vectors, vect_dimension))) 
model.add(Dense(vect_dimension))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, Y_train, batch_size=50, nb_epoch=10, validation_split=0.15)

最后,我的问题是,我怎样才能避免将那些 2D 张量转换为 3D 张量重塑自己并改用嵌入层?我想在 model =equential() 之后我必须添加类似的内容:

model.add(Embedding(?????))

可能答案很简单,我只是被嵌入层的文档弄糊涂了。

【问题讨论】:

【参考方案1】:

你可以这样:

注意:

    我生成了一些 X 和 y 作为 0,只是为了让您了解输入结构。

    如果您有一个多类 y_train,则需要进行二值化。

    如果您有不同长度的数据,您可能需要添加填充。

    如果我正确理解了在时间 t+1 的预测,您可能需要查看序列到序列学习。

尝试类似:

hidden_neurons = 4
nb_classes =3
embedding_size =10

X = np.zeros((128, hidden_neurons), dtype=np.float32)
y = np.zeros((128, nb_classes), dtype=np.int8)


model = Sequential()
model.add(Embedding(hidden_neurons, embedding_size))
model.add(SimpleRNN(hidden_neurons, return_sequences=False)) 
model.add(Dense(nb_classes))
model.add(Activation("softmax"))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', class_mode="categorical")
model.fit(X, y, batch_size=1, nb_epoch=1)

【讨论】:

也许我应该在我所有的数字后面添加一个“.0”。我实际上并不想进行分类分析。【参考方案2】:

据我目前所知,嵌入层似乎或多或少地用于降维,例如word embedding。所以从这个意义上说,它似乎不适用于一般的整形工具。

基本上,如果您将单词映射到整数,例如 car: 1, mouse: 2 ... zebra: 9999,您的输入文本将是由整数 id 表示的单词向量,例如 [1, 2, 9999 ...],这意味着[汽车,鼠标,斑马...]。但是将单词映射到具有词汇长度的实数向量似乎是有效的,因此如果您的文本有 1000 个唯一单词,您会将每个单词映射到长度为 1000 的实数向量。我不确定,但我认为它主要代表了一个词的含义与所有其他词的相似程度,但我不确定这是正确的,是否还有其他嵌入词的方法。

【讨论】:

以上是关于如何在 Keras 中为循环神经网络 (RNN) 使用嵌入层的主要内容,如果未能解决你的问题,请参考以下文章

Keras之RNN和LSTM

Keras深度学习实战——使用循环神经网络构建情感分析模型

文本分类:Keras+RNN vs 传统机器学习

Keras深度学习实战(27)——循环神经详解与实现

如何使用 tf.keras 在 RNN 中应用层规范化?

小白学习keras教程五基于reuters数据集训练不同RNN循环神经网络模型