首页 > 解决方案 > 除非我使用嵌入,否则 RNN 分类会失败。没有嵌入,所有预测都是同一个类

问题描述

我正在尝试对X长度为 200 的向量列表进行分类,其中包含从vocab长度为 100 的特征的字典中选择的整数值,它们属于 0 类或 1 类。这是我的输入数据的一个示例:

X=[[1,22,77,54,51,...],[2,3,1,41,3,...],[12,17,31,4,12,...],...]
y=[0,1,1,...]

例如np.array(X).shape=(1000,200)y.shape=(200,)。班级分为50-50。我做了一个标准的 train_test 分成(X,y)和(X_test,y_test)。

我的模型是:

from keras import layers as L
model = keras.models.Sequential()
model.add(L.Embedding(input_dim=100+1,output_dim=32,\
                      input_length=200))
model.add(L.SimpleRNN(64))           
model.add(L.Dense(1,activation='sigmoid'))
model.compile(optimizer='adam',loss='binary_crossentropy',\
              metrics=['accuracy'])

model.fit(X,y,batch_size=128,epochs=20,validation_data=(X_test,y_text))

当我将它与训练和测试数据相匹配时,这非常有效。但是,我想尝试跳过嵌入,因为我有一个“小”的特征空间(9026)。我通过除以对训练数据进行归一化,9206.并尝试构建简单的 RNN 模型,如下所示:

model = keras.models.Sequential()
model.add(L.InputLayer(200,1))
model.add(L.SimpleRNN(64))           
model.add(L.Dense(1,activation='sigmoid'))
model.compile(optimizer='adam',loss='binary_crossentropy',\
              metrics=['accuracy'])
model.fit(X[:,:,np.newaxis],y,batch_size=128,epochs=20,validation_data=(X_test[:,:,np.newaxis],y_text))

我必须添加np.newaxis才能让模型编译。当我将它与数据拟合时,我总是得到 0.5 的训练和验证准确度,这是我在 0 类到 1 类中的分数。我尝试了不同的激活、不同的优化器、RNN 中不同数量的单元、不同的批量大小, LSTM, GRU, 添加 dropout, 多层....没有用。

我的问题是:

  1. 我有固定长度 (200) 的向量要分类,词汇表只有 100 个特征。没有嵌入就不能做到这一点吗?

  2. 有没有人对让非嵌入模型进行实际训练有有用的建议?

标签: pythontensorflowkerasrnn

解决方案


循环层需要形状的输入,(batch_size, timesteps, input_dim)其中input_dim输入数据中的类别数是单热编码的,例如[1, 3], [0, 2]变为[[0, 1, 0, 0], [0, 0, 0, 1]], [[1, 0, 0, 0], [0, 0, 1, 0]].

现在您的数据是形状(batch_size, timesteps)和稀疏编码的,这意味着上述1编码中类似的位置由类别编号隐式给出。只需向数组添加一个新轴即可使其形状正确,因此 Keras 不会引发任何错误,但数据未正确编码,因此您的训练显然根本不起作用。

它实际上与Embedding层一起工作,因为与层相反Recurrent,嵌入期望输入具有给定形状和编码(将RNN的输入形状与Embedding的输入形状进行比较)。

要解决此问题,您只需对数据进行一次热编码。Keras 为此提供了非常方便的to_categorical实用程序功能,但您也可以手动完成。


推荐阅读