Страницы

Поиск по вопросам

четверг, 16 мая 2019 г.

Какие могут быть пути улучшения обобщающей способности ИНС на базе Keras?

Несколько дней назад я создавал тему с похожим вопросом: Проблема с обучением сети в Keras: нет обобщающей способности сети, и там получил резонное замечание и совет. Решив попробовать поработать с данными, в которых информация не утрачена (нежели в прошлом топике), я собрал подобную ИНС, предварительно нормализовав данные (использование StandardScaler оказалось лучше MinMax).
Дано: База из 71 осциллограммы с 3002 отсчетами. Диапазон данных: от 0 до 10Е6. Данные векторы разбиты на обучающую выборку и тестовую (36 и 35).
Задача: входным векторам присваивать значения на выходе в виде определенного числа (от 30 до 100).
Ограничения: нет возможности получить огромный датасет (из тысяч векторов) и возможный максимум - сотня-полторы векторов.
Текущая конфигурация сети довольно неплохо обучается (в сравнении с предыдущей), однако проблема с обобщением результатов все также существует. Хоть результат и лучше он все еще не устраивает меня. Меняя конфигурации многослойного персептрона (число нейронов в слое, число слоев) мне не удавалось сильно изменять выходной результат (разве что, кроме времени обучения, что логично). Возможно я не подобрался к самой оптимальной структуре ИНС, но пока есть только это. Кстати да, функцию обучения выбирал методом научного тыка. Перепробовал разные методы и данный показал себя лучше всего.
Итак, отсюда у меня вопросы: Какие возможные пути изменения ИНС для улучшения результата? К сожалению я все еще новичок в этой области и знаком только с персептронами. Быть может вы сможете посоветовать какие-то другие типы сетей? Если после нормализации у меня диапазон значений вектора от -2 до 6, то как это влияет? На сколько мне известно, то на вход сети следует подавать данные в диапазоне [0 1] или [-1 1].
Код сети:
#загружаем файл с образами TRAIN_FILE="TRAIN30_100km.csv" TEST_FILE="TEST30_100km.csv"
# размер вектора img_rows, img_cols = 1, 3002
# Загружаем данные для обучения train_dataset = np.loadtxt(TRAIN_FILE, skiprows=0, dtype='int', delimiter=",") test_dataset = np.loadtxt(TEST_FILE, skiprows=0, dtype='int', delimiter=",")
# Выделяем данные для обучения X_train = train_dataset[:, 1:] X_test = test_dataset[:, 1:]
# нормализуем данные scaler = StandardScaler() x_train=scaler.fit_transform(X_train) x_test=scaler.fit_transform(X_test)
# Выделяем правильные ответы y_train = train_dataset[:,0] y_test = test_dataset[:,0]
# рисуем график нормализованного вектора и оригинального y10 = x_train[6, :] y11=X_train[6, :] plt.figure(figsize=(8, 8)) plt.plot(y10) plt.show() plt.figure(figsize=(8, 8)) plt.plot(y11) plt.show()
# Выделяем правильные ответы y_train = train_dataset[:,0] y_test = test_dataset[:,0]
model = Sequential()
model.add(Dense(10, input_dim=3002, activation="relu",kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(15, activation='relu', kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(5, activation='relu', kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(5, activation='relu')) model.add(Dense(1)) model.compile( optimizer='Adagrad', loss="mse", metrics=['mae'])
print(model.summary()) model.fit(x_train, y_train, epochs=30, batch_size=1, verbose=2,validation_data=(x_test, y_test))
Epoch 30/30 - 0s - loss: 0.9548 - mean_absolute_error: 0.1053 - val_loss: 102.0822 - val_mean_absolute_error: 7.7214
mse, mae = model.evaluate(x_test, y_test, verbose=0) predictions=model.predict(x_test) print(predictions) # ответы (правильные 31 33 35 37) [20.31354 ] [18.931906] [21.085878] [20.537167]
Ссылка на датасет


Ответ

Немного подумав, решил упростить НС по-максимуму и получил лучшие показатели.
Архитектура:
model = Sequential() model.add(Dense(128, input_dim=3002, activation="relu", kernel_regularizer=l2(0.01))) model.add(BatchNormalization()) model.add(Dense(1)) model.compile( optimizer='Adagrad', loss="mse", metrics=['mae', 'mse']) hist = model.fit(x_train, y_train, epochs=300, batch_size=3, verbose=2,validation_data=(x_test, y_test), callbacks=callbacks)
вывод:
Epoch 00147: val_mean_squared_error did not improve from 13.76798 Epoch 148/300 - 0s - loss: 183.8615 - mean_absolute_error: 10.9775 - mean_squared_error: 180.3115 - val_loss: 23.7155 - val_mean_absolute_error: 3.2763 - val_mean _squared_error: 20.1659
Epoch 00148: val_mean_squared_error did not improve from 13.76798 Epoch 00148: early stopping
оценка:
In [206]: model = load_model(model_fn)
In [207]: model.evaluate(x_test, y_test, verbose=1) 18/18 [==============================] - 2s 135ms/step Out[207]: [17.30735206604004, 3.1715924739837646, 13.767986297607422]
сравнение тестового набора с предсказанными значениями:
In [208]: from sklearn.metrics import mean_absolute_error, mean_squared_error
In [209]: df = pd.DataFrame({'y_test':y_test.ravel(), 'y_pred':model.predict(x_test).ravel()})
In [210]: mean_squared_error(df['y_test'], df['y_pred']) Out[210]: 13.76798614917061
In [211]: mean_absolute_error(df['y_test'], df['y_pred']) Out[211]: 3.171592500474718
In [212]: df['abs_err'] = np.abs(df['y_test'] - df['y_pred'])
In [213]: df Out[213]: y_test y_pred abs_err 0 39.0 41.414223 2.414223 1 41.0 38.207268 2.792732 2 43.0 49.000561 6.000561 3 73.0 73.476303 0.476303 4 33.0 32.048149 0.951851 5 78.0 76.682877 1.317123 6 53.0 57.643074 4.643074 7 54.0 58.276382 4.276382 8 67.0 63.092651 3.907349 9 49.0 53.009842 4.009842 10 89.0 87.252930 1.747070 11 65.0 62.399197 2.600803 12 63.0 68.281502 5.281502 13 58.0 55.078934 2.921066 14 48.0 43.649544 4.350456 15 80.0 72.487808 7.512192 16 60.0 60.331455 0.331455 17 47.0 45.445320 1.554680
In [217]: df[['y_test','y_pred']].plot() Out[217]:

Комментариев нет:

Отправить комментарий