Skip to main content
 首页 » 编程设计

python之神经网络验证准确性有时不会改变

2025年05月04日17bonelee

我正在使用神经网络解决二元分类问题,但遇到了一些麻烦。有时在运行我的模型时,我的验证准确性根本没有改变,有时它工作得很好。我的数据集有 1200 个样本和 28 个特征,我有一个类不平衡(200 类 a 1000 类 b)。我所有的特征都被归一化并且在 1 和 0 之间。正如我之前所说,这个问题并不总是发生,但我想知道原因并修复它

我曾尝试更改优化函数和激活函数,但这对我没有好处。我还注意到,当我增加网络中的神经元数量时,这个问题发生的频率会降低,但并没有解决。我也尝试增加 epoch 的数量,但问题有时会不断发生

model = Sequential() 
model.add(Dense(28, input_dim=28,kernel_initializer='normal', activation='sigmoid')) 
model.add(Dense(200, kernel_initializer='normal',activation='sigmoid'))  
model.add(Dropout(0.5)) 
model.add(Dense(300, kernel_initializer='normal',activation='sigmoid'))  
model.add(Dropout(0.5)) 
model.add(Dense(300, kernel_initializer='normal',activation='sigmoid'))  
model.add(Dropout(0.5)) 
model.add(Dense(150, kernel_initializer='normal',activation='sigmoid'))  
model.add(Dropout(0.4)) 
model.add(Dense(1,kernel_initializer='normal')) 
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy']) 
history = model.fit(X_train, y_train, 
                    epochs=34, 
                    batch_size=32, 
                    validation_data=(X_val, y_val), 
                    verbose=1) 

这是我有时从训练模型中得到的结果

Epoch 1/34 
788/788 [==============================] - 1s 2ms/step - loss: 1.5705 - acc: 0.6865 - val_loss: 0.6346 - val_acc: 0.7783 
Epoch 2/34 
788/788 [==============================] - 0s 211us/step - loss: 1.0262 - acc: 0.6231 - val_loss: 0.5310 - val_acc: 0.7783 
Epoch 3/34 
788/788 [==============================] - 0s 194us/step - loss: 1.7575 - acc: 0.7221 - val_loss: 0.5431 - val_acc: 0.7783 
Epoch 4/34 
788/788 [==============================] - 0s 218us/step - loss: 0.9113 - acc: 0.5774 - val_loss: 0.5685 - val_acc: 0.7783 
Epoch 5/34 
788/788 [==============================] - 0s 199us/step - loss: 1.0987 - acc: 0.6688 - val_loss: 0.6435 - val_acc: 0.7783 
Epoch 6/34 
788/788 [==============================] - 0s 201us/step - loss: 0.9777 - acc: 0.5343 - val_loss: 0.5643 - val_acc: 0.7783 
Epoch 7/34 
788/788 [==============================] - 0s 204us/step - loss: 1.0603 - acc: 0.5914 - val_loss: 0.6266 - val_acc: 0.7783 
Epoch 8/34 
788/788 [==============================] - 0s 197us/step - loss: 0.7580 - acc: 0.5939 - val_loss: 0.6615 - val_acc: 0.7783 
Epoch 9/34 
788/788 [==============================] - 0s 206us/step - loss: 0.8950 - acc: 0.6650 - val_loss: 0.5291 - val_acc: 0.7783 
Epoch 10/34 
788/788 [==============================] - 0s 230us/step - loss: 0.8114 - acc: 0.6701 - val_loss: 0.5428 - val_acc: 0.7783 
Epoch 11/34 
788/788 [==============================] - 0s 281us/step - loss: 0.7235 - acc: 0.6624 - val_loss: 0.5275 - val_acc: 0.7783 
Epoch 12/34 
788/788 [==============================] - 0s 264us/step - loss: 0.7237 - acc: 0.6485 - val_loss: 0.5473 - val_acc: 0.7783 
Epoch 13/34 
788/788 [==============================] - 0s 213us/step - loss: 0.6902 - acc: 0.7056 - val_loss: 0.5265 - val_acc: 0.7783 
Epoch 14/34 
788/788 [==============================] - 0s 217us/step - loss: 0.6726 - acc: 0.7145 - val_loss: 0.5285 - val_acc: 0.7783 
Epoch 15/34 
788/788 [==============================] - 0s 197us/step - loss: 0.6656 - acc: 0.7132 - val_loss: 0.5354 - val_acc: 0.7783 
Epoch 16/34 
788/788 [==============================] - 0s 216us/step - loss: 0.6083 - acc: 0.7259 - val_loss: 0.5262 - val_acc: 0.7783 
Epoch 17/34 
788/788 [==============================] - 0s 218us/step - loss: 0.6188 - acc: 0.7310 - val_loss: 0.5271 - val_acc: 0.7783 
Epoch 18/34 
788/788 [==============================] - 0s 210us/step - loss: 0.6642 - acc: 0.6142 - val_loss: 0.5676 - val_acc: 0.7783 
Epoch 19/34 
788/788 [==============================] - 0s 200us/step - loss: 0.6017 - acc: 0.7221 - val_loss: 0.5256 - val_acc: 0.7783 
Epoch 20/34 
788/788 [==============================] - 0s 209us/step - loss: 0.6188 - acc: 0.7157 - val_loss: 0.8090 - val_acc: 0.2217 
Epoch 21/34 
788/788 [==============================] - 0s 201us/step - loss: 1.1724 - acc: 0.4061 - val_loss: 0.5448 - val_acc: 0.7783 
Epoch 22/34 
788/788 [==============================] - 0s 205us/step - loss: 0.5724 - acc: 0.7424 - val_loss: 0.5293 - val_acc: 0.7783 
Epoch 23/34 
788/788 [==============================] - 0s 234us/step - loss: 0.5829 - acc: 0.7538 - val_loss: 0.5274 - val_acc: 0.7783 
Epoch 24/34 
788/788 [==============================] - 0s 209us/step - loss: 0.5815 - acc: 0.7525 - val_loss: 0.5274 - val_acc: 0.7783 
Epoch 25/34 
788/788 [==============================] - 0s 220us/step - loss: 0.5688 - acc: 0.7576 - val_loss: 0.5274 - val_acc: 0.7783 
Epoch 26/34 
788/788 [==============================] - 0s 210us/step - loss: 0.5715 - acc: 0.7525 - val_loss: 0.5273 - val_acc: 0.7783 
Epoch 27/34 
788/788 [==============================] - 0s 206us/step - loss: 0.5584 - acc: 0.7576 - val_loss: 0.5274 - val_acc: 0.7783 
Epoch 28/34 
788/788 [==============================] - 0s 215us/step - loss: 0.5728 - acc: 0.7563 - val_loss: 0.5272 - val_acc: 0.7783 
Epoch 29/34 
788/788 [==============================] - 0s 281us/step - loss: 0.5735 - acc: 0.7576 - val_loss: 0.5275 - val_acc: 0.7783 
Epoch 30/34 
788/788 [==============================] - 0s 272us/step - loss: 0.5773 - acc: 0.7614 - val_loss: 0.5272 - val_acc: 0.7783 
Epoch 31/34 
788/788 [==============================] - 0s 225us/step - loss: 0.5847 - acc: 0.7525 - val_loss: 0.5272 - val_acc: 0.7783 
Epoch 32/34 
788/788 [==============================] - 0s 239us/step - loss: 0.5739 - acc: 0.7551 - val_loss: 0.5272 - val_acc: 0.7783 
Epoch 33/34 
788/788 [==============================] - 0s 216us/step - loss: 0.5632 - acc: 0.7525 - val_loss: 0.5269 - val_acc: 0.7783 
Epoch 34/34 
788/788 [==============================] - 0s 240us/step - loss: 0.5672 - acc: 0.7576 - val_loss: 0.5267 - val_acc: 0.7783 

请您参考如下方法:

鉴于您报告的类别不平衡,您的模型似乎没有学到任何东西(报告的准确性似乎与仅将所有内容预测为多数类别一致)。但是,您的代码存在问题;对于初学者:

  1. 将除输出层之外的所有激活函数替换为activation = 'relu'。
  2. 在最后一层 activation='sigmoid' 添加一个 sigmoid 激活函数;事实上,你的是一个回归网络(最后一层的默认线性输出)并且不是分类网络。
  3. 从所有层中删除所有 kernel_initializer='normal' 参数,即将其留给 default一个 kernel_initializer='glorot_uniform',众所周知,它可以实现(好得多)更好的性能。

另外,不清楚为什么要使用 28 个单元的输入密集层 - 不。这里的单位与输入维度无关;请参阅Keras Sequential model input layer .

默认情况下,Dropout 不应进入网络 - 先尝试不使用它,然后在必要时添加。

总而言之,这是您的模型应该如何寻找初学者:

model = Sequential() 
model.add(Dense(200, input_dim=28, activation='relu'))  
# model.add(Dropout(0.5)) 
model.add(Dense(300, activation='relu'))  
# model.add(Dropout(0.5)) 
model.add(Dense(300, activation='relu'))  
# model.add(Dropout(0.5)) 
model.add(Dense(150, activation='relu'))  
# model.add(Dropout(0.4)) 
model.add(Dense(1, activation='sigmoid')) 
 
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy']) 

并且,如前所述,根据您的实验结果取消注释/调整丢失层。