Python 3.x 具有可变尺寸图像的二维卷积神经网络

Python 3.x 具有可变尺寸图像的二维卷积神经网络,python-3.x,theano,convolution,keras-2,Python 3.x,Theano,Convolution,Keras 2,我用Keras实现了一个卷积自动编码器,使用Theano后端。我正在改变我的方法,尝试处理不同大小的图像。只要我使用numpy的stack函数来构建数据集(大小相等的图像),我就是黄金。但是,对于不同大小的图像,我们不能使用stack,而fit需要一个numpy数组。因此我改为fit_generator,以避免尺寸检查。问题是最后一层期望16作为输入中的最后一个维度,我无法理解为什么它得到原始图像的维度 看看下面的代码和错误输出 import numpy as np import keras

我用Keras实现了一个卷积自动编码器,使用Theano后端。我正在改变我的方法,尝试处理不同大小的图像。只要我使用numpy的
stack
函数来构建数据集(大小相等的图像),我就是黄金。但是,对于不同大小的图像,我们不能使用
stack
,而
fit
需要一个numpy数组。因此我改为
fit_generator
,以避免尺寸检查。问题是最后一层期望16作为输入中的最后一个维度,我无法理解为什么它得到原始图像的维度

看看下面的代码和错误输出


import numpy as np
import keras
from keras.models import Sequential, Model
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D

AE_EPOCHS = 10
VERB = 1
batchsz = 16
outfun = 'sigmoid'

data = []
dimensions = [(10, 15), (12, 15), (7,15), (20,15), (25,15)]

for d in dimensions:
    dd = np.random.rand(*d)
    dd = dd.reshape((1,)+dd.shape)
    data.append(dd)

input_img = Input(shape=(1, None, 15))
filtersz = 3
pad_it = 'same'
size1 = 16
size2 = 8
x = Conv2D(size1, (filtersz, filtersz), activation='relu', padding=pad_it)(input_img)
x = MaxPooling2D((2, 2), padding=pad_it)(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = MaxPooling2D((2, 2), padding=pad_it)(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
encoded = MaxPooling2D((2, 2), padding=pad_it)(x)

x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(encoded)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
x = Conv2D(size1, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
decoded = Conv2D(1, (filtersz, filtersz), activation=outfun, padding=pad_it)(x)

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

x_train = data[1:]
x_test= data[0].reshape((1,)+ data[0].shape)

def mygen(xx, *args, **kwargs):
    for i in xx:
        yield (i,i)

thegen = mygen(x_train)
#If I use this generator somehow None is returned so it is not used
thegenval = mygen(np.array([x_test]))

hist = autoencoder.fit_generator(thegen,
                epochs=AE_EPOCHS,
                steps_per_epoch=4,
                verbose=VERB,
                validation_data=(x_test, x_test),
                validation_steps=1
                )

回溯(最近一次呼叫最后一次):

文件“stacko.py”,第107行,在 验证步骤=1

文件“/usr/local/lib/python3.5/dist-packages/keras/legacy/interfaces.py”,第88行,在包装器中 返回函数(*args,**kwargs)

文件“/usr/local/lib/python3.5/dist-packages/keras/engine/training.py”,第1847行,在fit_生成器中 val_x,val_y,val_样品重量)

文件“/usr/local/lib/python3.5/dist-packages/keras/engine/training.py”,第1315行,在用户数据中 异常(前缀='target')

文件“/usr/local/lib/python3.5/dist-packages/keras/engine/training.py”,第139行,输入数据 str(array.shape))

ValueError:检查目标时出错:预期conv2d_7具有形状(无,1,无,16),但获得具有形状(1,1,10,15)的数组


上面的代码有两个问题:第一,图像轴的大小必须是每层最小过滤器数量的倍数(在本例中为8);其次,
fit\u generator
的生成器必须返回批(4D numpy数组)

生成器使用
itertools.cycle
实现,并将图形重塑为一个样本批次(如果使用多个具有常见尺寸的图像,则每个尺寸组可以有不同尺寸的批次)。工作示例如下所示


import numpy as np
from itertools import cycle

import keras
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D

AE_EPOCHS = 10
VERB = 1
outfun = 'sigmoid'

data = []
dimensions = [(16, 32), (24, 32), (8,32), (32,32)]
for d in dimensions:
    dd = np.random.rand(*d)
    dd = dd.reshape((1,)+dd.shape)
    data.append(dd)

input_img = Input(shape=(1, None, 32))
filtersz = 3
pad_it = 'same'
size1 = 16
size2 = 8
x = Conv2D(size1, (filtersz, filtersz), activation='relu', padding=pad_it)(input_img)
x = MaxPooling2D((2, 2), padding=pad_it)(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = MaxPooling2D((2, 2), padding=pad_it)(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
encoded = MaxPooling2D((2, 2), padding=pad_it)(x)

x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(encoded)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
x = Conv2D(size2, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
x = Conv2D(size1, (filtersz, filtersz), activation='relu', padding=pad_it)(x)
x = UpSampling2D((2, 2), data_format="channels_first")(x)
decoded = Conv2D(1, (filtersz, filtersz), activation=outfun, padding=pad_it)(x)

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


x_train = data[1:]
x_test= [data[0]]

def mygen(xx, *args, **kwargs):
    for i in cycle(xx):
        ii = i.reshape((1,)+i.shape)
        yield ii,ii

thegen = mygen(x_train)
thegenval = mygen(x_test)

hist = autoencoder.fit_generator(
                thegen,
                epochs=AE_EPOCHS,
                steps_per_epoch=3,
                verbose=VERB,
                validation_data=thegenval,
                validation_steps=1
                )