神经网络验证准确率有时不变

我在使用神经网络进行二元分类问题时遇到了麻烦。有时运行我的模型时,验证准确率完全没有变化,而有时它又能正常工作。我的数据集有1200个样本,包含28个特征,并且存在类别不平衡(200个A类,1000个B类)。所有特征都已归一化,值在0到1之间。如前所述,这个问题并不总是发生,但我希望了解原因并解决它。

我尝试更改了优化函数和激活函数,但没有效果。我还注意到,当我增加网络中的神经元数量时,这个问题发生的频率会降低,但问题并未完全解决。我也尝试增加了训练轮数,但问题有时仍然会发生。

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

回答:

鉴于您报告的类别不平衡情况,您的模型似乎没有学到任何东西(报告的准确率似乎只是预测了多数类)。尽管如此,您的代码存在一些问题;首先:

  1. 将输出层以外的所有激活函数替换为activation = 'relu'
  2. 在最后一层添加sigmoid激活函数activation='sigmoid';目前,您的网络是回归网络(最后一层默认线性输出),而不是分类网络。
  3. 从所有层中删除kernel_initializer='normal'参数,即将其留给默认kernel_initializer='glorot_uniform',这是已知性能(远)更好的选择。

另外,不清楚您为什么选择28个单位的输入密集层 – 这里的单位数量与输入维度无关;请参阅Keras Sequential模型输入层

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'])

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

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注