You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

孪生RNN网络时间序列分类准确率始终50%问题求助

问题根源分析与解决方案

核心问题:Embedding网络的输出设计错误

你的孪生网络中,Embedding网络最后用了Dense(2, activation='softmax'),这是分类任务的输出头,而非度量学习所需的特征嵌入。Softmax会把输出压缩为和为1的概率分布,导致两个样本的嵌入失去特征空间的区分度,无论输入如何,计算出的欧氏距离都无法有效反映样本相似性,最终模型只能随机猜测,准确率卡在50%。

修正步骤

1. 重构Embedding网络

移除最后的softmax分类层,保留高维特征向量作为嵌入输出:

def euclidean_distance(vects):
    x, y = vects
    sum_square = tf.math.reduce_sum(tf.math.square(x - y), axis=1, keepdims=True)
    return tf.math.sqrt(tf.math.maximum(sum_square, tf.keras.backend.epsilon()))

input = layers.Input((1000, 4))

x = SimpleRNN(100, input_shape=(1000,4))(input)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
# 移除softmax层,直接输出128维特征作为嵌入
embedding_network = keras.Model(input, x)

input_1 = layers.Input((1000, 4))
input_2 = layers.Input((1000, 4))

tower_1 = embedding_network(input_1)
tower_2 = embedding_network(input_2)

merge_layer = layers.Lambda(euclidean_distance)([tower_1, tower_2])
# 移除不必要的BatchNormalization和sigmoid层,contrastive loss直接基于距离计算
siamese = keras.Model(inputs=[input_1, input_2], outputs=merge_layer)

2. 正确实现Contrastive Loss

确保损失函数逻辑匹配孪生网络的输出(欧氏距离):

def contrastive_loss(y_true, y_pred):
    margin = 1.0
    square_pred = tf.math.square(y_pred)
    margin_square = tf.math.square(tf.math.maximum(margin - y_pred, 0))
    return tf.math.reduce_mean(y_true * square_pred + (1 - y_true) * margin_square)

3. 数据对构造验证

  • 确保训练数据中同类样本对(y=0)和异类样本对(y=1)比例均衡
  • 样本对标签需准确:同类对标签为0(距离应较小),异类对标签为1(距离应大于margin)

4. 其他调优建议

  • 替换SimpleRNN为LSTM或GRU,更好捕捉时间序列的长期依赖
  • 调整Embedding网络的层数和神经元数量,增强特征提取能力
  • 在0.5到2.0区间内尝试不同margin值,结合验证集损失变化选择最优值

补充说明

原网络在距离后添加的BatchNormalization和sigmoid层是多余的,Contrastive Loss直接基于欧氏距离与标签的关系计算损失,无需将距离转换为概率值。

内容的提问来源于stack exchange,提问作者msskx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:50:28