Я пытаюсь создать последовательную нейронную сеть, в которой на выходе будет 12 неисключительных вероятностей (вероятность A, вероятность B, вероятность C, ...). Моя сеть, кажется, запоминает наиболее распространенный вывод и всегда предсказывает это для каждого входа. Все мои выходные значения всегда равны «1» или «0», между ними нет ничего, и всегда одно и то же значение в одной и той же позиции (подробности ниже).
Я далеко не эксперт по ML, поэтому возможно, что решение очень простое.
Я пытался использовать пакеты разных размеров (от 8 до 128) и много разных функций потерь, но ни одна из них не помогла.
Как я создал модель с помощью Keras:
model = Sequential()
model.add( Dense( 150, input_dim=9600, activation='relu') )
model.add( LeakyReLU(alpha=.01) )
model.add( Dense( 50, activation='relu') )
model.add( LeakyReLU(alpha=.01) )
model.add( Dense( 12, activation='sigmoid') )
metrics_to_output=[ 'accuracy' ]
# I've tried many loss functions, not just mean_squared_error
model.compile( loss='mean_squared_error', optimizer='adam', metrics=metrics_to_output )
Это может не относиться к делу, но именно так я готовлю данные и обучаю модель. Я также пытался использовать train_on_batch
:
def generate_data_from_files( file1, file2 ):
input = numpy.load( file1, allow_pickle=True )
output = numpy.load( file2, allow_pickle=True )
# The file only has 2 values, and I generate 12 probabilities derived from those 2 values
transformed_output = output.copy()
new_shape = ( output.shape[ 0 ], 12 )
transformed_output.resize( new_shape )
for x in range( 0, len( output ) ):
#First 6 probabilities model the value of output[ x ][ 0 ]
transformed_output[ x ][ 0 ] = 1 if output[ x ][ 0 ] <= -5.0 else 0
transformed_output[ x ][ 1 ] = 1 if output[ x ][ 0 ] <= -3.0 else 0
transformed_output[ x ][ 2 ] = 1 if output[ x ][ 0 ] <= -1.0 else 0
transformed_output[ x ][ 3 ] = 1 if output[ x ][ 0 ] >= 1.0 else 0
transformed_output[ x ][ 4 ] = 1 if output[ x ][ 0 ] >= 3.0 else 0
transformed_output[ x ][ 5 ] = 1 if output[ x ][ 0 ] >= 5.0 else 0
#Second 6 probabilities model the value of output[ x ][ 1 ]
transformed_output[ x ][ 6 ] = 1 if output[ x ][ 1 ] <= -5.0 else 0
transformed_output[ x ][ 7 ] = 1 if output[ x ][ 1 ] <= -3.0 else 0
transformed_output[ x ][ 8 ] = 1 if output[ x ][ 1 ] <= -1.0 else 0
transformed_output[ x ][ 9 ] = 1 if output[ x ][ 1 ] >= 1.0 else 0
transformed_output[ x ][ 10] = 1 if output[ x ][ 1 ] >= 3.0 else 0
transformed_output[ x ][ 11] = 1 if output[ x ][ 1 ] >= 5.0 else 0
return input, transformed_output
input, output = generate_data_from_file( file1, file2 )
model.fit( x=input, y=output, batch_size=8, epochs=1 )
Я ожидаю получить 12 значений в диапазоне от 0 до 1, каждое из которых моделирует вероятность. Однако, когда я использую сеть, чтобы делать прогнозы (даже на данных обучения), я всегда получаю один и тот же идентичный вывод:
0 1 1 0 0 0 0 0 0 0 0 0
Это разумное среднее предположение, потому что 2-е и 3-е логические значения обычно верны, а все остальное обычно ложно, но я никогда не вижу каких-либо отклонений от этого прогноза, даже в обучающих данных, где ожидаемый результат является чем-то другим. Иногда я вижу 0,999999 или 0,000001 вместо 0 или 1, но даже это редко.
Мой вывод: я настраиваю модель, чтобы всегда прогнозировать средний случай. Любая обратная связь или совет будет принята с благодарностью. Заранее спасибо!
Edit:
Спасибо всем за совет. Прочитав больше об этом, я думаю, что происходит то, что мой выходной слой становится насыщенным. Я переключаюсь на использование softsign вместо сигмоида (и корректирую логику, ожидая, что -1 будет полом вместо 0), и, надеюсь, это поможет.