#python #tensorflow #machine-learning #keras #neural-network
#python #тензорный поток #машинное обучение #keras #нейронная сеть
Вопрос:
Мне нужно разработать нейронную сеть с Keras для прогнозирования заболевания с использованием генетических данных. Известно, что предсказание этого заболевания возможно даже с помощью логистической регрессии (однако прогнозы в этом случае очень низкого качества). Стоит упомянуть, что мои данные несбалансированы, поэтому я ввел веса классов позже.
Я решил начать с самого простого способа его прогнозирования — с сети, аналогичной логистической регрессии — один скрытый слой с одним нейроном и добился плохого, но хоть какого-то результата — 0,12-0,14 балла F1. Затем я попробовал использовать 2 скрытых и 1 выходной слои с разным количеством нейронов в первом скрытом слое — от 1 до 8. Оказывается, что в некоторых случаях он что-то изучает, а в некоторых прогнозирует один и тот же результат для каждого образца. Я отобразил функцию точности и потерь за эпохи, и это то, что я получаю:
Функция потерь сети по эпохам. Понятно, что функция потерь имеет примерно одинаковое значение для обучающих данных.
Точность сети по эпохам. Понятно, что точность не улучшается, а колеблется от 0 до 1
Я искал похожие вопросы, и предложения были следующими:
- Сделайте больше нейронов — мне просто нужно заставить его работать с 1, 2 или более нейронами в первом слое, поэтому я не могу добавить нейроны к этому. Я увеличил количество нейронов во втором скрытом слое до 20, но затем он перестал предсказывать что-либо с любым количеством нейронов в конфигурации первого слоя.
- Создайте больше слоев — я попытался добавить еще один слой, но все та же проблема
- Чтобы ввести отсев и увеличить его — о каком отсеве мы говорим, если он может учиться только с одним слоем и одним нейроном в нем
- Уменьшить скорость обучения — уменьшил ее с 10 ^ (-3) по умолчанию до 10 ^ (-4)
- Уменьшите размер пакета — измените его с 500 выборок в мини-пакете до 1 (стохастический градиентный спуск)
- Больше эпох — разве недостаточно от 20 до 50 эпох для выборки из 500 000 наборов данных?
Вот модель:
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
Комментарии:
1. Ваш набор данных был нормализован?
2. С вашими ярлыками что-то не так. Являются ли тестовые данные только одним классом? Ваша точность увеличивается с 0 до 100 и обратно до 0 каждую эпоху
Ответ №1:
Это небольшая сеть, которая должна быть способна сходиться к чему-то, что не является atractor (застревание на одном значении).
Я предлагаю взглянуть на веса всех нейронов с активацией ReLU. RELU хороши тем, что позволяют выполнять быстрые вычисления; но половина relu имеет производную от нуля, что не помогает при градиентном спуске. Это может быть ваш случай.
В предположении, что в вашем случае врагом будет первый нейрон.
Чтобы преодолеть эту проблему, я бы попытался упорядочить входные данные (чтобы все выборки были сосредоточены вокруг 0,5 и масштабировались по стандартному отклонению). Если вы сделаете это с ReLU, вы заставите его игнорировать все, что находится между [-inf, sd] .
если это не устраняет часть проблемы, переключитесь на другую функцию активации на первом уровне. Сигмоид будет работать очень хорошо, и это не слишком дорого для одного нейрона.
Кроме того, внимательно посмотрите на свое распределение входных данных. На самом деле ваша сеть выполняет сигмоидальную классификацию, затем использует от 4 до 8 нейронов для «масштабирования» / исправления важных частей функции, которые не учитывало первое преобразование.