我正在制作一个简单的二元分类模型,该模型接受30个时间戳,每个时间戳有5个特征,并应返回某一类别的概率。
我遇到了模型损失在训练轮次中不下降的问题。我检查了模型的摘要和输出,发现模型没有产生单一的输出数值(类别的概率),而是产生了一个包含30个概率的数组,这可能导致模型无法学习。
模型代码如下:
print(train['inputs'].shape) #(3511,30,5)print(train['labels'].shape) #(3511,1)lstm_model = tf.keras.models.Sequential([ tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(1, activation='sigmoid') ]) lstm_model.compile( loss="binary_crossentropy", optimizer=tf.optimizers.Adam(learning_rate=0.0001), metrics=["accuracy"]) history = lstm_model.fit(x=train['inputs'], y=train['labels'], epochs=1, validation_data=(val['inputs'], val['labels']), )
增加层数似乎并没有影响这个问题(我尝试增加层数是为了让模型过拟合)。
模型的摘要如下:
Model: "sequential_108"_________________________________________________________________Layer (type) Output Shape Param # =================================================================dense_297 (Dense) (1, 30, 256) 1536 _________________________________________________________________activation_128 (Activation) (1, 30, 256) 0 _________________________________________________________________dense_298 (Dense) (1, 30, 256) 65792 _________________________________________________________________activation_129 (Activation) (1, 30, 256) 0 _________________________________________________________________dense_299 (Dense) (1, 30, 256) 65792 _________________________________________________________________activation_130 (Activation) (1, 30, 256) 0 _________________________________________________________________dense_300 (Dense) (1, 30, 256) 65792 _________________________________________________________________activation_131 (Activation) (1, 30, 256) 0 _________________________________________________________________dense_301 (Dense) (1, 30, 1) 257 =================================================================Total params: 199,169Trainable params: 199,169Non-trainable params: 0
如您所见,输出层返回了一个形状为(30,1)的数组,使用模型进行实际预测时也出现了相同的情况。
我还尝试将标签重塑为(3511)和(3511,1,1),但这似乎并没有解决问题。
是什么导致了这种行为?
回答:
我认为您想使用LSTM层,因为您处理的是三维时间戳输入。
您只需在最后一个LSTM层中将return_sequences
设置为False
,例如:
lstm_model = tf.keras.models.Sequential([ tf.keras.layers.LSTM(5, return_sequences=True, dropout=0.2, recurrent_dropout=0.2), tf.keras.layers.LSTM(10, return_sequences=True, activation='relu'), tf.keras.layers.LSTM(64, return_sequences=False, activation='relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(256), tf.keras.layers.Activation('relu'), tf.keras.layers.Dense(1, activation='sigmoid') ])
关于LSTM层中形状如何工作的一些解释可以在以下问题中找到: