大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
个人主页-Sonhhxg_柒的博客_CSDN博客
欢迎各位→点赞 + 收藏⭐️ + 留言
系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟
文章目录
用于语义分割的 TensorFlow DeepLab 概述
Spatial Pyramid Pooling(空间金字塔池化)
Atrous convolution(空洞卷积)
Encoder-decoder network
编码器模块
解码器模块
DeepLab 中的语义分割——示例
谷歌 Colab、谷歌云 TPU 和 TensorFlow
使用 DCGAN 生成人工图像
Generator(生成器)
Discriminator(鉴别器)
训练
使用 DCGAN 进行图像修复
TensorFlow DCGAN – 示例
使用 OpenCV 进行图像修复
了解神经风格迁移
概括
深度神经网络的应用不仅限于在图像中寻找对象(我们在前几章中已经了解)——它还可以用于将图像分割成空间区域,从而生成人造图像并从一个图像中转移风格图像到另一个。
在本章中,我们将使用 TensorFlow Colab 来执行所有这些任务。语义分割预测图像的每个像素是否属于某个类别。这是一种有用的图像叠加技术。您将了解 TensorFlow DeepLab,以便您可以对图像执行语义分割。深度卷积生成对抗网络( DCGAN ) 是强大的工具,用于生成人脸和手写数字等人工图像。它们也可用于图像修复。我们还将讨论如何使用 CNN 将风格从一张图像转移到另一张图像。
在本章中,我们将介绍以下主题:
语义分割是在像素级别理解和分类图像内容的任务。与对象检测不同,在多个对象类别上绘制一个矩形边界框(类似于我们对 YOLOV3 的了解),语义分割学习整个图像并将封闭对象的类别分配给图像中的相应像素。因此,语义分割可以比对象检测更强大。语义分割的基础架构基于编码器-解码器网络,其中编码器创建一个高维特征向量并在不同层次上聚合它,而解码器在神经网络的不同层次上创建一个语义分割掩码。编码器使用传统的 CNN,而解码器使用反池化、反卷积和上采样。DeepLab 是谷歌推出的一种特殊类型的语义分割,它使用 Atrous Convolution、空间金字塔池化而不是常规的最大池化和编码器-解码器网络。DeepLabV3+ 是由 Liang-Chieh Chen、Yukun Zhu、George Papandreou、Florian Schro 和 Hartwig Adam在他们的论文Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation ( https://arxiv.org/abs/1802.02611 ) 中介绍。
DeepLab 于 2015 年从 V1 开始,并于 2019 年迅速移至 V3+。不同 DeepLab 版本的比较如下表所示:
DeepLab V1 | DeepLab V2 |
DeepLab V3 |
DeepLab V3+ |
|
Paper | 使用深度卷积网络和完全连接的 CRF 进行语义图像分割,2015 |
DeepLab:使用深度卷积网络、Atrous 卷积和完全连接的 CRF 进行语义图像分割, 2017 |
重新思考用于语义图像分割的 Atrous 卷积, 2017 |
用于语义图像分割的具有 Atrous 可分离卷积的编码器-解码器, 2018 |
作者 |
Liang-Chieh Chen、George Papandreou、Iasonas Kokkinos、Kevin Murphy 和 Alan L. Yuille |
Liang-Chieh Chen、George Papandreou、Iasonas Kokkinos、Kevin Murphy 和 Alan L. Yuille |
Liang-Chieh Chen、George Papandreou、Florian Schroff 和 Hartwig Adam |
Liang-Chieh Chen, Yukun Zhu, George Papandreou, Florian Schro, and Hartwig Adam |
关键概念 |
Atrous 卷积,全连接条件随机场( CRF ) |
Atrous 空间金字塔池化( ASPP ) |
ASPP、图像级特征和批量标准化 |
ASPP 和编码器/解码器模块 |
DeepLabV3+ 使用空间金字塔池( SPP ) 的概念来定义其架构。
我们在第 5 章,神经网络架构和模型中介绍的大部分 CNN模型,需要固定的输入图像大小,这限制了输入图像的纵横比和比例。固定大小约束不是来自卷积操作;相反,它来自需要固定输入大小的全连接层。卷积操作从 CNN 不同层中图像的边缘、角落和不同形状生成特征图。不同层的特征图是不同的,并且是图像内形状的函数。作为输入大小的函数,它们不会发生很大变化。SPP 替换了最后一个池化层,就在全连接层之前,它由平行排列的空间 bin 组成,其大小与输入图像大小成正比,但其总数固定为全连接层的数量。
DeepLabV3 的架构基于两种类型的神经网络——Atrous 卷积和编码器-解码器网络。
我们在第 4 章“图像深度学习”中介绍了卷积的概念,但没有深入探讨各种类型的 Atrous 卷积。空洞卷积,也称为空洞卷积,增加了卷积的视野。传统的 CNN 使用最大池化和步幅来快速减小层的大小,但这样做也降低了特征图的空间分辨率。Atrous 卷积是一种用来解决这个问题的方法。它通过使用 Atrous 值修改步幅来实现这一点,从而有效地改变过滤器的值字段,如下图所示:
上图显示了速率 = 2 的 Atrous 卷积。与深度卷积相比,它跳过了每个其他单元格。实际上,如果我们应用 stride = 2,则 3 x 3 内核是 5 x 5 内核。与简单的深度较小的特征图相比,Atrous 卷积增加了视野并捕获了边界信息(与最大池化相比,其中对象边界缺失),从而产生丰富的图像上下文。由于其在每个后续层中保持视野相同的特性,Atrous 卷积用于图像分割。
DeepLabV3 执行几个并行的 Atrous 卷积,所有这些都以不同的速率运行,就像我们之前描述的空间池化层概念一样。上图说明了 Atrous 卷积和并行模块彼此相邻堆叠以形成 SPP。与传统卷积相比,最终特征向量的深度和宽度比原始图像减小,Atrous 卷积保留了图像大小。因此,图像的更精细的细节不会丢失。这在构建具有丰富图像上下文的分割图时很有帮助。
编码器是一种神经网络,它获取图像并生成特征向量。解码器与编码器相反;它采用特征向量并从中生成图像。编码器和解码器一起训练以优化组合损失函数。
编码器-解码器网络导致编码器路径中的计算速度更快,因为不必在编码器路径中扩展特征并且在解码器路径中恢复尖锐对象。编码器-解码器网络包含一个编码器模块,用于捕获更高的语义信息,例如图像中的形状。它通过逐渐减少特征图来做到这一点。另一方面,解码器模块保留了空间信息和更清晰的图像分割。
编码器和解码器主要使用多尺度的 1 x 1 和 3 x 3 Atrous 卷积。让我们更详细地看一下它们。
编码器模块的主要特点如下:
解码器模块的主要特点如下:
使用 TensorFlow 训练 DeepLab 的详细代码可以在以下由 TensorFlow 管理的 GitHub 页面找到:https ://github.com/tensorflow/models/tree/master/research/deeplab 。
Google Colab 包含基于多个预训练模型的内置 DeepLab Python 代码。这可以在https://colab.research.google.com/github/tensorflow/models/blob/master/research/deeplab/deeplab_demo.ipynb找到。
在深入示例代码的细节之前,我们先了解一下谷歌机器学习的一些基本特性,所有这些特性都是免费提供的,这样我们就可以开发出强大的计算机视觉和机器学习代码:
前面的屏幕截图显示了 Google Colab 文件夹相对于 Google Drive 的位置。它使您可以处理.ipynb文件,然后存储它们。
如前面的屏幕截图所示,打开 Cloud TPU 将有助于加快您处理神经网络的训练和预测阶段的速度。
Google Colab DeepLab 笔记本包含三个示例图像,还为您提供了获取 URL 的选项,以便您可以加载自定义图像。当您获取图像的 URL 时,请确保该 URL.jpg位于末尾。从互联网上提取的许多图像没有此扩展名,程序会说找不到它。如果您有自己想要使用的图像,请将它们存储在您的 GitHub 页面上,然后下载 URL。以下屏幕截图显示了基于以下内容接收到的输出mobilenetv2_coco_voctrainaug:
前面的屏幕截图显示了四个不同的图像——停放的自行车、繁忙的纽约街道、城市道路和带家具的房间。在所有情况下,检测都非常好。需要注意的是,该模型只检测了以下 20 个类,外加一个背景类:background , plane , bike , bird , boat , bottle , bus , car , cat , chair , cow , Diningtable , dog , horse , motorbike , person ,盆栽,羊,沙发,火车,电视。以下屏幕截图显示了使用不同模型运行的相同四个图像,即xception_coco_voctrainval:
与 MobileNet 模型相比,对象对异常模型的预测显示出更大的改进。与 MobileNet 模型相比,异常模型已清楚地检测到自行车、人类和桌子的分割。
MobileNet 是一种用于手机和边缘设备的高效神经网络模型。它使用深度卷积而不是普通卷积。有关 MobileNet 和深度卷积的详细了解,请参阅第 11 章,边缘深度学习与 GPU/CPU 优化。
在第 5 章,神经网络架构和模型中,我们了解了 DCGAN。它们由生成器模型和判别器模型组成。生成器模型接收代表图像特征的随机向量,并通过 CNN 运行以生成人工图像G(z)。因此,生成器模型返回生成新图像及其类别的绝对概率G(z) 。鉴别器(D)网络是一个二元分类器。它从样本概率、图像分布(p-data)和来自生成器的人工图像中获取真实图像,以生成概率P(z),即最终图像是从真实图像分布中采样的。因此,鉴别器模型返回最终图像的类别来自给定分布的条件概率。
鉴别器将生成真实图像的概率信息提供给生成器,生成器使用该信息来改进其预测,以创建人造图像G(z)。随着训练的进行,生成器在创建可以欺骗判别器的人造图像方面变得更好,而判别器将发现更难区分真实图像和人造图像。这两个模型相互对立——因此得名对抗网络。当判别器无法再将真实图像与人工图像分开时,模型就会收敛。
GAN 训练遵循判别器和生成器训练几个时期的替代模式,然后重复直到达到收敛。在每个训练周期中,其他组件保持固定,即我们训练生成器时,判别器保持固定,训练判别器时,生成器保持固定,以尽量减少生成器和判别器相互追逐的机会.
前面的描述应该已经为您提供了对 GAN 的高级理解。但是,为了编写 GAN,我们需要更多地了解模型架构。让我们开始吧。
DCGAN的生成器网络架构如下图所示:
从上图中,我们可以看到以下内容:
DCGAN的判别器网络架构如下图所示:
从上图中,我们可以看到以下内容:
训练时要考虑的主要特征如下:
下图显示了 DCGAN 在训练阶段的损失项:
当生成器接收到随机输入时开始训练,生成器损失被定义为它产生假输出的能力。鉴别器损失被定义为它区分真实输出和假输出的能力。梯度用于更新生成器和判别器。在训练过程中,生成器和判别器同时进行训练。训练过程通常只要我们需要同时训练两个模型。请记住,两个模型彼此同步。
图像修复是根据来自相邻点的信息填充图像或视频的缺失部分的过程。图像修复工作流程涉及以下步骤:
TensorFlow.org 有一个很好的图像修复示例,您可以在 Google Colab 或您自己的本地机器上运行它。该示例可以在 Google Colab 中运行,网址为https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/generation/dcgan.ipynb#scrollTo=xjjkT9KAK6H7。
此示例显示了基于 MNIST 数据集训练 GAN,然后生成人工数字。使用的模型与我们在前面几节中描述的相似。
OpenCV提供了两种图像修复方法,如下:
import numpy as np
import cv2 as cv
img = cv.imread('/home/.../krishmark.JPG')
mask = cv.imread('/home/.../markonly.JPG',0)
dst = cv.inpaint(img,mask,3,cv.INPAINT_TELEA)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
import numpy as np
import cv2 as cv
img = cv.imread('/home/.../krish_black.JPG')
mask = cv.imread('/home/.../krish_white.JPG',0)
dst = cv.inpaint(img,mask,3,cv.INPAINT_NS)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
最终输出如下图所示:
正如我们所看到的,两个预测都部分成功,但没有完全删除该行。
神经风格转移是一种技术,您可以通过匹配内容图像和样式图像的特征分布来混合内容图像和样式图像,以生成与内容图像相似但以样式图像的样式进行艺术绘制的最终图像。风格迁移可以在 TensorFlow 中以两种不同的方式完成:
以下代码输入一个 VGG 模型并从模型中提取样式和内容层:
vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')
vgg.trainable = False
for layer in vgg.layers:
print(layer.name)
以下结果显示了卷积块及其序列:
input_2
block1_conv1
block1_conv2
block1_pool
block2_conv1
block2_conv2
block2_pool
block3_conv1
block3_conv2
block3_conv3
block3_conv4
block3_pool
block4_conv1
block4_conv2
block4_conv3
block4_conv4
block4_pool
block5_conv1
block5_conv2
block5_conv3
block5_conv4
block5_pool
我们将使用我们从前面的输出生成的卷积结果来开发内容层和样式层,如以下代码所示:
#Content layer:
content_layers = ['block5_conv2']
#Style layer:
style_layers = ['block1_conv1','block2_conv1','block3_conv1', 'block4_conv1', 'block5_conv1']
style_outputs = [vgg.get_layer(name).output for name in style_layers]
content_outputs = [vgg.get_layer(name).output for name in content_layers]
vgg.input = style_image*255
输入的四个维度分别是batch size、图像宽度、图像高度和图像通道数。255 乘数将图像强度转换为 0 到 255 的比例:
model = tf.keras.Model([vgg.input], outputs)
如前所述,这种风格可以用 gram 矩阵表示。在 TensorFlow 中,gram 矩阵可以表示为tf.linalg.einsum。
因此,我们可以编写以下内容:
for style_output in style_outputs:
gram_matrix = tf.linalg.einsum(‘bijc,bijd->bcd’,style_outputs,style_outputs)/tf.cast(tf.shape(style_outputs[1]*style_outputs[2]))
损失计算如下:
style_loss = tf.add_n([tf.reduce_mean((style_outputs[name]-style_targets[name])**2) for name in style_outputs.keys()])
style_loss *= style_weight / num_style_layers
content_loss = tf.add_n([tf .reduce_mean((content_outputs[name]-content_targets[name])**2) for name in content_outputs.keys()])
content_loss *= content_weight / num_content_layers
loss = style_loss + content_loss
最终代码可以从https://www.tensorflow.org/tutorials/generation/style_transfer的 TensorFlow 教程中获得。代码结构如here所述。我在下面的图像上运行它,输出如下:
请注意图像输出如何从沙漠中的少量石粒过渡到完全充满石头,同时保持沙漠的一些结构。最后一次迭代(迭代 1,000 次)确实展示了一种艺术融合。
在本章中,我们学习了如何使用 TensorFlow 2.0 和 Google Colab 来训练神经网络来执行许多复杂的图像处理任务,例如语义分割、图像修复、生成人工图像和神经风格迁移。我们了解了生成网络和判别网络的功能,以及如何以平衡的方式同时训练神经网络以创建假输出图像。我们还学习了如何使用 Atrous 卷积、空间池化和编码器-解码器网络来开发语义分割。最后,我们使用 Google Colab 训练神经网络来执行神经风格迁移。
在下一章中,我们将使用神经网络进行活动识别。