【发布时间】:2021-01-07 18:32:30
【问题描述】:
我需要使用 Keras 开发一个神经网络,以使用遗传数据预测疾病。众所周知,即使使用逻辑回归也可以预测这种疾病(但是在这种情况下,预测质量非常差)。值得一提的是,我的数据是不平衡的,所以我在后面介绍了类权重。
我决定从最简单的预测方法开始 - 使用类似于逻辑回归的网络 - 一个带有一个神经元的隐藏层,并取得了一个糟糕的但至少有一些结果 - 0.12-0.14 F1 分数。然后我尝试使用 2 个隐藏层和 1 个输出层,在第一个隐藏层中具有不同数量的神经元 - 从 1 到 8。 事实证明,在某些情况下,它会学到一些东西,在某些情况下,它会为每个样本预测相同的输出。我展示了各个时期的准确性和损失函数,这就是我得到的:
Network loss function by epoch。很明显,对于训练数据,损失函数的值大致相同。
Network accuracy by epoch。很明显准确率没有提高,而是从0到1波动
我搜索了类似的问题,建议如下:
- 制作更多神经元 - 我只需要让它与第一层中的 1 个、2 个或更多神经元一起工作,因此我无法将神经元添加到这一层。我将第二个隐藏层中的神经元数量增加到了 20 个,但它随后停止预测任何第一层配置中任何数量的神经元。
- 制作更多层 - 我尝试再添加一层,但仍然遇到同样的问题
- 引入 dropout 并增加它 - 如果它可以只使用一层和一个神经元进行学习,我们所说的 dropout 是什么
- 降低学习率 - 将其从默认的 10^(-3) 降低到 10^(-4)
- 减少批量大小 - 将小批量中的 500 个样本变为 1 个(随机梯度下降)
- 更多 epoch - 500'000 个样本数据集上的 20 到 50 个 epoch 还不够吗?
这是模型:
def run_nn_class_weights(data, labels, model):
n_iter = 20
predicted = None
true = None
print('Splitting the data')
x_train, x_valid, y_train, y_valid = train_test_split(data, labels, test_size = 0.05)
#model = create_model()
early_stopping_monitor=EarlyStopping(patience=240)
class_weights = class_weight.compute_class_weight('balanced',
np.unique(labels),
labels)
class_weights = dict(enumerate(class_weights))
hist = model.fit(x_train, y_train, validation_data=[x_valid, y_valid], class_weight=class_weights,
epochs=n_iter, batch_size=500, shuffle=True, callbacks=[early_stopping_monitor],verbose=1)
proba = model.predict(data)
predicted = proba.flatten()
true = labels
return(model, proba, hist)
def old_model_n_pred(n_neurons_1st = 1):
model = Sequential()
model.add(Dense(n_neurons_1st, activation='relu', input_shape=(7516,), kernel_initializer='glorot_normal'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
#model.add(Flatten())
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
【问题讨论】:
-
你的数据集标准化了吗?
-
您的标签有问题。测试数据只有一类吗?你的准确率从 0 跳到 100,然后每个 epoch 又回到 0
标签: python tensorflow machine-learning keras neural-network