Вопрос или проблема
Я создаю простую архитектуру нейронной сети. Но я постоянно получаю NAN в результате и не могу понять, почему. Ниже представлен мой код.
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline
from collections import Counter
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.preprocessing import StandardScaler
#from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
X, Y = make_classification(n_samples=10, n_features=2000, n_informative=15, n_redundant=5, random_state=3)
# кодировать значения классов как целые числа
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
# преобразовать целые числа в фиктивные переменные (т.е. one hot кодирование)
dummy_y = np_utils.to_categorical(encoded_Y)
# определить базовую модель
def baseline_model():
# создать модель
model = Sequential()
model.add(Dense(10, input_dim=10, activation='relu'))
model.add(Dense(3, activation='softmax'))
# Компилировать модель
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
return model
estimator = KerasClassifier(build_fn=baseline_model, epochs=200, batch_size=500, verbose=0)
kfold = KFold(n_splits=10, shuffle=True)
results = cross_val_score(estimator, X, dummy_y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Я получаю следующее
Baseline: nan% (nan%)
Не могу понять, почему. Также есть ли способы, как это можно улучшить?
Думаю, вам стоит добавить этот error_score="raise"
в результаты, чтобы можно было точно визуализировать ошибку. Возможно, вам нужно изменить форму ваших данных.
Ответ или решение
При разработке нейронной сети с использованием Keras вы столкнулись с проблемой получения значения NaN
в результатах, что может быть вызвано несколькими факторами. Давайте разберем ваш код и причины возникновения данной проблемы.
Причины возникновения NaN в результатах
-
Проблемы с данными:
- Убедитесь, что входные данные, которые вы предоставляете в модель, не содержат значений
NaN
или бесконечных значений. Это может быть вызвано неправильной нормализацией или отсутствием данных. - В вашем коде вы используете метод
make_classification
для генерации синтетических данных. Убедитесь, что он возвращает корректные данные. Можно использоватьnp.isnan(X).any()
иnp.isinf(X).any()
, чтобы проверить наличие ненормальных значений.
- Убедитесь, что входные данные, которые вы предоставляете в модель, не содержат значений
-
Неправильная конфигурация модели:
- Вы используете
input_dim=10
, но в вашем наборе данных 2000 признаков. Убедитесь, что количество входных параметров соответствует размерности ваших данных. - Измените строку
model.add(Dense(10, input_dim=10, activation='relu'))
наmodel.add(Dense(10, input_dim=2000, activation='relu'))
, чтобы она соответствовала 2000 признакам.
- Вы используете
-
Размеры пакетов при обучении:
- Параметр
batch_size=500
может быть слишком большим для вашего небольшого набора данных из 10 выборок. Попробуйте использовать меньший размер пакета, например,batch_size=2
илиbatch_size=5
.
- Параметр
Исправленный код
Вот доработанный код с учетом вышеизложенных замечаний:
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# Генерация синтетических данных
X, Y = make_classification(n_samples=10, n_features=2000, n_informative=15, n_redundant=5, random_state=3)
# Проверка на наличие NaN или бесконечных значений
if np.isnan(X).any() or np.isinf(X).any():
raise ValueError("Входные данные содержат NaN или бесконечные значения.")
# Кодирование классов
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
dummy_y = np_utils.to_categorical(encoded_Y)
# Определение базовой модели
def baseline_model():
model = Sequential()
model.add(Dense(10, input_dim=2000, activation='relu')) # Изменено на 2000
model.add(Dense(3, activation='softmax'))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=['accuracy'])
return model
estimator = KerasClassifier(build_fn=baseline_model, epochs=200, batch_size=2, verbose=0) # Размер пакета изменен
kfold = KFold(n_splits=10, shuffle=True)
results = cross_val_score(estimator, X, dummy_y, cv=kfold, error_score='raise') # Добавлен error_score
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Рекомендации по улучшению
-
Сбалансированность данных:
Проверьте уравновешенность классов в вашем наборе данных. Если классы несбалансированы, стоит рассмотреть использование методов, таких как Oversampling или Undersampling. -
Попробуйте разные архитектуры:
Экспериментируйте с глубиной сети или количеством нейронов в скрытых слоях, а также с различными функциями активации. -
Регуляризация:
Вы можете добавить слои регуляризации, такие как Dropout, для предотвращения переобучения. -
Нормализация данных:
Попробуйте стандартную нормализацию ваших данных (например, с помощьюStandardScaler
из sklearn) перед подачей в модель.
Следуя приведённым рекомендациям, вы сможете избежать возникновения NaN
и улучшить результаты вашей модели.