You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Keras的Python神经网络模型无法学习问题求助

问题诊断与解决方案

首先,你的模型核心问题是损失函数与输出激活函数的搭配错误,这是导致初始无学习效果、归一化后波动异常的主要原因,而非数据集无法支持学习——毕竟1NN能达到80%准确率,说明数据本身是有可区分的模式的。

1. 为什么初始模型完全不学习?

你当前的设置是:

model.add(Dense(10, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
  • binary_crossentropy是用于二分类任务多标签分类任务(每个样本可属于多个类别)的损失函数;
  • 而你的任务是单标签多分类(每个样本仅属于10类中的一类,Y是独热编码),这种场景下应该使用categorical_crossentropy损失,搭配输出层的softmax激活函数——softmax会让输出的10维值总和为1,对应每个类别的概率,和独热编码的标签匹配度更高。

用错损失函数会让模型的优化方向完全偏离任务目标,自然无法有效学习。

2. 归一化后的波动代表有效学习吗?

从你给出的前10个epoch日志来看,loss和准确率来回波动、没有稳定下降/上升的趋势,这不是有效学习的表现,更像是模型在错误的优化目标下随机试探,无法找到正确的收敛方向。

3. 具体修改建议

(1)修正核心配置

把模型的输出层和损失函数改成如下:

model = Sequential()
model.add(Dense(4320, input_dim=4320, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(10, activation='softmax'))  # 替换sigmoid为softmax
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])  # 替换损失函数

(2)优化模型结构,避免过拟合与冗余

你的输入层直接接4320个神经元的Dense层,参数数量高达4320*4320 + 4320 ≈ 1890万,对于仅1000个样本的数据集来说,极易过拟合,而且计算效率极低:

  • 建议大幅减少第一层的神经元数量,比如改成256、512,既降低参数规模,又能提取有效特征;
  • 可以加入Dropout层抑制过拟合:
model = Sequential()
model.add(Dense(512, input_dim=4320, activation='relu'))
model.add(Dropout(0.3))  # 随机丢弃30%的神经元
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

(3)调整训练参数

  • 增大batch_size:当前batch_size=10,对于1000样本来说,每次更新的梯度噪声较大,改成32或64会让梯度更新更稳定;
  • 调整学习率:如果修改后模型收敛还是不稳定,可以尝试调小Adam的学习率,比如:
from tensorflow.keras.optimizers import Adam
model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.0001), metrics=['accuracy'])
  • 加入验证集:训练时添加validation_split=0.1,观察模型在验证集上的表现,判断是否过拟合:
model.fit(X, Y, epochs=150, batch_size=32, validation_split=0.1)

总结

你的数据集是具备学习价值的,问题完全出在模型的核心配置错误上。按照上述修改后,模型应该能开始稳定收敛,准确率也会逐步提升。

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

火山引擎 最新活动