Сверточный автоэнкодер не обучается на наборе данных (62,47,1), «Ожидаемая ошибка формы» - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь реализовать сверточный автоэнкодер на гранях в наборе данных Wild, который состоит из изображений в формате 62x47x3.

Однако пример сверточного автоэнкодера Keras в наборе данных mnist не работает сэтот новый набор данных, на котором я тренируюсь.

Он выдает эту ошибку

Error when checking target: expected conv2d_102 to have shape (60, 44, 3) but got array with shape (62, 47, 3)

о том, что определенный слой получает неправильную форму, даже после включения

padding='same'

команды, которые должны сделать входные и выходные формы равными.

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

Вот основныекод, с которым я работаю


import tensorflow
import keras
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Model, Sequential
from keras.layers import Dense, Conv2D, Dropout, BatchNormalization, Input, Reshape, Flatten, Deconvolution2D, Conv2DTranspose, MaxPooling2D, UpSampling2D, LeakyReLU
from keras.layers.advanced_activations import LeakyReLU
from keras.optimizers import adam

from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split

#importing the dataset in color cause that's dope
lfw_data = fetch_lfw_people(color=True)

#putting the data of images into a variable
x = lfw_data.images

#making a train and validation set
(x_train,x_test) = train_test_split(x, test_size=0.25)

#normalizing the pixel values
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.

print(x_train.shape)

x_train = x_train.reshape(len(x_train), 62,47,3)
x_test = x_test.reshape(len(x_test), 62,47,3)

from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras import backend as K

input_img = Input(shape=(62, 47, 3))  # adapt this if using `channels_first` image data format

x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)

# at this point the representation is (4, 4, 8) i.e. 128-dimensional

x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(16, (3, 3), activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

autoencoder.summary()

и вывод сводной информации о модели

Model: "model_14"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_18 (InputLayer)        (None, 62, 47, 3)         0         
_________________________________________________________________
conv2d_103 (Conv2D)          (None, 62, 47, 16)        448       
_________________________________________________________________
max_pooling2d_45 (MaxPooling (None, 31, 24, 16)        0         
_________________________________________________________________
conv2d_104 (Conv2D)          (None, 31, 24, 8)         1160      
_________________________________________________________________
max_pooling2d_46 (MaxPooling (None, 16, 12, 8)         0         
_________________________________________________________________
conv2d_105 (Conv2D)          (None, 16, 12, 8)         584       
_________________________________________________________________
max_pooling2d_47 (MaxPooling (None, 8, 6, 8)           0         
_________________________________________________________________
conv2d_106 (Conv2D)          (None, 8, 6, 8)           584       
_________________________________________________________________
up_sampling2d_42 (UpSampling (None, 16, 12, 8)         0         
_________________________________________________________________
conv2d_107 (Conv2D)          (None, 16, 12, 8)         584       
_________________________________________________________________
up_sampling2d_43 (UpSampling (None, 32, 24, 8)         0         
_________________________________________________________________
conv2d_108 (Conv2D)          (None, 30, 22, 16)        1168      
_________________________________________________________________
up_sampling2d_44 (UpSampling (None, 60, 44, 16)        0         
_________________________________________________________________
conv2d_109 (Conv2D)          (None, 60, 44, 1)         145       
=================================================================
Total params: 4,673
Trainable params: 4,673
Non-trainable params: 0
____________________________

Когда я пытаюсь тренироваться

#train for 100 epochs
history = autoencoder.fit(x_train, x_train,epochs=100,batch_size=256, shuffle=True, validation_data=(x_test, x_test))

, я получаю это сообщение об ошибке

Error when checking target: expected conv2d_102 to have shape (60, 44, 3) but got array with shape (62, 47, 3)

Любая помощь или объяснение того, почему она выдает эту ошибку, была бы великолепна!

1 Ответ

1 голос
/ 08 октября 2019

Это из-за того, что пулы и отступы не совпадают. Ваши данные имеют форму (62,47), но ваша модель выдает (60,44). Вам необходимо правильно скорректировать модель или данные.

В зависимости от того, как работает пул (разделите на 2), и учитывая, что у вас есть 3 пула, размер вашего изображения будет правильно совпадать только с пулами, если он кратен 2^ 3 = 8. Поскольку размеры 64 и 48 очень близки к размерам ваших изображений, кажется, что самым простым решением было бы добавить отступы к изображениям.

Итак, сделайте так, чтобы ваши данные имели размер (64,48). - Это позволит создать до 4 пулов без необходимости использования пользовательских подстановок в модели.

x_train = np.pad(x_train, ((0,0), (1,1), (0,1), (0,0)), mode='constant')
x_test = np.pad(x_test, ((0,0), (1,1), (0,1), (0,0)), mode='constant')

Не забудьте установить padding='same' на все слои. Есть одна свертка, которая пропускает ее (предшествующая последней)

Возможно, некоторые из перечисленных режимов здесь могут работать лучше, чем другие. (Я бы попробовал mode='edge', например.)

...