如何将MLP的数据调整为LSTM(预期ndim=3,发现ndim=2错误)
How to adjust a data for MLP to LSTM (expected ndim=3, found ndim=2 Error)
我有数据表明在多层感知器架构上工作是这样的
X_train_feature.shape
(52594, 16)
X_train_feature[0]
array([1.18867208e-03, 1.00000000e+00, 8.90000000e+01, 8.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00])
y_train
(52594, 2)
y_train[0].toarray()
array([[0., 1.]])
通过第一个维度:样本数
第二个:X_train 是特征数量,y_train 是单热编码器。
并且我想在 LSTM/Bi-LSTM 上使用相同的数据,所以我从互联网上复制代码并将输入值更改为与 MLP
相同的值
def define_model():
model = Sequential()
model.add(LSTM(20, input_shape=X_train_feature[0].shape, return_sequences=True))
model.add(TimeDistributed(Dense(1, activation='sigmoid')))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) # compile
print('Total params: ', model.count_params())
return model
但是当我尝试创建模型时,关于输入形状的错误将被追加
model = define_model()
ValueError: Input 0 is incompatible with layer lstm_30: expected ndim=3, found ndim=2
我需要调整我的数据以应用于 LSTM 还是需要更改架构配置?非常感谢。
LSTM(与感知器不同)不是前馈网络。它需要一个历史来预测下一个点。因此,LSTM 的适当输入张量应该具有 (timesteps, num_features)
的形状,这意味着每个样本都是 timesteps
观察的序列,使得细胞状态在序列的第一次观察中启动并经过整个序列。
因此,输入张量的形状应为 (num_sequences, seq_length, num_features)
,其中:
num_sequences
:样本数量,即你有多少序列来训练模型?
seq_length
:这些序列有多长。对于可变长度序列,您可以提供 None
.
num_features
: 在给定的序列中有多少特征有一个观察值?
LSTM 层的输入是一个 3d 张量,形状为 (data_length,时间步长,n_features)
要做到这一点,您首先必须使用类似以下内容转换数据:
def slice_data(self, data, n_steps, n_ahead=1):
X_data = data.drop(['y'], axis=1)
y_data = data['y']
X = []
y = []
for i in range(len(X_data)):
end_point = i + n_steps
if end_point + n_ahead > len(X_data)-1:
break
slice_x, slice_y = X_data[i:end_point], y_data.loc[end_point]
X.append(slice_x)
y.append(slice_y)
X, y = np.array(X), np.array(y)
self.n_features = X.shape[2]
X = X.reshape((X.shape[0], X.shape[1], X.shape[2]))
return X, y
或者您可以使用我自己制作的工具:EasyLSTM
EasyLSTM 只需一行代码就可以将您的输入数组整形为 LSTM 友好的数组
我有数据表明在多层感知器架构上工作是这样的
X_train_feature.shape
(52594, 16)
X_train_feature[0]
array([1.18867208e-03, 1.00000000e+00, 8.90000000e+01, 8.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00])
y_train
(52594, 2)
y_train[0].toarray()
array([[0., 1.]])
通过第一个维度:样本数 第二个:X_train 是特征数量,y_train 是单热编码器。
并且我想在 LSTM/Bi-LSTM 上使用相同的数据,所以我从互联网上复制代码并将输入值更改为与 MLP
相同的值def define_model():
model = Sequential()
model.add(LSTM(20, input_shape=X_train_feature[0].shape, return_sequences=True))
model.add(TimeDistributed(Dense(1, activation='sigmoid')))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) # compile
print('Total params: ', model.count_params())
return model
但是当我尝试创建模型时,关于输入形状的错误将被追加
model = define_model()
ValueError: Input 0 is incompatible with layer lstm_30: expected ndim=3, found ndim=2
我需要调整我的数据以应用于 LSTM 还是需要更改架构配置?非常感谢。
LSTM(与感知器不同)不是前馈网络。它需要一个历史来预测下一个点。因此,LSTM 的适当输入张量应该具有 (timesteps, num_features)
的形状,这意味着每个样本都是 timesteps
观察的序列,使得细胞状态在序列的第一次观察中启动并经过整个序列。
因此,输入张量的形状应为 (num_sequences, seq_length, num_features)
,其中:
num_sequences
:样本数量,即你有多少序列来训练模型?seq_length
:这些序列有多长。对于可变长度序列,您可以提供None
.num_features
: 在给定的序列中有多少特征有一个观察值?
LSTM 层的输入是一个 3d 张量,形状为 (data_length,时间步长,n_features)
要做到这一点,您首先必须使用类似以下内容转换数据:
def slice_data(self, data, n_steps, n_ahead=1):
X_data = data.drop(['y'], axis=1)
y_data = data['y']
X = []
y = []
for i in range(len(X_data)):
end_point = i + n_steps
if end_point + n_ahead > len(X_data)-1:
break
slice_x, slice_y = X_data[i:end_point], y_data.loc[end_point]
X.append(slice_x)
y.append(slice_y)
X, y = np.array(X), np.array(y)
self.n_features = X.shape[2]
X = X.reshape((X.shape[0], X.shape[1], X.shape[2]))
return X, y
或者您可以使用我自己制作的工具:EasyLSTM EasyLSTM 只需一行代码就可以将您的输入数组整形为 LSTM 友好的数组