Несколько дней назад я создавал тему с похожим вопросом: Проблема с обучением сети в 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]:
Комментариев нет:
Отправить комментарий