我在Keras上处理一个机器学习问题。我的目标是训练一个模型,其输入是一个(4214, 22311)
的矩阵,输出是一个(22311,)
的向量。
这种二维数据可以被视为图像输入,但大多数图像分类器只能处理较小的图像,例如形状为(200, 200)
的图像。
我尝试了几种在Keras上构建模型的方法,例如CNN、双向LSTM,或者一个简单的神经网络(展平和全连接层)。但这些方法都不奏效。
我收到了killed
的提示,训练甚至无法完成一个epoch。所以我想知道什么样的结构可以处理这样的大输入。
回答:
完全卷积模型可能是一个可行的选择,你必须在任何展平/全连接层之前消除空间维度。但由于会有大量的卷积操作处理相同的数据,这似乎不是最佳选择…
而且由于你需要一个包含22311个结果的输出,可能LSTM方法(考虑到唯一不同的变量是第一个)会是最有用的…
LSTM模型:
首先,你可以尝试一个无状态的LSTM模型。
但不要将最后的维度视为特征(20000个特征会产生太多的参数)!而是将它们视为时间步长。
将特征转换为步长可能会使模型更难理解。另一方面,如果不这样做,你的内存总是会爆满。但如果唯一不同的数据是第一步,那么所有后续(和重复)的数据可能会获得一些额外的意义。
所以,首先,我们将数据重塑为只有一个特征:
inp = Input((4214,1))out = Lambda(yourFunction, output_shape=(4214,22312))(inp)out = Reshape((4214,22312,1))(out)
现在,让我们尝试一个技巧,使其看起来像是一系列序列,添加TimeDistributed包装器(这允许增加维度):
out = TimeDistributed(LSTM(cells,return_sequences=True))(out)#你可以添加更多
保持return_sequences = True
,因为你希望模型末端的步数非常相似。
在某个点上,让我们折叠4214维度,将其放在末尾,就好像它是时间步长(甚至可以视为特征 – 这很冒险,但比23312个特征要安全得多)。在这里,由于它们是独立的,Bidirectional
包装器可能会派上用场:
out = Permute((2,1,3))(out)
1 – 如果你选择4214步长:
#你可以在这一层之前使用一个或多个return_sequences=True的层out = TimeDistributed(Bidirectional(LSTM(cells,return_sequences=False)))(out)
2 – 如果你选择4214特征:
#移除最后一个维度,它是1out = Reshape((22312,4214)) #不需要关心它们是否是序列,不需要TimeDistributed,也不需要Bidirectional。 out = LSTM(cells,return_sequences=True)(out) #这里的return_sequences=True与22312步长相关 #但你需要回到每步一个特征:out = Reshape((22312,1))(out)
现在4214维度已经折叠,一切都变成了形状为(batchSize, 22312, 1)
的序列。由于我们不再是4D,而是3D,我们可以放弃TimeDistributed包装器:
out = LSTM(cells,return_sequences=True)(out)
最后,使用一个lambda层来丢弃这个序列的第一个元素(只是为了匹配你想要的输出):
out = Lambda(lambda x: x[:,1:,:], output_shape=(22311,1))(out)out = Reshape((22311,))(out)model = Model(inp,out)