#python #нейронные_сети #машинное_обучение #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] Ссылка на датасет.
Ответы
Ответ 1
Немного подумав, решил упростить НС по-максимуму и получил лучшие показатели. Архитектура: 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]:Ответ 2
Немного поигрался с вашими данными - лучшее что у меня получилось: mae: 3.8784 mse: 22.78249 вот весь код: import pandas as pd import numpy as np from pathlib import Path from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from keras import Sequential from keras.layers import * from keras.regularizers import l2, l1 from keras.callbacks import EarlyStopping, ModelCheckpoint from keras.models import save_model, load_model def get_data(path, test_size=0.25): data = pd.concat([pd.read_csv(f, header=None) for f in Path(path).glob('*.csv')], ignore_index=True).values scaler = StandardScaler() x, y = scaler.fit_transform(data[:, 1:]), data[:, [0]] return train_test_split(x, y, test_size=test_size) path = r'/path/to/directory_with_data' x_train, x_test, y_train, y_test = \ get_data(path, test_size=0.25) model_fn = str(Path(path) / 'model.h5') early_stop = EarlyStopping(monitor='val_mean_squared_error', min_delta=0.0001, patience=60, verbose=1, mode='auto') chkpt = ModelCheckpoint(model_fn, monitor='val_mean_squared_error', verbose=1, save_best_only=True, mode='auto') callbacks = [early_stop, chkpt] model = Sequential() model.add(Dense(45, input_dim=3002, activation="relu", kernel_regularizer=l2(0.01))) model.add(BatchNormalization()) model.add(Dropout(0.04)) model.add(Dense(20, activation='relu', kernel_regularizer=l2(0.01))) model.add(Dropout(0.01)) model.add(Dense(6, activation='relu', kernel_regularizer=l2(0.01))) model.add(Dense(5, activation='relu')) model.add(Dense(1)) model.compile( optimizer='adam', 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) Сохраненная модель ...
Комментариев нет:
Отправить комментарий