2017-07-11 123 views
2

我已經使用Theano後端實現了具有Keras的卷積自動編碼器。我正在改變我的方法來嘗試處理不同大小的圖像。只要我使用numpy的stack函數來建立數據集(等大小的圖像),我是金。但是,對於不同大小的圖像,我們不能使用stack,而fit需要一個numpy數組。所以我改爲fit_generator以避免大小檢查。問題在於最後一層預期將16作爲輸入中的最後一個維度,我不明白爲什麼它會獲得原始圖像的維度。具有可變尺寸圖像的2D卷積神經網絡

看看下面的代碼和錯誤輸出。


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 
       ) 

Traceback (most recent call last):

File "stacko.py", line 107, in validation_steps=1

File "/usr/local/lib/python3.5/dist-packages/keras/legacy/interfaces.py", line 88, in wrapper return func(*args, **kwargs)

File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 1847, in fit_generator val_x, val_y, val_sample_weight)

File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 1315, in _standardize_user_data exception_prefix='target')

File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 139, in _standardize_input_data str(array.shape))

ValueError: Error when checking target: expected conv2d_7 to have shape (None, 1, None, 16) but got array with shape (1, 1, 10, 15)

回答

0

有兩個問題與上面的代碼:第一,圖像軸的大小必須是每層的過濾器的最小數量的倍數(在此情況下8);其次,fit_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 
       ) 

相關問題