Вопрос или проблема
Здесь у меня есть два различных набора данных. dataset1 — это данные с платформы силы, а dataset2 — данные о подошвенном давлении. dataset1 имеет размер (2050,2), а dataset2 имеет размер(2050,89). Перед обучением я нормализовал данные, используя minmaxscaler() с масштабом от 0 до 1. После нормализации данных я выполнил предварительную обработку данных для dataset2, используя PCA. Здесь я собираюсь уменьшить размерность данных о подошвенном давлении до 12, так что текущий размер данных по подошвенному давлению составляет (2050,12).
Вот моя модель CNN:
import math
import numpy as np
import pandas as pd
import tensorflow as tf
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Activation, Dense, BatchNormalization, LeakyReLU, Conv2D, MaxPooling1D, Conv1D, Flatten, Dropout
from tensorflow.keras.losses import sparse_categorical_crossentropy
from tensorflow.keras.optimizers import Adam, RMSprop, SGD, Adadelta, Adagrad
from sklearn.decomposition import PCA
from sklearn.model_selection import KFold
from numpy import zeros, newaxis
from sklearn.feature_selection import mutual_info_regression
from sklearn.feature_selection import mutual_info_regression, SelectKBest
np.set_printoptions(suppress=True)
%matplotlib inline
Insole = pd.read_csv('1119_Rwalk40s2_list.txt', header=None, low_memory=False)
SIData = np.asarray(Insole)
df = pd.read_csv('1119_Rwalk40s2.csv', low_memory=False)
columns = ['Fx', 'Fz']
selected_df = df[columns]
FCDatas = selected_df[:2050]
SmartInsole = np.array(SIData[:2050])
FCData = np.array(FCDatas)
scaler_x = MinMaxScaler(feature_range=(0, 1))
scaler_x.fit(SmartInsole)
xscale = scaler_x.transform(SmartInsole)
scaler_y = MinMaxScaler(feature_range=(0, 1))
scaler_y.fit(FCData)
yscale = scaler_y.transform(FCData)
SIDataPCA = xscale
pca = PCA(n_components=0.99)
pca.fit(SIDataPCA)
SIdata_pca = pca.transform(SIDataPCA)
X_train, X_test, y_train, y_test = train_test_split(SIdata_pca, yscale, test_size=0.10, random_state=2)
model = Sequential()
model.add(Conv1D(64, kernel_size=2, strides=1, padding='same', data_format="channels_last", input_shape=(X_train.shape[1], 1)))
model.add(Activation('relu'))
model.add(MaxPooling1D(pool_size=2, strides=2))
model.add(Conv1D(32, kernel_size=2, strides=1, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling1D(pool_size=2, strides=2))
model.add(Conv1D(16, kernel_size=2, strides=1, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling1D(pool_size=2, strides=2))
model.add(LSTM(units=16))
model.add(Dense(16, activation='relu'))
model.add(Dense(2, activation='sigmoid'))
model.summary()
model.compile(loss="mse", optimizer=Adam(), metrics=['mse'])
history = model.fit(X_train, y_train, batch_size=64, epochs=50,
validation_data=(X_test, y_test), verbose=2)
model.evaluate(SIdata_pca, yscale)
ypred = model.predict(SIdata_pca)
plt.figure()
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Потеря модели')
plt.ylabel('Потеря')
plt.xlabel('эпоха')
plt.legend(['обучение', 'валидация'], loc="upper right")
# plt.show()
plt.savefig('Результат потерь.png')
x = []
colors = ['red', 'green', 'brown', 'teal', 'gray', 'black', 'maroon', 'orange', 'purple']
colors2 = ['green', 'red', 'orange', 'black', 'maroon', 'teal', 'blue', 'gray', 'brown']
for i in range(0, 2050):
x.append(i)
for i in range(0, 2):
plt.figure(figsize=(15, 6))
# plt.figure()
plt.plot(x, yscale[0:2050, i], color=colors[i])
plt.plot(x, ypred[0:2050, i], markerfacecolor="none", color=colors2[i])
plt.title('Результат для регрессии ResNet')
plt.ylabel('Y значение')
plt.xlabel('Экземпляр')
plt.legend(['Реальное значение', 'Прогнозируемое значение'], loc="upper right")
plt.savefig('Результат регрессии.png'[i])
plt.show()
Ниже приведен график потерь модели
Смотря на потери модели на обучении, я не думаю, что есть какие-либо признаки переобучения в обучении, но почему моя модель не может предсказать высокие пики из обучающих данных?
Я не знаю содержание данных, но вот несколько советов на основе моего прошлого опыта:
- Цикл данных составляет около 100 шагов. В общем, размер партии должен быть около цикла данных, чтобы модель могла понять поведение циклов. То же самое касается слоя LSTM: я бы увеличил его размер. 16 нейронов может быть недостаточно, чтобы запомнить размер 100.
- Я не знаю, может ли смешивание Conv1D и LSTM снизить точность предсказания, так как они очень разные: Conv1D запоминает формы, а LSTM запоминает динамику. Возможно, вам стоит попробовать сначала один тип.
- Пики, похоже, очень короткие (2 или 3 шага). Я бы предложил шаг 1 с размером ядра 3, чтобы убедиться, что нейроны учатся на каждом шаге.
- Макс-пулинг может сгладить ваши данные и уменьшить обнаружение пиков, поскольку он уменьшает значения до ближайших.
- SGD или AdamW могут также дать лучшие результаты, чем Adam.
- Модель, похоже, слишком быстро сходится. Уменьшение скорости обучения и увеличение количества итераций может улучшить результаты.
- Если ваши данные имеют 50% значений 0 или 1, возможно, вы можете игнорировать их и проводить обучение только на значениях, которые имеют значение. Это улучшит результаты обучения, поскольку «бесполезные» данные могут повлиять на эффективность обучения.
- Вам может потребоваться больше данных для обучения. Я не могу объяснить, почему тестовые данные не так хороши. В общем, хорошее обучение имеет хорошую точность (около 80%) для хорошей генерализации. Ваша ситуация может быть переобучением.
В заключение, модель является смесью нескольких типов нейронов, и я не могу предсказать их поведение, потому что они ведут себя по-разному. Скорее всего, есть веские причины для их смешивания, потому что потеря является довольно низкой. Тем не менее, я рекомендую протестировать одно из предложений выше, потому что они могут объяснить, почему пики не обнаруживаются очень хорошо.
Если параметры слишком сложны для определения, я рекомендую использовать обучаемый оптимизатор, такой как Velo.
Ответ или решение
Ваши наблюдения о том, что модель CNN (сверточная нейронная сеть) не может точно предсказать высокие пики в данных, могут быть объяснены несколькими факторами. Давайте рассмотрим основные причины и возможные решения.
Причины плохой детекции пиков:
-
Структура данных и размер выборки:
- Размер ваших данных может быть недостаточным для тренировки сложной модели. Даже если у вас 2050 выборок, если высокие пики встречаются редко, модель может не обучаться на этих примерах должным образом.
-
Комбинация Conv1D и LSTM:
- Смешивание сверточных слоев (Conv1D) и слоев LSTM может вызвать трудности в обучении, поскольку эти архитектуры предназначены для обработки различных типов данных. Conv1D хорошо работает с фиксированными паттернами, в то время как LSTM лучше справляется с временными зависимостями. Попробуйте использовать одну архитектуру за раз, чтобы посмотреть, какая из них лучше подходит для ваших данных.
-
Параметры свертки и подвыборка:
- Ваши параметры свертки (kernel_size) и размер подвыборки (pool_size) могут быть слишком агрессивными. Когда вы используете Max Pooling, вы уменьшаете размерность данных, что может привести к потере информации о пиках. Попробуйте уменьшить размер свертки и использовать более мелкие шаги (strides).
-
Скорость обучения:
- Модель может сходиться слишком быстро, что не позволяет ей достигнуть оптимальных значений. Попробуйте уменьшить скорость обучения и увеличить количество итераций.
-
Дисбаланс данных:
- Если ваша выборка имеет большой процент значений, равных 0 или 1, возможно, стоит исключить их при обучении, чтобы сосредоточиться на более значимых данных, что может повысить качество обучения.
-
Переобучение:
- Даже если вы не наблюдаете явного переобучения, модель может иметь недостаточную способность к обобщению. Возможно, вам стоит исследовать методы регуляризации или попробовать более простые модели.
-
Параметры LSTM:
- Параметры LSTM, такие как число нейронов, также могут быть слишком малы. Увеличение числа нейронов может помочь LSTM лучше запоминать важные временные зависимости, особенно если циклы в ваших данных около 100 шагов.
Рекомендации по улучшению модели:
-
Увеличьте размер обучающей выборки:
- Постарайтесь получить больше данных, если это возможно, чтобы обеспечить лучшее обучение модели.
-
Измените архитектуру модели:
- Попробуйте использовать только Conv1D или LSTM, чтобы избежать проблем с комбинированной архитектурой. Это поможет лучше понять, какая структура лучше подходит для вашей задачи.
-
Адаптируйте параметры обучения:
- Экспериментируйте с параметрами, такими как размер батча, количество эпох и скорость обучения.
-
Используйте методы предобработки данных:
- Обратите внимание на аугментацию данных. Это может помочь в увеличении разнообразия примеров и улучшении обучения модели.
-
Проведите анализ ошибок:
- Посмотрите на случаи, когда модель ошибилась, и попробуйте понять, почему это произошло. Визуализация предсказаний на данных может помочь узнать больше о том, какие аспекты модели требуют доработки.
В целом, анализируя вашу проблему, можно понять, что необходимость более глубокого изучения структуры модели и данных — это ключ к решению задачи. Экспериментирование и настройка параметров также играют важную роль в достижении лучших результатов.