我正在尝试对长度为200的向量列表X
进行分类,这些向量包含从长度为100的字典vocab
中选择的整数值,属于类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,添加辍学,多层...。没有任何效果。
我的问题是:
我有固定长度的向量(200)可以分类,词汇只有100个特征。没有嵌入就不能做到这一点吗?
对于让非嵌入模型进行实际训练,有人有有用的建议吗?
答案 0 :(得分:1)
循环层需要输入形状为(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之一)。
要解决此问题,您只需one-hot encode您的数据。 Keras为此提供了非常方便的to_categorical util函数,但您也可以by hand做到这一点。