Вопрос или проблема
Я пытаюсь построить модель ожидания для моих данных размером (19502,3) с помощью модели Keras Sequential. Этот набор данных был сгенерирован с использованием параметрического прохода в программном обеспечении для моделирования.
С помощью этой модели я хочу ожидать длину и массу предмета на основе стоимости. Это похоже на обратную задачу.
Я использовал два скрытых слоя (первый со входной формой) и один выходной слой. Я пытался улучшить свой код, оптимизируя некоторые параметры, например, количество слоев, количество единиц внутри каждого слоя, активацию, оптимизатор, функцию потерь и эпохи. Результаты хорошие и уместные. Результат моей модели можно проверить с помощью того же программного обеспечения для моделирования, с помощью которого я сгенерировал свой набор данных. Например, ожидаемые значения для входных данных = 80 соответствуют 100 в программном обеспечении для моделирования. Этот результат очень хороший, однако, мне бы хотелось знать, можно ли как-то его улучшить.
Я использую правильную модель? Я делаю это правильно?
Любая помощь, предложение, рекомендация или комментарий будут очень ценны!
Большое спасибо
Алекс
Вот мой код:
from IPython import get_ipython
get_ipython().magic('reset -sf')
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
model = Sequential()
from tensorflow.keras.layers import Dense
data_file_path="F:/Dl_project/dss_project/data_price.csv"
my_data = pd.read_csv(data_file_path)
my_data.columns = ["length","weight","cost"]
X = my_data['cost']
y = my_data.drop(columns=['cost'])
predictionData = ([[80]])
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.10, random_state=40)
X_train= X_train.values.reshape(-1, 1)
#y_train= y_train.values.reshape(-1, 1)
X_test = X_test.values.reshape(-1, 1)
model.add(Dense(units=128, kernel_initializer="uniform", activation='sigmoid')) #скрытый слой 1 с входом
model.add(Dense(units=128, kernel_initializer="uniform",activation='sigmoid'))#скрытый слой 2
model.add(Dense(units=2)) #выходной слой
model.compile(loss="MeanAbsolutePercentageError",optimizer="Adamax",metrics=['accuracy'])
model.fit(X_train, y_train, epochs=15, batch_size=32)
print(model.predict(predictionData),'\n')
```
- смените активацию на relu, потому что это задача регрессии. Сигмоида используется в классификационных задачах
- узнайте, является ли модель и высокая смещенность или дисперсия. Если дисперсия высокая, используйте регуляризацию.
Ответ или решение
Для улучшения модели Keras для задачи регрессии на основе ваших наблюдений, имеются несколько ключевых направлений, которые стоит рассмотреть. Они могут существенно повысить эффективность и точность вашего решения. Давайте подробно рассмотрим каждое из них.
1. Выбор активационной функции
Как вы отметили, использование функции активации sigmoid
в скрытых слоях не является оптимальным решением для задач регрессии. В таких случаях лучше всего использовать ReLU
(Rectified Linear Unit), так как она помогает избежать проблемы затухающего градиента и позволяет модели быстро обучаться. Так, вот как можно изменить вашу модель:
model.add(Dense(units=128, kernel_initializer="uniform", activation='relu')) # Скрытый слой 1
model.add(Dense(units=128, kernel_initializer="uniform", activation='relu')) # Скрытый слой 2
2. Регуляризация
Важно проверить, страдает ли ваша модель от переобучения (высокая вариативность) или недообучения (высокая смещенность). Для этого можно использовать следующие методы:
-
Добавление Dropout: Можно добавить слой
Dropout
между вашими слоями для уменьшения вероятности переобучения:from tensorflow.keras.layers import Dropout model.add(Dense(units=128, kernel_initializer="uniform", activation='relu')) model.add(Dropout(0.2)) # Слой Dropout model.add(Dense(units=128, kernel_initializer="uniform", activation='relu')) model.add(Dropout(0.2)) # Слой Dropout
-
L2-регуляризация: Также можно добавить L2-регуляризацию к весам вашего слоя:
from tensorflow.keras.regularizers import l2 model.add(Dense(units=128, kernel_initializer="uniform", activation='relu', kernel_regularizer=l2(0.01)))
3. Настройка гиперпараметров
Вы можете экспериментировать с различными гиперпараметрами:
- Количество эпох: Увеличьте количество эпох до 100 или более, чтобы ваша модель могла лучше обучиться.
- Размер пакета (batch size): Попробуйте разные размеры пакета (например, 16 или 64) и посмотрите, как это влияет на скорость и качество обучения.
- Оптимизаторы: Попробуйте использовать
Adam
илиRMSprop
, которые часто более эффективны в задачах регрессии.
4. Нормализация данных
Важно нормализовать входные и выходные данные. Это может быть выполнено с использованием StandardScaler
или MinMaxScaler
из библиотеки sklearn
.
from sklearn.preprocessing import MinMaxScaler
scaler_x = MinMaxScaler()
scaler_y = MinMaxScaler()
X_scaled = scaler_x.fit_transform(X.reshape(-1, 1))
y_scaled = scaler_y.fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.10, random_state=40)
5. Улучшенная модель
С учетом вышеперечисленных рекомендаций, вот пример улучшенной модели:
model = Sequential()
model.add(Dense(units=128, kernel_initializer="uniform", activation='relu', input_shape=(1,)))
model.add(Dropout(0.2))
model.add(Dense(units=128, kernel_initializer="uniform", activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(units=2)) # Выходной слой
model.compile(loss="MeanAbsolutePercentageError", optimizer="Adam", metrics=['mae'])
model.fit(X_train, y_train, epochs=100, batch_size=32)
Заключение
Ваши текущие результаты выглядят многообещающе, и внесение вышеупомянутых изменений может помочь повысить их качество. Рекомендуется проводить регулярные тесты, анализируя возможные переобучения и недообучения, а также внедрять новые подходы и методы для оптимизации модели. Надеюсь, эта информация окажется полезной для вас в ваших будущих изысканиях. Если возникнут дополнительные вопросы или понадобится помощь в внедрении предложенных улучшений, не стесняйтесь обращаться!