我需要用Keras开发一个神经网络,以便使用遗传数据预测疾病。众所周知,即使通过逻辑回归也可以预测这种疾病(但是,在这种情况下,预测的质量很差)。值得一提的是,我的数据不平衡,因此我在稍后介绍了类权重。
我决定从最简单的预测方法开始-与逻辑回归类似的网络-具有一个神经元的一个隐藏层,并取得了不好的结果,但至少取得了一些结果-0.12-0.14 F1得分。然后,我尝试在第一个隐藏层中使用2个隐藏层和1个输出层,其中神经元数量不同,从1到8。 事实证明,在某些情况下,它会学到一些东西,而在某些情况下,则可以为每个样本预测相同的输出。我显示了历时的准确性和损失函数,这就是我得到的:
Network loss function by epoch。显然,对于训练数据,损失函数具有大致相同的值。
Network accuracy by epoch。显然,精度并没有提高,而是从0波动到1
我搜索了类似的问题,建议如下:
这是模型:
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 :(得分:0)
这是一个小型网络,应该可以收敛到不是引子的东西(卡在一个单一的值上)。
我建议看看具有ReLu激活的所有神经元的权重。 ReLus很棒,因为可以快速进行计算。但是一半的relu的导数为零,这对梯度下降没有帮助。这可能是您的情况。
在这种情况下,敌人可能是第一个神经元。
为了克服这个问题,我将尝试对输入进行正则化(使所有样本均以0.5为中心并按标准偏差进行缩放)。如果对ReLU执行此操作,则会使其忽略[-inf,sd]之间的任何内容。
if 不能解决问题的 part ,在第一层中具有不同的激活功能。乙状结肠会很好地工作,而且对于一个神经元来说并不太昂贵。
此外,请仔细查看您的输入分布。您的网络实际上是在做类似S形的分类,然后使用4到8个神经元来“缩放” /校正第一个转换未解释的功能的重要部分。