前提・実現したいこと
kerasのimagedatageneratorを使って,各画像の平均を0にする処理を行おうとしたのですが,以下のようなエラーが発生してしまいました.
generatorのoutputが正しくないといわれているようなのですが,kerasの公式ドキュメントを見ても修正方法がよくわかりませんでした.お手数お掛けいたしますが,どのように修正したら良いかご教示いただけますと大変助かります.
発生している問題・エラーメッセージ
ValueError Traceback (most recent call last) <ipython-input-7-86574fd9be32> in <module>() 340 validation_steps=epochs, 341 verbose=1, --> 342 callbacks=callbacks) 343 344 plot_results(models, data, batch_size=batch_size, model_name="vae_OCT") ValueError: Output of generator should be a tuple `(x, y, sample_weight)` or `(x, y)`. Found: [[[[-0.12498678] [-0.12498678] [-0.12498678] ... [-0.03086913] [-0.07400638] [-0.12498678]] [[-0.12498678] [-0.12498678] [-0.12498678] ... [-0.05439854] [-0.08184952] [-0.12106521]] [[-0.12498678] [-0.12498678] [-0.12498678] ... [-0.08577108] [-0.0975358 ] [-0.1093005 ]] ...
該当のソースコード
Python
from __future__ import absolute_import from __future__ import division from __future__ import print_function from keras.layers import Lambda, Input, Dense from keras.models import Model from keras.models import Sequential, model_from_json from keras.losses import mse, binary_crossentropy from keras.layers import Conv2D, Flatten from keras.layers import Reshape, Conv2DTranspose from keras.utils import plot_model, np_utils from keras.utils import plot_model from keras.callbacks import Callback, EarlyStopping, TensorBoard, ModelCheckpoint, LearningRateScheduler, CSVLogger from keras import optimizers from keras import backend as K from keras.preprocessing.image import array_to_img, img_to_array,load_img from keras.preprocessing.image import ImageDataGenerator from keras.layers import Activation, BatchNormalization import numpy as np import matplotlib.pyplot as plt import argparse import os import re import glob import random as rn import tensorflow as tf import cv2 from PIL import Image import warnings warnings.filterwarnings('ignore') %matplotlib inline get_ipython().run_line_magic('matplotlib', 'inline') #reparameterization trick # instead of sampling from Q(z|X), sample eps = N(0,I) # z = z_mean + sqrt(var)*eps def sampling(args): """Reparameterization trick by sampling fr an isotropic unit Gaussian. # Arguments args (tensor): mean and log of variance of Q(z|X) # Returns z (tensor): sampled latent vector """ z_mean, z_log_var = args batch = K.shape(z_mean)[0] dim = K.int_shape(z_mean)[1] # by default, random_normal has mean=0 and std=1.0 epsilon = K.random_normal(shape=(batch, dim)) return z_mean + K.exp(0.5 * z_log_var) * epsilon def plot_results(models, data, batch_size=25, model_name="vae_OCT"): """Plots labels and MNIST digits as function of 2-dim latent vector # Arguments models (tuple): encoder and decoder models data (tuple): test data and label batch_size (int): prediction batch size model_name (string): which model is using this function """ encoder, decoder = models x_test = data os.makedirs(model_name, exist_ok=True) filename = os.path.join(model_name, "vae_mean.png") # display a 2D plot of the digit classes in the latent space z_mean, _, _ = encoder.predict(x_test, batch_size=batch_size) #original dataset #train filenames = glob.glob("./NORMAL_resize_pixel_100_1_0506/*.jpeg") x_train= [] for filename in filenames: img = img_to_array(load_img( filename, color_mode = "grayscale" , target_size=(512,496))) x_train.append(img) x_train = np.asarray(x_train) print(x_train.shape) #test filenames = glob.glob("./NORMAL_resize_pixel_0506/*.jpeg") x_test= [] for filename in filenames: img = img_to_array(load_img( filename, color_mode = "grayscale" , target_size=(512,496))) x_test.append(img) x_test = np.asarray(x_test) image_size_width = x_train.shape[1] image_size_height = x_train.shape[2] original_dim = 512 * 496 #3削除 x_train = np.reshape(x_train, [-1, image_size_width,image_size_height,1]) x_test = np.reshape(x_test,[ -1, image_size_width,image_size_height,1]) x_train = x_train.astype('float32') / 255 x_test = x_test.astype('float32') / 255 #numpy配列をタプルに変換 x_train = tuple(x_train) x_test = tuple(x_test) #各サンプルの平均を0にする train_datagen = ImageDataGenerator(samplewise_center=True) train_generator = train_datagen.flow(x_train, batch_size=32) validation_datagen = ImageDataGenerator(samplewise_center=True) validation_generator = validation_datagen.flow(x_test, batch_size=32) print(x_train.shape) print(x_test.shape) # network parameters input_shape = (image_size_width,image_size_height,1) batch_size = 25#50 kernel_size = 3 filters = 16 latent_dim = 2 epochs = 100 # VAE model = encoder + decoder # build encoder model inputs = Input(shape=input_shape, name='encoder_input') x = inputs for i in range(4): filters *= 2 x = Conv2D(filters=filters, kernel_size=kernel_size, activation = 'relu', strides=2,padding='same')(x) #x = BatchNormalization()(x) #x = Activation('relu')(x) # shape info needed to build decoder model shape = K.int_shape(x) # generate latent vector Q(z|X) x = Flatten()(x) x = Dense(64, activation='relu')(x) z_mean = Dense(latent_dim, name='z_mean')(x) z_log_var = Dense(latent_dim, name='z_log_var')(x) # use reparameterization trick to push the sampling out as input # note that "output_shape" isn't necessary with the TensorFlow backend z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var]) # instantiate encoder model encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder') encoder.summary() plot_model(encoder, to_file='vae_cnn_encoder.png', show_shapes=True) # build decoder model latent_inputs = Input(shape=(latent_dim,), name='z_sampling') x = Dense(shape[1] * shape[2] * shape[3], activation='relu')(latent_inputs) x = Reshape((shape[1], shape[2], shape[3]))(x) for i in range(4): x = Conv2DTranspose(filters=filters, kernel_size=kernel_size, activation = 'relu', strides=2,padding='same')(x) #x = BatchNormalization()(x) #x = Activation('relu')(x) filters //= 2 outputs = Conv2DTranspose(filters=1, kernel_size=kernel_size, activation='sigmoid', padding='same', name='decoder_output')(x) #outputs = BatchNormalization()(outputs)#(x) #outputs = Activation('sigmoid')(outputs)#(x) # instantiate decoder model decoder = Model(latent_inputs, outputs, name='decoder') decoder.summary() plot_model(decoder, to_file='vae_cnn_decoder.png', show_shapes=True) # instantiate VAE model outputs = decoder(encoder(inputs)[2]) vae = Model(inputs, outputs, name='vae') def plot_history(history): # ?????????? plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('model loss') plt.xlabel('epoch') plt.ylabel('loss') plt.legend(['loss', 'val_loss'], loc='lower right') plt.savefig('loss.png') # -----(2) plt.show() if __name__ == '__main__': parser = argparse.ArgumentParser() help_ = "Load h5 model trained weights" parser.add_argument("-w", "--weights", help=help_) help_ = "Use mse loss instead of binary cross entropy (default)" parser.add_argument("-m", "--mse", help=help_, action='store_true') args = parser.parse_args([]) models = (encoder, decoder) data = (x_test) # VAE loss = mse_loss or xent_loss + kl_loss if args.mse: reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs)) else: reconstruction_loss = binary_crossentropy(K.flatten(inputs), K.flatten(outputs)) reconstruction_loss *= image_size_width * image_size_height kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) vae.add_loss(vae_loss) Adam = optimizers.Adam(lr=0.0005) vae.compile(optimizer=Adam) vae.summary() plot_model(vae, to_file='vae_cnn.png', show_shapes=True) callbacks = [] callbacks.append(ModelCheckpoint(filepath="model.ep{epoch:02d}.h5", save_best_only = True, period=5)) callbacks.append(EarlyStopping(monitor='val_loss', patience=7, verbose=1)) callbacks.append(CSVLogger("history.csv")) if args.weights: vae.load_weights(args.weights) else: # train the autoencoder history = vae.fit_generator(train_generator, steps_per_epoch=x_train.shape[0] // batch_size, epochs=epochs,#20, validation_data=(validation_generator,None), validation_steps=x_test.shape[0] // batch_size, verbose=1, callbacks=callbacks) plot_results(models, data, batch_size=batch_size, model_name="vae_OCT") plot_history(history)
試したこと
validatioon_stepsの書き方が悪いのかと思い,「20」と整数を入れたりもしてみましたが,結果は変わりませんでした.
補足情報(FW/ツールのバージョンなど)
google colabを使っています.
まだ回答がついていません
会員登録して回答してみよう