У меня есть набор данных, который я пытаюсь обучить с помощью Keras, но каждый раз, когда я получаю эту ошибку: «ValueError: Shapes (None, 1) и (None, 48, 48, 96) несовместимы», и я не могу понять это в чем дело. Я читал другие связанные вопросы, но не мог понять суть моей проблемы
DATASET_PATH = "/Users/user/Documents/ML Projects/Dataset"
CLASSNAME_SIZE = 96
IMG_SIZE = 48
#Creating Dictionary of Classname
with open(JSON_PATH) as classnameJSON:
CLASSNAME = json.loads(classnameJSON.read())
trainingData = []
X = []
Y = []
#loading data
def loadTrainingData():
for instance in range(CLASSNAME_SIZE):
joinedPath = os.path.join(DATASET_PATH, str(instance))
label = str(instance)
for img in os.listdir(joinedPath):
try:
img_array = cv2.imread(os.path.join(joinedPath,img), cv2.COLOR_BGR2RGB)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
trainingData.append([new_array, label])
except Exception as err:
pass
loadTrainingData()
print(len(trainingData))
def distributeTrainingData():
for img, label in trainingData:
X.append(img)
Y.append(label)
distributeTrainingData()
print("distributing data")
X = np.array(X, dtype='float32')
Y = np.array(Y, dtype='float32')
print(len(X))
print(len(Y))
def cnn_model():
model = Sequential()
model.add(Dense(128, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(CLASSNAME_SIZE, activation='softmax'))
return model
model = cnn_model()
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(X, Y, batch_size=32, epochs=3)
Прежде чем добавлять плотные слои, попробуйте добавить:
model.add(keras.layers.InputLayer(input_shape=(X.shape[1],)))
Есть две проблемы с вашим кодом.
Во-первых, вам нужно решить, хотите ли вы сразу закодировать свои цели и использовать потерю categorical_crossentropy
или передать их как 1D-тензор и использовать потерю sparse_categorical_crossentropy
.
Вы передаете их как одномерный тензор при использовании потери categorical_crossentropy
. Эти двое несовместимы. Легкое решение для вас - изменить потерю на sparse_categorical_crossentropy
.
Вторая проблема заключается в том, что вы передаете 3D-тензор (изображение) в плотный слой, который ожидает плоский ввод. Если вы не хотите использовать сверточные слои (и даже если), вам нужно будет сгладить ввод, прежде чем передавать его в плотные слои. Вы можете использовать keras.layers.Flatten()
для этого.
Итак, измените метод compile
на
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
и добавьте слой Flatten
к своей модели.
def cnn_model():
model = Sequential()
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(CLASSNAME_SIZE, activation='softmax'))
return model
model = cnn_model()
Если вы хотите добавить несколько сверточных (keras.layers.Conv2D
) слоев перед плотными слоями, слой Flatten
будет добавлен между сверточной основой и плотным верхом.
def cnn_model():
model = Sequential()
model.add(Conv2D(...))
# ... more conv/pool layers
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(CLASSNAME_SIZE, activation='softmax'))
return model