使用 Python 和 Keras 中的卷积神经网络识别手写数字

深度学习技术能力的一个流行演示是图像数据中的目标识别。

机器学习和深度学习中对象识别的“你好世界”是用于手写数字识别的 MNIST 数据集。

在这篇文章中,您将学习如何使用 Keras 深度学习库在 Python 中开发一个深度学习模型,以在 MNIST 手写数字识别任务上实现接近最先进的性能。

完成本教程后,您将了解:

  • 如何在 Keras 中加载 MNIST 数据集
  • 如何开发和评估用于 MNIST 问题的基线神经网络模型
  • 如何为 MNIST 实现和评估一个简单的卷积神经网络
  • 如何为 MNIST 实现一个接近最先进的深度学习模型

通过我的新书《使用 Python 进行深度学习启动您的项目,包括分步教程和所有示例的 Python 源代码文件。

让我们开始吧。

  • 2016 年 6 月:首次发布
  • 2016 年 10 月更新:更新至 Keras 1.1.0、TensorFlow 0.10.0 和 scikit-learn v0.18
  • 2017 年 3 月更新:更新至 Keras 2.0.2、TensorFlow 1.0.1 和 Theano 0.9.0
  • 2019 年 9 月更新:更新至 Keras 2.2.5 API
  • 2022 年 7 月更新:更新至 TensorFlow 2.x API

请注意,本教程的扩展版本,请参阅

Handwritten Digit Recognition using Convolutional Neural Networks in Python with Keras

使用 Python 和 Keras 中的卷积神经网络识别手写数字
照片由 Jamie 拍摄,保留部分权利。

MNIST 手写数字识别问题描述

MNIST 问题是 Yann LeCun、Corinna Cortes 和 Christopher Burges 开发的一个数据集,用于评估机器学习模型在手写数字分类问题上的表现。

该数据集是从国家标准与技术研究院 (NIST) 提供的多个扫描文档数据集中构建的。数据集的名称由此而来,即 Modified NIST 或 MNIST 数据集。

数字图像取自各种扫描文档,经过大小归一化和居中处理。这使其成为评估模型的绝佳数据集,让开发人员能够专注于机器学习,而无需最少的数据清理或准备。

每个图像都是一个 28×28 像素的正方形(总共 784 像素)。使用标准的数据集拆分来评估和比较模型,其中 60,000 张图像用于训练模型,另外 10,000 张图像用于测试模型。

这是一个数字识别任务。因此,有十个数字(0 到 9)或十个类别需要预测。结果使用预测误差报告,这无非是反向的分类准确率。

出色的结果可以实现低于 1% 的预测误差。使用大型卷积神经网络可以实现大约 0.2% 的最先进预测误差。在 Rodrigo Benenson 的网页上列出了 MNIST 和其他数据集的最先进结果以及相关论文的链接。

Python 深度学习需要帮助吗?

参加我的免费为期两周的电子邮件课程,发现 MLP、CNN 和 LSTM(附代码)。

立即点击注册,还将免费获得本课程的 PDF 电子书版本。

在 Keras 中加载 MNIST 数据集

Keras 深度学习库提供了一种方便的方法来加载 MNIST 数据集。

首次调用此函数时,数据集将自动下载并存储在您的主目录中 ~/.keras/datasets/mnist.npz,文件大小为 11MB。

这对于开发和测试深度学习模型非常方便。

为了演示加载 MNIST 数据集是多么容易,首先,编写一个小脚本来下载并可视化训练数据集中的前四张图像。

您可以看到,下载和加载 MNIST 数据集就像调用 mnist.load_data() 函数一样简单。运行上面的示例,您应该会看到下面的图像。

Examples from the MNIST dataset

MNIST 数据集中的示例

带多层感知器的基线模型

您真的需要像卷积神经网络这样的复杂模型才能在 MNIST 上获得最佳结果吗?

使用只有单个隐藏层的非常简单的神经网络模型可以获得非常好的结果。在本节中,您将创建一个简单的多层感知器模型,该模型实现了 1.74% 的错误率。您将以此作为基线来比较更复杂的卷积神经网络模型。

让我们首先导入您需要的类和函数。

现在,您可以使用 Keras 辅助函数加载 MNIST 数据集。

训练数据集被构造为一个三维数组,包含实例、图像宽度和图像高度。对于多层感知器模型,您必须将图像缩小为像素向量。在这种情况下,28×28 大小的图像将是 784 个像素输入值。

您可以使用 NumPy 数组上的 reshape() 函数轻松完成此转换。您还可以通过强制像素值的精度为 32 位来减少内存需求,这也是 Keras 默认使用的精度。

像素值是介于 0 和 255 之间的灰度值。在使用神经网络模型时,对输入值进行一些缩放几乎总是一个好主意。由于比例是众所周知且表现良好的,因此您可以通过将每个值除以最大值 255 来非常快速地将像素值归一化到 0 到 1 的范围。

最后,输出变量是一个从 0 到 9 的整数。这是一个多类分类问题。因此,对类别值使用 One-Hot 编码,将类别整数向量转换为二进制矩阵是一个好习惯。

您可以使用 Keras 中内置的 tf.keras.utils.to_categorical() 辅助函数轻松完成此操作。

现在您已经准备好创建您的简单神经网络模型。您将在一个函数中定义您的模型。如果您想稍后扩展示例并尝试获得更好的分数,这会很方便。

该模型是一个简单的神经网络,有一个隐藏层,其中神经元的数量与输入(784 个)相同。隐藏层中的神经元使用整流器激活函数。

输出层使用 softmax 激活函数,将输出转换为类似概率的值,并允许从十个类别中选择一个作为模型的输出预测。对数损失用作损失函数(在 Keras 中称为 categorical_crossentropy),并且高效的 ADAM 梯度下降算法用于学习权重。

现在您可以拟合和评估模型了。模型经过十个 epoch 的拟合,每 200 张图像更新一次。测试数据用作验证数据集,让您可以查看模型训练时的技能。使用 verbose 值为 2 以将每个训练 epoch 的输出减少到一行。

最后,使用测试数据集评估模型,并打印分类错误率。

将所有这些整合在一起后,完整的代码列表如下。

在 CPU 上运行示例可能需要几分钟。

注意:由于算法或评估过程的随机性或数值精度差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

您应该会看到下面的输出。这个用很少代码行定义的非常简单的网络实现了 2.3% 的可观错误率。

用于 MNIST 的简单卷积神经网络

既然您已经了解了如何加载 MNIST 数据集并训练一个简单的多层感知器模型,那么现在是时候开发一个更复杂的卷积神经网络(CNN)模型了。

Keras 确实提供了许多创建卷积神经网络的功能。

在本节中,您将为 MNIST 创建一个简单的 CNN,演示如何使用现代 CNN 实现的所有方面,包括卷积层、池化层和 Dropout 层。

第一步是导入所需的类和函数。

接下来,您需要加载 MNIST 数据集并将其重塑,使其适合训练 CNN。在 Keras 中,用于二维卷积的层期望像素值具有 [像素][宽度][高度][通道] 的维度。

请注意,在此示例中,为了保持一致性,您强制使用所谓的通道优先排序。

在 RGB 的情况下,最后一个维度像素将为 3,分别表示红色、绿色和蓝色分量,就像每个彩色图像有三个图像输入一样。在 MNIST 的情况下,像素值为灰度,因此像素维度设置为 1。

和以前一样,将像素值归一化到 0 到 1 的范围并对输出变量进行 One-Hot 编码是一个好主意。

接下来,定义你的神经网络模型。

卷积神经网络比标准的多层感知器更复杂,因此您将从使用一个简单结构开始,该结构使用所有元素以获得最先进的结果。下面总结了网络架构。

  1. 第一个隐藏层是一个称为 Convolution2D 的卷积层。该层有 32 个特征图,大小为 5×5,并使用整流器激活函数。这是输入层,它期望具有上述结构:[像素][宽度][高度] 的图像。
  2. 接下来,定义一个池化层,它采用最大值,称为 MaxPooling2D。它配置为 2×2 的池大小。
  3. 下一层是一个使用 Dropout 的正则化层。它被配置为随机排除层中 20% 的神经元,以减少过拟合。
  4. 接下来是一个将二维矩阵数据转换为向量的层,称为 Flatten。它允许输出由标准的全连接层处理。
  5. 接下来是一个包含 128 个神经元和整流器激活函数的全连接层。
  6. 最后,输出层有十个神经元,对应十个类别,并使用 softmax 激活函数为每个类别输出类似概率的预测。

和以前一样,模型使用对数损失和 ADAM 梯度下降算法进行训练。

您以与多层感知器相同的方式评估模型。CNN 经过十个 epoch 的拟合,批量大小为 200。

将所有这些整合在一起后,完整的示例列在下面。

运行示例后,会打印每个 epoch 的训练和验证测试的准确率,最后打印分类错误率。

注意:由于算法或评估过程的随机性或数值精度差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在 GPU 上(例如,在 AWS 上)运行一个 epoch 可能需要大约 45 秒。您可以看到该网络的错误率为 1.19%,这比我们上面简单的多层感知器模型要好。

用于 MNIST 的大型卷积神经网络

既然您已经了解了如何创建一个简单的 CNN,那么让我们看看一个能够接近最先进结果的模型。

您将导入类和函数,然后像前面的 CNN 示例一样加载和准备数据。

这次您将定义一个包含额外卷积层、最大池化层和全连接层的大型 CNN 架构。网络拓扑可以总结如下:

  1. 30 个特征图的卷积层,大小为 5×5
  2. 在 2*2 补丁上进行最大池化的池化层
  3. 15 个特征图的卷积层,大小为 3×3
  4. 在 2*2 补丁上进行最大池化的池化层
  5. 概率为 20% 的 Dropout 层
  6. 展平层
  7. 具有 128 个神经元和整流器激活的全连接层
  8. 具有 50 个神经元和整流器激活的全连接层
  9. 输出层

与前两个实验一样,模型经过十个 epoch 的拟合,批量大小为 200。

将所有这些整合在一起后,完整的示例列在下面。

运行示例会打印每个 epoch 的训练和验证数据集的准确率,以及最终的分类错误率。

注意:由于算法或评估过程的随机性或数值精度差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

该模型每个 epoch 运行大约 100 秒。这个稍大的模型实现了 0.83% 的可观分类错误率。

这不是一个优化的网络拓扑。也不是对近期论文中网络拓扑的复现。您有很大的机会来调整和改进此模型。

您能达到的最佳错误率是多少?

在评论中发布您的配置和最佳分数。

MNIST 资源

MNIST 数据集经过深入研究。以下是您可能想查阅的一些额外资源。

总结

在这篇文章中,您发现了 MNIST 手写数字识别问题以及使用 Keras 库在 Python 中开发的能够取得出色结果的深度学习模型。

通过本教程,您学会了

  • 如何在 Keras 中加载 MNIST 数据集并生成数据集图表
  • 如何重塑 MNIST 数据集并开发一个简单但性能良好的多层感知器模型来解决该问题
  • 如何使用 Keras 创建用于 MNIST 的卷积神经网络模型
  • 如何开发和评估能够达到接近世界级结果的更大规模的 MNIST CNN 模型。

您对手写识别深度学习或这篇文章有任何疑问吗?请在评论中提出您的问题,我将尽力回答。

337 条评论:使用 Python 和 Keras 中的卷积神经网络识别手写数字

  1. nitangle 2016 年 7 月 6 日下午 2:18 #

    感谢您的教程。它很棒。尽管(听起来可能很傻)我如何实际操作呢?我的意思是,如果我想看它预测图像的答案,我该怎么做?
    再次感谢。

  2. Adrian 2016 年 8 月 29 日上午 8:19 #

    您有识别数字的可用程序吗?

    • Jason Brownlee 2016 年 8 月 30 日上午 8:23 #

      仅此教程中的示例,Adrian。

    • komal 2020 年 8 月 15 日下午 6:55 #

      你拿到工作程序了吗?

  3. Matthew 2016 年 9 月 6 日下午 1:22 #

    当我使用 MLP 运行基线模型时,我得到的结果比您展示的差得多(错误率为 53.64%)。您知道为什么我使用相同的代码会看到如此截然不同的结果吗?谢谢。

    • Jason Brownlee 2016 年 9 月 7 日上午 9:17 #

      你好 Matthew,这些数字如此不同令人惊讶。

      Theano 后端?还是 TensorFlow?什么平台?什么版本的 Python?

      尝试运行示例 3 次并报告所有 3 个分数。

      • Adrian 2016 年 9 月 19 日上午 1:14 #

        我也有同样的问题。我使用 Theano 后端。平台:Pycharm。版本 3.5

    • John Ellis 2016 年 11 月 22 日下午 12:25 #

      要获得如此高的错误率,代码肯定是复制不正确或类似的原因。除此之外,请注意,每次运行此代码时,最终输出都会略有不同,因为神经网络中存在 Dropout 层。它每次运行时都会随机选择 20% 的神经元,从而略微影响最终结果。

      • pramod anantha 2017 年 3 月 24 日下午 11:34 #

        是的。但是即使我删除了 dropout 层,结果精度也各不相同。有什么想法吗?精度不应该改变,对吧?

  4. Vinay 2016 年 9 月 12 日上午 5:08 #

    您能否提供一个简单的 CNN 示例,例如在 UCI 存储库数据集中。CNN 是否可以应用于数值特征。

  5. Dinesh 2016 年 9 月 21 日下午 6:22 #

    你好 Jason,我尝试运行脚本,但是基线模型花费了太多时间……它已经运行了 20 多个小时,仍然在第 4 个纪元,您能提出一些加快过程的方法吗?我正在使用 4 GB 内存的计算机,并在 Anaconda Theano 后端 Keras 上运行

    • Jason Brownlee 2016 年 9 月 22 日上午 8:09 #

      很抱歉听到这个消息,Dinesh。

      也许可以尝试在 AWS 上进行训练。
      https://machinelearning.org.cn/develop-evaluate-large-deep-learning-models-keras-amazon-web-services/

      • Dinesh 2016 年 9 月 22 日下午 6:38 #

        嗨,Jason,

        您使用什么机器配置来运行模型?您是否使用了 GPU 来提高性能?您花了多长时间?

        另外,AWS 是一个付费平台,有没有免费的平台可以运行 ML 算法?

        谢谢

        • Jason Brownlee 2016 年 9 月 23 日上午 8:26 #

          我使用的是一台 8 核、8GB 内存的机器。它在合理的时间内完成了内存操作。

          AWS 的价格非常合理,我认为每小时不到 1 美元。非常适合像这样的单次模型。

        • MCoates 2019 年 6 月 26 日下午 6:29 #

          对我来说,10 个 epoch 大约 6 分钟就运行完了,也是 4GB 内存。检查你的代码?

  6. Mike 2016 年 10 月 2 日下午 6:44 #

    嗨!很棒的文章!我试了一下,但第一个 CNN 似乎无法编译。我得到了

    ValueError:过滤器不得大于输入:过滤器:(5, 5) 输入:(1, 28)

    就在 model = baseline_model() 之后

  7. Jack 2016 年 10 月 6 日下午 7:45 #

    你好 Jason,我试了一下,但是出现了下面的错误。我使用的是 tensorflow r0.11。我不确定这是否是原因。

    使用 TensorFlow 后端。
    回溯(最近一次调用)
    文件“/Users/Jack/.pyenv/versions/3.5.1/lib/python3.5/site-packages/tensorflow/python/framework/common_shapes.py”,第 594 行,在 call_cpp_shape_fn 中
    状态)
    文件“/Users/Jack/.pyenv/versions/3.5.1/lib/python3.5/contextlib.py”,第 66 行,在 __exit__ 中
    下一个(self.gen)
    文件“/Users/Jack/.pyenv/versions/3.5.1/lib/python3.5/site-packages/tensorflow/python/framework/errors.py”,第 463 行,在 raise_exception_on_not_ok_status 中
    pywrap_tensorflow.TF_GetCode(状态))
    tensorflow.python.framework.errors.InvalidArgumentError: 负维度大小由 5 减去 1 引起

    • Jason Brownlee 2016 年 10 月 7 日上午 7:54 #

      哎呀,Jack,这看起来不太好。

      看起来 API 已经改变了。我将深入研究并修复示例。

      • Jason Brownlee 2016 年 10 月 7 日上午 11:46 #

        好的,我已更新示例。

        首先,我建议使用 TensorFlow 0.10.0,而不是 0.11,因为最新版本存在问题。

        其次,您必须添加以下两行才能使 CNN 正常工作

        修复方案取自此处:https://github.com/fchollet/keras/issues/2681

        希望这能帮到你,Jack。

        • Ermia 2016年10月29日下午5:49 #

          你好,Jason。
          感谢这篇很棒的教程。

          您的评论尚未解决问题,我们仍然遇到相同的错误,您能否修改您的模型以与TensorFlow后端一起工作?

    • komal 2017年10月26日上午4:17 #

      Keras更改了其输入格式。它现在是[宽度, 高度, 像素],而不是[像素, 宽度, 高度]。
      在Conv2D和reshape调用中将input_shape = (28, 28, 1)更改为(28, 28, 1)。

      • Deepak 2017年12月15日上午1:14 #

        在Input层Conv2D中使用参数:data_format='channels_first'

        model.add(Conv2D(32, kernel_size=(3, 3) , activation=’relu’,data_format=’channels_first’, input_shape=(1,28,28)))

        或者您需要更改默认的Keras配置

        在~/.keras/keras.json中

        从“image_data_format”: “channels_last” => “image_data_format”: “channels_first”

        谢谢

        • Deependra Pushkar 2019年3月31日下午8:54 #

          谢谢,它解决了我的问题。

  8. Abhai Kollara 2016年10月15日上午1:32 #

    嗨,感谢您提供的精彩教程!

    我尝试用测试集进行预测,并得到了独热编码的预测。我只是想知道是否有内置函数可以将其转换回原始标签(0,1,2,3…)。

  9. Berisha Mekayhu 2016年10月31日上午5:15 #

    你好,

    非常感谢您一如既往的简明扼要和全面的说明和讨论。

  10. gs 2016年11月2日下午9:01 #

    你好,

    完成学习后,如何使用此网络识别自己的图片。

    • Jason Brownlee 2016年11月3日上午7:58 #

      好问题gs,我目前没有示例。

      您需要以与MNIST数据集相同的方式编码您自己的图片——主要是缩放到相同大小。然后将它们作为像素值矩阵加载,您就可以进行预测了。

      • jitender nara 2018年5月23日下午11:00 #

        Jason你能详细说明一下吗???拜托

  11. Nick 2016年11月3日下午11:58 #

    你好,
    感谢您提供了一个很棒的示例,但是如何保存网络的 currentState,
    我的意思是网络学习了60000个示例,然后它测试并尝试猜测10000个
    但是如果我想每天都使用它,例如,我怎样才能每天使用它而无需每天训练它?

  12. John Ellis 2016年11月22日下午12:28 #

    Jason,您的书是否解释了“为什么”您在此教程中选择了各种层,并阐明了如何以及为何为不同的数据集选择某些设计?

    • Jason Brownlee 2016年11月23日上午8:50 #

      不,只讲了方法,John。

      “为什么”很难,在大多数情况下,最好的结果是通过试错法实现的。没有“神经网络理论”可以帮助您配置它们。

  13. Nassim 2016年11月24日下午9:29 #

    你好
    当我尝试对自己的图像进行预测时,网络出错了
    这让我很沮丧。
    我使用命令 model.predict_classes(img)
    请问有没有办法获得我手写数字的正确答案

    • Jason Brownlee 2016年11月25日上午9:33 #

      也许你需要更多不同的训练示例,Nassim?

      也许一些图像增强可以使您的模型更健壮?

  14. Anthony 2016年11月26日上午10:04 #

    Jason,你真是个了不起的教程,事实上你是最棒的,非常容易上手,我喜欢你所有的教程,谢谢你!事实上,
    我一度使用GPU实现了0.74的错误率,运行时间大约30秒。

  15. BWen 2016年12月19日上午5:17 #

    感谢这篇很棒的教程。只有一个地方我不明白。在Convolution2D层中,有一个border_mode=”valid”参数。这是做什么的?它的目的是什么?Keras文档似乎也没有对此进行解释。

  16. Sanjaya Subedi 2016年12月19日上午6:53 #

    杰森,出色的教程。我非常喜欢阅读和实现它。我刚刚发现,如果你安装了cuDNN,它会使事情变得更快(至少对于我尝试过的玩具示例)。我建议任何阅读本文的人安装cuDNN并配置theano来使用它。你只需将其放入
    [dnn]
    enabled = True
    在theanorc文件中。

  17. Ganesh 2017年1月4日下午10:06 #

    嗨,Jason,
    我正在尝试将CONVOLUTION1D应用于IRIS数据。
    代码如下

    —————————————————————————————–
    max_features = 150
    maxlen = 4
    batch_size = 16
    embedding_dims = 3
    nb_epoch = 3
    nb_classes =3
    dropoutVal = 0.5
    nb_filter = 5
    hidden_dims = 500
    filter_length = 4

    import pandas as pd
    data_load = pd.read_csv(“iris.csv”)

    data = data_load.ix[:,0:4]
    target = data_load.ix[:,4]
    X_train = np.array(data[:100].values.astype(‘float32’))
    Y_train = np.array(target[:100])
    Y_train = np_utils.to_categorical(Y_train,nb_classes)
    X_test = np.array(data[100:].values.astype(‘float32′))
    Y_test = np.array(target[100:])
    Y_test = np_utils.to_categorical(Y_test,nb_classes)

    std = StandardScaler()
    X_train = X_train_scaled = std.fit_transform(X_train)
    X_test = X_test_scaled = std.transform(X_test)

    X_train1 = sequence.pad_sequences(X_train_scaled,maxlen=maxlen)
    X_test1 = sequence.pad_sequences(X_test_scaled,maxlen=maxlen)

    model = Sequential()
    model.add(Embedding(max_features,embedding_dims,input_length=maxlen))

    model.add(Convolution1D(nb_filter=nb_filter,filter_length=filter_length, border_mode=’valid’,activation=’relu’))
    model.add(GlobalMaxPooling1D())

    model.add(Dense(hidden_dims,activation=’softmax’))

    model.add(Dense(nb_classes))
    model.add(Activation(‘sigmoid’))
    model.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])

    model.fit(X_train1, Y_train, nb_epoch=5, batch_size=10)

    scores = model.evaluate(X_test1, Y_test, verbose=0)

    predictions = model.predict(X_test1)

    —————————————————————————————-
    我想检查我是否朝这个方向走对了。
    我的准确率没有超过66%,这相当令人惊讶。

    我的嵌入层做得对吗?因为当我查看嵌入层权重时,我发现我设置的层参数与我检索到的权重之间存在差异。

    请指教。

    此致
    Ganesh

  18. Ger 2017年1月20日上午4:19 #

    非常感谢这篇帖子。(

  19. Remon 2017年1月26日下午9:09 #

    你能告诉我如何给系统一张图片,然后它告诉我图片上的数字是多少吗?对不起,我是新手,谢谢!

    • Jason Brownlee 2017年1月27日下午12:05 #

      嗨 Remon,

      图像必须缩放到与网络预期尺寸相同的尺寸。

      此外,在此示例中,网络期望图像具有特定的比例,并且是黑色背景上的白色数字。新的示例必须以相同的方式准备。

  20. joe 2017年1月31日上午6:41 #

    你好 jason,
    您的代码片段
    ————————-
    在“加载数据”步骤中
    (X_train, y_train), (X_test, y_test) = mnist.load_data()
    # 重塑为 [样本][像素][宽度][高度]
    X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype(‘float32’)
    X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype(‘float32’)

    您正在使用mnist数据。它是什么样的数据结构?
    如何将图像(列表)和标签(列表)预处理成这种结构并将其馈送给Keras模型?

    这行代码到底
    X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype(‘float32’)

    是做什么的?
    谢谢
    joseph

    • Jason Brownlee 2017年2月1日上午10:30 #

      嗨 Joe,

      MNIST数据在Keras中可用。

      它以NumPy像素数据数组的形式存储。

      与CNN一起使用时,数据会重塑为以下格式:[样本,像素,宽度,高度]

      希望这能有所帮助。

  21. Amy 2017年2月1日上午3:52 #

    嗨 Jason,是什么让您选择128个神经元用于全连接层?(计算进入全连接层的激活数量,它远大于128)谢谢!

  22. Shaik Mohammed Siraj 2017年2月6日上午10:52 #

    嗨 @Jason Brownlee,首先,您的教程太棒了..!!
    在以下几行中有一个小问题

    小型卷积神经网络
    # 构建模型
    model = baseline_model()

    大型卷积神经网络
    # 构建模型
    model = larger_model()

    使用最新版本的Tensorflow会抛出AttributeError
    => AttributeError: module ‘tensorflow.python’ has no attribute ‘control_flow_ops’ <=

    解决方案
    添加以下行

    import tensorflow as tf
    tf.python.control_flow_ops = tf

    参考
    https://github.com/fchollet/keras/issues/3857

    你能更新一下代码吗..!!
    再次感谢你的精彩教程。
    继续努力..!!

  23. Mouz 2017年2月15日上午1:04 #

    您的帖子非常适合Keras的入门。我非常喜欢它,先生。

  24. Faruk Ahmad 2017年2月17日下午6:12 #

    您好,先生,感谢您精彩的写作和详尽的解释。我已经尝试过了,它有效。但是,我如何使用自己的手写数据集而不是MNIST数据来训练网络。

    如果您能对此有所启发,将非常有帮助。

    提前感谢。

    • Jason Brownlee 2017年2月18日上午8:37 #

      嗨 Faruk,

      一般来说,您需要首先使数据在维度上保持一致。

      从那里,您可以将数据分成训练/测试集或类似的东西,并开始探索不同的配置。

      这有帮助吗?也许我误解了问题?

  25. Arash 2017年2月21日上午4:32 #


    感谢您的详细解释。我成功地训练了您在此处介绍的所有网络。但是,当我想使用训练好的模型进行一些预测时,使用这段代码

    im=misc.imread(‘test8.png’)
    im=im[:,:,1]
    im=im.flatten()
    print(model.predict(im))

    它给我一个错误
    ValueError: 检查时出错:预期的dense_input_1形状为(None, 784),但得到的数组形状为(784, 1)

    “im”的形状是(,784),我如何输入一个大小为(None,784)的数组?

    • Jason Brownlee 2017年2月21日上午9:37 #

      嗨 Arash,

      考虑如下重塑

  26. Jundong 2017年2月25日上午2:21 #

    嗨,Jason,

    感谢您精彩的教程!

    我有一个关于“model.add(Dropout(0.2))”的问题。正如您在帖子中指出的“下一层是使用Dropout的正则化层,称为Dropout。它被配置为随机排除层中20%的神经元以减少过拟合。”Dropout在Keras中被视为一个独立的层,而不是对现有层(如卷积层和全连接层)的正则化操作。这是如何实现的?

    由于这个Dropout位于MaxPooling和下一个全连接层之间,Dropout应用于了权重的哪个部分?

    非常感谢!

    • Jason Brownlee 2017年2月25日上午6:01 #

      好问题,它会影响插入它所在层之间的权重。

      • srikar 2018年11月2日下午8:40 #

        嗨 Jason 先生,我们有没有机会将 AdaBoost 应用于手写数字识别,我想知道实际的准确率是多少

        • Jason Brownlee 2018年11月3日上午7:02 #

          我没有,我建议使用 sklearn 的 adaboost 实现。

  27. ANJI 2017年2月26日下午8:38 #

    您好,先生,感谢您详细的解释。我已经尝试过了,它运行良好。但是,我如何使用自己的手写数据集而不是MNIST数据集来训练网络。

    如果您能对此有所启发,将不胜感激。

    提前感谢。

    • Jason Brownlee 2017年2月27日上午5:50 #

      您需要从文件中加载数据,调整它以使其具有相同的维度,然后拟合您的模型。

      抱歉,我目前没有处理自定义数据的示例。

  28. pramod 2017年3月3日下午6:09 #

    我用theano后端尝试了简单的CNN。

    ”’ImportError: (‘编译节点时发生以下错误’, DotModulo(A, s, m, A2, s2, m2), ‘\n’, ‘/home/pramod/.theano/compiledir_Linux-4.8–generic-x86_64-with-debian-stretch-sid-x86_64-2.7.13-64/tmpXpzrkl/d16654b784f584f17fdc481825fd2cca.so: undefined symbol: _ZdlPvm’, ‘[DotModulo(A, s, m, A2, s2, m2)]’)”’

    我在运行基线模型时遇到了这个错误。

    您能告诉我如何纠正这个错误吗?我尝试了多种安装theano的方法,包括pip和conda。

    我猜我的theano安装有问题。
    不知所措,请帮忙。

    谢谢你

    • Jason Brownlee 2017年3月6日上午10:43 #

      我没有见过这个错误,抱歉。

      我的许多学生在使用Anaconda Python的Keras和Theano时都取得了巨大的成功。

  29. Chris Hanning 2017年3月13日下午4:03 #

    上面是原封不动的代码,只做了一个更改
    X_train = X_train[:-20000 or None]
    y_train = y_train[:-20000 or None]
    以减少在Mac OSX El Capitan(GeForce 650M,512MB)上运行时的内存使用。
    错误率稍高,为
    1.51%
    我使用Keras和tensorflow-GPU后端。

  30. Vikalp 2017年3月19日上午1:28 #

    嗨,Jason,

    对于像我这样的初学者来说,这确实是对Keras和数字识别的绝佳介绍。
    您正在使用MNIST数据集,它以腌制对象的形式存在(我猜)。但我的问题是,如何将一组现有图像转换为这种腌制对象?

    其次,您正在计算与您的测试数据集相比的错误率。但是假设我有一张写有数字的图像,您如何在不改变太多上述程序的情况下返回它的类别标签。

    • Jason Brownlee 2017年3月19日上午9:09 #

      谢谢你,Vikalp。

      我建议将您的图像数据加载为numpy数组并直接使用它们。

      您可以使用网络进行预测 (y = model.predict(x)),并使用 numpy argmax() 函数将独热编码的输出转换为类别索引。

      • Vikalp 2017年3月22日下午4:02 #

        嗨,Jason,

        感谢您的快速回复。

        我正在研究您建议的方法。以下是该代码

        color_image = cv2.imread(“two.jpg”)
        gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
        a = model.predict(numpy.array(gray_image))
        print(a)

        但得到以下错误
        ValueError: 检查时出错:预期的 dense_1_input 形状为 (None, 784) 但得到的数组形状为 (1024, 791)

        我不确定我是否做得对。请指导我。谢谢。

        • Jason Brownlee 2017年3月23日上午8:46 #

          加载的图像必须与用于拟合模型的图像具有完全相同的尺寸。

          您可能需要调整其大小。

    • Amogh 2018年4月18日下午8:09 #

      你成功了吗?能给我代码吗

  31. Marten 2017年3月30日上午1:36 #

    你好,

    我尝试按照您在另一篇文章中描述的方式保存和加载模型,但我总是遇到以下错误
    ValueError: 检查模型目标时出错:期望 dense_3 的形状为 (None, 1),但得到的数组形状为 (10000, 10)

    错误发生在
    score = model.evaluate(…)
    加载后的行

    #

    # 保存模型和权重
    print("正在保存模型...")
    model_json = model.to_json()
    with open('mnist_model.json', 'w') as json_file
    json_file.write(model_json)
    model.save_weights("mnist_weights.h5")
    print("模型已保存到磁盘")

    # 加载模型和权重
    print("正在加载模型...")
    with open('mnist_model.json') as json_file
    model_json = json_file.read()

    model = model_from_json(model_json)
    model.load_weights('mnist_weights.h5')
    print("模型已从磁盘加载")

    print("正在编译模型...")
    model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    scores = model.evaluate(X_test, y_test, verbose=0)
    print("基线错误:%.2f%%" % (100-scores[1]*100))

  32. Dhanachandra 2017年3月30日下午5:04 #

    如何获得预测输出的精确度、召回率和F值?

  33. Steve 2017年3月31日下午1:18 #

    嗨,Jason,

    很棒的网站和教程。我理解您尚未能够描述如何预处理我们自己的图像,以便在我们的MNIST训练模型中读取,正如这里的许多其他人所问的那样。如果您没有时间解释如何做到这一点,我完全理解。

    您能否指导我如何继续我的搜索以做到这一点?我尝试创建一个新的28x28像素图像,黑色背景,白色前景用于图像绘制,将其转换为灰度(用于1,28,28输入维度)。然后我将其除以255。这些自定义图像的预测准确率非常低(该模型在MNIST测试图像上的准确率为99%)。

    查看各个特征,我发现如上所述预处理的自定义图像的十进制位置与MNIST图像的十进制位置似乎大不相同,十进制和0的位置与MNIST数据相比大相径庭。完全不同的模式。这让我相信除了上面直观的步骤之外,一定还有更复杂的预处理。我查阅了MNIST页面上关于预处理如何进行的说明,但不知道如何在python中实现这些说明。似乎也有一些预处理脚本,但我无法使它们工作。

    关于我如何继续寻找预处理自定义图像的方法,还有其他建议吗?谷歌上的所有说明都过于复杂,或者实现似乎失败了。

    • Jason Brownlee 2017年4月1日上午5:48 #

      一般来说,您需要在一个代表您以后需要进行预测的图像类型的数据上训练模型。

      图像需要具有相同的尺寸(宽度x高度)和相同的颜色。

      如果您预计字符在图像中的位置会有很大变化,您可以使用图像增强来创建具有随机变换的输入数据副本。
      https://machinelearning.org.cn/image-augmentation-deep-learning-keras/

      希望这些能作为一个开始有所帮助。

    • mahie 2018年11月14日上午12:06 #

      嘿,你能告诉我如何让mnist数据集可读吗,我已经以csv格式下载了它,现在我想让我的图像可读

  34. Andreas 2017年4月3日上午5:58 #

    嗨,Jason,
    谢谢您的精彩课程!

    我的问题是,为什么像素应该标准化到0…1?

    我有这样的输入

    70.67, 3170.27, 56.31, 1.28, 0.39, 0
    204.70, 26419.57, 162.54, 0.42, -0.97, 1
    173.70, 20141.12, 141.92, 0.61, -1.14, 3
    219.80, 42211.29, 205.45, 0.55, -1.41, 0
    243.00, 43254.00, 207.98, 0.23, -1.73, 0
    241.22, 21973.94, 148.24, 0.07, -0.60, 3
    245.42, 46176.45, 214.89, 0.29, -1.80, 0
    164.78, 25253.94, 158.91, 1.08, -0.13, 0
    115.29, 9792.57, 98.96, 0.56, -1.25, 1

    最后一行是我分离并转换为独热编码的结果。
    我尝试了许多模型和许多不同的参数,但都没有学习到任何东西。即使尝试对几个列进行过采样并查看模型是否可以重现训练输出也失败了!

    但是您的所有示例都运行正常,并产生与您描述的相同的结果。所以我的设置:最新的Python 3.6,在Windows 10上运行Anaconda,应该都没问题。

    所以我担心我的输入有问题:(。我应该标准化它们吗?我该怎么做?稍后我还会遇到混合输入:数字和字符串。我该如何处理这个问题?

    如果能得到您的帮助,将不胜感激!

    谢谢!
    (请原谅我学校学到的很差的英语)

  35. Girindra Gautama 2017年5月1日上午5:36 #

    嗨,Jason,

    感谢!这真的很有帮助。我只是想知道;我意识到你使用了所有60,000个训练数据。如果你只使用1万或3万个训练数据,但仍能达到低错误率,代码会是什么样子?

    谢谢!

  36. Ehsan 2017年5月1日上午9:24 #

    你好,
    谢谢你的代码。
    我有一个问题。
    我如何向此代码添加新的激活函数?
    我找到了可以添加激活函数的地方,但我不知道应该在哪里添加新激活函数的导数。
    如果您能帮助我,我将不胜感激。
    谢谢。
    Ehsan。

    • Jason Brownlee 2017年5月2日上午5:53 #

      嗨 Ehsan,

      您可以指定层之间的激活函数(例如 model.add(...))或在层上指定(例如 Dense(activation='...'))。

  37. Paul 2017年5月19日上午7:26 #

    你好,
    我无法运行上面的例子。
    得到以下错误。

    runfile(‘C:/Users/Paul/Desktop/CNN.py’, wdir=’C:/Users/Paul/Desktop’)
    回溯(最近一次调用)

    File “”, line 1, in
    runfile(‘C:/Users/Paul/Desktop/CNN.py’, wdir=’C:/Users/Paul/Desktop’)

    文件“C:\Users\Paul\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py”,第714行,在runfile中
    execfile(filename, namespace)

    文件“C:\Users\Paul\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py”,第74行,在execfile中
    exec(compile(scripttext, filename, 'exec'), glob, loc)

    文件“C:/Users/Paul/Desktop/CNN.py”,第54行,在
    model = larger_model()

    文件“C:/Users/Paul/Desktop/CNN.py”,第40行,在larger_model中
    model.add(Conv2D(30, (5, 5), input_shape=(1, 28, 28), activation=’relu’))

    TypeError: __init__() takes at least 4 arguments (4 given)

    你能帮我一下吗?

    • Jason Brownlee 2017年5月19日上午8:26 #

      很抱歉听到这个消息,Paul,您的错误原因对我来说并不明显。

      也许请确认您已安装所有库的最新版本,并且代码没有复制粘贴错误。

  38. jose mendez 2017年5月23日下午12:43 #

    干得好,Jason,谢谢你…它对我有用。我使用的是Anaconda和GPU

  39. lakshmi 2017年5月24日下午5:30 #

    你好团队,我有以下疑问,请帮我
    # 创建模型
    model = Sequential()
    model.add(Conv2D(30, (5, 5), input_shape=(1, 28, 28), activation=’relu’))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    在上面的代码中,input shape=(1,28,28)用于二值图像,对于彩色图像我们保留(3,28,28)...但对于非图像数据我们保留什么?

    我有一个包含10248个观测值和18个变量的数据集,其中包括目标变量。

    input_shape应该保留什么?

    请帮帮我。

    • Jason Brownlee 2017年6月2日上午11:31 #

      CNN用于图像数据。

      对于非图像数据,您可能需要考虑使用MLP。对于序列数据,请考虑使用RNN。

  40. Joy 2017年5月29日下午8:51 #

    先生,我的神经网络输入是一个numpy数组,例如 [[1,1,1,2], [1,2,1,2], ……..],在这行代码中
    X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype(‘float32’)

    编译器抛出错误
    ValueError: 新数组的总大小必须保持不变

    期待问题的解决方案

    • Jason Brownlee 2017年6月2日下午12:26 #

      如果您的数据不是图像数据,请考虑从MLP而不是CNN开始。

  41. Wenjing 2017年5月31日下午9:27 #

    嗨,Jason。很棒的教程!这是我的第一个CNN,我简直不敢相信它真的有效,太兴奋了!

    我只是想知道为什么在CNN中不需要使用“kernel_initializer=”来初始化权重?在基线MLP中,您初始化了每一层,而在CNN中,这些行不存在,无论是卷积层、最大池化层还是最终的全连接层。

    我错过了什么吗?提前感谢。

  42. Nahid Hasan 2017年6月2日下午9:32 #

    干得好。谢谢先生。完成训练和测试后,我想预测一个字符,我有一个包含新手写字符的新字符图像。我该怎么做呢,先生。请帮助我

  43. Russel 2017年6月6日下午2:49 #

    我如何评估我的模型并估计它们在未见数据上的性能?
    在未见数据上。

  44. li 2017年6月12日下午9:49 #

    嗨,Jason
    我的问题是
    test_data用于在您已经定义模型(通过使用train_data)后检查模型。
    为什么您在模型训练中使用测试数据?

    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
    # 模型的最终评估
    scores = model.evaluate(X_test, y_test, verbose=0)

    • Jason Brownlee 2017年6月13日上午8:20 #

      它仅用于报告模型在训练期间(验证数据集)未见过的数据上的性能。

      • saeed 2018年11月13日上午3:05 #

        嗨 Jason,我仍然不清楚(Keras如何划分数据集)?
        验证数据就是测试数据本身吗..?
        这就是我在模型拟合方程中看到的!
        所以数据集只被Keras划分为训练集和测试集..
        然后用测试数据而不是验证数据进行拟合?
        我无法理解,但就是这样!
        我说的对吗?
        非常感谢你
        saeed

  45. Herve Nsangu 2017年6月13日上午5:36 #

    晚上好,我非常喜欢您关于手写字符识别的解释,它对我理解Keras中CNN的架构和操作非常有帮助。但是,我有一个疑问,您有没有好的教程可以处理CNN的人脸识别问题……我已经尝试过OpenCV、dlib等其他方法……但是,我想用CNN来实现。
    谢谢你……

  46. Abhranil 2017年6月16日下午9:24 #

    如何预测新的测试示例?

    • Jason Brownlee 2017年6月17日上午7:25 #

      在整个可用数据集上拟合模型,然后将图像传递给

  47. Antonio 2017年6月23日上午5:53 #

    嗨,Jason。在Keras中用mnist和CNN玩耍的开始,您的帖子非常有帮助!
    谢谢!

    我有一个问题:在我的测试中,我得到了糟糕的概率分布。在大多数情况下,预测类得到1,其他类得到0。我尝试找出如何获得更具信息量的分布,特别是为了能够找到可能的预测错误。最初我以为结果与sigmoid激活函数有关,但在模型中我们只有ReLu和Sofmax线性函数。关于如何获得更具描述性的概率分布,有什么建议吗?

    • Antonio 2017年6月23日上午6:14 #

      我刚才看到我们正在使用Sofplus而不是Softmax函数。我将尝试线性函数和relu函数,看看输出有什么不同 =)

      • Jason Brownlee 2017年6月23日上午6:46 #

        告诉我进展如何。

        • Antonio 2017年6月23日上午10:20 #

          嗯,首先我必须纠正我函数名称上的错误。我从最后一个例子中的相同模型开始,即使用Softmax:一个非线性函数。当用predict_proba()激活时,在概率ndarray中得到二元0或1。

          用线性函数进行一次测试,学习收敛缓慢,我决定暂时放弃这个测试……

          用Softplus(我曾认为它类似于线性函数)得到非归一化的概率数组,但更有趣的是,在模型未能预测的情况下,概率数组中的所有值都为零!这在试图捕获模型无法预测的情况时非常有用。

          最后一次使用Sigmoid进行测试,我得到了与Softplus相同的行为,在失败的情况下,predict_proba()返回的所有值都为0,但在正确预测的情况下,预测类的值为1。这在归一化概率下更有意义,但没有一种情况具有非二元概率分布。

          总结一下:效果最好的函数仍然是Softmax;当用predict_proba()激活时,没有一个函数得到非二元分布;Softplus和Sigmoid在失败情况下predict_proba()返回的所有值都为0时表现出有趣的特性。

          总而言之,我仍在努力寻找一种方法来获得更具描述性的概率分布。

          • Jason Brownlee 2017年6月24日上午7:53 #

            模型不是试图输出概率,它正在近似一个函数。

            无论如何,您都必须对输出进行处理才能得到类似概率的值。

          • Antonio 2017年6月29日上午2:57 #

            更新…
            我发现我的错误了。在预测中,我只是忘记将像素值从0-255的uint8归一化到0-1的浮点数。我想也许这种输入会饱和,并将所有情况下的输出设置为1或0。

          • Jason Brownlee 2017年6月29日上午6:38 #

            很高兴你弄明白了。

  48. CNNExplorer 2017年6月23日下午5:06 #

    感谢您的另一篇精彩文章。您能否为我们指出可能有助于检测网络学习到的哪些图像块/区域与预测最相关的技术?这类似于特征重要性。

    例如,是否有可能分析最后一个隐藏层以找出给定图像的哪些部分对做出十个预测之一贡献最大?

  49. Tacacs1101 2017年6月28日下午9:46 #

    嗨,Jason,我尝试在我的Windows 8.1机器上运行这个代码教程,安装了theano 0.9和keras 2.0.5,使用了Geforce 940M GPU,但我的模型基线错误率最差,几乎达到90%。请帮忙

    • Jason Brownlee 2017年6月29日上午6:37 #

      考虑多运行几次示例。

      • Tacacs1101 2017年6月30日上午3:59 #

        先生,我试过了,但它没有帮助我。请建议。

  50. Stefan Langenborg 2017年7月14日下午12:20 #

    Jason,我正在尝试使用 Kaggle 竞赛中的相同数据集来重现这些结果,但我在 CNN 部分遇到了一个奇怪的问题。

    当我使用常规神经网络模型时,它在几个 epoch 内达到了接近 99% 的训练集准确率。然而,当我使用本文中的 CNN 代码时,第一个 epoch 的准确率约为 53-54%,并且在训练集上仅缓慢地爬升到最高约 94% 的准确率。

    我使用的是 42000 张图像而不是 60000 张图像的训练集,但我无法想象这会对模型的性能产生如此大的影响。有什么其他可能出错的地方吗?

    (顺便说一下,我两种神经网络都使用 tensorflow 后端)

    • Jason Brownlee 2017年7月15日上午9:37 #

      仔细检查您是否已对输入数据进行了归一化。

      • Stefan Langenborg 2017年7月15日下午1:44 #

        这似乎已经解决了问题。现在我在第一个 epoch 就有了 90% 的准确率。在接下来的操作中,我想我可能在之前已经对像素值进行了归一化之后,又不小心再次将它们除以了 255。

        • Jason Brownlee 2017年7月16日上午7:57 #

          很高兴听到您解决了问题,Stefan。

          • Stefan Langenborg 2017年7月16日上午10:30 #

            谢谢你的帮助。您知道有什么文章解释不同类型的网络拓扑以及如何决定使用哪种网络吗?这都是试错法吗,还是有某些类型的网络适合不同的问题?

          • Jason Brownlee 2017年7月17日上午8:45 #

            很好的问题。

            通常,无论如何,都以 MLP 作为基线。它们可以做很多事情,并为更复杂的模型提供一个很好的起点。

            将 CNN 用于具有空间输入(如图像)的问题,但也值得在文本、音频和其他模拟数据上尝试。

            将 RNN 用于具有时间分量(例如随时间变化的观测值)作为输入和/或输出的问题。

            这有帮助吗?

          • Stefan Langenborg 2017年7月24日上午11:03 #

            非常感谢,这很有帮助。我还想知道是否有任何标准方法可以确定特征图的大小和数量、池化层补丁以及全连接层中的神经元数量。我见过一些关于全连接层中神经元数量的经验法则,但我不确定如何在不反复运行网络的情况下决定选择哪个值。

            顺便抱歉一直打扰您,我很感谢您的帮助。

          • Jason Brownlee 2017年7月25日上午9:23 #

            据我所知没有。在这个阶段,它更多的是艺术而非科学。测试。

  51. John Williams 2017年7月26日上午1:16 #

    在为您的 2D 神经网络创建模型时,您为什么选择 32 作为滤波器输出维度?我正在自学这个过程,并对如何优化这些变量很感兴趣。

    • Jason Brownlee 2017年7月26日上午8:00 #

      这是任意的,32 在 CNN 演示中常用。

      我建议针对您的问题调整模型的超参数以获得最佳性能。

  52. Marianico 2017年8月3日下午8:48 #

    你好 Jason!你知道我为什么会收到这个错误吗?https://stackoverflow.com/questions/45479009/how-to-train-a-keras-ltsm-with-a-multidimensional-input

    • Jason Brownlee 2017年8月4日上午6:59 #

      抱歉,我无法为您调试代码,我没有这个能力。我相信您能理解。

  53. seshu 2017年8月8日上午2:18 #

    你好 Jason,你用 DropConnect 试过这个吗,你能告诉我如何在 MNIST 中实现 Dropconnect 吗?

    • Jason Brownlee 2017年8月8日上午7:52 #

      抱歉,我没有在 Keras 中使用过 Drop Connect。

  54. Matt 2017年9月5日下午7:37 #

    初始化/默认特征图从何而来?它们长什么样/检查什么?

  55. Shakya dutta 2017年9月13日下午5:01 #

    你好,我是机器学习新手

    print(model.predict_classes(x_test[1:5]))
    print(y_test[1:5])
    这里我想要预测 x_test 中的前五个元素,输出是
    [2 1 0 4](前五个元素)
    [[ 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
    [ 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
    [ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
    [ 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]
    我的问题是,在上面的预测中我得到了一个 2D 数组,如果我想用数字打印出来
    [2]
    [1]
    [0]
    [4]

    • Jason Brownlee 2017年9月15日下午12:00 #

      这听起来像是一个 Python 数组问题。

      您可以将预测作为每个预测的第一个元素来访问

  56. Dhamu Chinnavelusamy 2017年9月25日下午8:52 #

    你好,
    我看到每个人都渴望检查自己的手写图像,请按照以下步骤操作
    1)打开画图工具并写下任意数字(0-9),然后将其保存为 28×28 像素的图像。
    2)使用此代码进行预测
    import cv2
    test = cv2.imread(‘Test Image’)
    test = cv2.cvtColor( test, cv2.COLOR_RGB2GRAY )
    test = test.reshape(1, 1, 28, 28)
    test = cv2.bitwise_not(test)
    pred = model.predict_classes(test)
    print(pred)

    谢谢!享受神经网络吧。

    • Jason Brownlee 2017年9月26日上午5:37 #

      感谢分享。

    • Ricky 2017年11月2日上午1:43 #

      你好,
      我试了你的代码,但是它抛出了以下错误

      ValueError: 检查时出错:预期 dense_1_input 具有 2 个维度,但获得了形状为 (1, 1, 28, 28) 的数组

      有什么想法吗?

      • Saleem 2018年5月4日晚上12:16 #

        你好,
        我得到了同样的错误。你解决了吗?

        萨利姆

    • Srihari T 2019年8月30日上午1:34 #

      你能告诉我“测试图像”应该保存在哪个位置吗?

  57. slavik 2017年10月18日上午10:19 #

    第三个输出打印是不是有错字?

    代码是这样写的
    print(“Baseline Error: %.2f%%” % (100-scores[1]*100))

    而输出屏幕显示
    CNN 错误:x.xx%

  58. Dipo A 2017年11月19日上午1:19 #

    您好,非常感谢您提供这个程序。我已经运行了程序并训练了模型,它正在工作,那么我如何将其用于从我自己的图像输入中检测数字?

    • Jason Brownlee 2017年11月19日上午11:09 #

      您的新图像需要与 MNIST 示例以相同的方式格式化和调整大小。

      抱歉,我没有示例。

  59. Staś 2017年11月26日上午7:14 #

    嗨,Jason,
    感谢分享代码,我学到了很多。我还将它用于一篇学校论文(我进行了一项“实验”,其中我改变了训练集的大小并观察了准确率)。这可以吗(如果我引用它的话,当然)?
    谢谢!!!

    • Jason Brownlee 2017年11月26日上午7:36 #

      干得好!

      当然可以,请引用本网站或此页面即可。

  60. amanda 2017年11月30日下午8:27 #

    嗨,Jason,
    我正在学习神经网络课程,我很欣赏您为像我这样的新手所做的工作。在那门课程中,他们提出将这个分类问题作为线性回归问题来对两个类别进行分类。这个使用 mnist 数据集的问题也是线性回归分类 10 个类别吗?

    谢谢!

    • Jason Brownlee 2017年12月1日上午7:29 #

      抱歉,我没有用于分类的线性回归示例。

      • amanda 2017年12月2日晚上12:50 #

        你的例子不是通过线性回归来计算给定图像属于特定类别的概率吗?

        • Jason Brownlee 2017年12月2日上午9:04 #

          上面的例子演示了一个神经网络,而不是线性回归。

  61. Socrates 2017年12月13日上午3:50 #

    嗨,Jason,

    感谢如此精彩的教程!!!我非常感谢您投入时间精力编写代码和文本,并回答每个人的问题!

    当我尝试按照“用于 MNIST 的简单卷积神经网络”下的代码运行时,我收到以下错误。您能帮忙吗?我正在 Jupyter Notebook 上使用 Tensorflow 1.2.1 版本。

    预先感谢,
    苏格拉底

    ________________________________________________________

    AttributeError Traceback (最近一次调用)
    in ()
    44
    45 # 构建模型
    —> 46 model = baseline_model()
    47
    48 # 拟合模型

    在 baseline_model() 中
    32 # 创建模型
    33 model = Sequential()
    —> 34 model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation=’relu’))
    35 model.add(MaxPooling2D(pool_size=(2, 2)))
    36 model.add(Dropout(0.2))

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\models.py 中的 add(self, layer)
    462 # 并创建连接当前层的节点
    463 # 到我们刚刚创建的输入层。
    –> 464 layer(x)
    465
    466 if len(layer.inbound_nodes[-1].output_tensors) != 1

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\engine\topology.py 中的 __call__(self, inputs, **kwargs)
    601
    602 # 实际调用层,收集输出、掩码和形状。
    –> 603 output = self.call(inputs, **kwargs)
    604 output_mask = self.compute_mask(inputs, previous_mask)
    605

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\layers\convolutional.py 中的 call(self, inputs)
    162 padding=self.padding,
    163 data_format=self.data_format,
    –> 164 dilation_rate=self.dilation_rate)
    165 if self.rank == 3
    166 outputs = K.conv3d(

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\backend\tensorflow_backend.py 中的 conv2d(x, kernel, strides, padding, data_format, dilation_rate)
    3178 raise ValueError(‘未知数据格式 ‘ + str(data_format))
    3179
    -> 3180 x, tf_data_format = _preprocess_conv2d_input(x, data_format)
    3181
    3182 padding = _preprocess_padding(padding)

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\backend\tensorflow_backend.py 中的 _preprocess_conv2d_input(x, data_format)
    3060 tf_data_format = ‘NHWC’
    3061 if data_format == ‘channels_first’
    -> 3062 if not _has_nchw_support()
    3063 x = tf.transpose(x, (0, 2, 3, 1)) # NCHW -> NHWC
    3064 else

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\backend\tensorflow_backend.py 中的 _has_nchw_support()
    268 “””
    269 explicitly_on_cpu = _is_current_explicit_device(‘CPU’)
    –> 270 gpus_available = len(_get_available_gpus()) > 0
    271 return (not explicitly_on_cpu and gpus_available)
    272

    ~\Anaconda3\envs\tensorflow-sessions\lib\site-packages\keras\backend\tensorflow_backend.py 中的 _get_available_gpus()
    254 global _LOCAL_DEVICES
    255 if _LOCAL_DEVICES is None
    –> 256 _LOCAL_DEVICES = get_session().list_devices()
    257 return [x.name for x in _LOCAL_DEVICES if x.device_type == ‘GPU’]
    258

    AttributeError: ‘Session’ 对象没有属性 ‘list_devices’

    ________________________________________________________

    • Jason Brownlee 2017年12月13日上午5:44 #

      看起来是您的 TensorFlow 版本或 Keras 版本有问题。请确保您安装了最新版本。

      另外,或许可以先尝试在 CPU 上运行,然后再尝试在 GPU 上运行。

      • Socrates 2017年12月13日上午6:04 #

        感谢您的即时回复,Jason!

        以下是 Keras 和 Tensorflow 的版本

        Keras:2.1.1
        Tensorflow:1.2.1

        我也不是在 GPU 上运行它。事实上,我的机器没有 GPU。它是一台带有 Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz 的 T450s 联想笔记本电脑。

        • Jason Brownlee 2017年12月13日下午4:09 #

          我建议更新到最新版本的 Keras 2.1.2 和 TensorFlow 1.4.1。

          • Socrates 2017年12月14日下午1:20 #

            谢谢 Jason!

            彻底卸载了 Anaconda 并重新安装。然后在上面安装了 TensorFlow 和 Keras。它运行良好!!!

          • Jason Brownlee 2017年12月14日下午4:45 #

            干得好!

  62. Abhay Goyal 2017年12月20日晚上12:54 #

    嗨 Jason,我发现你的帖子信息量很大,但是我遇到了一个错误,提示“无法导入名称‘backend’”。我该如何解决呢?

    • Jason Brownlee 2017年12月20日上午5:47 #

      也许仔细检查一下你的 Keras 版本是否是最新的?

  63. Degendra 2017年12月25日下午7:38 #

    最后,输出变量是介于 0 到 9 之间的整数。应该是 0 到 0.9。

    • Jason Brownlee 2017年12月26日上午5:14 #

      不,这里我评论的是我们归一化之前的输出范围。

  64. chiraz 2018年1月4日上午1:50 #

    非常感谢。
    请问,我有一个问题。如何使用 keras 创建我自己的自定义池化层,而不是使用传统的最大池化层?
    再次感谢。

    • Jason Brownlee 2018年1月4日上午8:13 #

      我没做过那个。也许你可以使用现有的 Keras 代码作为模板?

  65. Kevin 2018年1月13日上午6:54 #

    嗨,Jason,
    我喜欢你的代码,它对我帮助很大!
    我有一个问题:在您的简单 CNN 示例中,为什么您选择 Conv2D(32,(5,5),..)(我的意思是您为什么选择 32 和 5 这些数字)。还有,为什么您在第五层选择了 128 个神经元?
    在您更大的 CNN 示例中,为什么您选择 Conv2D(30,..)。我搞不清楚您选择这些数字而不是其他数字(例如 31、32、33、34)的原因。
    谢谢!

  66. Carl Granström 2018年1月15日上午11:13 #

    我达到了

    CNN 错误率:0.67%

    我使用了高级 PReLU 激活而不是 relu,但不确定这是否真的有帮助,因为我不知道如何最好地初始化 alpha,所以就保持默认了。

    我还会尝试使用优化器。可能会尝试比 ADAM 更高级的优化器。

  67. Sathiya_Chakra 2018年1月28日上午3:51 #

    在构建基线模型时,我遇到了“值错误:检查目标时出错:预期 dense_8 具有形状 (None, 784),但得到了形状 (60000, 10) 的数组”错误。我还进行了一次热编码,但仍然遇到相同的错误。

    解决方案是什么?

  68. Jagadeesh 2018年2月1日下午3:54 #

    这真是一篇好文章,对许多从事 CNN 工作的学生很有用。
    我是 Jagadeesh,目前在 AMRITA UNIVERSITY(印度)读本科 (B.Tech)。我们正在尝试使用 CNN 对产品评论进行情感分析。我的项目设计如下
    步骤 1:从亚马逊收集带标签的数据集
    步骤 2:使用 word2vec 工具,将文本转换为向量
    步骤 3:将这些向量作为输入馈送给 CNN。

    现在我们卡在将文本转换为向量这一步,word2vec 为一个单词提供了许多向量,我不知道如何从为该单词生成的 180 个向量中获取单个向量。
    请好心帮助我。
    我必须在 2 月 20 日之前完成这个项目。
    谢谢你,先生。

  69. Atefeh 2018年2月7日下午3:48 #

    你好

    我运行了简单的 CNN,但什么都没发生。我怎么才能知道代码正在运行呢?
    我在 jupyter notebook 中编写了代码。

    • Jason Brownlee 2018年2月8日上午8:22 #

      尝试从命令行运行。

      尝试在 fit() 函数调用上启用详细输出。

  70. Atefeh 2018年2月7日下午4:07 #

    再次问好
    它奏效了,CNN 错误率为 0.93%。
    我真的非常感谢您提供的有用代码。

  71. Atefeh 2018年2月12日下午5:59 #

    你好
    我有一个用于波斯语手写数字的数据集,它包含 10 个文件夹,分别对应 10 个数字 (0, 1, 2, ..., 9),每个文件夹中包含 6000 个样本,每个样本都是 61*61 大小的二值图像(黑白)。

    现在我如何在您的“用于 MNIST 的大型卷积神经网络”代码中加载此数据集?

    数据是存储在 MNIST 图像中还是矩阵中?

    再次非常感谢您的帮助。

  72. Valentina 2018年2月13日上午1:33 #

    你好,Jason。🙂

    我已经把它降到了 0.16% 🙂 会继续调整。

    感谢您的教程,它非常有用且易于理解!🙂

    祝好!

  73. Dibakar Saha 2018年2月15日上午1:19 #

    嗨,Jason,
    我是神经网络新手。所以这个问题听起来可能很傻,但它确实困扰着我。

    在“用于 MNIST 的简单卷积神经网络”部分,我看到您在第一个卷积层使用了 32 个 5×5 滤波器。对吗?为什么只使用 32 个滤波器?有什么数学原因吗?即使在 Tensorflow 指南网站 https://tensorflowcn.cn/tutorials/layers 上,我也发现他们使用了 32 个滤波器。如果我使用 100 个滤波器或者 10 个或 64 个呢?

    我理解了本节之前的部分。也感谢您提供如此棒、易于理解的教程。

    谢谢。

    • Jason Brownlee 2018年2月15日上午8:45 #

      没有特定原因,这是试错法,32 是惯例,因为它通常能很好地适应 GPU 内存。尝试一下,看看什么适用于您的数据。

  74. Praveena Ramanan 2018年2月23日晚上12:48 #

    这只适用于数字吗?我如何自定义它以识别手写单词?

    谢谢!

    • Jason Brownlee 2018年2月23日上午11:58 #

      也许先将单词分割成字母?

      • Praveena Ramanan 2018年2月23日下午5:49 #

        谢谢您的快速回复.. 即使如此,我仍然对标签部分感到困惑。我们是否将单词本身标记为标签,还是只使用映射到它的整数值?

        • Jason Brownlee 2018年2月24日上午9:11 #

          您分割的每个字母都需要映射到标签结果。

  75. Casey 2018年3月3日下午10:01 #

    你好!

    非常感谢这篇精彩的教程。

    我跟着你做,但是当我尝试拟合模型时,我得到一个 InternalError: GPU sync failed。

    有什么办法解决这个问题吗?

    我正在使用 Keras + tensorflow 和 GPU

    • Jason Brownlee 2018年3月4日上午6:03 #

      这听起来像是您的环境有问题。也许可以尝试在 stackoverflow 上搜索/发帖?

      • Casey 2018年3月4日下午10:46 #

        我最后只是卸载了 Tensorflow 并重新安装了 CPU 版本。虽然慢了一点,但没有错误了 🙂

  76. mohsen 2018年3月5日下午6:35 #

    你好。谢谢你的出色帖子。
    你能告诉我 set_image_dim_ordering 的作用吗?

    • Jason Brownlee 2018年3月6日上午6:11 #

      这行代码强制 Keras 框架在每个平台上以相同的方式工作,无论后端如何。这有助于我解释如何准备输入数据。

  77. Pash 2018年3月6日下午3:57 #

    你好,
    我是机器学习新手。首先,感谢您提供如此棒的教程。

    我运行了示例代码,一切正常。有没有办法可以使用您的示例代码来使用我自己的训练和测试图像集?

    谢谢

    • Jason Brownlee 2018年3月7日上午6:10 #

      是的。您需要准备数据,确保所有图像的大小一致。

      然后加载数据,并像我们处理 MNIST 示例一样使用它。

  78. Carlos Aguayo 2018年3月9日下午1:43 #

    嗨,Jason,
    我擅自将您的代码用于 Google Colab 的 Notebook 示例,并在其中提到了您。
    如果这不符合您的意愿,请告诉我。
    https://colab.research.google.com/notebook#fileId=15t4LIQdLVe4y_X1t6Mup0IZ4uO0h8mSJ
    感谢这些精彩的教程!
    卡洛斯

    • Jason Brownlee 2018年3月10日上午6:21 #

      我很乐意让您玩弄代码,但我宁愿它不要被重新发布到其他地方并公开。

  79. uDude 2018年3月17日上午4:46 #

    对于卷积模型,我认为您需要进行一些修正

    1. MaxPooling2D

    data_format 的默认值为“channels_last”,而您的数据已重新格式化,通道在数据维度之前……它应该是

    MaxPooling2D(pool_size=(2,2), data_format=’channels_first’)

    2. 拟合/评估

    您有以下代码

    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
    # 模型的最终评估
    scores = model.evaluate(X_test, y_test, verbose=0)

    您已经从测试中提取了验证数据。虽然测试数据未经训练,但您通常会将验证数据和测试数据解耦,例如

    split = 1./6. # 在拟合期间使用训练集中的 10,000 个元素作为验证
    model.fit(X_train, y_train, validation_split=split, epochs=10, batch_size=200, verbose=2)
    ^^^^^^^^^^^^^^^^^^^^

    像以前一样评分。

    感谢您的示例代码,它很有帮助。

    uDude

  80. ru 2018年4月9日上午4:10 #

    嗨!
    首先感谢您的示例,我尝试运行代码,但 python 在运行时出现错误

    num_pixels = X_train.shape[1] * X_train.shape[2]
    X_train = X_train.reshape(X_train.shape[0], num_pixels).astype(‘float32’)
    X_test = X_test.reshape(X_test.shape[0], num_pixels).astype(‘float32’)

    IndexError Traceback (最近一次调用)
    in ()
    —-> 1 num_pixels = X_train.shape[1] * X_train.shape[2]
    2 X_train = X_train.reshape(X_train.shape[0], num_pixels).astype(‘float32’)
    3 X_test = X_test.reshape(X_test.shape[0], num_pixels).astype(‘float32’)
    4 X_train = X_train / 255
    5 X_test = X_test / 255

    IndexError: 元组索引超出范围

    • Jason Brownlee 2018年4月9日上午6:13 #

      您能确认一下您的环境是最新的并且您已按原样复制了所有代码吗?

  81. Kavi 2018年4月24日上午9:46 #

    感谢您,Jason,提供这个教程。我是神经网络新手,您的教程对我帮助很大。我得到了 0.70 的错误率,并且能够用我自己的图像进行预测,效果非常好。

  82. gabi 2018年4月25日下午9:09 #

    Jason,很棒的文章!我有一个简单的问题,如果你能回答我的话,我想用新的图像输入重新训练我的模型(这意味着将这个图像数组及其标签添加到我的数据集中)。

  83. Saleem 2018年5月4日晚上12:02 #

    嗨,Jason,
    我是新手,非常感谢!!!这对初学者来说是一个很棒的示例,可以让他们亲自动手编写代码。

    在加载图像并尝试预测输出时,我遇到了一些错误。我使用的是带有多层感知器的基线模型示例代码。

    下面是我的示例代码,用于加载图像。

    img_pred = cv2.imread(“C:/ProgramData/Anaconda3/mycode/PythonApplication2/PythonApplication2/1.png”, 0)
    #print(img_pred)

    如果 img_pred.shape != [28,28]
    img2 = cv2.resize(img_pred, (28, 28))
    img_pred = img2.reshape(28,28,-1);
    否则
    imp_pred = img_pred.reshape(28,28,-1);

    img_pred = img_pred.reshape(1, 1, 28, 28)

    pred = model.predict_classes(img_pred)

    pred_proba = model.predict_proba(img_pred)
    print(pred_proba)

    我得到的错误是
    ValueError: 检查时出错:预期 dense_1_input 具有 2 个维度,但获得了形状为 (1, 1, 28, 28) 的数组

    任何帮助解决此问题都将不胜感激。

    谢谢,
    萨利姆

  84. Saleem 2018年5月4日下午4:58 #

    我试过了,没用。
    这是我的完整代码,看看这是否有助于解决问题。

    import numpy
    from keras.datasets import mnist
    来自 keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import Dropout
    from keras.utils import np_utils
    import cv2

    # 设置随机种子以保证结果可复现
    seed = 7
    numpy.random.seed(seed)

    # 加载数据
    (X_train, y_train), (X_test, y_test) = mnist.load_data()

    # 将 28*28 图像展平为每张图像的 784 向量
    num_pixels = X_train.shape[1] * X_train.shape[2]
    X_train = X_train.reshape(X_train.shape[0], num_pixels).astype(‘float32’)
    X_test = X_test.reshape(X_test.shape[0], num_pixels).astype(‘float32′)

    # 将输入从 0-255 归一化到 0-1
    X_train = X_train / 255
    X_test = X_test / 255

    # one hot 编码输出
    y_train = np_utils.to_categorical(y_train)
    y_test = np_utils.to_categorical(y_test)
    num_classes = y_test.shape[1]

    # 定义基线模型
    def baseline_model()
    # 创建模型
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, kernel_initializer=’normal’, activation=’relu’))
    model.add(Dense(num_classes, kernel_initializer=’normal’, activation=’softmax’))
    # 编译模型
    model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])
    return model

    # 构建模型
    model = baseline_model()
    # 拟合模型
    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2)
    # 模型的最终评估
    scores = model.evaluate(X_test, y_test, verbose=0)
    print(“Baseline Error: %.2f%%” % (100-scores[1]*100))

    img_pred = cv2.imread(“C:/ProgramData/Anaconda3/mycode/PythonApplication2/PythonApplication2/1.png”, 0)
    #print(img_pred)

    如果 img_pred.shape != [28,28]
    img2 = cv2.resize(img_pred, (28, 28))
    img_pred = img2.reshape(28,28,-1);
    否则
    imp_pred = img_pred.reshape(28,28,-1);

    img_pred = img_pred.reshape(1, 28, 28)

    pred = model.predict_classes(img_pred)
    print(pred_proba)

    pred_proba = model.predict_proba(img_pred)
    print(pred_proba)

  85. Kemas Farosi 2018年5月8日下午1:48 #

    嗨,Jason,

    如果我完成了模型的训练和测试,并且性能足够好,我如何识别真实图像?因为我想要识别一张图像中的字母,而我的图像与模型的矩阵大小不同。

  86. akefar 2018年5月11日上午5:34 #

    你好 Jason,
    我可以用你的代码处理另一个数据集吗?
    如果可以,
    那么我需要做出什么类型的改变呢?
    谢谢你

    • Jason Brownlee 2018年5月11日上午6:39 #

      是的。更改确实取决于数据。

      我尽量提供足够的上下文,以便您可以自己进行这些更改。

  87. atefeh 2018年5月16日下午6:32 #

    嗨,Jason 先生
    如果我想使用 14*28 图像作为 CNN 输入,我应该在您的主简单 CNN 代码中更改哪些参数?

    我只是更改了与输入大小相关的数字,我的意思是将所有 28,28 更改为 14,28,但我遇到了错误“ValueError: Error when checking target: expected dense_5 to have 2 dimensions, but got array with shape (60001, 10, 2)”。

    谢谢你的帮助

    • Jason Brownlee 2018年5月17日上午6:28 #

      您将在“input_shape”参数中指定图像大小。

  88. Akshay Chaturvedi 2018年5月23日下午1:24 #

    感谢您撰写如此精彩的文章。只是想知道是否有类似于 MNIST 的字母数据集。由于 Tesseract OCR 在我的应用程序中工作不正常,我希望有一个类似的模型来识别手写或印刷字母。

    请告诉我,
    再次感谢

  89. Nitin 2018年5月24日下午10:03 #

    当我尝试运行 CNN 代码时,我收到了这个错误

    --
    ValueError 回溯 (最近一次调用)
    in ()
    1 #构建模型
    —-> 2 model = larger_model()
    3 #拟合模型
    4 model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2)
    5

    在 larger_model() 中
    9 model.add(Dropout(0.2))
    10 model.add(Flatten())
    —> 11 model.add(Dense(128, activation=’relu’))
    12 model.add(Dense(50, activation=’relu’))
    13 model.add(Dense(num_classes, activation=’softmax’))

    ~\Anaconda3\lib\site-packages\keras\models.py 中的 add(self, layer)
    490 output_shapes=[self.outputs[0]._keras_shape])
    491 else
    –> 492 output_tensor = layer(self.outputs[0])
    493 if isinstance(output_tensor, list)
    494 raise TypeError(‘Sequential 模型中的所有层 ‘

    ~\Anaconda3\lib\site-packages\keras\engine\topology.py 中的 __call__(self, inputs, **kwargs)
    590 ‘layer.build(batch_input_shape)‘)
    591 if len(input_shapes) == 1
    –> 592 self.build(input_shapes[0])
    593 else
    594 self.build(input_shapes)

    ~\Anaconda3\lib\site-packages\keras\layers\core.py 中的 build(self, input_shape)
    840 name=’kernel’,
    841 regularizer=self.kernel_regularizer,
    –> 842 constraint=self.kernel_constraint)
    843 if self.use_bias
    844 self.bias = self.add_weight(shape=(self.units,),

    ~\Anaconda3\lib\site-packages\keras\legacy\interfaces.py 中的 wrapper(*args, **kwargs)
    89 warnings.warn(‘更新您的 ' + object_name +
    90 '
    调用到 Keras 2 API:’ + signature, stacklevel=2)
    —> 91 return func(*args, **kwargs)
    92 wrapper._original_function = func
    93 return wrapper

    ~\Anaconda3\lib\site-packages\keras\engine\topology.py 中的 add_weight(self, name, shape, dtype, initializer, regularizer, trainable, constraint)
    411 if dtype is None
    412 dtype = K.floatx()
    –> 413 weight = K.variable(initializer(shape),
    414 dtype=dtype,
    415 name=name,

    ~\Anaconda3\lib\site-packages\keras\initializers.py 中的 __call__(self, shape, dtype)
    215 limit = np.sqrt(3. * scale)
    216 return K.random_uniform(shape, -limit, limit,
    –> 217 dtype=dtype, seed=self.seed)
    218
    219 def get_config(self)

    ~\Anaconda3\lib\site-packages\keras\backend\theano_backend.py 中的 random_uniform(shape, minval, maxval, dtype, seed)
    2304 seed = np.random.randint(1, 10e6)
    2305 rng = RandomStreams(seed=seed)
    -> 2306 return rng.uniform(shape, low=minval, high=maxval, dtype=dtype)
    2307
    2308

    ~\Anaconda3\lib\site-packages\theano\sandbox\rng_mrg.py 中的 uniform(self, size, low, high, ndim, dtype, nstreams, **kwargs)
    860 raise ValueError(
    861 “指定大小包含维度值 862 size)
    863
    864 else

    ValueError: (‘指定大小包含维度值 <= 0', (-150, 128))

  90. atefeh 2018年5月26日下午7:50 #

    你好

    请问您能帮我找到导致您的简单 CNN 识别错误的错误分类样本吗?

    我想确切地知道哪些类别在学习和分类过程中导致了最大的错误。

    非常感谢

  91. atefeh 2018年5月30日下午8:52 #

    你好,Jason Brownlee 博士

    我希望提高识别准确率?
    我使用你的简单 CNN 处理我的数据,得到了 2.64% 的错误率。
    现在,通过添加层是否有可能提高我的准确率?
    你还有什么建议可以实现这个目标?
    是否需要对图像进行预处理?

    感谢你对混淆矩阵的指导,我已经成功运行并得到了表格。
    现在我想看看那些被错误分类的图像,我该怎么做?

  92. Billy 2018年6月12日上午1:11 #

    嗨,Jason!

    我想尝试一些我自己捕获的图像。我的图像有 3 位数字。

    有没有办法知道 CNN 预测的结果?我想知道结果是否可以与原始图像数字进行比较?

    • Jason Brownlee 2018年6月12日上午6:45 #

      您的图像必须与训练数据以相同的方式准备。

      网络的输出是类别,也是图像上表示的整数。

  93. Rohit Chauhan 2018年6月21日下午8:56 #

    我想训练脑部图像,并且需要对其进行分割……

    先生,请给我一些博客指导。

    • Jason Brownlee 2018年6月22日上午6:06 #

      抱歉,我没有处理大脑图像或分割图像的示例。

  94. Udaya 2018年6月26日上午3:14 #

    我尝试过一个带有单层隐藏层的简单神经网络。我反复运行脚本时得到了不同的准确率。原因是什么?

  95. ROSHAN KUMAR 2018年6月27日上午3:50 #

    InvalidArgumentError 回溯(最近一次调用在最后)
    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py 中的 _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    685 graph_def_version, node_def_str, input_shapes, input_tensors,
    –> 686 input_tensors_as_shapes, status)
    687 except errors.InvalidArgumentError as err

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py 中的 __exit__(self, type_arg, value_arg, traceback_arg)
    472 compat.as_text(c_api.TF_Message(self.status.status)),
    –> 473 c_api.TF_GetCode(self.status.status))
    474 # 从内存中删除底层状态对象,否则它会一直存在

    InvalidArgumentError: ‘conv2d_1/convolution’(op: ‘Conv2D’)因从 1 中减去 5 导致负维度大小,输入形状:[?,1,28,28], [5,5,28,32]。

    处理上述异常时,发生了另一个异常

    ValueError 回溯 (最近一次调用)
    in ()
    1 # 构建模型
    —-> 2 model = baseline_model()
    3 # 拟合模型
    4 model.fit(X_train, Y_train, validation_data=(X_eval, Y_eval), epochs=10, batch_size=200, verbose=2)
    5 # 模型的最终评估

    在 baseline_model() 中
    2
    3 model = Sequential()
    —-> 4 model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation=’relu’))
    5 model.add(MaxPooling2D(pool_size=(2, 2)))
    6 model.add(Dropout(0.2))

    ~\Anaconda3\lib\site-packages\keras\models.py 中的 add(self, layer)
    465 # 并创建连接当前层的节点
    466 # 到我们刚刚创建的输入层。
    –> 467 layer(x)
    468
    469 if len(layer._inbound_nodes[-1].output_tensors) != 1

    ~\Anaconda3\lib\site-packages\keras\engine\topology.py 中的 __call__(self, inputs, **kwargs)
    617
    618 # 实际调用层,收集输出、掩码和形状。
    –> 619 output = self.call(inputs, **kwargs)
    620 output_mask = self.compute_mask(inputs, previous_mask)
    621

    ~\Anaconda3\lib\site-packages\keras\layers\convolutional.py 中的 call(self, inputs)
    166 padding=self.padding,
    167 data_format=self.data_format,
    –>> 168 dilation_rate=self.dilation_rate)
    169 if self.rank == 3
    170 outputs = K.conv3d(

    ~\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py 中的 conv2d(x, kernel, strides, padding, data_format, dilation_rate)
    3333 strides=strides,
    3334 padding=padding,
    -> 3335 data_format=tf_data_format)
    3336
    3337 if data_format == ‘channels_first’ and tf_data_format == ‘NHWC’

    ~\Anaconda3\lib\site-packages\tensorflow\python\ops\nn_ops.py 中的 convolution(input, filter, padding, strides, dilation_rate, name, data_format)
    752 dilation_rate=dilation_rate,
    753 name=name, data_format=data_format)
    –>> 754 return op(input, filter)
    755
    756

    ~\Anaconda3\lib\site-packages\tensorflow\python\ops\nn_ops.py 中的 __call__(self, inp, filter)
    836
    837 def __call__(self, inp, filter): # pylint: disable=redefined-builtin
    –>> 838 return self.conv_op(inp, filter)
    839
    840

    ~\Anaconda3\lib\site-packages\tensorflow\python\ops\nn_ops.py 中的 __call__(self, inp, filter)
    500
    501 def __call__(self, inp, filter): # pylint: disable=redefined-builtin
    –>> 502 return self.call(inp, filter)
    503
    504

    ~\Anaconda3\lib\site-packages\tensorflow\python\ops\nn_ops.py 中的 __call__(self, inp, filter)
    188 padding=self.padding,
    189 data_format=self.data_format,
    –>> 190 name=self.name)
    191
    192

    ~\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_nn_ops.py 中的 conv2d(input, filter, strides, padding, use_cudnn_on_gpu, data_format, dilations, name)
    723 “Conv2D”, input=input, filter=filter, strides=strides,
    724 padding=padding, use_cudnn_on_gpu=use_cudnn_on_gpu,
    –>> 725 data_format=data_format, dilations=dilations, name=name)
    726 _result = _op.outputs[:]
    727 _inputs_flat = _op.inputs

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py 中的 _apply_op_helper(self, op_type_name, name, **keywords)
    785 op = g.create_op(op_type_name, inputs, output_types, name=scope,
    786 input_types=input_types, attrs=attr_protos,
    –>> 787 op_def=op_def)
    788 return output_structure, op_def.is_stateful, op
    789

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py 中的 create_op(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_shapes, compute_device)
    3160 op_def=op_def)
    3161 self._create_op_helper(ret, compute_shapes=compute_shapes,
    ->> 3162 compute_device=compute_device)
    3163 return ret
    3164

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py 中的 _create_op_helper(self, op, compute_shapes, compute_device)
    3206 # compute_shapes 参数。
    3207 if op._c_op or compute_shapes: # pylint: disable=protected-access
    ->> 3208 set_shapes_for_outputs(op)
    3209 # TODO(b/XXXX): 在移除 _USE_C_API 标志后,将其移动到 Operation.__init__。
    3210 self._add_op(op)

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py 中的 set_shapes_for_outputs(op)
    2425 return _set_shapes_for_outputs_c_api(op)
    2426 else
    ->> 2427 return _set_shapes_for_outputs(op)
    2428
    2429

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py 中的 _set_shapes_for_outputs(op)
    2398 shape_func = _call_cpp_shape_fn_and_require_op
    2399
    ->> 2400 shapes = shape_func(op)
    2401 if shapes is None
    2402 raise RuntimeError(

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py 中的 call_with_requiring(op)
    2328
    2329 def call_with_requiring(op)
    ->> 2330 return call_cpp_shape_fn(op, require_shape_fn=True)
    2331
    2332 _call_cpp_shape_fn_and_require_op = call_with_requiring

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py 中的 call_cpp_shape_fn(op, require_shape_fn)
    625 res = _call_cpp_shape_fn_impl(op, input_tensors_needed,
    626 input_tensors_as_shapes_needed,
    –>> 627 require_shape_fn)
    628 if not isinstance(res, dict)
    629 # 处理 _call_cpp_shape_fn_impl 调用 unknown_shape(op) 的情况。

    ~\Anaconda3\lib\site-packages\tensorflow\python\framework\common_shapes.py 中的 _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    689 missing_shape_fn = True
    690 else
    –>> 691 raise ValueError(err.message)
    692
    693 if missing_shape_fn

    ValueError: ‘conv2d_1/convolution’(op: ‘Conv2D’)因从 1 中减去 5 导致负维度大小,输入形状:[?,1,28,28], [5,5,28,32]。

    • Jason Brownlee 2018年6月27日上午8:21 #

      也许确认您已安装最新版本的 Keras、TensorFlow,并且已从教程中复制了所有代码?

      • r-1 2019年1月23日上午10:53 #

        这可以解决问题

        from keras import backend as K
        K.set_image_dim_ordering(‘th’)

        🙂

        • Jason Brownlee 2019年1月23日下午12:04 #

          是的,这强制代码使用通道优先顺序。

  96. Atefeh 2018年8月2日晚上12:17 #

    你好,Brownlee 先生

    首先,我再次感谢您提供的上述代码。

    我已将其应用于我的数据库(28*28 图像),效果良好。

    现在我有一个问题,

    如果我想用从数字图像中提取的 HOG 特征来馈送 CNN,我该怎么做?

    我的意思是,我想使用每个图像的 HOG 特征,而不是将 28*28 图像作为 CNN 的输入。

    感谢您的帮助

  97. Jeff Nyman 2018年8月13日 下午11:22 #

    我不清楚你为什么把那部分注释掉,像这样:

    # 重塑为 [样本][像素][宽度][高度]

    这使得问题的形状从 (60000, 28, 28) 变成了 (60000, 1, 28, 28)。

    但是因为像素维度永远是 1,这实际上对你有什么用?我知道文章说“重塑它以使其适合用于训练 CNN。” 但许多其他使用 MNIST 的例子并没有这样做。

    那么,重塑为什么会使其更适合而不是更不适合呢?

    • Jason Brownlee 2018年8月14日 上午6:20 #

      CNN 期望有一个或多个通道。对于黑白图像,这是一个通道;对于 RGB 图像,这是三个通道。

      我们必须满足模型的期望。

  98. Keerthi Prasad 2018年8月16日 上午12:12 #

    嗨,Jason,

    非常感谢如此精彩的教程!!

    我有几个问题:

    1. 对于包含手写文本行的图像,CNN 更好还是 RNN 更好(我不知道文本是否属于序列预测)?

    2. 如何训练模型以识别包含一系列手写文本的图像?我应该用所有可能的类别和标签进行训练吗?

    3. 我需要将文本分割成单个字符再进行评估吗?如果需要,请提供分割的参考资料。

    谢谢

  99. atefeh 2018年8月20日 下午6:28 #

    你好
    我的数据库包含向量,每个向量有 144 个元素。(1, 144)。
    我想对这些向量进行分类。(CNN 的输入是向量)

    你能给我展示一下如何编写代码吗?

    我真的很需要它。

    非常感谢

  100. atefeh 2018年8月21日 下午8:05 #

    我的问题是:

    1. 如何将我的数据库保存在我的系统中,以便可能对 CNN 输入有用?(所有向量都应该保存在一个矩阵中吗?例如,我有 10 个类别,每个类别有 6000 个样本,每个样本由一个 144 个元素的向量表示,如何保存这些向量以及以什么格式保存?)(我用 matlab2017 从图像中提取特征向量,然后我想将它们用作 Keras (jupyter notebook) 中 CNN 的输入,用于识别过程)

    2. 在一个简单的 CNN 中,输入是图像,现在我应该如何修改 CNN 代码以读取我的向量而不是图像作为输入?
    我的意思是,在您上面代码的“输入加载”和“独热编码输出”部分,需要更改哪些函数或代码?

    非常感谢您的帮助

    • Jason Brownlee 2018年8月22日 上午6:09 #

      Keras 期望数字向量作为输入。您可以按照您希望的任何方式保存数据,然后加载它并将其转换为 NumPy 数字数组。

      CNN 的输入是向量,它们可以是图像,也可以不是。搜索博客,我展示了如何将 CNN 用于许多其他情况,例如文本和时间序列。

  101. Fatemeh 2018年8月30日 上午8:13 #

    你好 Jason,你能为你的简单 CNN MNIST 画一个架构图吗?
    谢谢你

  102. Sitharth 2018年8月31日 下午9:50 #

    亲爱的 Jason,
    首先,我要感谢您精彩的数据科学教程。它确实是一个真正的学习指南。
    其次,我在代码实现上遇到了一个问题。您能帮忙看看并给出解决方案吗?

    错误报告
    在多层感知器基线模型示例中,我在下面这行代码处遇到了以下错误:
    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=128, verbose=2)
    错误
    ValueError: Error when checking target: expected dense_12 to have 2 dimensions, but got array with shape (60000, 10, 2, 2, 2, 2, 2, 2)

    您能否告诉我接下来该如何处理?

    • Jason Brownlee 2018年9月1日 上午6:20 #

      看起来你的数据形状和模型期望的不同。

  103. SKR 2018年9月6日 下午2:09 #

    您是深度学习界的杰森·伯恩!文章精彩,易读易懂,最令人惊叹的是您几乎回复了所有问题,回复率似乎接近 99%,甚至包括重复的问题。
    很抱歉多次发帖,但我无法决定确切发在哪里。
    JB,我目前专注于一个用例,我需要阅读此链接上的图纸:https://imgur.com/a/Mg8YrgE
    并且需要通过深度学习和图像处理完成以下任务:

    1) 读取所有非常清晰的文本,特别是像 8-N-120XXX-A01-NO 这样的行代码。我尝试了带有 LSTM 的 Tesseract 4.0,它可以识别所有文本,但它是最好的 OCR 吗?或者您建议使用其他方法?
    2) 计算图像中文本的位置。这可以用 Tesseract 实现吗?
    3) 通过一个已经训练好的 CNN 模型检测所有符号,无论是大是小,并通过边界框获取它们的位置。

    请随意回复您能回答的任何问题,并请指导我获取有用的资源以实现我的目标。非常感谢,请继续发布深度学习的新趋势和有用信息。

    • Jason Brownlee 2018年9月6日 下午2:16 #

      谢谢。

      你具体遇到了什么问题?例如,你卡在哪里了?

      • SKR 2018年9月7日 上午12:34 #

        感谢您的回复,Jason。我卡在了:

        1) Tesseract 几乎能给我图像中的所有文本,但我也需要文本位置。

        2) 检测图像中的符号及其位置,有什么好的方法吗?纯图像处理还是 CNN?

        谢谢

        • Jason Brownlee 2018年9月7日 上午8:08 #

          我预计需要大量的原型开发。我也预计需要结合计算机视觉方法和 CNN。

          • SKR 2018年9月7日 下午12:59 #

            你好 Jason,你说的“大量原型设计”是什么意思?你是说迭代试错法吗?你能具体说明哪些计算机视觉方法会有用吗?

            想象一下,在一份签名文件上,你必须检测手写签名及其在文件上的位置。你会如何处理?
            非常感谢您的回复。

          • Jason Brownlee 2018年9月7日 下午1:57 #

            我的意思是尝试不同的方法,看看哪种有效。

            我无法指导你最好的方法。应用机器学习是关于发现什么最有效,没有人知道,你无法被告知。

            我可以概述我可能如何解决这个问题,但我没有免费/任何咨询的能力,抱歉。

  104. Prashanth 2018年9月21日 上午3:29 #

    Jason,很棒的帖子!谢谢你。

    正如您在帖子中提到的:“您有很多机会来调整和改进此模型。”

    如果您能建议哪些参数最值得推荐(如果不是全部)进行调整,以及可能的调整方法,那将非常棒。应该使用网格搜索、随机搜索还是贝叶斯优化来调整呢?如果您能对此有所阐述,那就太好了。

  105. NIRBHAY KUMAR PANDEY 2018年11月20日 上午6:48 #

    为什么我会收到以下错误??
    使用 TensorFlow 后端。
    在 60000 个样本上训练,在 10000 个样本上验证
    纪元 1/1
    2018-11-20 01:11:49.591336: I tensorflow/core/platform/cpu_feature_guard.cc:141] 您的 CPU 支持此 TensorFlow 二进制文件未编译使用的指令:AVX2 FMA
    – 6s – 损失:0.2783 – 准确率:0.9211 – 验证损失:0.1408 – 验证准确率:0.9575
    基线错误:4.25%
    回溯(最近一次调用)
    文件“cnn2clean.py”,第 91 行,在
    model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=1, batch_size=200)
    文件“/root/anaconda3/lib/python3.6/site-packages/keras/engine/training.py”,第 952 行,在 fit
    batch_size=batch_size)
    文件“/root/anaconda3/lib/python3.6/site-packages/keras/engine/training.py”,第 789 行,在 _standardize_user_data
    exception_prefix=’target’)
    文件“/root/anaconda3/lib/python3.6/site-packages/keras/engine/training_utils.py”,第 128 行,在 standardize_input_data
    ‘形状为 ’ + str(data_shape))
    ValueError: 检查目标时出错:预期 dense_5 具有 2 个维度,但得到的数组形状为 (60000, 10, 2)
    nkp-Inspiron-15-3567 pca #

    • Jason Brownlee 2018年11月20日 下午2:01 #

      看起来您的数据与您的脚本不匹配。您可以更改数据或更改模型。

  106. Atefeh 2018年12月1日 上午12:32 #

    你好,布朗利先生
    我关于简单 CNN 有 2 个问题:

    1. 如果我想知道训练阶段和评估阶段各需要多长时间?我该如何实现?您能教我如何修改上面的代码以获取我提到的时间吗?

    2. 如果我想在每个卷积层之后查看输出图像,我该如何实现?我的意思是,我想知道一个样本图像在经过卷积层过滤器处理后会发生什么。我如何将卷积层的输出显示为图像?

    如果您能为这些目的提供 Keras 代码,我将不胜感激。

    • Jason Brownlee 2018年12月1日 上午6:51 #

      不,模型收敛具有挑战性。我们无法保证结果或所需时间。

      您可以绘制中间表示,抱歉,我没有示例。

  107. Shahbaz 2018年12月10日 上午3:37 #

    萨拉姆(祝你平安)杰森。
    我是沙赫巴兹
    你是我的机器学习老师,但我想问一下,这是一个完整的 OCR 吗,还是还需要进一步的工作?我可以在我的毕业设计中使用它吗?请教我如何为大学毕业设计开发我的 OCR 系统。
    我将非常感谢您的好意……

    • Jason Brownlee 2018年12月10日 上午6:06 #

      抱歉,这是我唯一关于这个主题的例子。

  108. Shouvik 2019年1月3日 下午6:06 #

    我的笔记本电脑有问题。请解决它。
    回溯(最近一次调用)
    文件 "C:/python/python37/testpy6.py", 第 17 行, 在
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    文件 "C:\python\python37\lib\site-packages\keras\datasets\mnist.py", 第 23 行, 在 load_data
    file_hash=’8a61469f7ea1b51cbae51d4f78837e45′)
    文件 "C:\python\python37\lib\site-packages\keras\utils\data_utils.py", 第 222 行, 在 get_file
    urlretrieve(origin, fpath, dl_progress)
    文件 "C:\python\python37\lib\urllib\request.py", 第 277 行, 在 urlretrieve
    block = fp.read(bs)
    文件 "C:\python\python37\lib\http\client.py", 第 449 行, 在 read
    n = self.readinto(b)
    文件 "C:\python\python37\lib\http\client.py", 第 493 行, 在 readinto
    n = self.fp.readinto(b)
    文件 "C:\python\python37\lib\socket.py", 第 586 行, 在 readinto
    return self._sock.recv_into(b)
    文件 "C:\python\python37\lib\ssl.py", 第 1009 行, 在 recv_into
    return self.read(nbytes, buffer)
    文件 "C:\python\python37\lib\ssl.py", 第 871 行, 在 read
    return self._sslobj.read(len, buffer)
    文件 "C:\python\python37\lib\ssl.py", 第 631 行, 在 read
    v = self._sslobj.read(len, buffer)
    ConnectionResetError: [WinError 10054] 现有连接被远程主机强制关闭
    >>>

    • Jason Brownlee 2019年1月4日 上午6:28 #

      抱歉,我没有遇到过这个问题,也许可以尝试在 Stack Overflow 上提问?

  109. David 2019年1月9日 上午1:45 #

    请告诉我解决方案……如何将此模型应用于图像或视频(API)?

    • Jason Brownlee 2019年1月9日 上午8:46 #

      抱歉,我没有关于处理视频数据的教程。

  110. Abhi 2019年1月18日 下午4:00 #

    # 用于根据训练好的模型预测本地存储图像的代码
    # 我的本地图像已经是 28 x 28
    import numpy as np
    from PIL import Image
    from keras.preprocessing import image
    img = image.load_img('文件路径包含完整文件名')# , target_size=(32,32))
    img = image.img_to_array(img)
    img = img.reshape((1,) + img.shape)
    #img = img/255
    img = img.reshape(-1,784)
    img_class=model.predict_classes(img)
    prediction = img_class[0]
    classname = img_class[0]
    print(“Class: “,classname)

    • Jason Brownlee 2019年1月19日 上午5:34 #

      干得好!

      • Miguel Saraiva 2019年1月29日 下午1:20 #

        您好,很棒的教程!
        我有几个问题:
        1) 您认为这个教程还算新颖吗,还是最近几年有什么更好的新东西?
        2) 在更大的模型中,每个 Conv2D 和全连接层之后的输出维度是多少?
        谢谢你

        • Jason Brownlee 2019年1月30日 上午8:03 #

          我认为这个模型可以改进。

          您可以通过查看 model.summary() 的输出来获取所有层的输出维度。

  111. louloua 2019年2月10日 下午7:06 #

    非常感谢您的解释
    我想问你,如何对普通图像进行操作

  112. Astri 2019年2月21日 下午6:46 #

    感谢您的教程。
    我是神经网络和框架的初学者。我想问一下,在这个例子中,权重是如何初始化的?以及这个模型是否通过我们在 model.fit 中决定的 epoch 数量进行训练,我是否可以修改它,使模型重复直到满足某个条件?

    • Jason Brownlee 2019年2月22日 上午6:16 #

      权重用小的随机值初始化。

      是的,您根据指定的训练周期数进行拟合。

  113. Hee 2019年3月19日 下午7:01 #

    谢谢 Jason:) 这篇文章对于理解 CNN 非常有帮助。
    我该如何显示结果?
    这篇帖子只看到了分数……我希望看到图像。

    • Jason Brownlee 2019年3月20日 上午8:27 #

      谢谢。

      你说的显示结果具体是什么意思?

  114. Kjell J 2019年4月9日 下午7:03 #

    如果你想实现一个真正的数字识别应用程序,你必须首先检查它是否是一个数字,然后你可以使用这个解决方案来查看它是什么数字(或者颠倒顺序)。这个一般问题更难。所以这里解决的问题是:“当你知道它是一个数字时,它是什么数字”。一个不检查输入的应用程序是不好的……

    试试上面的链接 http://myselph.de/neuralNet.html,画一个 X 字符,你可能会得到预测 = 8。画一个 H,你会得到 4。

    我在哪里可以找到更一般问题的解决方案?

    你也可以尝试我的应用程序 gubboit.se/digitapp。我打算解决更一般的问题。

  115. Astri 2019年5月15日 下午1:15 #

    你好,杰森
    感谢您的教程,它对初学者非常有帮助。
    我想知道如何以数组形式保存每一层(隐藏层、输出层)的输出?

    我尝试了 model.layers[i].output,但它只给我 Tensor(“dense_1/Relu:0”, shape=(?, 128), dtype=float32) 的结果

  116. Abdullah 2019年11月22日 上午3:39 #

    非常非常感谢,

  117. Abdullah 2019年12月23日 下午7:37 #

    嗨,Jason,

    我得到了 0.80 的错误率。谢谢您的教程!!

    您能指导我如何在自己的手写字符数据集上训练这个模型吗?
    谢谢 🙂

  118. Fernando 2020年1月20日 上午9:27 #

    嗨 Jason,感谢您的教程!我这个周末刚开始玩机器学习,它帮了我大忙!我制作了一个 tkinter 画布,可以自由绘制数字,然后将其输入模型进行预测。起初我感到很沮丧,因为结果与 CNN 模型训练后给出的 0.75% 错误率相去甚远。有些数字几乎从未被正确预测!

    直到我阅读了上面提到的 JavaScript 实现网页链接,我才意识到预处理的重要性。在将图像居中并重新缩放后,错误率变得可以忽略不计,即使是绘制得很糟糕的数字也能正确识别!

    • Jason Brownlee 2020年1月20日 下午2:06 #

      干得好,听起来是个有趣的项目扩展!

  119. Phil 2020年2月29日 上午6:59 #

    嗨,Jason,

    感谢您的教程,我想知道我是否可以在我正在构建的项目中使用这段代码?

  120. Ashutosh 2020年4月30日 下午3:11 #

    嗨,Jason,

    我是机器学习新手
    我想运行这段代码,但我不知道它需要什么环境设置。
    您能帮我吗?

  121. sai 2020年5月2日 上午5:55 #

    你好,
    感谢这个好的例子…
    但是它只识别单个数字。
    如果我想检测
    123 X 435
    234 X 543
    987 X 453
    这种手写信息一行一行地,我该如何实现?提前感谢

    • Jason Brownlee 2020年5月3日 上午6:04 #

      一种方法可能是先将输入分割成数字,然后对每个数字进行分类。

      • sai 2020年5月3日 下午9:28 #

        你能提供相关的教程吗?

      • sai 2020年5月4日 下午9:45 #

        但是分段真的有效吗?像我提到的一样逐行获取数字?这可能吗,或者有没有其他使用深度学习(Keras)的完美方法?

        • Jason Brownlee 2020年5月5日 上午6:27 #

          是的,它有效。抱歉,我没有关于这个主题的教程供您参考。

  122. kamal 2021年4月2日 下午4:39 #

    先生,请解释一下我们如何在我们的应用程序图像上应用已经训练好的模型。

  123. sai 2021年5月23日 下午8:33 #

    先生,为了这段代码,我需要 Streamlit 画布
    我还有一个疑问,就是隐藏层是否已经包含在内了

  124. Arpan Manna 2021年6月9日 上午12:59 #

    这里如何提供自己的数据集?

  125. Hendry Wijaya 2021年8月28日 下午5:28 #

    当我运行 build_model 函数时遇到了一个错误。

    但是消息没有显示任何错误的行?

    # 使用对数损失和 ADAM 梯度下降构建模型函数
    def baseline_model()
    # 创建模型
    model = Sequential()
    model.add(Conv2D(32, (5, 5), # 滤波器和核
    input_shape=(1, 28, 28),
    activation='relu'))
    model.add(MaxPooling2D())
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))

    # 编译模型
    model.compile(loss='categorical_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])
    return model

    —————————————————————————
    InvalidArgumentError 回溯(最近一次调用在最后)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs, op_def)
    1879 尝试
    -> 1880 c_op = pywrap_tf_session.TF_FinishOperation(op_desc)
    1881 except errors.InvalidArgumentError as e

    InvalidArgumentError: 由于从 1 中减去 5 导致维度大小为负,原因在于 ‘{{node conv2d_4/Conv2D}} = Conv2D[T=DT_FLOAT, data_format=”NHWC”, dilations=[1, 1, 1, 1], explicit_paddings=[], padding=”VALID”, strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](Placeholder, conv2d_4/Conv2D/ReadVariableOp)’,输入形状为:[?,1,28,28], [5,5,28,32]。

    处理上述异常时,发生了另一个异常

    ValueError 回溯 (最近一次调用)
    18 帧
    in ()
    1 # 运行模型函数
    —-> 2 model = baseline_model()
    3
    4 # 通过 fit 函数训练模型
    5 model.fit(X_train, y_train,

    在 baseline_model() 中
    5 model.add(Conv2D(32, (5, 5), # 滤波器和核
    6 input_shape=(1, 28, 28),
    —-> 7 activation='relu'))
    8 model.add(MaxPooling2D())
    9 model.add(Dropout(0.2))

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/training/tracking/base.py in _method_wrapper(self, *args, **kwargs)
    528 self._self_setattr_tracking = False # pylint: disable=protected-access
    529 尝试
    -> 530 结果 = 方法(self, *args, **kwargs)
    531 最后
    532 self._self_setattr_tracking = previous_value # pylint: disable=protected-access

    /usr/local/lib/python3.7/dist-packages/keras/engine/sequential.py in add(self, layer)
    200 # 并创建连接当前层
    201 # 到我们刚刚创建的输入层的节点。
    -> 202 layer(x)
    203 set_inputs = True
    204

    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py in __call__(self, *args, **kwargs)
    975 如果 _in_functional_construction_mode(self, inputs, args, kwargs, input_list)
    976 返回 self._functional_construction_call(inputs, args, kwargs,
    -> 977 input_list)
    978
    979 # 维护关于 `Layer.call` 堆栈的信息。

    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py in _functional_construction_call(self, inputs, args, kwargs, input_list)
    1113 # 检查层构建后设置的输入假设,例如输入形状。
    1114 outputs = self._keras_tensor_symbolic_call(
    -> 1115 inputs, input_masks, args, kwargs)
    1116
    1117 如果 outputs 为 None

    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py in _keras_tensor_symbolic_call(self, inputs, input_masks, args, kwargs)
    846 返回 tf.nest.map_structure(keras_tensor.KerasTensor, output_signature)
    847 否则
    -> 848 返回 self._infer_output_signature(inputs, args, kwargs, input_masks)
    849
    850 def _infer_output_signature(self, inputs, args, kwargs, input_masks)

    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py in _infer_output_signature(self, inputs, args, kwargs, input_masks)
    886 self._maybe_build(inputs)
    887 inputs = self._maybe_cast_inputs(inputs)
    -> 888 outputs = call_fn(inputs, *args, **kwargs)
    889
    890 self._handle_activity_regularization(inputs, outputs)

    /usr/local/lib/python3.7/dist-packages/keras/layers/convolutional.py in call(self, inputs)
    247 inputs = tf.pad(inputs, self._compute_causal_padding(inputs))
    248
    -> 249 outputs = self._convolution_op(inputs, self.kernel)
    250
    251 如果 self.use_bias

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py in wrapper(*args, **kwargs)
    204 “””调用目标,如果出现 TypeError 则回退到调度器。”””
    205 尝试
    -> 206 返回目标(*args, **kwargs)
    207 except (TypeError, ValueError)
    208 # 注意:convert_to_eager_tensor 目前会引发 ValueError,而不是

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/nn_ops.py in convolution_v2(input, filters, strides, padding, data_format, dilations, name)
    1136 data_format=data_format,
    1137 dilations=dilations,
    -> 1138 name=name)
    1139
    1140

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/nn_ops.py in convolution_internal(input, filters, strides, padding, data_format, dilations, name, call_from_convolution, num_spatial_dims)
    1266 data_format=data_format,
    1267 dilations=dilations,
    -> 1268 name=name)
    1269 否则
    1270 如果 channel_index == 1

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/nn_ops.py in _conv2d_expanded_batch(input, filters, strides, padding, data_format, dilations, name)
    2720 data_format=data_format,
    2721 dilations=dilations,
    -> 2722 name=name)
    2723 返回 squeeze_batch_dims(
    2724 input,

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/gen_nn_ops.py in conv2d(input, filter, strides, padding, use_cudnn_on_gpu, explicit_paddings, data_format, dilations, name)
    971 padding=padding, use_cudnn_on_gpu=use_cudnn_on_gpu,
    972 explicit_paddings=explicit_paddings,
    -> 973 data_format=data_format, dilations=dilations, name=name)
    974 _result = _outputs[:]
    975 如果 _execute.must_record_gradient()

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(op_type_name, name, **keywords)
    748 op = g._create_op_internal(op_type_name, inputs, dtypes=None,
    749 name=scope, input_types=input_types,
    -> 750 attrs=attr_protos, op_def=op_def)
    751
    752 # `outputs` 作为单独的返回值返回,以便输出

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in _create_op_internal(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_device)
    599 return super(FuncGraph, self)._create_op_internal( # pylint: disable=protected-access
    600 op_type, captured_inputs, dtypes, input_types, name, attrs, op_def,
    -> 601 compute_device)
    602
    603 def capture(self, tensor, name=None, shape=None)

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in _create_op_internal(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_device)
    3567 input_types=input_types,
    3568 original_op=self._default_original_op,
    -> 3569 op_def=op_def)
    3570 self._create_op_helper(ret, compute_device=compute_device)
    3571 return ret

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in __init__(self, node_def, g, inputs, output_types, control_inputs, input_types, original_op, op_def)
    2040 op_def = self._graph._get_op_def(node_def.op)
    2041 self._c_op = _create_c_op(self._graph, node_def, inputs,
    -> 2042 control_input_ops, op_def)
    2043 name = compat.as_str(node_def.name)
    2044

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs, op_def)
    1881 except errors.InvalidArgumentError as e
    1882 # 为向后兼容性转换为 ValueError。
    -> 1883 raise ValueError(str(e))
    1884
    1885 return c_op

    ValueError: Negative dimension size caused by subtracting 5 from 1 for ‘{{node conv2d_4/Conv2D}} = Conv2D[T=DT_FLOAT, data_format=”NHWC”, dilations=[1, 1, 1, 1], explicit_paddings=[], padding=”VALID”, strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](Placeholder, conv2d_4/Conv2D/ReadVariableOp)’ with input shapes: [?,1,28,28], [5,5,28,32]。

    • Adrian Tam
      Adrian Tam 2021年8月28日 下午11:04 #

      代码看起来没问题,但似乎你的输入形状可能是原因。

  126. Hendry Wijaya 2021年8月30日 下午6:43 #

    输入形状怎么了?

    这是我加载数据时的代码:
    ——————————————————————————————————————–
    # 加载数字数据
    (X_train, y_train), (X_test, y_test) = mnist.load_data()
    ——————————————————————————————————————–

    然后我进行转换,我一直按照您的代码操作:
    ——————————————————————————————————————–
    # 将数据重塑为 [samples][width][heights][channels]
    X_train = X_train.reshape((X_train.shape[0], 28, 28, 1)).astype('float32')
    X_test = X_test.reshape((X_test.shape[0], 28, 28, 1)).astype('float32')
    ——————————————————————————————————————–

    然后我将数字数据归一化为 0-1:
    ——————————————————————————————————————–
    # 将输入归一化从 0-255 到 0-1
    X_train = X_train / 255
    X_test = X_test / 255
    ——————————————————————————————————————–

    然后我对每个输出进行独热编码:
    ——————————————————————————————————————–
    # 对每个输出标签进行独热编码
    y_train = np_utils.to_categorical(y_train)
    y_test = np_utils.to_categorical(y_test)
    num_classes = y_test.shape[1]
    ——————————————————————————————————————–

    这是我运行 build_model 函数时的代码:
    ——————————————————————————————————————–
    # 运行模型函数
    model = baseline_model()

    # 通过 fit 函数训练模型
    model.fit(X_train, y_train,
    validation_data = (X_test, y_test),
    epochs=10, batch_size= 200, verbose=2)
    ——————————————————————————————————————–

  127. Hendry Wijaya 2021年8月30日 下午6:57 #

    抱歉,如果我在模型构建阶段之前的代码中犯了错误,我可能没有意识到,所以如果我错了,你能纠正我吗?

    • Adrian Tam
      Adrian Tam 2021年9月1日 上午7:56 #

      我太忙了,无法为每个人调试代码。我的建议是,直接运行代码,看看是否出现任何错误。通常,模型中的错误会在您开始训练时立即导致一些错误。

  128. Arpit 2021年12月1日 下午5:27 #


    基线卷积模型函数定义中似乎有一个错误
    你在卷积层中定义的输入形状是 1,28,28,但你在下一节中使用了 28,28,1,并且你使用了通道在后的布局,但写成了 [像素][宽度][高度]

    • Adrian Tam
      Adrian Tam 2021年12月2日 上午2:50 #

      你说的没错。已更正。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。