Когда я подхожу под свою модель, я получаю ошибку ValueError: Ввод 0 последовательного слоя несовместим со слоем

#python #tensorflow #machine-learning #keras #deep-learning

Вопрос:

Я пытаюсь эмулировать LeNet, используя набор данных mnist,

Я делаю следующее,

 import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras import layers, models
from tensorflow.keras.utils import plot_model
from tensorflow.keras.optimizers import SGD

import matplotlib.pyplot as plt
import numpy as np

# Import dataset
(train_ds, test_ds), info_ds = tfds.load('mnist', split=['train','test'], 
                               as_supervised = True,
                               with_info=True,
                               batch_size = -1)

train_images, train_labels = tfds.as_numpy(train_ds)
test_images, test_labels = tfds.as_numpy(test_ds)

# Split test to obtain validation dataset
val_size = int(len(test_images) * 0.8)
val_images, test_images = test_images[:val_size], test_images[val_size:]
val_labels, test_labels = test_labels[:val_size], test_labels[val_size:]

# Normalizing images between 0 to 1
train_images, test_images = train_images / 255.0, test_images / 255.0

# Create the model
model = models.Sequential()
model.add(layers.Conv2D(filters=6, kernel_size=(5,5), activation='relu', input_shape=(32,32,3)))
model.add(layers.MaxPooling2D(pool_size=(2,2)))
model.add(layers.Conv2D(filters=16, kernel_size=(5,5), activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(120,activation='relu'))
model.add(layers.Dense(84,activation='relu'))
model.add(layers.Dense(10,activation='softmax'))

# Compile
opt = SGD(learning_rate=0.1)
model.compile(optimizer=opt,
               loss='categorical_crossentropy',
               metrics=['accuracy'])

# Fit
history = model.fit(train_images, train_labels,
                    epochs=10, batch_size=128,
                    validation_data=(val_images, val_labels),
                    verbose=2)
 

Когда подходит, я получаю эту ошибку:

Ошибка значения: Ввод 0 последовательного слоя несовместим со слоем: ожидаемая ось -1 входной формы должна иметь значение 3, но полученный ввод с формой (нет, 28, 28, 1)

Это означает, что я должен изменить форму изображений mi?

Я подумал, что, возможно, мне придется преобразовать свои ярлыки в категоричные, как это

 from tensorflow.keras.utils import to_categorical

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
 

Но затем снова появляется та же ошибка,

Ошибка значения: Ввод 0 слоя sequential_1 несовместим со слоем: ожидаемая ось -1 входной формы должна иметь значение 3, но полученный ввод с формой (нет, 28, 28, 1)

Может ли кто-нибудь помочь мне разобраться в этом?

Большое спасибо!

Комментарии:

1. Посмотрите на это: input_shape=(32,32,3), вы видите здесь что-нибудь не так по сравнению с вашим сообщением об ошибке?

2. Фок, это потому, что я тоже пробовал использовать набор данных Cifar10, чтобы понять, была ли проблема в оттенках серого…

Ответ №1:

В вашем коде есть две проблемы. Такие как

  • (Выпуск 1) Вы устанавливаете input_shpae = (32,32,3) в своей модели, в то время как образцы mnist являются (28, 28, 1) . Если вы проверите свои образцы форм, вы увидите:
 train_images.shape, train_labels.shape
((60000, 28, 28, 1), (60000,))
 

Но вы определяете свою входную форму как не ту же самую в определении модели.

 # current: and not OK, according to the sample shapes 
...kernel_size=(5,5), activation='relu', input_shape=(32,32,3))) 

# should be, otherwise resize your input 
...kernel_size=(5,5), activation='relu', input_shape=(28,28,3))) 
 
  • (Выпуск 2) Входные метки являются целочисленными (а не однократно закодированными), проверьте train_labels[:5] , но вы установили categorical_crossentropy , тогда как это должно быть sparse_categorical_crossentropy для целочисленной цели.
 current
model.compile(optimizer=opt,
               loss='categorical_crossentropy', # when labels are one-hot encoded 
               metrics=['accuracy'])

should be 
model.compile(optimizer=opt,
               loss='sparse_categorical_crossentropy',  # when label are integers 
               metrics=['accuracy'])
 

Теперь, как вы упомянули позже, что вы попытались to_categorical одним нажатием закодировать целевую метку, в этом случае вы можете использовать categorical_crossentropy ее в качестве функции потерь.

Комментарии:

1. Спасибо! Первая проблема заключалась в ошибке с использованием набора данных cifar10, когда я пытался решить вторую проблему, а вторая возникла из-за того, что я забыл классифицировать метки проверки и потому, что мои знания о категории_кроссентропии и разрежение_категории_корссентропии очень низкие. Теперь я буду читать о них, чтобы понять, когда интересно использовать то или иное! 🙂