首页 > 编程问答 >每隔一个 Keras 纪元在所有日志中都会返回零

每隔一个 Keras 纪元在所有日志中都会返回零

时间:2024-08-03 05:28:41浏览次数:11  
标签:python tensorflow keras image-classification

我正在尝试使用 Keras 和 Python 构建一个简单的二进制图像分类器。每隔一个训练周期,准确性、损失、val_accuracy 和 val_loss 都会返回零。其他时期运行良好,训练进展正常。我正在使用 25000 张独特的图像进行训练,其中包含三组卷积和池化。我对训练/测试图像进​​行了 90-10 的分割,并且所有图像都被打乱。我目前正在为我的标签和数据使用 Adam 优化器和标准化 ImageDataGenerator。

这是错误:

Epoch 1/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 170s 2s/step - accuracy: 0.9974 - loss: 0.4769 - val_accuracy: 0.7968 - val_loss: 0.9699
Epoch 2/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.0000e+00 - loss: 0.0000e+00 - val_accuracy: 0.0000e+00 - val_loss: 0.0000e+00
Epoch 3/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 175s 2s/step - accuracy: 0.9988 - loss: 0.4260 - val_accuracy: 0.8052 - val_loss: 0.9283
Epoch 4/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 0s 728us/step - accuracy: 0.0000e+00 - loss: 0.0000e+00 - val_accuracy: 0.0000e+00 - val_loss: 0.0000e+00
etc...

这是我的模型结构:

model1 = keras.models.Sequential([
    keras.layers.Conv2D(16,(3,3), activation='relu', input_shape=(150, 150, 3)),
    keras.layers.MaxPooling2D(2,2),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(32,(3,3), activation='relu'),
    keras.layers.MaxPooling2D(2,2),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64,(3,3), activation='relu'),
    keras.layers.MaxPooling2D(2,2),
    keras.layers.BatchNormalization(),
    keras.layers.Flatten(),
    keras.layers.Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.001)),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(1, activation='sigmoid')
])
model1.compile(optimizer=Adam(learning_rate=0.0002), loss='binary_crossentropy', metrics=['accuracy'])

train_CD = ImageDataGenerator(rescale=1.0/255.)
train_generator_CD = train_CD.flow_from_directory(
    './images/cat_dog/train_data/',
    target_size = (150, 150),
    batch_size = 250,
    class_mode = 'binary')

test_CD = ImageDataGenerator(rescale=1.0/255.)
test_generator_CD = test_CD.flow_from_directory(
    './images/cat_dog/test_data/',
    target_size = (150, 150),
    batch_size = 250,
    class_mode = 'binary')

history1=model1.fit(
    train_generator_CD,
    validation_data = test_generator_CD,
    epochs = 20,
    steps_per_epoch = 90,
    validation_steps = 10,
    callbacks=[myCallback()]
    )

问题可能出在你在 model.fit 中同时设置了 steps_per_epoch validation_steps 。 你将 steps_per_epoch 设置为 90,将 validation_steps 设置为 10,这会导致每隔一个周期就出现奇怪的行为。

让我们来分解一下原因:

  • steps_per_epoch :这决定了在认为一个周期完成之前从你的训练生成器中提取多少批次。你将其设置为 90,这意味着你的模型将在每个周期中训练 90 批次数据。由于你的批次大小为 250,因此你每个周期将训练 90 * 250 = 22500 张图像。
  • validation_steps :这决定了在每个周期结束时从你的验证生成器中提取多少批次来评估指标。你将其设置为 10,这意味着你每个周期将使用 10 批次验证数据。

问题在于,当 validation_steps 小于验证数据中的批次数时,Keras 不会在每个周期都遍历所有验证数据。相反,它仅使用 validation_steps 指定的批次数。在你的情况下,你只有 10 个步骤用于 2500 张验证图像(25000 张图像的 10%),这意味着每 2.5 个周期才会看到整个验证集。

这种不一致的验证采样会导致你在每隔一个周期报告的指标(准确率、损失等)出现不稳定的行为。你在一个周期中看到的零值可能是由于模型仅在有限且可能不具有代表性的验证数据子集上进行评估造成的。

要解决这个问题,你可以尝试以下两种方法之一:

  1. 删除 validation_steps 参数: 这将强制 Keras 在每个周期结束时使用整个验证集,从而提供更准确和一致的验证指标。
history1=model1.fit(
    train_generator_CD,
    validation_data=test_generator_CD,
    epochs=20,
    steps_per_epoch=90,
    callbacks=[myCallback()]
)
  1. validation_steps 设置为覆盖整个验证集: 计算验证集中所需的步骤数,并相应地设置 validation_steps 。在你的情况下,你拥有 2500 张验证图像,批次大小为 250,因此你需要 10 个验证步骤:
validation_steps = 2500 // 250 
history1=model1.fit(
    train_generator_CD,
    validation_data=test_generator_CD,
    epochs=20,
    steps_per_epoch=90,
    validation_steps=validation_steps,
    callbacks=[myCallback()]
)

通过实施这些更改之一,你应该会看到你的验证指标以更一致且可靠的方式计算,而不会出现每隔一个周期就出现零值的情况。

标签:python,tensorflow,keras,image-classification
From: 77668911

相关文章

  • 如何在系统PATH中永久添加路径? - Python
    我正在为我的一个项目创建一个安装程序,下载该项目的二进制文件(在ZIP文件中),然后将其解压缩到操作系统程序文件夹中的一个目录中,我想将此目录添加到|||。我的脚本是一个带有UI的安装程序,其目的是编译为PATH/可执行文件。如果你能找到我一种.exe平台无关......
  • 找不到 Keras.utils.layer_utils
    如何解决该错误:"Nomodulecalledlayer_utils"当我尝试从Keras或Tensorflow安装或导入它时,我收到一条错误消息,指出它不存在。我正在按照一个教程安装来自需求的各种依赖项.txt文件,但可能缺少一些内容。keras.utils.layer_utils在较新版本的Keras中......
  • python数据分析与可视化基础
    一、数据分析介绍:1.数据分析含义:数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,将它们加以汇总和理解并消化,以求最大化地开发数据的功能,发挥数据的作用。数据分析是为了提取有用信息和形成结论而对数据加以详细研究和概括总结的过程。数据分析的数学基础在20世纪早......
  • 为什么要设置 os.environ[“PYTHONHASHSEED“] = “0“,这样做具体会影响哪些随机值?
    ......
  • Python,Geopandas报错,AttributeError: The geopandas.dataset has been deprecated and
    Python版本3.9,Geopandas版本1.0.1问题描述:这是执行的代码,importpandasaspdimportgeopandasimportmatplotlib.pyplotaspltworld=geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))world.plot()plt.show()这是报错信息,Traceback(mo......
  • Python,Maskrcnn训练,cannot import name ‘saving‘ from ‘keras.engine‘ ,等问题集合
    Python版本=3.9,tensorflow=2.11.0,keras==2.11.0问题一、module'keras.engine'hasnoattribute'Layer'Traceback(mostrecentcalllast):File"C:\Users\Administrator\Desktop\20240801\代码\test.py",line16,in<module>......
  • 7-Python数据类型——列表和元组的详解(增删改查、索引、切片、步长、循环)
    一、列表1.1列表list有序且可变的容器,可以存放多个不同类型的元素列表就是专门用来记录多个同种属性的值列表:存储同一个类别的数据,方便操作字符串,不可变:即:创建好之后内部就无法修改【内置功能都是新创建一份数据】name="xiaochaun"data=name.upper()print(nam......
  • python中的 is 和 ==
    一前言环境:win10python3.10二is和isnot1比较对象的identityis和isnot是python的比较运算符,比较运算符除了这两个,还有下图中的这些is和isnot比较的是两个对象的是identityidentity是啥,内置函数id()返回的就是这个东西通过上面id函数的解释,现在知道,identi......
  • Python应用开发——30天学习Streamlit Python包进行APP的构建(23):构建多页面应用程序
    创建动态导航菜单通过st.navigation,可以轻松创建动态导航菜单。您可以在每次重新运行时更改传递给st.navigation的页面集,从而更改与之匹配的导航菜单。这是创建自定义、基于角色的导航菜单的便捷功能。本教程使用st.navigation和st.Page,它们是在Streamlit1.36.0版中......
  • Python数据结构第二天—循环链表、树、二叉搜索树
    双向链表之前学习的单向链表只能从头遍历到尾,过程是单向的,而双向链表既可以从头遍历到尾,也可以从尾遍历到头,它的过程是双向的。既然它是双向的,那么我们要实现一个双向链表,就需要在单向链表的基础上,给每一个结点增加一个向前的引用。双向链表的创建:"""我们要实现的是一......