Keras LSTM:检查模型输入维度时出现错误。

3

我是keras的新用户,正在尝试实现一个LSTM模型。为了测试,我声明了以下模型,但由于输入维度的差异而失败了。虽然我在这个网站上找到了类似的问题,但我自己找不到错误。

ValueError: 
Error when checking model input: 
expected lstm_input_4 to have 3 dimensions, but got array with shape (300, 100)

我的环境

  • Python 3.5.2
  • Keras 1.2.0(Theano)

代码

from keras.layers import Input, Dense
from keras.models import Sequential
from keras.layers import LSTM
from keras.optimizers import RMSprop, Adadelta
from keras.layers.wrappers import TimeDistributed
import numpy as np

in_size = 100
out_size = 10
nb_hidden = 8

model = Sequential()
model.add(LSTM(nb_hidden, 
               name='lstm',
               activation='tanh',
               return_sequences=True,
               input_shape=(None, in_size)))
model.add(TimeDistributed(Dense(out_size, activation='softmax')))

adadelta = Adadelta(clipnorm=1.)
model.compile(optimizer=adadelta,
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# create dummy data
data_size = 300
train = np.zeros((data_size, in_size,), dtype=np.float32)
labels = np.zeros((data_size, out_size,), dtype=np.float32)
model.fit(train, labels)

编辑1(在 Marcin Możejko 的评论之后仍然无法工作)

感谢 Marcin Możejko。但是我遇到了与下面类似的错误。我更新了虚拟数据来检查,但这段代码有什么问题呢?

ValueError:检查模型目标时出错:预期 timedistributed_36 具有 3 维,但得到了形状为 (208, 1) 的数组

def create_dataset(X, Y, loop_back=1):
    dataX, dataY = [], []
    for i in range(len(X) - loop_back-1):
        a = X[i:(i+loop_back), :]
        dataX.append(a)
        dataY.append(Y[i+loop_back, :])
    return np.array(dataX), np.array(dataY)

data_size = 300
dataset = np.zeros((data_size, feature_size), dtype=np.float32)
dataset_labels = np.zeros((data_size, 1), dtype=np.float32)

train_size = int(data_size * 0.7)
trainX = dataset[0:train_size, :]
trainY = dataset_labels[0:train_size, :]
testX = dataset[train_size:, :]
testY = dataset_labels[train_size:, 0]
trainX, trainY = create_dataset(trainX, trainY)
print(trainX.shape, trainY.shape) # (208, 1, 1) (208, 1)

# in_size = 100
feature_size = 1
out_size = 1
nb_hidden = 8

model = Sequential()
model.add(LSTM(nb_hidden, 
               name='lstm',
               activation='tanh',
               return_sequences=True,
               input_shape=(1, feature_size)))

model.add(TimeDistributed(Dense(out_size, activation='softmax')))
adadelta = Adadelta(clipnorm=1.)
model.compile(optimizer=adadelta,
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(trainX, trainY, nb_epoch=10, batch_size=1)

请提供导入。 - j0e1in
@j0e1in 抱歉,我添加了完整的导入。 - jef
我完全误解了LSTM。输入必须是[样本数,时间步长,特征数]。我会在重新实现后上传我的代码。 - jef
哈 - 我刚刚给出了相同的答案 :) - Marcin Możejko
1个回答

3
这是一个关于KerasLSTM的经典问题。LSTM的输入形状应该是二维的,形式是(序列长度, 特征数量)。第三个额外的维度来自样本维度,所以传给模型的数据表的形状应该是(样本数量, 序列长度, 特征数量)。这就是你遇到的问题所在。记住,一个一维的序列应当被表示为一个形状为(序列长度, 1)的二维数组。这应该是你的LSTM的输入形状。
model.add(LSTM(nb_hidden, 
           name='lstm',
           activation='tanh',
           return_sequences=True,
           input_shape=(in_size, 1)))

请务必记住将您的输入数据进行重构以适合相应的格式。


谢谢您的评论。但我遇到了类似下面的错误。我已经更新了我的代码。您能再次检查我的代码吗? - jef
这里是:print(trainX.shape, trainY.shape) # (208, 1, 1) (208, 1)。我猜测seq_length==1且num_of_features==1。 - jef
你的代码有问题。为什么要在长度为1的序列上使用LSTM? - Marcin Możejko
为了简单起见,我的实际数据集假设是人与机器之间的对话数据,实际序列长度比1更长。但我认为seq_length == 1不是这个错误的原因。 - jef
你可以用两种方法来处理这个错误。第一种是通过 Y.reshape((Y.shape[0], 1, Y.shape[1])) 来重新塑形 Y,第二种是简单地设置 return_sequences=False 并且只使用 Dense 而不需要 TimeDistributed 包装器。 - Marcin Możejko
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接