Вопрос или проблема
У меня есть проблемы с построением слоев в Keras. Я объясню всю проблему:
- У меня есть матрица признаков с размерами: 2023 (строки) x 65 (признаки);
- Я пытался построить 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
требует трехмерный тензор, и корректная подготовка данных для нейронной сети критически важна для ее успешной работы. Убедитесь, что ваши данные соответствуют ожидаемому формату, и старайтесь всегда задать явные формы входных данных для слоя.