keras - ожидался другой ответ

Входные данные по типу

x_train = array([[1.3590000e+03, 1.3180000e+03, 1.7082020e+07, 1.2000000e+03], [4.0380000e+03, 4.6170000e+03, 1.7082020e+07, 1.2000000e+03], [2.6300000e+03, 3.9840000e+03, 1.7082020e+07, 1.0540000e+03], [3.4460000e+03, 4.5310000e+03, 1.8102014e+07, 2.1610000e+03], [9.1500000e+02, 4.5310000e+03, 1.8102014e+07, 2.1610000e+03], [3.4460000e+03, 4.4570000e+03, 1.8102014e+07, 2.1610000e+03]])
y_train = array([[ 1., 2., 2.], [ 1., 2., 2.], [ 1., 2., 2.], [16., 2., 1.], [16., 4., 1.], [16., 0., 1.]])
но результат [[1616849.4   1550158.4     54270.72 ]
 [1616645.    1549958.6     54247.965]
 [1530179.1   1467063.      51288.938]
 [1529552.4   1466477.8     51272.31 ]
 [1531608.9   1468432.5     51389.453]
 [1529679.2   1466598.      51271.816]
 [1529510.4   1466437.1     51267.277]
 [1531926.    1468735.9     51406.277]
 [1529213.1   1466153.1     51250.47 ]
 [1529175.5   1466111.1     51226.37 ]
 [1529424.9   1466356.1     51264.93 ]
 [1531726.    1468537.9     51373.17 ]
 [1531182.4   1468027.1     51378.06 ]
 [1532010.6   1468815.6     51411.83 ]
 [1531546.9   1468376.6     51398.44 ]
 [1531727.9   1468543.2     51385.023]
 [1447227.9   1387525.2     48541.914]
 [1447429.9   1387724.8     48575.203]
 [1447145.4   1387455.6     48571.164]
 [1444912.    1385329.5     48432.594]
 [1446700.2   1387032.      48556.8  ]
 [1446735.2   1387061.6     48540.684]
 [1445760.2   1386125.1     48466.57 ]]# как обучить нейроную сеть близку к результату y_train ?

код:

x_train,y_train = np.load('datsx.npy'),np.load('datsy.npy')
wb = None
from keras.models import Sequential
from keras.layers import Dense
from keras.models import load_model
import h5py

# Среднее значение
mean = x_train.mean(axis=0)
# Стандартное отклонение
std = x_train.std(axis=0)
x_train -= mean
x_train /= std

model = Sequential()
model.add(Dense(128, activation='relu', input_shape=(x_train.shape[1],)))#shape 1
model.add(Dense(100))
model.add(Dense(100))
model.add(Dense(3))
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.fit(x_train, y_train, epochs=100, batch_size=1, verbose=2)
x_test, y_test = importdata()
mse, mae = model.evaluate(x_test, y_test, verbose=0)
print("Средняя абсолютная ошибка (тысяч долларов):", mae)
pred = model.predict(x_test)

print("Предсказанная стоимость:", pred*-1, ", правильная стоимость:", y_test)

Ответы (1 шт):

Автор решения: CrazyElf

Так вы же нормализуете x_train, а x_test не нормализуете. Предобработка тренировочных и тестовых входных данных должна совпадать, иначе и правда ерунда получится.

x_test, y_test = importdata()
# добавил нормализацию
x_test -= mean
x_test /= std

Нужно ли вычислять mean и std для x_text заново - вопрос нетривиальный, но по идее, если данные из одной генеральной совокупности, у них эти значения не должны сильно отличаться. Обычно для преобразования тестовых данных используют функцию преобразования, "натренированную" на тренировочных данных, то есть вычислять их заново не нужно. Но можно попробовать и так и так.

Не исключаю, что вы уже делаете нормализацию в функции importdata, но из приведённого кода это узнать невозможно. Хотя если судить по вашим предсказаниям - нормализации тестовых данных у вас точно нет.

И отдельно непонятно, зачем вы печатаете pred*-1 (то есть по сути -pred), а не просто pred.

Потестировал в варианте x_test, y_test = x_train.copy(), y_train.copy() с нормализацией, получил вполне терпимую ошибку:

Средняя абсолютная ошибка (тысяч долларов): 0.13467107713222504

Если увеличить число эпох (для повышения точности) и размер батча (для повышения скорости расчётов), то результат вообще отличный (хотя и сильно варьируется с каждым запуском):

model.fit(x_train, y_train, epochs=2000, batch_size=20, verbose=0)

Средняя абсолютная ошибка (тысяч долларов): 0.001550681539811194
→ Ссылка