首页 > 其他分享 >TensorFlow-图像深度学习实用手册-全-

TensorFlow-图像深度学习实用手册-全-

时间:2024-10-05 17:16:32浏览次数:9  
标签:模型 学习 神经网络 图像 TensorFlow Docker 我们 实用手册

TensorFlow 图像深度学习实用手册(全)

零、前言

TensorFlow 是谷歌广受欢迎的机器学习和深度学习产品。它已经迅速成为一种流行的工具选择,用于执行快速、高效和准确的深度学习任务。

本书向您展示了现实世界项目的实际实现,教您如何利用 TensorFlow 的功能来执行高效的深度学习。在本书中,您将熟悉执行深度学习的不同范例,如深度神经网络、卷积神经网络、循环神经网络等,以及如何使用 TensorFlow 实现它们。

我们将借助三个真实项目的端到端实施来展示这一点,这三个项目涉及热门话题领域,如自然语言处理、图像分类和欺诈检测。

到本书结束时,你将掌握深度学习的所有概念,以及它们与 TensorFlow 和 Keras 的实现。

这本书是给谁的

这本书是为应用开发人员、数据科学家和机器学习从业者准备的,他们希望将机器学习集成到应用软件中,并通过在 TensorFlow 中实施实际项目来掌握深度学习。要充分利用这本书,需要 Python 编程知识和深度学习的基础知识。

这本书涵盖的内容

第一章,机器学习工具包,着眼于安装 Docker,建立机器学习 Docker 文件,与你的主机共享数据,运行 REST 服务提供环境。

第二章,图像数据,讲授 MNIST 数字,如何获取它们,张量如何实际上只是多维数组,以及我们如何将图像数据和分类数据编码为张量。然后,我们有一个快速回顾和食谱方法来考虑维度和张量,以便为机器学习准备数据。

第三章、经典神经网络,涵盖了一大堆素材!我们看到了经典的或密集的神经网络的结构。我们学习激活、非线性和 softmax。然后,我们设置测试和训练数据,并学习如何用DropoutFlatten构建网络。我们还学习了所有关于解算器的知识,或者机器实际上是如何学习的。然后,我们探索超参数,最后,我们通过网格搜索微调我们的模型。

第四章,卷积神经网络,教你卷积,这是一种松散连接的方式,在图像上移动以提取特征。然后我们学习池,它总结了最重要的特性。我们将使用这些技术构建一个卷积神经网络,并且我们将卷积和池的许多层结合起来,以便生成一个深度神经网络。

第五章,一个图像分类服务器,使用一个 Swagger API 定义来创建一个 REST API 模型,该模型然后声明性地生成 Python 框架,以便我们为该 API 提供服务。然后,我们创建一个 Docker 容器,它不仅捕获我们的运行代码(即我们的服务),还捕获我们预先训练的机器学习模型。这就形成了一个包,这样我们就能够部署和使用我们的容器。最后,我们使用这个容器来提供服务和进行预测。

从这本书中获得最大收益

你需要:

  • 使用命令行 shell 的经验
  • Python 脚本或应用开发经验

下载示例代码文件

你可以从你在www.packtpub.com的账户下载本书的示例代码文件。如果你在其他地方购买了这本书,你可以访问 www.packtpub.com/support 的并注册,让文件直接通过电子邮件发送给你。

您可以按照以下步骤下载代码文件:

  1. www.packtpub.com登录或注册。
  2. 选择支持选项卡。
  3. 点击代码下载和勘误表。
  4. 在搜索框中输入图书名称,然后按照屏幕指示进行操作。

下载文件后,请确保使用最新版本的解压缩或解压文件夹:

  • WinRAR/7-Zip for Windows
  • 适用于 Mac 的 Zipeg/iZip/UnRarX
  • 用于 Linux 的 7-Zip/PeaZip

该书的代码包也托管在 GitHub 的 https://GitHub . com/packt publishing/Hands-On-Deep-Learning-for-Images with tensor flow 上。如果代码有更新,它将在现有的 GitHub 库中更新。

我们在也有丰富的书籍和视频目录中的其他代码包。看看他们!

使用的惯例

本书通篇使用了许多文本约定。

CodeInText:表示文本中的码字、数据库表名、文件夹名、文件名、文件扩展名、路径名、伪 URL、用户输入和 Twitter 句柄。这里有一个例子:“你只需要输入docker --help来确保所有的东西都被安装了。”

任何命令行输入或输出都按如下方式编写:

C:\11519>docker build -t keras .

Bold :表示一个新术语、一个重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词出现在文本中,如下所示。下面是一个例子:“我们将选择并复制我们稍后将使用的测试命令,然后单击 Apply。”

警告或重要提示如下所示。

提示和技巧是这样出现的。

取得联系

我们随时欢迎读者的反馈。

总体反馈:发送电子邮件[email protected],在邮件主题中提及书名。如果您对本书的任何方面有疑问,请发邮件至[email protected]联系我们。

勘误表:虽然我们已经尽力确保内容的准确性,但错误还是会发生。如果你在这本书里发现了一个错误,请告诉我们,我们将不胜感激。请访问 www.packtpub.com/submit-errata,选择您的图书,点击勘误表提交表格链接,并输入详细信息。

盗版:如果您在互联网上遇到我们作品的任何形式的非法拷贝,如果您能提供我们的地址或网站名称,我们将不胜感激。请通过[email protected]联系我们,并提供材料链接。

如果你有兴趣成为一名作家:如果有你擅长的主题,并且你有兴趣写书或投稿,请访问 authors.packtpub.com。

复习

请留下评论。一旦你阅读并使用了这本书,为什么不在你购买它的网站上留下评论呢?潜在的读者可以看到并使用您不带偏见的意见来做出购买决定,我们 Packt 可以了解您对我们产品的看法,我们的作者可以看到您对他们的书的反馈。谢谢大家!

更多关于 Packt 的信息,请访问packtpub.com

一、机器学习工具包

在本章中,我们将探讨以下主题:

  • 安装 Docker
  • 构建机器学习 Docker 文件
  • 在您的主机和 Docker 容器之间来回共享数据
  • 构建一个 REST 服务,它使用在 Docker 容器中运行的机器学习基础设施

安装 Docker

我们需要下载 Docker 来安装它,在这一节中,您将看到我们如何在 Windows 上安装 Docker,并使用一个适合在 Linux 上安装的脚本。

让我们安装来自 https://www.docker.com/的 Docker。完成这项工作的最快方法是直接看菜单。在这里,我们将选择下载 Windows 版本。点击它,这将把你带到 Docker 商店,在那里你可以为你的平台下载特定的安装程序,如下面的截图所示:

坞站安装程序窗口

这里所有的平台都有。我们只需下载 Windows 版的 MSI。它下载相对较快,一旦它在你的电脑上,你只需点击 MSI 安装程序,它将迅速继续。

在 Ubuntu 上安装最好使用脚本。因此,我提供了一个示例安装脚本(install-docker.sh),它将更新您的本地包管理器,指向官方的 Docker 发行库,然后简单地使用应用来完成安装。

在 Linux 上安装 Docker 非常简单:只需运行我提供的install-docker shell 脚本。这些软件包将会更新、下载,然后安装。当你到达它的末尾时,你只需要输入docker --help来确保所有的东西都被安装了:

输出—docker - help 命令

现在,对于 GPU 支持,这将使你的 Keras 和 TensorFlow 模型运行得更快,有一个名为nvidia-docker的特殊版本,它将 Ubuntu 上的设备暴露给你的 Docker 容器,以允许 GPU 加速。这也有一个安装脚本(install-nvidia-docker.sh)。现在,假设你有一个真正的 NVIDIA 显卡,你可以用 NVIDIA Docker 代替 Docker。

这里,我们正在运行一个使用 NVIDIA SMI 的测试命令,它实际上是一个状态程序,向您显示您计算机上的 GPU 状态:

gps 状态

你可以看到,我们的泰坦 X 完全暴露在 Docker 下。安装 Docker 是一个相对简单的操作。

在下一节中,我们将看看如何创作一个 Docker 文件来建立一个完整的机器学习环境。

机器学习 Docker 文件

现在,让我们开始准备机器学习 Docker 文件。在本节中,我们将了解克隆源文件、Docker 所需的基本映像、安装额外的必需包、公开一个卷以便您可以共享您的工作,以及公开端口以便您可以看到 Jupyter 笔记本,这是我们将用来探索机器学习的工具。

现在,您需要获得这些部分附带的源代码。前往github.com/wballard/kerasvideo/tree/2018,在那里您可以快速克隆存储库。在这里,我们只是使用 GitHub for Windows 作为一种相对快速的方法来克隆这个库,但是您可以以任何您喜欢的方式使用 Git。你把这些文件放在什么目录下并不重要;我们只是把它们下载到本地工作目录中。然后,我们将使用这个位置作为开始构建实际 Docker 容器的地方。

在克隆存储库中,查看 Docker 文件:

Docker 文件代码

这是我们将用来创造我们的环境。我们从具有 CUDA 和 cuDNN 驱动程序的基础 NVIDIA 映像开始,这将在未来支持 GPU。现在,在下一节中,我们将更新容器上的包管理器,以确保我们有更新的gitwget图形包,以便我们能够在笔记本上绘制图表:

Docker 文件代码

现在,我们将安装 Anaconda Python。我们从互联网上下载它,然后作为一个 shell 脚本运行,这将把 Python 放在机器上。完事之后我们会收拾干净的。

Docker 文件代码

Anaconda 是一个用于机器学习和数据科学任务的方便的 Python 发行版,因为它附带了预构建的数学库,特别是 Pandas、NumPy、SciPy 和 scikit-learn,它们是用优化的英特尔数学内核库构建的。这是因为,即使您没有 GPU,使用 Anaconda 通常也可以获得更好的性能。它还具有安装的优势,不是作为一个根或者全局地安装在你的系统下,而是安装在你的主目录中。因此,您可以将它添加到现有的系统中,而不用担心破坏可能依赖 Python 的系统组件,比如说,在用户的bin中或者您的全局包管理器安装了什么。

现在,我们将在名为 Keras 的容器上设置一个用户:

Docker 文件代码

当我们运行笔记本电脑时,它们将以此用户身份运行,因此您将随时知道谁拥有这些文件。创建一个特定的用户来设置你的容器并不是绝对必要的,但是保证你有一个一致的设置是很方便的。随着您对 Docker 更多地使用这些技术,您可能会探索不同的基本映像,在这些映像上设置的用户目录可能与您预期的不完全一样。例如,您可能使用不同的 shell 或有不同的主目录路径。设置你自己的允许这是一致的。

现在,我们实际上将在我们的环境中安装conda:

Docker 文件代码

这将是我们在这里使用的 Python,我们将在它上面安装 TensorFlow 和 Keras,以便有一个完整的环境。你会注意到这里我们同时使用了condapip。因此,conda是 Anaconda Python 附带的包管理器,但是您也可以通过使用普通的pip命令添加不作为conda预打包映像提供的包。因此,在这种方式下,您可以随时混合搭配并获得您需要的包。

在最后几节中,我们将设置一个所谓的VOLUME:

Docker 文件代码

这将允许访问您机器上的本地硬盘驱动器,这样当您编辑和处理文件时,它们不会在容器中丢失。然后,我们将公开一个端口,IPython 笔记本将通过该端口共享。因此,容器将提供端口8888,在容器上运行 IPython 笔记本,然后您将能够从您的 PC 上直接访问它。

请记住,这些设置是从容器的角度来看的:当我们说VOLUME src时,我们实际上说的是在容器上,创建一个/src,它准备好从您的主机接收一定数量的数据,这将在稍后实际运行容器时完成。然后,我们说USER keras:这是我们之前创建的用户。之后,我们说WORKDIR,它说当我们最终运行我们的命令时,使用/src目录作为当前工作目录,也就是jupyter notebook。这设置了一切,所以我们有一些合理的默认值。我们正在以我们期望的用户身份运行,并且我们将在我们期望的目录中运行命令,该命令是从我们的 Docker 容器的网络端口上公开的。

现在我们已经准备好了 Docker 文件,让我们看看一些安全设置以及如何与容器共享数据。

共享数据

在这一节中,我们将看看 Docker 容器和桌面之间的数据共享。我们将介绍一些必要的安全设置以允许访问。然后,我们将运行自检,以确保我们的安全设置是正确的,最后,我们将运行实际的 Docker 文件。

现在,假设你已经安装并运行了 Docker,你需要从设置中可爱的小鲸鱼进入 Docker 设置...菜单。所以,到任务栏的右下角,右击鲸鱼,选择设置...:

Docker 设置

为了让我们的VOLUME正常工作,我们需要进行一些安全设置,以便我们的 Docker 容器可以查看我们的本地硬盘。我已经从 whale 弹出了这个设置,我们将选择并复制稍后将使用的测试命令,然后单击 Apply:

Docker 设置窗口

现在,这将弹出一个新窗口,要求输入密码,以便我们允许 Docker 将共享驱动器映射回我们的 PC,这样我们的 PC 硬盘就可以从容器中看到了。这个共享位置是我们将要工作和编辑文件的地方,这样我们就可以保存我们的工作。

现在我们有了从对话框中复制的命令,我们将继续并将其粘贴到命令提示符中,或者您可以在我们要运行测试容器的位置键入它,只是为了确保我们的 Docker 安装可以实际看到本地硬盘驱动器:

C:\11519>docker run --rm -v c:/Users:/data alpine ls /data

因此,您可以看到,使用-v开关,我们说看到c:/Users:,它实际上在我们的本地 PC 上,然后看到/data,它实际上在容器上,这是卷和alpine测试机。你可以看到它正在下载alpine测试容器,然后运行ls命令,我们可以访问:

输出— ls 命令

请注意,如果您运行在 Linux 上,您将不必执行这些步骤;您只需用sudo运行 Docker 命令,这取决于您实际共享的文件系统。在这里,我们运行dockernvidia-docker来确保我们可以访问我们的主目录:

运行 docker 和 nvidia-docker

请记住,nvidia-docker是 Docker 的一个专门版本,带有插件,有一个漂亮方便的包装器,允许您的 Linux 安装上的本地 GPU 设备从 Docker 容器中可见。如果你打算使用 GPU 支持,你需要记得用nvidia-docker来运行它。

现在,我们实际上要用docker build命令构建我们的容器。我们将使用-t来给它命名为keras,然后继续运行下面的命令:

C:\11519>docker build -t keras .

这实际上会运行得相对较快,因为我实际上以前在这台计算机上构建过它,并且缓存了许多文件:

输出—docker 构建

但是要知道,第一次运行它可能需要 30 分钟。

方便的是,在 Linux 上构建的命令与在 Windows 上用 Docker 构建的命令完全相同。然而,如果您在 Linux 主机上使用 GPU 支持,您可以选择使用nvidia-docker进行构建。那么,docker build是做什么的呢?它获取 Docker 文件并执行它,下载包,创建文件系统,运行命令,然后保存对虚拟文件系统的所有更改,以便以后可以重用。每次运行 Docker 容器时,它都从运行构建时的状态开始。这样,每次跑步都是一致的。

现在我们已经运行了 Docker 容器,我们将继续下一部分,在这里我们将使用 Jupyter Notebook 设置并运行 REST 服务。

机器学习休息服务

既然我们已经构建了 Docker 文件并且可读,我们将在容器中运行 REST 服务。在这一节中,我们将看一看运行 Docker 和正确的命令行参数,从我们的 REST 服务公开的 URL,然后最后我们将验证 Keras 是否完全安装和运行。

现在来看看回报:我们实际上将使用 docker run 命令运行我们的容器。这里有几个开关我们要经过。-p将告诉我们容器上的端口8888是我们 PC 上的端口8888,并且-v命令(实际上我们将挂载我们的本地工作目录,这是我们从 GitHub 克隆源代码的地方)将被挂载到容器上的卷中:

C:\11519>docker run -p 8888:8888 -v C:/11519/:/src keras

按下 Enter ,您会突然看到一个令牌,我们将使用它来测试通过我们的 web 浏览器登录到 IPython 容器:

输出—docker 运行

请注意,此令牌在每次实例运行时都是唯一的,并且会因您的 PC 而异。

现在,如果您在基于 Linux 的机器上有一个 GPU,那么在gpu文件夹中有一个单独的 Docker 文件,您可以用它来构建 Docker 容器,以便获得加速的 GPU 支持。因此,正如您在这里看到的,我们正在构建 Docker 容器,并将其命名为keras-gpu:

建筑码头集装箱

构建容器需要一点时间。输出中确实没有什么重要的东西值得注意;您只需要确保容器最终被成功构建:

建筑码头集装箱

现在,随着容器的构建,我们将继续运行它。我们将使用nvidia-docker运行它,这将 GPU 设备暴露给 Docker 容器:

sudo nvidia-docker run -p 8888:8888 -v ~/kerasvideo/:/src keras-gpu

除此之外,命令行开关与我们实际运行直接 Keras 容器时使用的开关相同,只是它们是nvidia-dockerkeras-gpu。现在,一旦容器启动并运行,您将获得一个 URL,然后将这个 URL 粘贴到您的浏览器中,以访问由容器提供服务的 IPython 笔记本:

输出—docker 在 Ubuntu 系统上运行

现在,我们将快速制作一个新的 IPython 笔记本。当它启动时,我们将import keras,确保它加载,这需要一秒钟才能出现:

Loading Keras

然后,我们将使用以下使用 TensorFlow 的代码来检测 GPU 支持:

from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())

因此,我们将运行前面的代码来查看库和设备:

检测库和设备

现在,我们可以看到我们有GPU

翻到我们的网络浏览器,粘贴网址,然后:

浏览器窗口(lacalhost)

哎呀!达不到是因为0.0.0.0不是真正的计算机;我们将它切换到localhost,点击,输入,果然我们有了一个 IPython 笔记本:

IPython 笔记本

我们将继续创建一个新的 Python 3 笔记本,并通过查看是否可以导入keras库来对其进行快速测试,以确保一切正常。

看起来我们都准备好了。我们的 TensorFlow 后端已经准备就绪!

这就是我们将在本书中运行的环境:一个准备就绪的 Docker 容器,您只需启动它,运行它,然后使用托管在其中的 Keras 和 IPython 笔记本,这样您每次都可以拥有一个简单、可重复的环境。

摘要

在这一章中,我们看了如何安装 Docker,包括从www.docker.com/那里获得它,建立一个机器学习 Docker 文件,与你的主机共享数据,最后,运行一个 REST 服务来提供我们将在本书中使用的环境。

在下一章中,我们将深入研究并开始查看实际数据。然后,我们将从了解如何获取图像数据并为其在机器学习模型中的使用做准备开始。

二、图像数据

在前一章中,我们准备了我们的机器学习工具包,在那里我们设置了 Keras 和 Docker,以便允许我们运行 Jupyter 笔记本来处理机器学习。

在这一章中,我们将研究如何准备用于机器学习的图像数据,以及将这些数据与 Keras 挂钩所涉及的步骤。我们将从学习 MNIST 数字开始。这些是图像形式的手写字符,我们将通过机器学习有效地对其执行光学字符识别 ( OCR )。然后,我们要讲张量。张量听起来像一个数学单词,确实如此,但作为一名程序员,你已经见过多维数组,所以你实际上已经在使用张量,我会向你展示它的等价性。之后,我们要把图像变成张量。正如你习惯于在计算机上看到的那样,图像需要一种特殊形式的编码来用于机器学习。

然后,我们将转向分类。在这种情况下,我们将使用 0 到 9,它们是单个数字的字符,并将它们转换为类别标签。最后,我们将回顾一下,我将向你们展示一本关于当你为机器学习准备数据时如何思考数据的烹饪书。

MNIST 数字

现在,让我们学习 MNIST 数字。在这一部分,我们将看看我准备的ImageData笔记本,它可以帮助我们理解如何处理图像数据;下载并获取 MNIST 数字;将图像视为原始数据;最后,基于这些数字数据来可视化真实的图像。

我们将要使用的代码包含在一个 IPython 笔记本中。这是我们设置容器的方式,所以你要像我们在设置你的机器学习工具包的最后提到的那样运行你的容器。我还准备了一个我们将要使用的 IPython 笔记本。我们将从导入所有必要的包开始,我们将打开 Matplotlib 以便自动绘图。这意味着当我们显示一个图像时,我们不必调用.plot;它会自动为我们完成:

导入包

实际上,Keras 内置了 MNIST 数字作为数据集,因此我们将利用这一便利,继续加载它们。

你需要一个互联网连接,因为它将从亚马逊 S3 下载这些文件。

当我们加载数据时,将有一个 Python 元组,我们将把它解包成两组:一个训练集,和一个测试集:

Python 元组

把你的数据分割成段,其实是机器学习的一个常见约定。您使用它是为了查看您的模型实际上正在使用训练集进行学习。然后,您可以使用测试集来确保您的模型不会过度拟合,这实际上是考虑到您的模型是在记忆训练数据还是在实际学习。

现在,让我们看看 NumPy 的格式选项的快速设置。当我们打印数组时,我们将图像作为数组的数组进行循环,然后打印出数据。如您所见,该图像实际上只是从0255的数字:

灰度图像(阵列阵列)

这是一张灰度图像,这里的每一个整数都记录了这个特定像素有多暗。

现在,让我们绘制图像,看看这些数字到底是什么样子。Matplotlib 有一个简单的plot函数,你可以给出一个数组的数组,或者基本上是一个由 XY 像素组成的二维数组,它会把它绘制成一个.image文件。接下来,你可以看到看起来非常像零的东西:

绘图图像

张量——多维数组

现在我们已经了解了一些 MNIST 数字,我们将花时间来看看张量,以及什么是张量。我们将会看到一组多维数组。多维数组也叫张量。数学词汇可能有点让人不知所措,但是我们将向你展示它比你想象的要简单得多。然后,我们来看看张量形状。张量形状实际上是维度的数量,或者,就数组而言,是你用来访问它们的不同索引的数量。最后,我们将看看数据类型。张量或多维数组可以保存各种不同的数据类型,我们将解释其中的一些差异。

让我们从基础开始。你能想象到的最基本的张量是一个张量,在编程语言中,它被称为数组。它只是一系列有序的打包在一起的数字。下一个是两个张量。如果你看灰度图像(数组的数组)截图,每行是一维,每列是另一维。

所以,一行接一行,这加起来就是两个张量。同样,它只是一个数组的数组。你可以看到有带括号零的训练图像;我们实际上是在一系列图像中挑选出第一张图像。因此,前面有图像数据的三张量实际上是一个图像阵列,每个图像都有一个像素的列和行的阵列。所以,三张量是我们存储黑白图像的基本方式。

作为一个快速的可视化,正如你在索引一的图像中看到的, XsYs (数字后面显示的坐标)就是张量的维数:

张量的维数

现在,我们来谈谈形状。你可以看到我们在 NumPy 多维数组或张量上调用.shape,它返回60000, 28, 28:

打电话。形状

这是构成我们三个张量的三个维度。它只是一个多维数组。然后,当然还有数据类型,或者dtype,就像你在 NumPy 多维数组中所说的那样。你可以看到这些图像被存储为uint8,或者 8 位整数,用来记录0255的值。嗯,我们经常将这种数据类型用于源数据,尤其是像前面这样的黑白图像。当我们将其转换成实际的机器学习格式时,我们将使用浮点运算。

将图像转换成张量

在上一节中,我们学习了一点张量是什么。现在,我们将使用这些知识来准备图像数据,作为机器学习的张量。首先,我们会问一个问题:为什么我们使用浮点数据?然后,我们将了解样本之间的差异以及样本末尾的数据点。最后,我们将标准化数据以用于机器学习。

那么,为什么是浮点呢?嗯,真正的原因是机器学习从根本上来说是一个数学优化问题,当我们处理浮点时,计算机试图优化一系列数学关系,以找到可以预测输出的学习函数。因此,为机器学习准备数据确实需要将普通的二进制数据(如图像)重新格式化为一系列浮点数,这不是我们通常在图像处理方面处理图像的方式,但这是让机器学习算法参与的必要条件。

现在,我们来谈谈样品。按照惯例,样本总是多维数据数组中的第一维。在这里,我们有多个样本,因为机器学习的基本工作原理是通过查看大量不同样本中的大量不同数据点,然后学习一个函数来预测结果。

因此,我们的train_images多维数组中的每个图像都是我们将要查看的样本之一。但是正如你在灰度图像(数组的数组)截图中看到的,我们现在拥有的样本肯定不是浮点型的;这些仍然是 8 位整数。

因此,我们必须想出一个原则性的方法来转换我们的图像从 8 位到浮点。

现在,我们将开始通过规范化来了解为机器学习准备数据到底需要什么。这实际上意味着你取你的数据(在这种情况下,它是在0255范围内的数字),然后除以另一个数字,这样你就缩小了从01的范围:

标准化输出

这是机器学习算法中数值稳定性所需要的。当您的数据在01的范围内标准化时,它们会做得更好,收敛更快,变得更准确。

就是这样!我们已经看到了如何处理输入数据。要记住两件事:我们将把所有东西都变成浮点,最好是在01的范围内标准化数据。

将类别转化为张量

在上一节中,我们讨论了如何将图像转换为用于机器学习的张量,在本节中,我们将讨论如何将输出值(类别)转换为用于机器学习的张量。

我们将讨论输出类,进行离散预测意味着什么,一次性编码的概念;然后,我们将想象一下一键编码作为图像是什么样子,然后我们将通过一本数据准备食谱来回顾一下,您应该使用它来处理机器学习的各种图像数据。

但是现在,我们来谈谈输出。当我们谈论数字时,有09,所以有十个不同的类,不是面向对象意义上的类,而是标签意义上的类。现在,从09的这些标签是独立的数字,我们想要做的预测需要是离散的。预测 1.5 对我们没有任何好处,没有这样的数字字符:

0 到 9 个预测

因此,为此,我们将使用数据转换技巧。这个东西被称为一个热点编码,它是你获取一系列标签可能性的地方,在这个例子中,数字09,并把它们变成一种位图,其中每个选项被编码为一列,并且对于每个给定的数据样本,只有一列被设置为1(因此是一个热点):

一键编码

现在,查看输入数字(此处为9)和输出位图,可以看到第四个索引设置了第九个位,可以看到我们在数据准备中使用了一个图像作为输入,另一个图像作为输出。它们只是碰巧被编码为张量(浮点数的多维数组):

输出位图

当我们创建机器学习算法时,我们要做的是让计算机学习或发现一个函数,将一个图像(数字 9)转换为另一个图像(第九列设置了一位的位图),这就是我们所说的机器学习。请记住,张量只是多维数组, xy 值只是像素。我们将这些值标准化,这意味着我们从 0 到 1 的范围内获取它们,以便它们在机器学习算法中有用。标签或输出类只是我们要映射的一个值数组,我们要用单热编码对它们进行编码,这也意味着只有一个是热的,或者设置为 1。

摘要

在这一章中,我们学习了 MNIST 数字,以及如何获得它们;张量实际上只是多维数组;我们如何将图像数据编码为张量;我们如何将分类数据编码为张量;然后我们有一个快速回顾和食谱方法来思考维度和张量,为机器学习准备数据。

既然我们已经学会了如何为机器学习设置输入和输出数据,我们将进入下一章,在这里我们将创建一个经典神经网络 ( CNN )。

三、经典神经网络

既然我们已经准备好了我们的图像数据,现在是时候利用我们所学的知识来构建一个经典的或密集的神经网络了。在本章中,我们将讨论以下主题:

  • 首先,我们将看看经典的密集神经网络及其结构。
  • 然后,我们将讨论激活函数和非线性。
  • 当我们开始实际分类时,我们需要另一个数学工具,softmax。我们将在本章后面讨论为什么这很重要。
  • 我们将查看训练和测试数据,以及DropoutFlatten,它们是新的网络组件,旨在使网络更好地工作。
  • 然后,我们将看看机器学习者实际上是如何解决的。
  • 最后,我们将学习超参数和网格搜索的概念,以便尽可能地微调和构建最佳神经网络。

让我们开始吧。

经典密集神经网络的比较

在这一节中,我们将着眼于经典或密集神经网络的实际结构。我们将从一个样本神经网络结构开始,然后我们将扩展它来构建一个可视化的网络,你将需要它来理解 MNIST 数字。最后,我们将学习张量数据是如何实际插入网络的。

让我们先来看看密集神经网络的结构。使用网络包,我们将绘制一个神经网络的图片。下面的屏幕截图显示了我们正在设置的三个层,即输入层、激活层和输出层,并将它们完全连接起来:

三层神经网络

这就是中间这两个循环的作用。他们在每一次输入和每一次激活之间,然后是每一次激活和每一次输出之间设置了一个边界。这就是密集神经网络的定义:所有输入和所有激活,所有激活和所有输出之间的完全连接。如你所见,它生成的图片连接非常紧密,因此得名!

现在,让我们将它扩展到两个维度,一个 28 x 28 像素的网格(这是输入网络),然后是一个 28 x 28 像素的激活网络,学习将在这里进行。最终,我们将登陆10职位分类网络,在那里我们将预测输出数字。从下面截图中的深色互连线可以看出,这是一个非常密集的结构:

二维网络

事实上,它是如此的密集,以至于很难看到单独线条的边缘。这些线路是网络内部进行数学运算的地方。激活函数,将在下一节中介绍,是沿着每一条线发生的数学运算。由此我们可以看出,张量和网络之间的关系相对简单:二维输入网格(在本图中是像素)是我们在上一节中了解的二维编码数据的位置。在网络内部,数学运算(通常是点积后跟激活函数)是将一个图层连接到另一个图层的线。

激活和非线性

我们将讨论为什么非线性很重要,然后我们将看看两个最常用的非线性函数的一些可视化形式:sigmoidrelu

因此,非线性可能听起来像一个复杂的数学概念,但你基本上需要知道的是,它不是直线运动的。这使得神经网络能够学习更复杂的形状,而这种对网络结构内部复杂形状的学习正是神经网络和深度学习实际学习的内容。

那么,我们来看看sigmoid函数:

Sigmoid 函数

这是一个范围从 0 到 1 的 S 曲线。它实际上是由 e 的指数和比值构成的。现在,好消息是,你实际上永远不需要编写你在这里看到的数学代码,因为当我们想在 Keras 中使用sigmoid时,我们只需通过名称sigmoid来引用它。

现在,我们来看看relurelu非线性函数在技术上是一种非线性函数,因为当它小于零时,它是一条直线:

ReLu 非线性函数—小于零

当它大于零时,也是一条直线。但是两者的组合,零之前的平坦部分和零之后的角度一起,不形成一条直线:

ReLu 非线性函数—大于零。

因为它是一个非常恒定的函数,当在计算机内部执行时,这在数学上是有效的,所以你会看到relu在许多生产神经网络模型中使用,只是因为它计算更快。但是relu函数的技巧,正如我们在前一章讨论规范化时所了解到的,是它们可以生成大于 1 的值,因此在构建神经网络时,通常需要各种技巧和技术,包括规范化和创建更多层,以使relu函数表现良好。

机器学习中发生的很多事情都涉及到反复计算这些relusigmoid函数的输入。

机器学习模型可能有数百、数千甚至数百万个单独的数字参数通过relusigmoid运行。

有大量的数学在进行,因此大量非线性的交互允许机器学习者在概念上围绕答案绘制高维数学形状。

Softmax

在本节中,我们将了解称为softmax的输出激活功能。我们将看看它与输出类的关系,以及学习softmax如何生成概率。

我们来看看吧!当我们构建一个分类器时,神经网络将输出一堆数字,通常是一个数组,其中一个槽对应于我们的每个类。在我们现在看到的模型中,它是从 0 到 9 的数字。softmax所做的是将一大堆数字平滑成一组概率分数,这些分数的总和为 1:

一堆数字

这很重要,这样你才能知道哪个答案最有可能。因此,作为一个我们可以用来理解softmax的例子,让我们看看我们的值数组。我们可以看到有三个值。假设神经网络输出为125。我们正试着把这些分成红色、绿色和蓝色三类。现在,我们通过softmax运行它,我们可以看到概率得分。你可以清楚地看到,它应该是蓝色的,这用概率表示。读出softmax的方法是使用argmax。您查看具有最高值的单元格,并提取该索引作为您的预测类。但是如果你看看实际的数字——125——你可以看到这些加起来是 8,但是5的输出概率是0.93。那是因为softmax与指数一起工作。不仅仅是数字的线性组合,比如 5 除以 8,然后说 5/8 是属于那个类的概率。我们在这里说的是,最强的信号将会支配较弱的信号,这个指数实际上将会超过具有较高值的类的概率,以便当事物相对接近时,你的神经网络在分类中更有效。请记住,对于一个实际的神经网络,您不会输出漂亮的125数字,您将输出相对较小的十进制数字,例如0.00007,非常小的浮点数,然后我们需要能够将它们分成类。

现在你可能会想,考虑到你可以很容易地从数字125中判断出5是最大值,我们为什么要为此费心。这个想法是,如果你有以概率表示的东西,你可以模拟信心。在某种意义上,你可以在模型之间分享分数,并且知道你的模型实际上有多自信。另外,不同的型号在不同的范围内会产生不同的数字。仅仅因为你在你尝试的第一个模型中使用了125,这并不意味着它们在另一个模型中具有相同的相对值。因此,将它们分解成概率可以让你进行比较。现在,随着数学问题的解决,我们可以开始考虑构建实际的神经网络了。好消息是你实际上不需要记住或知道我们刚才列出的数学。你只需要记住数学的名称,因为在 Keras 中,你用一个简单的名字来引用激活函数。

培训和测试数据

在本节中,我们将了解如何获取培训和测试数据。我们将查看实际数据的加载,然后我们将重新讨论规范化和一次性编码,然后我们将快速讨论为什么我们实际上使用训练和测试数据集。

在本节中,我们将学习上一章中关于准备图像数据并将其压缩成几行代码的内容,如下面的屏幕截图所示:

加载数据

我们加载训练和测试数据以及训练和测试输出。然后,我们归一化,也就是除以最大值,我们知道这个值是255。然后,我们将输出变量分解成分类编码,或者说是一次性编码。对于我们的训练和测试数据集,我们以完全相同的方式做这两件事(标准化和一键编码)。在我们试图在机器学习模型中使用数据之前,我们的数据必须以相同的方式准备好,这一点很重要。这里有一个关于形状的快速注释。注意,训练数据(xy)具有相同的初始编号:

正在加载。形状(训练)

在这两种情况下,第一个维度都是60000,但是看看第二个和第三个维度(2828)——这是输入图像的大小——以及10图。嗯,这些不一定要完全匹配,因为当我们通过模型运行时,我们所做的是将数据从2828维度转换到10维度。

另外,看检测数据。可以看到是第一维度的10000(2828,然后是第二维度的1000010,如下截图所示:

正在加载。形状(测试)

这些维度以适当的方式匹配非常重要。因此,对于一个训练集,第一个维度必须匹配您的xy值(您的输入和输出),并且在您的测试集上,同样的事情也必须是正确的。但是还要注意,第二维度和第三维度2828对于训练和测试数据都是相同的,并且10(输出维度)对于测试和训练数据都是相同的。在准备信息时,没有将这些数据集对齐是最常见的错误之一。但是为什么呢?!一句话:过拟合

过度拟合本质上就是你的机器学习模型记忆了一组输入。您可以把它想象成一个非常复杂的哈希表,它用大量的数字对输入和输出映射进行了编码。但是对于机器学习,我们不想要哈希表,即使我们可以很容易地拥有一个。相反,我们希望有一个模型能够处理未知的输入,然后预测适当的输出。测试数据代表那些未知的输入。当你通过训练数据训练你的模型,并拿出测试数据时,测试数据就在那里,让你验证你的机器学习模型可以处理和预测它从未见过的数据。

好了,现在我们已经加载了我们的训练和测试数据,我们将继续学习DropoutFlatten,并组装一个实际的神经网络。

辍学和扁平化

在本节中,我们将实际构建神经网络模型,并使用DropoutFlatten来创建一个完整的神经网络。

我们将从使用功能 Keras 模型实际组装神经网络开始,查看输入和层堆栈,以便端到端地组装神经网络。然后,我们来解释为什么会有DropoutFlatten,它们对你的模型有什么影响。最后,我们将展示一个模型摘要:这是一种可以可视化机器学习模型中参数和层的总数的方法。

这里,我们使用的是 Keras 的功能模型。您可以将神经网络视为一系列层,每一层都由一个函数定义。该函数传递一组参数来配置层,然后您将它作为参数传递给网络中的前一层,以将它们链接在一起。如下面的截图所示,这个微小的代码块实际上是一个完整的神经网络:

Keras 的功能模型

我们从一个输入层开始,它的形状与我们的一个输入样本相同。在我们的例子中,我们选择了一个训练图像,我们从前面的课程中知道它的尺寸为 28x28 像素。现在,我们将它传递给一个堆栈。密集层之后是dropout_1,密集层之后是dropout_2,我们最终将其转化为softmax激活,将其移交给输出层。然后,我们将这些作为输入和输出组合到我们的模型中。然后,我们打印summary,看起来像这样:

模型摘要输出

因此,您可以从这里看到,参数最初被传递给层,然后层本身被传递以形成一个链。那么,这些DropoutFlatten层呢?Dropout参数本质上是一个技巧。当我们设置Dropout参数(这里是0.1)时,我们告诉神经网络在每个训练周期中随机断开 10%的激活。这是让神经网络学会归纳;这才是真正的学习,而不是简单的记忆输入的数据。Flatten层处理尺寸。因为我们有一个 28x28 像素的二维输入图像,所以我们使用Flatten将它转换成一个长的一维数字串用于784。这被馈送到输出softmax层。

打印出模型的概要是计算参数大小和尺寸的好方法。这最终成为使用 Keras 的一个更棘手的部分,例如当您有一组输入样本时——在我们的例子中是 28x28 图像——您需要在到达softmax时将它们转换成一个由十个可能的输出值组成的数组。当我们通过每一层时,你可以看到形状是如何变化的。最后,Flatten将它转化为每个样本的一个维度,然后再转化为一个包含十个可能输出值的维度。

好了,现在是运行模型的时候了。现在我们已经了解了如何将模型放在一起,包括DropoutFlatten层,我们将继续讨论解算器,这是我们用来实际执行机器学习模型的工具。

解决者(solver 的复数形式)

在本节中,我们将设置学习和优化功能,编译模型,使其适合训练和测试数据,然后实际运行模型,并观看动画,了解对损耗和精度的影响。

在下面的截图中,我们正在用lossoptimizermetrics编译我们的模型:

编译模型

loss函数是一个数学函数,告诉optimizer它做得有多好。一个optimizer函数是一个数学程序,它搜索可用的参数以最小化loss函数。metrics参数是你的机器学习模型的输出,应该是人类可读的,这样你就可以了解你的模型运行得有多好。现在,这些lossoptimizer参数充满了数学。总的来说,你可以把它当作一本食谱。当你用 Keras 运行机器学习模型时,你应该有效地选择adam(这是默认的)。就loss函数而言,当你处理分类问题时,比如 MNIST 数字,你应该使用分类交叉熵。这种食谱式的配方应该对你有好处。

现在,我们将准备用我们的x训练数据(由实际的 MNIST 数字图像组成)和y训练参数(由 0 到 9 个分类输出标签组成)来拟合模型。我们这里有一个新概念是batch_size。这是每次执行循环的图像数量。通常,这受到可用内存的限制,但是较小的批处理大小(32 到 64)通常性能更好。还有这个奇怪的词怎么样:纪元。Epochs 只是指循环的次数。例如,当我们说八个时期时,我们的意思是机器学习模型将在训练数据上循环八次,并将使用测试数据来查看模型变得有多精确八次。正如您在下面的屏幕截图中看到的那样,由于模型重复查看相同的数据,因此准确性会提高:

模型运行

最后,我们来看验证数据,也称为测试数据。这实际上是用来计算精度的。在每个时期结束时,模型被部分训练,然后测试数据通过模型运行,生成一组试验预测,用于对准确性进行评分。机器学习涉及到人类大量的等待。我们将继续前进,跳过每个时代的进程;当您运行这些示例时,您将有很多机会看到这些进度条自己成长。

现在,让我们来谈谈前面的输出。随着进度条的增长,您可以看到它正在运行的样本图像的数量。但是还有loss函数和metrics参数;在这里,我们使用的是准确性。所以,反馈给学习者的loss功能,这就是机器学习真正的学习方式;它试图通过迭代设置模型内部的数值参数来最小化loss,以便让loss数下降。准确性就在那里,这样你就能明白发生了什么。在这种情况下,精确度代表模型猜测正确数字的频率。所以,就像把这当成一本食谱一样,分类交叉熵是你总是想要有效地用于像这样的分类问题的loss函数,而adam是学习算法,是最明智的默认选择;accuracy是一个很棒的输出metrics,你可以用它来查看你的模型运行的有多好。

超参数

在这一节中,我们将探索超参数,即机器无法完全学习的参数。

我们还将介绍可训练参数(求解器学习的参数)、不可训练参数(模型中不需要训练的附加参数),最后是超参数(传统求解器不学习的参数)。

在我们的模型摘要输出截图中,请注意截图底部突出显示的代码部分中可训练参数的数量。这是我们的模型中包含的单个浮点数的数量,我们的adam优化器,结合我们的分类交叉熵loss函数,将探索这个数量,以便找到可能的最佳参数值。所以,这个可训练的参数数是我们的optimizer函数学习的唯一一组数。然而,在这段代码和前面的截图中还有许多其他的数字。这些不可训练的参数呢?在我们当前的模型中,没有不可训练的参数。然而,Keras 中不同种类的图层可能具有常量值,因此它们将显示为不可训练的。同样,这仅仅意味着不需要对它们进行训练,并且我们的optimizer函数不会试图改变它们的值。

那么,什么是超参数?很简单,超参数是一个值——一个参数——在模型本身之外。所以最简单的超参数就是实际的模型结构。在这种情况下,我们创建层的次数是一个超参数,层的大小是一个超参数,我们在密集层中选择的32单位是一个超参数,0.1 dropout 设置是一个超参数,甚至激活函数本身——比如说选择relu而不是sigmoid——也是一个超参数。现在你可能在想,等一下,我不得不在这里选择一大堆参数; 我以为机器应该在学习。确实是!然而,问题在于optimizer无法学习我们需要知道的所有东西来构建一个最佳模型。

网格搜索

在本节中,我们将探索网格搜索。

我们将讨论优化与网格搜索,设置模型生成器功能,设置参数网格,进行交叉验证网格搜索,最后,报告网格搜索的结果,以便我们选择最佳模型。

那么,为什么从根本上说,这里有两种不同的机器学习活动呢?嗯,优化通过来自loss函数的反馈来求解参数:这是高度优化的。具体来说,求解器不必为了工作而尝试每个参数值。它利用偏导数的数学关系,沿着所谓的梯度移动。这使得它在数学上走下坡路来寻找正确的答案。

网格搜索并不那么聪明。其实完全是蛮力。当我们谈论进行网格搜索时,我们实际上是在谈论探索参数值的每一种可能的组合。网格搜索源于这样一个事实,即两组不同的参数形成了一个棋盘或网格,网格搜索涉及运行每个方格中的值。因此,如你所见,网格搜索的效率远远低于优化。那么,你为什么要用网格搜索呢?嗯,当你需要学习优化器无法解决的参数时,你可以使用它,这是机器学习中的一个常见场景。理想情况下,你会有一个算法,解决所有的参数。然而,目前还没有这样的算法。

好了,让我们来看一些代码:

模型生成函数和构想两个超参数

我们将使用 scikit-learn,这是一个经常与 Keras 和其他机器学习软件一起使用的工具包,用于进行网格搜索和分类报告,这将告诉我们最佳模型。然后,我们还将导入 Keras 的KerasClassifier包装器,使其与scikit_learn兼容。

所以现在,让我们关注一个模型生成函数,设想两个超参数。其中一个是dropout,另一个是每个密集隐藏层中的单元数。因此,我们在这里构建一个名为dense_model的函数,它接受unitsdropout,然后像之前一样计算我们的网络。但是不是硬编码的320.1(例如),而是实际的参数将被传入,它将为我们编译模型,然后将该模型作为输出返回。这一次,我们使用顺序模型。以前,当我们使用 Keras 功能模型时,我们将我们的层一个接一个地链接在一起。对于顺序模型,它更像一个列表:从顺序模型开始,一层一层地添加,直到顺序模型本身为您形成了链。现在是超参数网格。这是我们指出网格搜索相对于优化器的一些缺点的地方。您可以在前面的屏幕截图中看到我们选择的值。为了让事情运行得更快,我们将做一个 epoch,并且我们将保持一个恒定的64图像的batch_size,这些图像将在3264128隐藏单元之间变化,并且会丢失0.10.20.4。网格搜索有一个很大的缺点:你在这里看到的超参数是唯一会被执行的——网格搜索不会探索中间的超参数值。

现在,我们设置我们的KerasClassifier,将我们刚刚创建的模型构建函数交给它,并将verbose设置为0,以隐藏每次 Keras 运行的进度条。然后,我们设置一个计时器;我想知道这需要多长时间。现在,我们建立一个交叉验证的网格搜索。对于它的估计器,我们给它我们的模型,也就是我们的KerasClassifier包装器,和我们的grid参数(参见前面的超参数),我们说cv=6,意思是将数据(训练数据)分成六个不同的部分,然后交叉验证。在5进行训练,并使用六分之一的时间进行验证,并反复重复,以搜索最佳超参数值。另外,将verbose设置为4,这样我们可以看到很多输出。现在 Keras 已经运行了很多,我们调用fit函数从我们的x训练数据(同样,这些是我们的输入图像)到我们的y训练数据(这些是从数字 0 到 9 的标签),然后打印出我们的最佳结果。注意,我们实际上还没有接触到我们的测试数据;我们一会儿将使用它来对网格搜索报告的最佳模型的值进行评分。

现在,我们测试结果。这就是我们使用argmax的地方。同样,这是一个查看数组并挑选出其中具有最大值的索引的函数。实际上,这将一个由十个独热编码值组成的数组转换成了一个数字,这个数字就是我们要预测的数字。然后,我们使用一个分类报告,它将打印出x网格,向我们显示一个数字被正确预测的频率与被预测的数字总数的比较。

好了,前面代码的输出如下:

输出—打印分数

我们正在探索超参数网格中的每个参数,并打印出分数。这就是网格搜索搜索最佳可用模型的方式。当我们都完成后,一个单一的模型将被选中。在这种情况下,它是隐藏单元数量最多的一个,我们将通过分类报告来评估该模型使用我们的测试数据的情况。

在下面的屏幕截图中,您可以看到打印输出包含我们已经识别的每一个数字,以及精度(我们正确分类该数字的时间百分比)和召回率(我们实际召回的数字的数量):

输出—最终得分

你可以看到我们的分数相当不错:总体准确率为 96%。

摘要

在这一章中,我们实际上涵盖了大量的材料。我们看到了经典或密集神经网络的结构。我们学习了激活和非线性,我们还学习了softmax。然后,我们设置测试和训练数据,并学习如何用DropoutFlatten构建网络。我们还学习了所有关于解算器的知识,或者机器学习实际上是如何学习的。然后,我们探索超参数,最后,我们用网格搜索微调我们的模型。

在下一章中,我们将利用我们所学的知识,改变我们的网络结构,构建一个所谓的卷积神经网络 ( CNN )。

四、卷积神经网络

在前一章中,我们学习了所有关于密集神经网络的知识。

在这一章中,我们将继续讨论一种更新的技术:卷积神经网络。这是一种可以用来处理各种图像的方法,你会发现,正如我们向你展示它是如何工作的,它实际上比经典的神经网络更加准确和有效。

在本节中,我们将学习所有关于卷积的知识,以及如何将它们应用于图像,然后我们将学习另一种称为池化的操作。有了这两种新技术,我们将建立一个实际的卷积神经网络,并用我们的 MNIST 数字对其进行训练,这将表明它更加准确。最后,我们要建立一个真正的深度网络。深度学习背后的想法是,你将这些层结合起来,形成更大的网络,我们将向你展示这是如何进行的。

回旋

在这一节中,我们将学习卷积。我们将看到卷积网络的结构,然后我们将它应用到二维空间,就像我们将它用于图像一样。最后,我们将讨论卷积网络的优势,以及为什么您会选择使用它。

好吧,让我们开始吧!首先,我们将导入networkx包和matplotlib,就像我们对经典神经网络所做的那样:

导入包

这里的代码类似于我们在上一章学到的,但是有一个小的变化:

从输入连接到激活

你会注意到,我们从输入连接到激活,而不是将每个输入连接到每个激活,我们有一个窗口。在这种情况下,我们使用三个窗口,然后该窗口产生一组更稀疏的连接。正如您在实际图像中看到的,稀疏的连接集意味着不是每个输入都连接到每个激活;取而代之的是一个滑动窗口:

推拉窗

如果你看左下方的点,你会发现它实际上是一个,两个,三个向上,向下连接到下一列的第一个激活,然后类似地一个,两个,三个向上,向下连接到第二列的第二个点。在这里,我们将只设想网络的一部分。我们有一个 6×6 的像素网格连接到一个 6×6 的激活网格;所以我们要分 3 步走上xy。这意味着这是一个 3 x 3 的子图案。从输出图中绘制的弧线可以看出,左下方的 3 x 3 网格实际上连接到了右侧激活的一个像素:

可视化网络的一部分

上述代码的输出如下:

输出-可视化网络的一部分

这与密集神经网络非常不同,因为它将多个输入连接到单个输出,而不是每个输入连接到每个输出。使用它,您可以看到在一个更大的图像中,这个补丁是如何滑过图像编码区域进入输出变量的。这对于我们现在将要讨论的图像处理有特殊的好处。

那么,我们为什么要这样做呢?地区。卷积神经网络对图像区域进行编码,就像你用眼睛看图像一样。这具有重要的计算优势,因为它通过计算将图像的xy区域组合在一起,创建了数据的紧凑表示;处理卷积神经网络的效率要高得多,因为需要计算的连接更少。现在,卷积神经网络不仅更准确,而且总体上运行更快。

联营

现在,在这一部分,我们将继续讨论池化。我们将学习一维池操作。二维池操作,例如您将在图像上使用的操作;最后,我们将讨论图像通道以及如何在这些数据中使用它们。

好的,从顶部开始,我们这次将导入keras和一些额外的层,特别是MaxPooling1DMaxPooling2D,我们将导入卷积 2D 层,我们稍后会用到它。所以,如果你看一下代码,我们正在做的是建立一个矩阵,这个矩阵只有一些值。你可以把它想象成一个几乎全是 1 的方阵,但是我在这里加入了一些更高的值;有2345。最大池要做的是提取最高值。所以,我们要用一点小技巧。迄今为止,我们已经使用 Keras 来学习机器学习模型,但事实证明,您也可以直接运行这些层,并做一点数学计算:

导入包

因此,正如您已经知道的,您可以看到弹出到屏幕中的值;2345;这些实际上是前缘上单个维度的最大值:

最大汇集操作单一矩阵

您可以在前面的屏幕截图中看到,组合在一起的顺序模型只有 max pooling 操作,我们直接将 NumPy 数组插入到预测的批处理中。我们基本上跳过了这里的培训步骤,只是将模型作为数学引擎来运行。但是这让您对 max pooling 操作的作用有所了解:它提取维度中的最大值。

我还想指出np.squeeze。这是做什么的?嗯,squeeze剔除只有一个潜在值的维度。因此,请记住,Keras 几乎总是成批工作。这里,我们的批处理只有一个批处理条目:这个矩阵在前面的屏幕截图中。因此,压缩消除了批量维度,这样我们就有了一个漂亮的平面数组作为输出。

为了向上移动到二维,我们将使用池大小为2MaxPooling2D操作符。这意味着我们将使用一个 2 x 2 平方的池来提取最大值。从截图上的值可以看到——1435——如果你回头看输入矩阵,你会看到左上角的1是输入左上角区域的最大值,而4是右上角区域的最大值:

最大池操作矩阵

你得到了基本的想法!它实际上通过引入最大值,将 4 x 4 变成了 2 x 2。好的,如果这只是二维,为什么我们会有三维呢?441。答案是像素有颜色;它们可以是红色、绿色或蓝色;在这种情况下,最终通道尺寸为 3。在我们处理的黑白图像中,你只是在那个维度上有一个 1。因此,当我们汇集资源时,我们实际上是在特定的渠道中汇集资源。在这种情况下,我们将黑白像素放在一起。

你可以看到这里有一个额外的调用,是带有-1np.expand_dims。这样做的是,它采用我们的一个完美的正方形数组(输入为 4 x 4),并在末尾添加一个额外的维度来编码通道形状,使其符合MaxPooling2D。然后,我们再次用np.squeeze在输出上撤销,这减少了所有的一维轴并丢弃它们,因此我们在输出上得到一个漂亮的方阵。

好吧,那我们为什么要进行联营呢?嗯,它提取强信号。池化操作的作用是减小图像的大小,并聚焦于最强的值。这有效地允许机器学习者帮助识别图像中最重要的像素和区域。

构建卷积神经网络

在本节中,我们将构建一个完整的卷积神经网络。我们将覆盖 MNIST 数字并转换该数据,让通道构建多层卷积神经网络,最后,运行并训练我们的卷积神经网络,看看它与经典密集网络相比如何。

好吧!让我们加载我们的 MNIST 数字,如下图所示:

正在加载 MNIST 数字

您可以看到,我们正在执行与密集神经网络类似的操作,只是我们正在对数据进行基本转换。这里,我们使用 NumPy 的expand_dims调用(再次传递-1,意为最后一个维度)来扩展我们的图像张量,从 28 x 28 像素的 MNIST 图像扩展到实际上有一个额外的维度,对颜色进行编码。在这种情况下,它是一个黑白图像,所以它是一个灰度像素;这些信息现在可以用于 Keras 中的卷积层。

好了,让我们开始添加我们的层。我们要做的第一件事是将一个内核大小为 3 x 3 的卷积 2D 层放在一起。这将在图像上滑动一个 3 x 3 像素矩阵,将其卷积为较少数量的输出,然后将其传递给第二个卷积 2D 层,也是一个 3 x 3 矩阵。从某种意义上说,这有助于建立一个形象金字塔。它将图像中的数据缩小并集中到更小的维度上,然后我们将它传递到最大池中,这将进一步缩小它。

现在,它开始看起来像我们以前的密集神经网络。为了避免过度拟合,我们进行了一次剔除;我们把它展平,去掉所有独立的维度,所以现在,只剩下一个维度;然后我们让它通过一个密集的神经网络,最后把它送给我们的朋友 softmax,正如你们所记得的,soft max 会把我们的数字从 0 到 9 分类,从 0 到 9 的单个书面数字。这就产生了我们的最终输出:

表演辍学

好的,这在总体结构上类似于一个密集的网络,除了我们添加了一组进行卷积的预处理层。

好吧,让我们试一试!

输出-预处理图层集

正如我之前提到的,机器学习肯定涉及到人类的等待,因为我们将运行和训练多个层次。但是您可以看到,我们运行的实际训练代码(模型编译和模型拟合)与我们之前使用密集神经网络时完全相同。这是 Keras 的好处之一:使其运行的管道代码大致保持不变,然后您可以更改架构,放入不同的层,放入不同数量的激活,或放入不同的激活函数,以便您可以试验不同的网络形状,这些形状可能更好地处理您的数据集。事实上,您可以在本笔记本中试验该层。例如,您可以将激活从 32 和 64 更改为 64 和 128,或者在最终 softmax 输出之前添加另一个密集层。

现在,在您的系统上运行此培训可能会很耗时。在我的机器上,完成整套训练大约需要 10 分钟。但是你马上会注意到,我们的精确度提高了很多。如果你回想一下上一节,我们的密集神经网络达到了大约 96%的准确率。我们的网络接近 99%,所以,通过增加卷积,我们已经成功地建立了一个更准确的分类神经网络。

深度神经网络

现在,我们将使用卷积创建一个实际的深度神经网络。

在这一节中,我们将介绍如何检查以确保我们正在 GPU 上运行,这是一个重要的性能技巧。然后,我们将加载我们的图像数据,然后我们将建立一个多块深度神经网络,它比我们以前创建的任何东西都要深得多。最后,我们将这个深度神经网络的结果与上一节中的浅卷积神经网络进行比较。

在顶部,我们正在导入必要的 Python 包:

导入包

这与我们对标准卷积神经网络所做的相同。关于制作深度神经网络的不同之处在于,我们只是将更多地使用相同的层。在下一个块中,我们将直接进入tensorflow并导入python库。我们看到的这个device_lib是什么?嗯,device_lib实际上让我们列出所有我们可以使用的设备,以便运行我们的神经网络。在这种情况下,我在 nvidia-docker 设置上运行它,并访问 GPU,这将提高性能:

系统状况

如果你没有 GPU,那也没关系!只需知道,在 CPU 设置上运行这些深度神经网络将需要更长的时间(可能长达 20 倍)。这里,我们正在导入 MNIST 数字训练数据,和以前一样:

导入 MNIST 数字训练数据

请记住,我们正在使用-1扩展维度(意味着我们正在扩展最后一个维度)来安装通道,并且我们正在根据最大值对该数据进行归一化,以便为学习输出值(y值)进行设置。我们再一次把它们转换成绝对的;有十种不同的类别,每一种对应于数字 0 到 9。

好吧!现在,使深度神经网络变深的东西是一系列重复的层。就层数而言,我们说它很深。因此,我们之前构建的网络在最终输出之前有一两层。在最终输出之前,我们这里的网络将有多层排列成块。好的,看第一块:

b 座

这实际上形成了一个链,我们对输入进行卷积,然后对卷积进行卷积,最后应用最大池,以获得最重要的特性。在这个卷积中,我们引入了一个以前没有使用过的新参数:填充。在这种情况下,我们使用same值填充它,这意味着我们希望图像的所有边都有相同的填充量。这种填充的实际作用是,当我们向下卷积时,由于我们的 3 x 3 内核大小,图像最终会比输入图像略小,因此填充会在图像边缘放置一圈零,以填充我们相对于卷积缩小的空间。然后,在第二块结束,你可以看到,当我们衰减图像时,我们从 64 次激活切换到 128 次激活:

b 座

本质上,我们将图像缩小到更密集的大小,因此我们将从 28 像素乘 28 像素通过这个 2 x 2 的合并层缩小到 14 像素乘 14 像素,但然后我们将更深入地使用隐藏层的数量来推断新的功能。所以,实际上你可以把图像想象成一种金字塔,我们从基础图像开始,通过卷积拉伸它,通过合并缩小它,然后通过卷积拉伸它,通过合并缩小它,直到我们得到一个比 10 个输出图层稍大的形状。然后,我们进行 softmax 预测,以生成最终结果。最后,在第三个模块中,与第二个模块非常相似,我们提升了多达 256 个隐藏功能:

b 座

这也是在我们使用我们的老朋友,密集神经网络,进行最终输出分类层之前,对图像进行拉伸和缩小。我们有两层密集编码,然后最终进入 10 输出 softmax。

因此,您可以看到,深度神经网络是卷积神经网络一层一层地深度串连在一起的组合,然后使用密集神经网络通过我们在前面章节中了解的 softmax 生成最终输出。让我们试一试吧!

输出-模型摘要

好的,你可以看到模型摘要打印出了所有的层,端到端地链接在一起,有 310 万个参数要学习。这是迄今为止我们创建的最大的网络。

现在,是时候根据我们的样本数据训练这个网络,看看它的预测能力如何。好的,我们现在正在训练这个模型,它进行得相当快:

训练模型

在我的电脑上,用我的 Titan X GPU 完成迭代大约需要 3.5 分钟,这真的是目前用单个 GPU 解决方案完成事情的最快速度。当我们在这里结束训练时,你可以看到我们的精度为 0.993,比我们的平面卷积神经网络好 1/10 或 1%。这看起来不是一个很大的改进,但绝对是一个改进!

所以,我们现在要问:为什么?简单地说,超过 99%的准确率,边际改善是非常非常困难的。为了达到更高的精度水平,需要创建更大的网络,而你必须花时间调整你的超参数。我们在本章中运行的示例运行了八个以上的时期。然而,我们也可以改变学习率,调整参数,执行网格搜索,或者改变特征的数量。我把这个留给你做实验。

摘要

好吧!我们已经学习了卷积,它是一种在图像上移动以提取特征的松散连接的方法;我们已经学习了池化,它总结了最重要的特性;我们用这些技术建立了一个卷积神经网络;最后,我们将多层卷积和池结合起来,以生成深度神经网络。

在下一章中,我们将转向更多的应用开发。我们将构建一个图像分类 REST 服务器,它可以接受不同的神经网络模型,并将其作为 API。

五、图像分类服务器

在这一章中,我们将采用我们所学过的机器学习模型,并将它们转化为用于图像分类的 REST 服务器。

在本章中,我们将讨论以下主题:

  • 用 OpenAPI 或 Swagger 定义 REST API
  • 创建 Docker 容器以创建可重复的构建环境
  • 使用我们的 API 进行预测,并通过 HTTP 发布图像

REST API 定义

让我们从定义 REST API 开始。这由四个活动组成:用 git 从 GitHub 获取项目源代码;安装必要的软件包并检查运行我们的服务器所需的软件包;在 YAML 编辑和创建 OpenAPI 或 Swagger 定义文件;然后最后处理代码中的后期图像,REST API 将实际的图像文件转换为张量。

首先,我们需要克隆我们已经提供的存储库,以便拥有 REST 服务。我在 HTTPS 得到这个,用命令行克隆它:

$ git clone https://github.com/wballard/kerasvideo-server/tree/2018.git

你可以把它放在任何你喜欢的目录里。之后,我们将能够在本节的剩余部分以及本书的剩余章节中使用这些源代码:

Kerasvideo-server-2018 中的文件

使用我本地安装的 Python,我实际上是在这里使用pip来安装这个服务的需求:

$ pip install -r requirements.txt

将它们安装到我们正在使用的 Python 中将允许我们以调试模式在本地运行服务。然而,如果您只是要检查源代码并运行和构建 Docker 容器(我们稍后会讲到),则没有必要执行这一步。

让我们打开我们的models.yaml文件:

Models.yaml 文件

这个 YAML 文件是一个 Swagger API 定义,也称为 OpenAPI。在这个文件中,API 是以声明方式定义的;我们指定端点、配置、参数、返回代码和作为运行时文档的附加注释。在文件的开头,我们指定它是 Swagger 2.0,这是当今最常用的 OpenAPI 版本。然后,紧接着,我们有一个信息块,它实际上只是描述我们的 API 的名称,并作为版本号和标题;这只是关于我们的 API 的描述性元数据。大部分配置与路径有关。从前面的截图可以看出,我们有/mnist/classify。这实际上是我们主要的 API 端点和定义。我们指定它需要一个 post 我们有摘要描述和操作 ID。操作 ID ( mnist.post_image)是当我们实际启动它时绑定到框架中的代码的东西。如果您仔细观察,您会发现它消耗了多部分/表单数据,这意味着我们实际上将向这个 API 端点发布一个文件,就像您上传一个带有 HTML 表单的文件一样。最后,这将返回 JSON,结果代码为 200。关于这个定义有趣的事情是,我们几乎完成了我们的服务器。通过用 YAML 声明 API,然后我们用很少的代码将它结合起来,使用连接框架来提供 REST API。

我们来看看吧!我们将打开我们的server.py:

server.py 文件

这是我们将用来为我们刚刚作为 REST 服务器创建的 YAML 配置提供服务的实际代码。如你所见,很简单。我们指定一个端口,使用该名称和端口创建一个连接应用,并使用models.yaml添加一个 API。这可能是您创建过的最简单的 web 服务器或 REST 服务器,因为连接框架使用我们刚刚创建的 YAML 定义来动态创建 REST 端点,然后映射到最后一段实际服务的代码。

现在让我们来看看:

mnist.py 文件

这最后一段代码是我们的 MNIST 模块。如果你记得 YAML,我们有mnist.post_image,这意味着模块 MNIST,和功能post_image。你可以在前面的mnist.py文件中看到,我们正在导入几段代码,即PIL,这是我们将用来处理图像的图像库。从这里,我们将对MNIST_MODEL号进行预加载。这是包含经过训练的机器学习模型的模块级变量;我们将在下一节中研究这个模型。现在,这个post_image方法的工作是获取一个文件,这是一个通过 HTML 多部分形式发布的文件,将它作为字节(在这里您可以看到我们有file.read),并使用Image.open将它转换成一个图像:

使用枕头命令

这实际上是将上传文件的字节流转化为内存中的图像对象。因为我们已经在 28 x 28 的标准尺寸图像上训练了MNIST_MODEL,所以我们必须调整图像的大小(以防你发布的图像比我们习惯的要大),然后将其灰度化(同样,以防你发布的是彩色图像)。因此,我们在这里对数据进行标准化,以符合MNIST_MODEL的预期。有了这些,我们将调整它的大小。我们将使用我们所学的关于创建样本和批次的知识来调整该图像的大小。因此,第一个维度是 1,这是样本(同样,在这个样本中只有一个图像,我们张贴);28 x 28 是尺寸;然后我们有 1,这是通道的数量(这里,它只是灰度)。我们得到这组数据并预测它。这将返回一个数字数组,这些数字是从 0 到 9 的独热编码。我们还必须反转一键编码,这就是argmax的作用。如果您还记得,它是一批 1,所以我们用返回数组的元素挑选出 0 来匹配我们的输入,然后使用argmax来找到我们被分类为哪一个数字(同样,反转一位热编码)。最后,我们将它作为一小段 JSON 代码返回。

JSON 编码器不理解 NumPy 整数类型,所以我们只是快速转换成 Python 整数。

既然我们已经了解了如何使用连接来创建 REST 服务并将其与 Keras 模型挂钩,那么让我们来看看如何将它转换成 Docker 容器,这样我们就可以拥有一个可重新创建、可部署的运行时环境。

码头集装箱中的训练模型

在上一节中,我们看了如何创建一个 REST 服务器来对图像进行分类。在这一节中,我们将研究如何准备一个 Docker 容器来为服务器创建一个合理的运行时环境。当我们研究这个问题时,我们会问这样一个问题:为什么要用 Docker 来打包我们的机器学习模型?然后,我们将实际调查模型训练,然后将训练好的模型保存在 Docker 容器中使用,随后是我们的服务器 Dockerfile,它会将所有这些打包在一起。最后,我们将为 REST 服务的可重用运行时构建 Docker 容器。

那么,为什么是 Docker?从根本上说,它使你的训练模型可移植。与您创建的大多数程序不同,它们大多是带有单独数据库的代码,机器学习模型通常会有一个相对较大的文件集,这些文件是存储的学习网络。这些文件通常太大,无法签入 GitHub 或通过其他方便的方式部署。虽然有些人会将它们发布在 S3 或其他文件共享解决方案上,但在我看来,将 REST 服务的运行时代码与经过训练的模型打包在一起,提供了一种创建可移植运行时环境的好方法,您可以跨多个不同的云提供商使用该环境,包括 Amazon、Microsoft 和 Kubernetes。

现在,让我们看看我们的train_mnist Python 源文件。这是一个只需从命令行运行的脚本。它将训练一个 Keras 模型,以便预测 MNIST 数字。这与我们在前面几节中所做的非常相似,正如您在下面的屏幕截图中所看到的,我们为 Keras 模型导入了所有必要的层,然后打印出我们本地设备的外观:

train_minst 文件

然后,我们加载训练和测试数据,就像我们在前面几节中所做的那样,我们从 Keras 预先打包的 MNIST 数字和模型中提取这些数据。最后,我们将其转换为分类数据(同样,使用一键编码)以预测数字:

培训用数据

为了打包到这里,我们将要训练的模型是一个相对简单的卷积模型,类似于我们在前几章中探索的模型:

卷积模型

我们使用 sequential 将一个input_shape减少到十个类,并使用两个卷积序列来构建特性。我们将使用 max pooling 来减少这种情况,dropout 来防止过度拟合,然后用 128 层激活将其展平到最终输出,这样我们就可以再进行一次 dropout。最后,我们将使用 softmax 执行密集编码。请记住,softmax 是我们将最终分数转换为每个类别的一组概率的方法。

然后,我们会用一个以前没用过的东西,就是model.save:

将模型保存在 HDF5 文件中

实际上,我们将在完成学习算法的拟合后保存整个预训练模型,以获得一个.h5文件,它实际上是一组矩阵定义、我们学习到的实际值以及整个网络的形状,以便我们可以加载并重用我们的训练网络。关于这个训练脚本,我们将在 Docker 文件中使用它,这样我们就可以创建一个 Docker 容器,并在 Docker 映像中存储预先训练和保存的模型。

这里,我们来看一下 Docker 文件:

Docker 文件

这就是我们要利用我们的培训脚本并打包一个可重用容器的地方。我们从之前准备 docker 文件时使用的同一个 NVIDIA 映像开始,我们将安装几个包,这些包对于 Python Miniconda 的完全支持是必要的。但是这里最大的不同是,我们没有使用 Anaconda,它是一个包含许多包的完整发行版,而是使用 Miniconda,它是一个精简的、高度可移植的 Python 发行版,我们只在它上面安装必要的包。现在我们已经安装了 Miniconda,我们将创建一个用户来运行这个 Keras,然后将我们签出源代码的当前目录复制到 Docker 容器上的 SRC 目录中,这将作为我们的构建路径点。然后,我们将pip install需求,这将引入 TensorFlow 和 Keras 连接,以及用于保存模型的h5 Python 库:

我们的服务器需要的包

这里是不同的部分:我们实际上将训练我们的模型作为 Docker 构建文件的一部分,这将创建一个模型,训练它,并保存它。但是,它将把它保存到 Docker 容器中,这样当我们构建 Docker 容器映像时,或者当我们分发它或在其他地方使用它时,这个经过训练的文件将随之而来。最后,我们使用run命令来运行 REST 服务,这将利用存储在 Docker 映像中的经过训练的模型文件:

运行我们的休息服务

现在,我们将构建我们的容器;我们使用了docker build命令,并再次使用-tkerasvideo-server中标记它。.表示我们正在运行当前目录中的 Dockerfile:

docker 构建命令

在我的系统上,这需要相当长的时间。用 CPU 训练它大约需要 30 分钟才能完成。这将根据您计算机的性能或您是否启用了 GPU 支持而有所不同。最后,我们将拥有一个准备运行的 Docker 容器,这样我们就可以将它用作我们的 REST 服务器环境:

码头集装箱

现在我们已经构建了一个 Docker 容器,上面有一个经过训练的模型和一个 REST 服务,我们将运行这个服务来进行预测。

做预测

在前一节中,我们设置了 Docker 容器,现在,在这一节中,我们将使用 Docker 容器运行 REST 服务器并进行预测。我们将运行我们刚刚创建的 Docker 容器,然后查看连接的内置用户界面来测试我们的 REST 服务。最后,我们将通过 REST 服务发布一张图片,这样我们就可以看到预测结果。我们还将看到如何使用 curl 调用您的服务,这是一个可以发布文件的命令行程序。

现在,我们将启动我们的 Docker 容器。我们将把本地端口5000映射到容器端口5000,这是 REST 服务中的默认端口。然后,我们将启动服务。kerasvideo-server容器是我们刚刚创建的容器,这个容器需要一秒钟启动并导入 TensorFlow。然后,我们将加载模型,并通过端口5000上的本地 IP 地址为其提供服务:

模型的加载

因此,我们在浏览器中打开 localhost 5000/ui,我们得到一个由记录了 Swagger API 的连接自动生成的用户界面:

用户界面

您可以看到我们已经创建的端点(mnist/classify),您只需单击并展开它,就可以查看我们的实施说明、描述、参数、响应类型和我们的文件上传:

探索默认选项

然后,我们将继续抓取我存储在磁盘上的一个sample数字,我们将把它发布到我们的 API 中进行试用!左下角的按钮。这将实际上为我们运行我们的 API。这显示了我们将在这里使用的来自命令行的等效的curl命令,以及请求 URL。下面是我们从响应主体返回的答案,它正确地将这个数字归类为一个0:

最终输出(回复正文)

现在,让我们从命令行尝试一下。从命令行来看,这是一个相对简单的操作。实际上,我们将在 UNIX 命令提示符下使用curl,使用-F提交表单数据。我们有file=,这里是@变量名的诀窍,所以它是@var/data/sample.png,这是我们的样本图像。然后,我们将它传递给 URL,这是我们的服务,我们将看到它正确分类:

$ curl -F file=@var/data/sample.png http://localhost:5000/mnist/classify

curl 命令的使用

现在,你必须记住,file=是匹配我们在 API 定义 YAML 中为 Swagger 创建的参数名,多部分表单数据是我们发布和上传图像的方式。因此,有了这种基本的技术,你可以使用curl,或者你可以使用其他的客户端库,比如说,从 web 浏览器,来将你的机器学习服务集成到你的应用的其余部分。

摘要

我们实际上使用了一个 Swagger API 定义来创建一个 REST API 模型,然后声明性地生成 Python 框架,以便我们为该 API 提供服务。我们只需要输入很少的代码就可以让它运行起来。然后,我们创建了一个 Docker 容器,它不仅捕获我们的运行代码(即我们的服务),还捕获我们预先训练的机器学习模型,然后形成一个包,以便我们能够部署和使用我们的容器。最后,我们使用这个容器来提供服务和进行预测。

标签:模型,学习,神经网络,图像,TensorFlow,Docker,我们,实用手册
From: https://www.cnblogs.com/apachecn/p/18448029

相关文章

  • TryOnDiffusion——生成拟合图像的最强大模型
    介绍论文地址:https://arxiv.org/pdf/2306.08276虚拟试穿是以人的图像和服装的图像为基础,目的是想象服装穿在人身上的效果。虚拟试穿可以改善网上购物体验,但大多数传统试穿方法只有在身体姿势和形状变化较小时才能奏效。主要的挑战在于如何根据目标体形对服装进行非刚性变......
  • 以鼠标位置进行图像非中心zoom
    #以鼠标位置进行图像非中心zoomimporttkinterastkfromPILimportImage,ImageTkimage_show_width=800image_show_height=600window_width=image_show_widthwindow_height=image_show_height+120root=tk.Tk()root.geometry(f"{window_width}x{window_he......
  • VisionTS:基于时间序列的图形构建高性能时间序列预测模型,利用图像信息进行时间序列预测
    构建预训练时间序列模型时面临的主要挑战是什么?获取高质量、多样化的时间序列数据。目前构建基础预测模型主要有两种方法:迁移学习LLM:通过针对时间序列任务定制的微调或分词策略,重新利用预训练的大型语言模型(LLM),如GPT-4或Llama。从零训练:构建大规模时间序列数据集,并从头开始预训......
  • Java-人工智能初学者实用手册-全-
    Java人工智能初学者实用手册(全)零、前言在一切都由技术和数据驱动的现代世界中,人工智能变得越来越重要,它是使任何系统或流程自动化的过程,以自动执行复杂的任务和功能,从而实现最佳生产率。面向初学者的Java人工智能实践解释了使用流行的基于Java的库和框架来构建智能应用程......
  • Java-图像处理秘籍-全-
    Java图像处理秘籍(全)原文:JavaImageProcessingRecipes协议:CCBY-NC-SA4.0一、JavaVM上的OpenCV几年前,在去上海的旅途中,我的一个非常好的朋友在OpenCV上给我买了一本大部头的书。它有大量的摄影操作、实时视频分析样本和非常有吸引力的深入解释,我迫不及待地想在我的本......
  • Recaptcha2 图像识别 API 对接说明
    Recaptcha2图像识别API对接说明本文将介绍一种Recaptcha2图像识别2API对接说明,它可以通过用户输入识别的内容和Recaptcha2验证码图像,最后返回需要点击的小图像的坐标,完成验证。接下来介绍下Recaptcha2图像识别API的对接说明。申请流程要使用API,需要先到Re......
  • 《OpenCV》—— 图像拼接
    下面是两张需要拼接的图片完整代码:importcv2importnumpyasnpimportsysdefcv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)defdetectAndDescribe(image):gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)descriptor=cv2.SIF......
  • OpenCV(图像对比度增强)
    目录1.直方图均衡化2.自适应直方图均衡化3.限制对比度自适应直方图均衡化4.线性对比度拉伸5.Gamma校正6.Retinex方法7.多尺度对比度增强8.方法选择与应用场景总结增强图像对比度是图像处理中的一个重要步骤,旨在提高图像中不同亮度区域之间的差异,使细节更加清晰和明显......
  • [数据集][图像分类]骨关节炎严重程度分类数据集14038张4分类
    数据集类型:图像分类用,不可用于目标检测无标注文件数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片图片数量(jpg文件个数):14038分类类别数:4类别名称:[“grade0”,“grade2”,“grade3”,“grade4”]每个类别图片数:类别名称图片数grade08080grade23691grade31843gra......
  • OPENCV判断图像中目标物位置及多目标物聚类
    文章目录在最近的项目中,又碰到一个有意思的问题需要通过图像算法来解决。就是显微拍摄的到的医疗图像中,有时候目标物比较偏,也就是在图像的比较偏的位置,需要通过移动样本,将目标物置于视野正中央,然后再次进行拍摄。就类似于下面的图像:基于这个需求,在图像上就需要使......