如何在多维数组上训练 LSTM 模型?
How to train an LSTM model on multi-dimentional array?
我最近写了一个 LSTM 模型来预测序列:
############### BUILD MODEL ###############
''' HERE WE ARE CREATING THE LSTM MODEL '''
model = Sequential()
model.add(LSTM(128, input_shape=(X.shape[1:]), activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(128,input_shape=(X.shape[1:]), activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))
# In[8]:
'''HERE WE ARE CREATING AN OPTIMIZER AND THEN TRAINING OUR MODEL'''
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'],
)
model.fit(X, Y, batch_size=10, epochs=1)
其中 np.shape(X) = (237, 30, 3)
和 np.shape(Y) = (237, 3)
。但是在将此数据拟合到模型时它返回错误:
ValueError: Error when checking target: expected dense_1 to have shape (1,) but got array with shape (3,)
这段代码有什么问题?
您似乎对标签进行了单热编码。要么不要对它们进行单热编码(即让它们成为稀疏标签)并使用 sparse_categorical_crossentropy
作为损失函数,或者对它们进行单热编码并使用 categorical_crossentropy
作为损失函数。
附带说明:您确定这是分类任务吗?由于您将 softmax 层用作具有 10 个单元的最后一层,但您提到标签有 3 类?!
如果你的数据形状是这样的:np.shape(X) = (237, 30, 3) and np.shape(Y) = (237, 3)
试试这个网络。
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1:]), activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(32, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(3, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'],
)
model.fit(X, Y, batch_size=10, epochs=1)
由于您使用的是 Keras Sequential Api,因此您不必为第二个 LSTM 层指定输入,并且在最后一个 Dense 层,您的 "Y" 形状是 (237, 3) 所以最终 Dense层也应该给出 3。
如果输入中的“3”(特征数量)对于每个样本都是常数,您还可以为第一个 LSTM 层提供 input_shape=(None, 3)。
我最近写了一个 LSTM 模型来预测序列:
############### BUILD MODEL ###############
''' HERE WE ARE CREATING THE LSTM MODEL '''
model = Sequential()
model.add(LSTM(128, input_shape=(X.shape[1:]), activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(128,input_shape=(X.shape[1:]), activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))
# In[8]:
'''HERE WE ARE CREATING AN OPTIMIZER AND THEN TRAINING OUR MODEL'''
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'],
)
model.fit(X, Y, batch_size=10, epochs=1)
其中 np.shape(X) = (237, 30, 3)
和 np.shape(Y) = (237, 3)
。但是在将此数据拟合到模型时它返回错误:
ValueError: Error when checking target: expected dense_1 to have shape (1,) but got array with shape (3,)
这段代码有什么问题?
您似乎对标签进行了单热编码。要么不要对它们进行单热编码(即让它们成为稀疏标签)并使用 sparse_categorical_crossentropy
作为损失函数,或者对它们进行单热编码并使用 categorical_crossentropy
作为损失函数。
附带说明:您确定这是分类任务吗?由于您将 softmax 层用作具有 10 个单元的最后一层,但您提到标签有 3 类?!
如果你的数据形状是这样的:np.shape(X) = (237, 30, 3) and np.shape(Y) = (237, 3) 试试这个网络。
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1:]), activation='relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(32, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(3, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
model.compile(
loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'],
)
model.fit(X, Y, batch_size=10, epochs=1)
由于您使用的是 Keras Sequential Api,因此您不必为第二个 LSTM 层指定输入,并且在最后一个 Dense 层,您的 "Y" 形状是 (237, 3) 所以最终 Dense层也应该给出 3。
如果输入中的“3”(特征数量)对于每个样本都是常数,您还可以为第一个 LSTM 层提供 input_shape=(None, 3)。