Нейронная сеть Keras предсказывает одно и то же число для всех входов - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь создать нейронную сеть keras для прогнозирования расстояния на дорогах между двумя точками в городе. Я использую Google Maps, чтобы получить расстояние путешествия, а затем обучаю нейронную сеть для этого.

import pandas as pd
arr=[]
for i in range(0,100):
    arr.append(generateTwoPoints(55.901819,37.344735,55.589537,37.832254))
    df=pd.DataFrame(arr,columns=['p1Lat','p1Lon','p2Lat','p2Lon', 'distnaceInMeters', 'timeInSeconds'])
print(df)

Архитектура нейронной сети:

from keras.optimizers import SGD
sgd = SGD(lr=0.00000001)
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential()
model.add(Dense(100, input_dim=4 , activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(1,activation='sigmoid'))
model.compile(loss='mse', optimizer='sgd', metrics=['mse'])

Затем я делю наборы для тестирования / обучения

Xtrain=train[['p1Lat','p1Lon','p2Lat','p2Lon']]/100
Ytrain=train[['distnaceInMeters']]/100000
Xtest=test[['p1Lat','p1Lon','p2Lat','p2Lon']]/100
Ytest=test[['distnaceInMeters']]/100000

Затем я вписываю данные в модель, но потери остаются то же самое:

history = model.fit(Xtrain, Ytrain,
                    batch_size=1,
                    epochs=1000,
                    # We pass some validation for
                    # monitoring validation loss and metrics
                    # at the end of each epoch
                    validation_data=(Xtest, Ytest))

Позже я распечатываю данные:

prediction = model.predict(Xtest)
print(prediction)
print (Ytest)

Но результат одинаков для всех входов:

[[0.26150784]
 [0.26171574]
 [0.2617755 ]
 [0.2615582 ]
 [0.26173398]
 [0.26166356]
 [0.26185763]
 [0.26188275]
 [0.2614446 ]
 [0.2616575 ]
 [0.26175532]
 [0.2615183 ]
 [0.2618127 ]]
    distnaceInMeters
2            0.13595
6            0.27998
7            0.48849
16           0.36553
21           0.37910
22           0.40176
33           0.09173
39           0.24542
53           0.04216
55           0.38212
62           0.39972
64           0.29153
87           0.08788

Не могу найти проблема. Что это? Я новичок в машинном обучении.

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Вы делаете очень элементарную ошибку: поскольку вы находитесь в настройке регрессии, вы должны , а не использовать sigmoid активацию для вашего последнего слоя (это используется для случаев двоичной классификации); измените свой последний слой на

model.add(Dense(1,activation='linear'))

или даже

model.add(Dense(1))

, поскольку, согласно docs , если вы не укажете аргумент activation, по умолчанию он на linear.

Различные другие советы, предлагаемые уже в другом ответе, и комментарии могут быть полезны (более низкий LR, больше слоев, другие оптимизаторы, например Adam), и вам, безусловно, необходимо увеличить размер пакета ; но ничто не будет работать с функцией активации sigmoid, которую вы в данный момент используете для своего последнего слоя.

Не имеет значения для проблемы, но в настройках регрессии вам не нужно повторять функцию потерь в качестве метрики; этого

model.compile(loss='mse', optimizer='sgd')

будет достаточно.

0 голосов
/ 04 февраля 2020

Было бы очень полезно, если бы вы могли публиковать информацию о прогрессировании потери и MSE (как в обучающем, так и в проверочном / тестовом наборе) по ходу обучения. Более того, было бы лучше, если бы вы могли визуализировать его согласно https://machinelearningmastery.com/display-deep-learning-model-training-history-in-keras/ и опубликовать визуализацию здесь.

А пока, основываясь на фактах: 1) Вы говорите о потере не уменьшается (я предполагаю на тренировочном наборе, во время обучения, основываясь на ваших аргументах компиляции). 2) Вы говорите, что «точность» прогноза на вашем тестовом наборе плохая. 3) Мой опыт / интуиция (не эмпирическая оценка) подсказывает мне, что ваша двухслойная плотная модель слишком мала, чтобы можно было уловить сложность, присущую вашим данным. АКА Ваша модель страдает от слишком высокого смещения https://towardsdatascience.com/understanding-the-bias-variance-tradeoff-165e6942b229

Самая быстрая и простая вещь, которую вы можете попробовать, это попытаться добавить как больше слоев, так и больше узлов к каждому слою.

Однако я должен отметить, что существует много причинно-следственной информации, которая может повлиять на расстояние вождения и время в пути , превышающее только расстояние между двумя координатами , которая может быть функцией, которую ваша нейронная сеть будет наиболее легко извлечь. Например, если вы едете по шоссе или по обочине дороги, светофоры c, повороты дорог или поворот или go прямо ... из всего этого выведите данные, для которых вам понадобятся огромные объемы данных. (примеры) на мой взгляд. Если бы вы могли добавить входные столбцы с, например, отсутствием расстояния до ближайшего шоссе из обеих точек, вы могли бы тренироваться с меньшим количеством данных

Я бы также рекомендовал вам дважды проверить, что вы кормите в качестве ввода то, что вы думаю, что вы кормите (и его форму), а также вам следует использовать некоторую стандартизацию из функции sklearn , которая может помочь модели учиться быстрее и быстрее сходиться к более высокой "точности".

Если и когда вы опубликуете больше кода или истории тренировок, я могу помочь вам больше (а также, сколько обучающих образцов).

РЕДАКТ. 1: Попробуйте изменить размер партии на большее, желательно batch_size=32 если он умещается в вашей памяти. Вы можете использовать небольшой размер пакета (например, 1) при работе с вводом с «богатой информацией», например с изображением, но при использовании данных с очень плохой информацией, таких как 4 числа с плавающей запятой (2 координаты), градиент будет указывать на каждую группу ( с batch_size=1) практически случайным (псевдо ...) направлением и не обязательно приближаться к локальному минимуму. Только принимая градиент на общую потерю большей партии (например, 32 и, возможно, больше), вы получите градиент, который по крайней мере приблизительно указывает в направлении локального минимума и сходится к лучшему результату. Кроме того, я предлагаю вам не связываться со скоростью обучения вручную и, возможно, переключиться на оптимизатор, такой как «Адам» или «RMSProp».

Edit 2 : @Desertnaut сделал отличное замечание, которое я полностью пропустил, исправление, без которого ваш код не будет работать должным образом. Он заслуживает похвалы, поэтому я не буду включать его здесь. Пожалуйста, обратитесь к его ответу. Кроме того, не забывайте увеличивать размер пакета, а не «связываться вручную» со скоростью обучения, например, «Адам» сделает это за вас.

...