NAN в результатах нейронной сети Keras

Вопрос или проблема

Я создаю простую архитектуру нейронной сети. Но я постоянно получаю 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 в результатах

  1. Проблемы с данными:

    • Убедитесь, что входные данные, которые вы предоставляете в модель, не содержат значений NaN или бесконечных значений. Это может быть вызвано неправильной нормализацией или отсутствием данных.
    • В вашем коде вы используете метод make_classification для генерации синтетических данных. Убедитесь, что он возвращает корректные данные. Можно использовать np.isnan(X).any() и np.isinf(X).any(), чтобы проверить наличие ненормальных значений.
  2. Неправильная конфигурация модели:

    • Вы используете input_dim=10, но в вашем наборе данных 2000 признаков. Убедитесь, что количество входных параметров соответствует размерности ваших данных.
    • Измените строку model.add(Dense(10, input_dim=10, activation='relu')) на model.add(Dense(10, input_dim=2000, activation='relu')), чтобы она соответствовала 2000 признакам.
  3. Размеры пакетов при обучении:

    • Параметр 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))

Рекомендации по улучшению

  1. Сбалансированность данных:
    Проверьте уравновешенность классов в вашем наборе данных. Если классы несбалансированы, стоит рассмотреть использование методов, таких как Oversampling или Undersampling.

  2. Попробуйте разные архитектуры:
    Экспериментируйте с глубиной сети или количеством нейронов в скрытых слоях, а также с различными функциями активации.

  3. Регуляризация:
    Вы можете добавить слои регуляризации, такие как Dropout, для предотвращения переобучения.

  4. Нормализация данных:
    Попробуйте стандартную нормализацию ваших данных (например, с помощью StandardScaler из sklearn) перед подачей в модель.

Следуя приведённым рекомендациям, вы сможете избежать возникновения NaN и улучшить результаты вашей модели.

Оцените материал
Добавить комментарий

Капча загружается...