基于GRU的钢琴键多标签分类模型无法正常学习的技术求助
GRU钢琴键触发概率预测模型训练异常排查
问题背景
搭建了GRU网络,用前600个时间步的钢琴键数据预测单一时间步88个钢琴键的触发概率,输入形状为(600,88),目标标签形状为(88,)。但训练过程中模型完全未学习,准确率始终维持在极低水平。
模型代码
import numpy as np import midi_processer from keras import models from keras import layers x_train, x_test = np.load("samples.npy", mmap_mode='r'), np.load("test_samples.npy", mmap_mode='r') y_train, y_test = np.load("labels.npy", mmap_mode='r'), np.load("test_labels.npy", mmap_mode='r') def build_model(): model = models.Sequential() model.add(layers.Input(shape=(600,88,))) model.add(layers.GRU(512,activation='tanh',recurrent_activation='hard_sigmoid')) model.add(layers.RepeatVector(600)) model.add(layers.GRU(512,activation='tanh', recurrent_activation='hard_sigmoid')) model.add(layers.Dense(88, activation = 'sigmoid')) return model x_partial, x_val = x_train[:13000], x_train[13000:] y_partial, y_val = y_train[:13000], y_train[13000:] model = build_model() model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy']) history = model.fit(x_partial, y_partial, batch_size = 50, epochs = , validation_data= (x_val,y_val))
训练日志
Epoch 1/15 260/260 [==============================] - 998s 4s/step - loss: -0.1851 - accuracy: 0.0298 - val_loss: -8.8735 - val_accuracy: 0.0310 Epoch 2/15 260/260 [==============================] - 827s 3s/step - loss: -33.6520 - accuracy: 0.0382 - val_loss: -56.0122 - val_accuracy: 0.0310 Epoch 3/15 260/260 [==============================] - 844s 3s/step - loss: -78.6130 - accuracy: 0.0382 - val_loss: -98.2798 - val_accuracy: 0.0310 Epoch 4/15 260/260 [==============================] - 906s 3s/step - loss: -121.0963 - accuracy: 0.0382 - val_loss: -139.3440 - val_accuracy: 0.0310 Epoch 5/15
问题诊断与修复方案
1. 模型结构冗余错误
当前模型采用了编码器-解码器架构(GRU+RepeatVector+GRU),但你的任务是单步序列预测,解码器完全多余。编码器输出的隐藏状态已经包含序列全局信息,直接连接Dense层输出即可:
def build_model(): model = models.Sequential() model.add(layers.Input(shape=(600,88,))) # 仅保留编码器GRU,输出单个隐藏状态向量 model.add(layers.GRU(512, activation='tanh', recurrent_activation='hard_sigmoid')) # 直接映射到88个钢琴键的触发概率 model.add(layers.Dense(88, activation='sigmoid')) return model
2. 损失值异常(负数)排查
binary_crossentropy损失值应为正数,日志中出现负数大概率是标签数据问题:
- 检查
y_train/y_val是否为0-1二值数据(触发为1,未触发为0) - 若标签为整数或非0-1值,会导致损失计算逻辑混乱,反向传播失效
3. 准确率指标不合理
默认accuracy是样本级准确率(必须88个键全预测正确才算对),在钢琴预测任务中几乎不可能实现,因此准确率始终极低。应改用多标签任务适配的指标:
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy']) # 每个键单独计算准确率后取平均
4. 其他潜在问题
- 确认
x_train与y_train的对应关系:每个输入序列是否准确对应下一个时间步的标签 - 检查数据是否存在异常值:输入序列是否为合法的0-1二值数据
- 调整学习率:Adam默认0.001,若模型不收敛,可尝试降至0.0001
内容的提问来源于stack exchange,提问作者Ilan Kayesar
相关产品推荐
相关产品推荐

