AutoEncoder на Cifar10 Ошибка установки набора данных - PullRequest
0 голосов
/ 28 апреля 2020

Я загрузил набор данных Cifar10 из tf.keras.datasets.

(X_train, y_train), (X_test, y_test) = tk.datasets.cifar10.load_data()    # tk = tensorflow.keras

Формы теста поезда: train - (50000, 32, 32, 3) | test - (10000, 32, 32, 3)

Затем я создал кодировщик со следующими слоями:

encoder = Sequential()
# L1
encoder.add(Conv2D(filters=32, kernel_size=(3,3), input_shape=(32,32,3), activation='relu'))
encoder.add(BatchNormalization())
encoder.add(Activation('relu'))
encoder.add(MaxPool2D(pool_size=(2,2)))
# L2
encoder.add(Conv2D(filters=16, kernel_size=(3,3), activation='relu'))
encoder.add(BatchNormalization())
encoder.add(Activation('relu'))
encoder.add(MaxPool2D(pool_size=(2,2)))

и декодер со следующими слоями:

decoder = Sequential()
#L3
decoder.add(Conv2D(filters=16, kernel_size=(3,3), activation='relu'))
decoder.add(BatchNormalization())
decoder.add(Activation('relu'))
decoder.add(UpSampling2D(size=(2,2)))
#L4
decoder.add(Conv2D(filters=32, kernel_size=(3,3), activation='relu'))
decoder.add(BatchNormalization())
decoder.add(Activation('softmax'))
decoder.add(UpSampling2D(size=(2,2)))

Я скомпилировал его:

autoencoder = Sequential([encoder, decoder])
autoencoder.compile(loss='binary_crossentropy', optimizer='adam')

Затем поместите его так:

autoencoder.fit(x=X_train, y=X_train, batch_size=1000, epochs=50)

Я получаю сообщение об ошибке:

ValueError: A target array with shape (50000, 32, 32, 3) was passed for an output of shape (None, 12, 12, 32) while using as loss `binary_crossentropy`. This loss expects targets to have the same shape as the output.

В чем может быть причина этой ошибки?

1 Ответ

0 голосов
/ 29 апреля 2020

Давайте разберемся в проблеме

Слой обрезки обрежет изображения пропорционально ядру, поэтому если вы назовете следующие строки:

encoder.summary()
decoder.summary()

вы получите

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 30, 30, 32)        896       
_________________________________________________________________
batch_normalization (BatchNo (None, 30, 30, 32)        128       
_________________________________________________________________
activation (Activation)      (None, 30, 30, 32)        0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 13, 13, 16)        4624      
_________________________________________________________________
batch_normalization_1 (Batch (None, 13, 13, 16)        64        
_________________________________________________________________
activation_1 (Activation)    (None, 13, 13, 16)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 16)          0         
=================================================================
Total params: 5,712
Trainable params: 5,616
Non-trainable params: 96
_________________________________________________________________
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 4, 4, 16)          2320      
_________________________________________________________________
batch_normalization_2 (Batch (None, 4, 4, 16)          64        
_________________________________________________________________
activation_2 (Activation)    (None, 4, 4, 16)          0         
_________________________________________________________________
up_sampling2d (UpSampling2D) (None, 8, 8, 16)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 6, 6, 32)          4640      
_________________________________________________________________
batch_normalization_3 (Batch (None, 6, 6, 32)          128       
_________________________________________________________________
activation_3 (Activation)    (None, 6, 6, 32)          0         
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 12, 12, 32)        0         
=================================================================

но вы ожидали, что размеры будут примерно такими (верно ?!):

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 32, 32, 32)        896       
_________________________________________________________________
batch_normalization (BatchNo (None, 32, 32, 32)        128       
_________________________________________________________________
activation (Activation)      (None, 32, 32, 32)        0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 16, 16, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 16, 16, 16)        4624      
_________________________________________________________________
batch_normalization_1 (Batch (None, 16, 16, 16)        64        
_________________________________________________________________
activation_1 (Activation)    (None, 16, 16, 16)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 16)          0         
=================================================================
Total params: 5,712
Trainable params: 5,616
Non-trainable params: 96
_________________________________________________________________
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 8, 8, 16)          2320      
_________________________________________________________________
batch_normalization_2 (Batch (None, 8, 8, 16)          64        
_________________________________________________________________
activation_2 (Activation)    (None, 8, 8, 16)          0         
_________________________________________________________________
up_sampling2d (UpSampling2D) (None, 16, 16, 16)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 16, 16, 32)        4640      
_________________________________________________________________
batch_normalization_3 (Batch (None, 16, 16, 32)        128       
_________________________________________________________________
activation_3 (Activation)    (None, 16, 16, 32)        0         
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 32, 32, 32)        0         
=================================================================

используйте параметр padding="same" в слое Conv (если вы не знаете, что такое отступы, просто ищите его), тогда возникает другая проблема, вы не можете создать авто-кодировщик, выходной канал которого (32) не равен входному каналу (3), поэтому я предлагаю другой слой. Теперь посмотрите решение ниже, это легко сейчас.

Теперь решение

import tensorflow as tf
import numpy as np

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()
encoder = tf.keras.Sequential()
# L1
encoder.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3,3), input_shape=(32, 32, 3), activation='relu', padding='same'))
encoder.add(tf.keras.layers.BatchNormalization())
encoder.add(tf.keras.layers.Activation('relu'))
encoder.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
# L2
encoder.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same'))
encoder.add(tf.keras.layers.BatchNormalization())
encoder.add(tf.keras.layers.Activation('relu'))
encoder.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))


decoder = tf.keras.Sequential()
#L3
decoder.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same'))
decoder.add(tf.keras.layers.BatchNormalization())
decoder.add(tf.keras.layers.Activation('relu'))
decoder.add(tf.keras.layers.UpSampling2D(size=(2,2)))
#L4
decoder.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3,3), activation='relu', padding='same'))
decoder.add(tf.keras.layers.BatchNormalization())
decoder.add(tf.keras.layers.Activation('relu'))
decoder.add(tf.keras.layers.UpSampling2D(size=(2,2)))

#L5
decoder.add(tf.keras.layers.Conv2D(filters=3, kernel_size=(3,3), activation='relu', padding='same'))
decoder.add(tf.keras.layers.BatchNormalization())
decoder.add(tf.keras.layers.Activation('softmax'))

autoencoder = tf.keras.Sequential([encoder, decoder])
autoencoder.compile(loss='binary_crossentropy', optimizer='adam')
autoencoder.fit(x=X_train, y=X_train, batch_size=1000, epochs=50)
...