Python3 KerasのImageDataGenerator利用時のエラーについて(Zero Division Error)
kerasのImageDataGeneratorを使って各画像の平均を0にする処理を行おうと思っているのですが、以下のようなエラーが発生してしまいました。
ZeroDivisionError Traceback (most recent call last)
<ipython-input-9-af749fe0781b> in <module>()
371 validation_steps=25,
372 verbose=1,
--> 373 callbacks=callbacks)
374
375 plot_results(models, data, batch_size=batch_size, model_name="vae_OCT")
11 frames
/usr/local/lib/python3.6/dist-packages/keras_preprocessing/image/iterator.py in _flow_index(self)
83 self._set_index_array()
84
---> 85 current_index = (self.batch_index * self.batch_size) % self.n
86 if self.n > current_index + self.batch_size:
87 self.batch_index += 1
ZeroDivisionError: integer division or modulo by zero
公式ドキュメント通りに記載したのですが、このエラーは何が原因なのでしょうか。
パス指定がうまくいっていないような感じがしたので、色々と書き方を変えてみたのですが、結果は変わりませんでした。
お手数をおかけしますがご存知の方、解決方法についてご教示頂けますと幸いです。
コード全文は以下のとおりです。ImageDataGeneratorを使う前は問題なく動いていました。
https://keras.io/preprocessing/image/#flow
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
test_datagen = data#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)
train_data_dir = 'train_data_dir'
test_data_dir = 'test_data_dir'
os.makedirs(train_data_dir, exist_ok=True)
os.makedirs(test_data_dir, exist_ok=True)
#各サンプルの平均を0にする
train_datagen = ImageDataGenerator(rescale=1. / 255,
samplewise_center=True)
#train_generator = train_datagen.flow(x_train, None, batch_size=32)
train_generator = train_datagen.flow_from_directory("VAE/NORMAL_resize_pixel_100_1_0506/",
target_size=(512, 496),
color_mode='grayscale',
classes=None,
class_mode=None,
batch_size=32,
shuffle=True,
seed=None,
save_to_dir='train_data_dir',
save_prefix='',
save_format='jpeg',
follow_links=False,
subset=None,
interpolation='nearest')
validation_datagen = ImageDataGenerator(rescale=1. / 255,
samplewise_center=True)
validation_generator = validation_datagen.flow_from_directory("VAE/NORMAL_resize_pixel_0506/",
target_size=(512, 496),
color_mode='grayscale',
classes=None,
class_mode=None,
batch_size=32,
shuffle=True,
seed=None,
save_to_dir='test_data_dir',
save_prefix='',
save_format='jpeg',
follow_links=False,
subset=None,
interpolation='nearest')
# 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 = (validation_generator)
# 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=25,
epochs=epochs,#20,
validation_data=validation_generator,
validation_steps=25,
verbose=1,
callbacks=callbacks)
plot_results(models, data, batch_size=batch_size, model_name="vae_OCT")
plot_history(history)