Keras 零除错误:整数除法或取模运算中的零。

4
我将使用Keras和Tensorflow实现一个卷积神经网络。
以下是我的代码:
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense

model = Sequential()
model.add(Conv2D(32, (2, 2), input_shape=(3, 150, 150), padding='SAME'))
model.add(Activation('relu'))
# model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_first"))

model.add(Conv2D(32, (2, 2), padding='SAME'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_first"))

model.add(Conv2D(64, (2, 2), padding='SAME'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_first"))

print("after declaring models")

model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

print("After creating the model\n")


batch_size = 16

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)

# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
        '../input/train',  # this is the target directory
        target_size=(150, 150),  # all images will be resized to 150x150
        batch_size=batch_size,
        class_mode='binary')  # since we use binary_crossentropy loss, we need binary labels            

model.fit_generator(
        train_generator,
        steps_per_epoch=2000 // batch_size,
        epochs=50)

问题在于我在最后一行得到了以下内容:
Epoch 1/50
17.3s
6
Exception in thread Thread-20:
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/opt/conda/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/utils/data_utils.py", line 590, in data_generator_task
    generator_output = next(self._generator)
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/preprocessing/image.py", line 737, in __next__
    return self.next(*args, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/preprocessing/image.py", line 1026, in next
    index_array, current_index, current_batch_size = next(self.index_generator)
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/preprocessing/image.py", line 720, in _flow_index
    current_index = (self.batch_index * batch_size) % n
ZeroDivisionError: integer division or modulo by zero

17.3s
7
Traceback (most recent call last):
  File "../src/script.py", line 115, in <module>
    epochs=50)
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/legacy/interfaces.py", line 87, in wrapper
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/models.py", line 1117, in fit_generator
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/legacy/interfaces.py", line 87, in wrapper
  File "/opt/conda/lib/python3.6/site-packages/Keras-2.0.5-py3.6.egg/keras/engine/training.py", line 1809, in fit_generator
StopIteration

怎么可能除以0呢?我不明白任何变量怎么会是0。

那个目录里有图片吗? - Srikar Appalaraju
有的。 - bsky
它们的格式是什么? - Marcin Możejko
问题显然是在current_index = (self.batch_index * batch_size) % n这一行中出现了模零。我怀疑flow_from_directory方法失败了,导致你没有可用的数据。 - JAustin
@octavian 对我来说,代码已经超过了从目录读取的部分。但它确实失败了。CNN架构是错误的。 - Srikar Appalaraju
@octavian 不确定,你是否已经解决了这个错误。需要检查的一件事是目录的读取权限。我遇到了同样的问题,并意识到 'flow_from_directory' 由于权限问题无法读取文件。希望能有所帮助。 - Pramit
2个回答

14

除零错误是由于n等于零。 n 是要循环遍历的数据集中样本的总数,这意味着您的图像生成器未能提供任何数据。最有可能的原因是训练数据的排列方式不正确。Keras希望图像按照每个图像类别包含一个子目录的方式排列,例如

input/
    train/
        class_0/
            class_0_0.jpg
            class_0_1.jpg
            ...
        class_1/
            class_1_0.jpg
            class_1_1.jpg
            ...
        ...
请注意,即使是非分类任务也适用。当 class_modeNone 时,flow_from_directory 仍然需要一个包含图像子目录的目录。

1
我的文件夹结构没有这样的子文件夹。所有图像都在一个文件夹中。与每个图像相对应的标签是写在一个单独的文件中的。我该如何调整我的文件结构,以便可以在Keras中使用它? - bsky
目前的 ImageDataGenerator 版本无法与您的设置正确配合使用。您必须将图像排列在子目录中,或编写自定义生成器。 - Sergii Gryshkevych
是否有替代ImageDataGenerator的方法? - bsky
你可以使用 fit 代替 fit_generator。在这种情况下,输入是以 numpy 数组的形式提供的。当然,这取决于你的训练集大小。 - Sergii Gryshkevych
在使用n_jobs=8的GridSearchCV进行keras分类问题时,我遇到了除以零的错误。这个问题出现在广泛的超参数范围内,如epochs [100,200...1000],batch_size [100,200...1000]和完整的激活函数、优化器等。我的数据集很小,只有952条记录,然后被分成80:20。这是因为数据太少的原因吗? - hanzgs
无论数据集大小是否是问题,n_jobs=1的情况下都可以工作。 - hanzgs

0

我的情况略有不同,但与您的错误信息一样,答案就在信息中。我的问题出现在Tensorboard回调中。我尝试使用update_freq=0禁用它:

tf.keras.callbacks.TensorBoard(
        log_dir=logdir,
        update_freq=0)

这给了我错误信息:

if self.update_freq != 'epoch' and batch % self.update_freq == 0:
ZeroDivisionError: integer division or modulo by zero

而且这个赠品是在 batch % self.update_freq == 0 中获得的。

阅读了Tensorboard回调文档后,我意识到我使用了一个无效的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接