Проблемы с формой Conv1D в Keras

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

У меня есть проблемы с построением слоев в Keras. Я объясню всю проблему:

  1. У меня есть матрица признаков с размерами: 2023 (строки) x 65 (признаки);
  2. Я пытался построить CNN, с Conv1D в качестве первого слоя;

Мой код:

def cnn_model():
    model = Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss="mse", optimizer="adam", metrics=['mse', 'mae'])
    model.fit(X, Y, epochs=100, batch_size=64, verbose=0)
    model.evaluate(X, Y)
    return model

scoring = make_scorer(score_func=pearson)
# оценка модели с использованием стандартизированного набора данных
estimation = []
estimation.append(('standardize', StandardScaler()))
estimation.append(('mlp', KerasRegressor(build_fn=cnn_model, epochs=50, batch_size=32, verbose=0)))
pipeline = Pipeline(estimation)
kfold = KFold(n_splits=10, shuffle=True, random_state=1)
results = cross_val_score(pipeline, X, Y, cv=kfold, scoring=scoring)

Проблема в том, что, когда я запускаю, я получаю следующую ошибку:

ValueError: Input 0 of layer sequential_9 is incompatible with the layer: : expected min_ndim=3, found ndim=2. Full shape received: (None, 64)

Я действительно не знаю, почему возникает эта ошибка. Возможно, это просто проблема с передачей параметров, я довольно новичок в этой области. Можете сказать мне что-то еще? Я пробовал множество способов, чтобы решить эту ошибку, но каждый раз получаю новые ошибки вместо решения. Спасибо всем.

Я только что попробовал вашу функцию cnn_model, и она работает правильно для меня.

Не уверен, в чем ваша проблема, но, похоже, дело в ваших X и Y. X не должен иметь форму (2023, 65), а форму (datasize, 2023, 65). И Y также должен иметь форму (datasize, 1). В противном случае ваша сеть воспринимает X как 2023 входа формы (None, 65), вместо того чтобы рассматривать это как n входов формы (None, 2023, 65).

Вот мой код на случай, если вы захотите его запустить (важная часть – определение X(ims) и Y(lab)):

import keras
from keras.layers import Conv1D, Dropout, MaxPooling1D, Flatten, Dense
import numpy as np

ims = np.random.randn(100, 2023, 65)
lab = np.random.randn(100, 1)

def cnn_model(X, Y):
    model = keras.Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss="mse", optimizer="adam", metrics=['mse', 'mae'])
    print('обучение')
    model.fit(X, Y, epochs=10, batch_size=32, verbose=0)
    print('обучение завершено')
    model.evaluate(X, Y)
    return model


m = cnn_model(ims, lab)
m.summary()

Если мы посмотрим на документацию Keras Здесь,

Форма входа

3+D тензор с формой: batch_shape + (steps, input_dim)

Итак, вход должен быть спроектирован как Batch, Seq, Dim.

В этом случае мы можем предположить длину последовательности 65 и размерность 1.

from sklearn.datasets import make_moons, make_circles, make_classification
from tensorflow import keras
from tensorflow.keras import layers

X, Y = make_classification(n_features=65, n_redundant=0, n_informative=1, n_clusters_per_class=1)

X = X.reshape(-1,65,1) # Изменено на Batch, Seq, Dim

model = keras.models.Sequential()
model.add(layers.Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(layers.Dropout(0.25))
model.add(layers.Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(layers.Dropout(0.25))
model.add(layers.MaxPooling1D(pool_size=2))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss="mse", optimizer="adam", metrics=['mse', 'mae'])
model.fit(X, Y, epochs=100, batch_size=64, verbose=0)
model.evaluate(X, Y)

Ответ или решение

Проблемы с форматом Conv1D в Keras: Подробный анализ

При построении сверточной нейронной сети (CNN) с использованием Keras многие пользователи сталкиваются с проблемами, связанными с неправильной формой входных данных для слоя Conv1D. В данной статье мы подробно рассмотрим типичные ошибки, касающиеся формата данных, и предложим решения для их устранения.

Понимание структуры данных

Для начала рассмотрим, каков правильный формат входных данных для Conv1D. По документации Keras, входные данные должны представлять собой 3D тензор с формой:

(batch_size, steps, input_dim)

Где:

  • batch_size — размер пакета данных
  • steps — длина последовательности (количество временных шагов)
  • input_dim — количество признаков (размерность входа на каждом временном шаге)

В вашем случае, если у вас есть матрица признаков размера 2023 x 65, вам необходимо преобразовать ее в правильный формат.

Решение проблемы с формой данных

С учетом указанного вами формата, X должен быть преобразован из (2023, 65) в (batch_size, 2023, 65), чтобы Keras смог правильно интерпретировать данные. Если вы хотите использовать весь ваш набор данных за один раз, batch_size будет равен 1, что приведет к следующему преобразованию:

import numpy as np

# Исходные данные
X = np.random.randn(2023, 65)

# Преобразование входных данных
X = X.reshape(1, 2023, 65)  # Превращаем оси в (batch_size, steps, input_dim)

# Y также нужно преобразовать соответственно, если у вас 2023 метки
Y = np.random.randn(1, 1)  # При условии одной метки для всего пакета

Если у вас есть множество примеров, вы можете создать массив с размерностью (num_samples, 2023, 65), где num_samples — это количество образцов в вашем наборе данных.

Пример кода с исправлением

from keras.models import Sequential
from keras.layers import Conv1D, Dropout, MaxPooling1D, Flatten, Dense

def cnn_model(X, Y):
    model = Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(2023, 65)))
    model.add(Dropout(0.25))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss="mse", optimizer="adam", metrics=['mse', 'mae'])

    model.fit(X, Y, epochs=100, batch_size=32, verbose=0)
    return model

# Пример задания входных данных
num_samples = 100  # Примерное количество образцов
X = np.random.randn(num_samples, 2023, 65)
Y = np.random.randn(num_samples, 1)

model = cnn_model(X, Y)
model.summary()

Заключение

Часто проблемы с форматом данных легко решаются через правильное понимание ожидаемой формы входных данных для различных слоев Keras. Важно помнить, что слой Conv1D требует трехмерный тензор, и корректная подготовка данных для нейронной сети критически важна для ее успешной работы. Убедитесь, что ваши данные соответствуют ожидаемому формату, и старайтесь всегда задать явные формы входных данных для слоя.

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

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