В последнее время я занимался сетью LSTM и хотел бы предсказать вывод с горячим кодированием (на данный момент 2 класса, я уже пробовал с двоичной перекрестной энтропией, и моя проблема остается прежней) с учетом 5 функций и 14 шагов ретроспективного анализа. (размер партии 1). Я использую TimeseriesGenerator:
generator = TimeseriesGenerator(scaled_train, train_targets, length=LOOKBACK, batch_size=BATCH_SIZE)
validation_generator = TimeseriesGenerator(scaled_test, test_targets, length=LOOKBACK, batch_size=BATCH_SIZE)
Цели поезда следующие (ниже, распределение):
array([[1., 0.],
[0., 1.],
[1., 0.],
...,
[1., 0.],
[1., 0.],
[1., 0.]], dtype=float32)
0 1
0.0 1.0 1619
1.0 0.0 1545
dtype: int64
и особенности/scaled_train
вот так:
array([[0.22189629, 0.21121072, 0.21790398, 0.19933957, 0.41803716],
[0.2106806 , 0.21783771, 0.2197984 , 0.2237905 , 0.18050205],
[0.21885786, 0.21532436, 0.21933581, 0.19678948, 0.16397564],
...,
[0.2104257 , 0.20155003, 0.22193512, 0.20173967, 0.12319585],
[0.2070304 , 0.19911522, 0.21276043, 0.19141927, 0.11876491],
[0.19873079, 0.18909128, 0.20785918, 0.19083925, 0.1407046 ]])
Тестовые данные форматируются одинаково.
Модель тоже очень простая:
model = Sequential()
model.add(LSTM(100, input_shape=(LOOKBACK, scaled_train.shape[1])))
model.add(Dense(2, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
Вот подходящий вывод:
По сути, когда я делаю прогнозы, он что-то возвращает > 0.5
в половине случаев, < 0.5
в другой половине. Показатели соответствия просто супер постоянны. Я также безуспешно пытался усложнить свою сеть несколькими слоями LSTM. Я также попытался загрузить другой набор данных, просто чтобы попробовать, но это ничего не изменило. Возможно, я делаю что-то не так с моими генераторами.
Что я делаю не так?
Спасибо!
Вы пробовали меньшую сеть LSTM? сравните параметры модели с размером вашего набора данных и выберите подходящее количество узлов. начните с малого и наращивайте, чтобы получить некоторую интуицию.
Можете ли вы показать нам, как вы предварительно обрабатываете и масштабируете свои обучающие данные?
Попробуйте, возможно, изменить ваши целевые данные, чтобы использовать binary_crossentropy
:
targets_binary=np.array([np.where(index==1)[0][0] for index in train_targets])
Таким образом, вместо векторов с горячим кодированием, таких как [[1., 0.],[0., 1.], [1., 0.]]
, у вас будет настоящая метка, такая как [0,1,0]
При этом ваш последний слой должен быть:
model.add(Dense(1, activation='sigmoid'))
Спасибо за ваш ответ! Пробовал, к сожалению, не улучшилось. Точность остается такой же, как и потеря binary_crossentropy. Я также пытался усложнить сеть несколькими слоями LSTM, но это ничего не изменило (кроме времени обучения, конечно, намного дольше).
(размер партии 1)
Попробуйте изменить это на что-то вроде 32.
Следующий поток содержит некоторые разумные ссылки на выбор размера мини-пакета. А также некоторые объяснения того, почему размер пакета 1 может привести к тому, что GD не сходится.
Еще одна проблема, которую вы, возможно, захотите иметь в виду, заключается в том, будет ли проблема решена человеком... сможет ли человек идентифицировать некоторые характеристики в данных, которые классифицируют некоторые примеры как четко относящиеся к классу 0 по сравнению с классом 1? Есть ли какая-то функция в последовательности, которую вы можете реализовать вручную, где вывод будет иметь значимую корреляцию с метками? Существуют сценарии, в которых доступных входных данных просто недостаточно для проведения корреляции. то есть процесс вывода не объясним входом. Например, если у вас есть временная последовательность цен для данной акции, очень маловероятно, что вы сможете предсказать следующую цену с какой-либо разумной точностью, учитывая, что процесс, который определяет выход, не фиксируется только этими предыдущими точками данных. .
Размер партии также может быть причиной этого. Один-один образец в каждой партии может не давать градиентам модели хорошее направление для оптимизации и выявления проблемы. Попробуйте увеличить размер пакета.
Если мы посмотрим на бинарные значения потерь кросс-энтропии, они, кажется, спотыкаются около минимумов. Как объясняется в этом посте, это может быть причиной более высокой скорости обучения, хотя маловероятно. https://towardsdatascience.com/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0
Наконец, учитывая, что точность бинарного классификатора при наименьшем отображаемом значении потерь (0,6926) составляет 0,5095, кажется, что модель действительно изо всех сил пытается разобраться в проблеме примерно с 42 602 параметрами. Поэтому попробуйте использовать более быструю и простую модель со сглаженными элементами 14*5 и плотным слоем с большим размером пакета. Может дать некоторую интуицию с четкими значениями функций.
Если все вышеперечисленное не помогает потерям или точности, это может произойти по двум причинам:
Мои предложения:
0.001
. Попробуйте заменить его на 0.0001
или 0.00001
. Очень большая скорость обучения в сочетании с batch_size, равным 1, может способствовать неспособности вашей сети учиться/сойтись.batch_size
до 8/16 и проверить, изменится ли поведение. Вы можете реализовать оба шага 2 и 3 одновременно, хотя я бы лично начал с 3-го шага на этом этапе, чтобы обеспечить степень «помощи», которая предоставляется для сходимости нейронной сети.14 == timesteps
для вашей проблемы? Вполне вероятно, что изменение этого параметра повлияет на ваш результат; если ваша сеть изо всех сил пытается учиться, увеличение количества временных шагов может быть полезным.
Что представляют собой ваши функции и цели? Бинарная кросс-энтропия ~ 0,6931 очень подозрительна — это соответствует ожидаемой потере случайного предиктора (например, см. здесь ). В основном это происходит, когда ваши входные данные неинформативны для вашей цели ( этот ответ также актуален).