TensorFlow与深度学习基础

TensorFlow与深度学习基础

目标识别与分类

卷积神经网络

简化的卷积层
在这里插入图片描述
简单的对应一下:
在这里插入图片描述
Tensorflow使用图像时检查样例输入的结构:

image_batch = tf.constant([
	[#第一幅图像
		[[0,255,0],[0,255,0],[0,255,0]],
		[[0,255,0],[0,255,0],[0,255,0]]
	],
	[#第二幅图像
		[[0,0,255],[0,0,255],[0,0,255]],
		[[0,0,255],[0,0,255],[0,0,255]]
	]
])
image_batch.get_shape()

得到输出:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

sess,run(image_batch)[0][0][0]

得到输出:
在这里插入图片描述

卷积

卷积运算图示:
在这里插入图片描述

输入和卷积核

卷积运算实验,推荐使用tf.nn.conv2d

可试验计算两个张量的卷积,并查看结果

#建立input和kernel
input_batch = tf.constant(
	[	#第一个输入
		[[0.0],[1.0]],
		[[2.0],[3.0]]
	],
	[	#第二个输入
		[[2.0],[4.0]],
		[[6.0],[8.0]]
	]
)

kernel = tf.constant([
	[
		[[1.0,2.0]]
	]

])

在这里插入图片描述
上述实例代码中包含了一个卷积核(变量kernel的第1维度)。该卷积核的作用是返回一个其中第一个通道等于原始输入,第二个通道等于原始输入值两倍的张量。

进行卷积运算

conv2d = tf.nn.conv2d(input_batch,kernel,strides=[1,1,1,1],padding = 'SAME')
sess,run(conv2d)

得到输出:
在这里插入图片描述
该输出是另一个与input_batch同秩的张量,但其维数与卷积核相同。若input_batch代表一幅图像,它拥有一个通道。在这种情形下,它将被视为一幅灰度图 像。该张量中的每个元素都表示这幅图像中的一个像素。该图像中右下角的像素值将为3.0

可将卷积运算tf.nn.conv2d视为图像(用input_batch表示)和卷积核张量kernel的组合。这两个张量的卷积会生成一幅特征图(feature map)。特征图是一个比较宽泛的术语,但在计算机视觉中,它与使用图像卷积核的运算的输出相关,而现在,特征图通过为输出添加新层代表了这些张量的卷积。

输入图像与输出的特征图之间的关系可结合代码来分析。访问输入批数据和特征图中的元素时使用的是相同的索引。通过访问输入批数据和特征图中位置相同的像素,可了解当输入与kernel进行卷积运算时,它的值是如何改变的。在下面的例子中,图像中右下方的像素经过卷积后的值变为3.01.0和3.02.0。这些值对 应于像素值和kernel中的相应值。

lower_right_image_pixel = sess.run(input_batch)[0][1][1]

lower_right_kernel_pixel = sess.run(conv2d)[0][1][1]

lower_right_image_pixel,lower_right_kernel_pixel

得到输出:
在这里插入图片描述

跨度

在计算机视觉中,卷积的价值体现在对输入(本例中为图像)降维的能力上。一幅2D图像的维数包括其宽度、高度和通道数。如果图像具有较高的维数,则
意味着神经网络扫描所有图像以判断各像素的重要性所需的时间呈指数级增长。利用卷积运算对图像降维是通过修改卷积核的strides(跨度)参数实现的。

参数strides使得卷积核可跳过图像中的一些像素,从而在输出中不包含它们。实际上,说这些像素“被跳过”并不十分准确,因为它们仍然会对输出产生影响。 strides参数指定了当图像维数较高,且使用了较为复杂的卷积核时,卷积运算应如何进行。当卷积运算用卷积核遍历输入时,它利用这个跨度参数来修改遍历输入 的方式。strides参数使得卷积核无需遍历输入的每个元素,而是可以直接跳过某些元素。

例如,假设需要计算一幅较大的图像和一个较大的卷积核之间的卷积运算。在这个例子中,图像的高度为6个像素,宽度为6个像素,而深度为1个通道 (6×6×1),卷积核尺寸为(3×3×1)。
在这里插入图片描述
输出结果:
在这里插入图片描述

通过将kernel在input_batch上滑动,同时跨过(或跳过)某些元素,input_batch与kernel便结合在一起。kernel每次移动时,都将input_batch的一个元素作为中心。然后,位置重叠的值相乘,再将这些乘积相加得到卷积的结果。卷积就是通过这种逐点相乘的方式将两个输入整合在一起的。利用下图可更容易地将卷积运算可视化。
在这里插入图片描述
上图所体现的是与之前的代码完全相同的逻辑。两个张量进行了卷积运算,但卷积核会跳过输入中的一些固定数目的元素。strides显著降低了输出的维数,而卷积核允许卷积使用所有的输入值。在输入数据中,没有任何元素在被跳过时被移除,但它仍然变成了一个形状更小的张量。

设置跨度是一种调整输入张量维数的方法。降维可减少所需的运算量,并可避免创建一些完全重叠的感受域。strides参数的格式与输入向量相同,即 (image_batch_size_stride、image_height_stride、image_width_stride、image_channels_stride)。第1个和最后一个跨度参数通常很少修改,因为它们会在tf.nn.conv2d运算中 跳过一些数据,从而不将这部分数据予以考虑。如果希望降低输入的维数,可修改image_height_stride和image_width_stride参数。

边界填充

当卷积核与图像重叠时,它应当落在图像的边界内。有时,两者尺寸可能不匹配,一种较好的补救策略是对图像缺失的区域进行填充,即边界填充。
TensorFlow会用0进行边界填充,或当卷积核与图像尺寸不匹配,但又不允许卷积核跨越图像边界时,会引发一个错误。tf.nn.conv2d的零填充数量或错误状态是由 参数padding控制的,它的取值可以是SAME或VALID。

·SAME :卷积输出与输入的尺寸相同。这里在计算如何跨越图像时,并不考虑滤波器的尺寸。选用该设置时,缺失的像素将用0填充,卷积核扫过的像素数 将超过图像的实际像素数。

·VALID :在计算卷积核如何在图像上跨越时,需要考虑滤波器的尺寸。这会使卷积核尽量不越过图像的边界。在某些情形下,可能边界也会被填充。

在计算卷积时,最好能够考虑图像的尺寸,如果边界填充是必要的,则TensorFlow会有一些内置选项。在大多数比较简单的情形下,SAME都是一个不错的选 择。当指定跨度参数后,如果输入和卷积核能够很好地工作,则推荐使用VALID。关于这两个参数的更多介绍,请参考https://www.tensorflow.org/versions/master/api_docs/python/nn.html#convolution。

数据格式

tf.nn.conv2d还有另外一个参数data_format未在上述例程中使用。tf.nn.conv2d文档详细解释了如何修改数据格式,以使input、kernel和strides遵循某种与到目前为止 所使用的格式不同的格式。如果有某个输入张量未遵循[batch_size,height,width,channel]标准,则修改该格式便非常有用。除了修改输入的格式,使之与标准匹 配外,也可修改data_format参数以使用一种不同的布局。

data_format:该参数可取为“NHWC”或“NCHW”,默认值为“NHWC”,用于指定输入和输出数据的格式。当取默认格式“NHWC”时,数据的存储顺序为 [batch,in_height,in_width,in_channels]。若该参数取为“NCHW”,数据存储顺序为[batch,in_channels,in_height,in_width]。
在这里插入图片描述

深入探讨卷积核

在TensorFlow中,滤波器参数用于指定与输入进行卷积运算的卷积核。滤波器通常用于摄影中以调整图片的属性,如允许到达摄像机透镜的光通量。在摄影中,摄影者可借助滤波器对所拍摄的图片做出大幅度的修改。摄影者之所以能够利用滤波器对图片进行修改,是因为滤波器能够识别到达透镜的光线的特定属 性。例如,红色透镜滤波器会吸收(或阻止)不同于红色的每种频率的光,使得只有红色光可通过该滤波器。
在这里插入图片描述
在计算机视觉中,卷积核(滤波器)常用于识别数字图像中的重要属性。当某些滤波器感兴趣的特征在图像中存在时,滤波器会使用特定模式突出这些特征。若将除红色外的所有颜色值减小,则可得到一个红色滤波器的卷积核。在这种情形下,红色值将保持不变,而其他任何匹配的颜色值将被减小。

本章一开始所展示的例子使用了一个专为边缘检测设计的卷积核。边缘检测卷积核在计算机视觉应用中极为常见,它可用基本的TensorFlow运算和一个 tf.nn.conv2d运算实现。

在这里插入图片描述
在这里插入图片描述
将一幅图像与一个边缘检测卷积核进行卷积所得到的输出将是所有被检测到边缘的区域。这段代码假设已有一个图像批数据(image_batch)可用。在这个例 子中,示例图像来自Stanford Dogs数据集,卷积核拥有3个输入和3个输出通道,这些通道对应于[0,255]区间内的RGB值,其中255为最大灰度值。调用tf.minimum 和tf.nn.relu的目的是将卷积值保持存在RGB颜色值的合法范[0,255]内。

在这个简单的示例中,也可使用许多其他的常见卷积核。这些卷积核中的每一个都会突出图像中的不同模式,从而得到不同的结果。下列卷积核通过增加颜色的变化幅度可产生锐化效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个卷积核的作用是增加卷积核中心位置像素的灰度,并降低周围像素的灰度。这种灰度的调整能够匹配那些具有较强灰度的像素的模式,并提升它们的灰度,从而使输出在视觉上呈现出锐化的效果。请注意,这里的卷积核四角的元素均为0,并不会对“+”形状的模式产生影响。

这些卷积核在比较初级的层次上能够与图像中的一些模式匹配。卷积神经网络通过使用从训练过程中学习到的复杂卷积核不但可以匹配边缘,还可以匹配更为复杂的模式。在训练过程中,这些卷积核的初值通常随机设定,随着训练迭代的进行,它们的值会由CNN的学习层自动调整。当CNN训练完成一轮迭代后,它 接收一幅图像,并将其与某个卷积核进行卷积,然后依据预测结果与该图像真实标签是否一致,对卷积核中的参数进一步调整。例如,若一幅牧羊犬的照片被 CNN模型预测为斗牛犬,则卷积核参数将适当调整以试图更好地匹配牧羊犬图片。

用CNN学习复杂的模式并非只用一个单层卷积就可完成,即使上述示例代码中包含了一个tf.nn.relu层用于准备输出以便可视化,也是不够的。在CNN中,卷 积层可多次出现,但通常也会包含其他类型的层。这些层联合起来构成了成功的CNN架构所必需的要素。

常见层

一个神经网络架构要成为CNN,必须至少包含一个卷积层(tf.nn.conv2d)。单层CNN的一种实际用途是检测边缘。对于图像识别和分类任务而言,更常见的情形是使用不同的层类型支持某个卷积层。这些层有助于减少过拟合,并可加速训练过程和降低内存占用率。

本章所涵盖的层主要集中于那些在CNN架构中经常使用的层上。CNN可使用的层并非只局限于这些层,它们完全可以与为其他网络架构设计的层混合使用。

卷积层

我们已经对一种类型的卷积层——tf.nn.conv2d进行了详细介绍,但对高级用户,还有一些注意事项需要说明。TensorFlow中的卷积层所完成的并非真正的卷积,
细节可参考https://www.tensorflow.org/versions/master/api_docs/python/nn.html#convolution。

实际上,卷积与TensorFlow所采用的运算的差异主要体现在性能上。TensorFlow 采用了一种可对所有不同类型的卷积层中的卷积运算进行加速的技术。

每种类型的卷积层都有一些用例,但tf.nn.conv2d是一个较好的切入点。其他类型的卷积也十分有用,但在构建能够完成目标识别和分类任务的网络时,并不需要它们。下面对这些卷积类型做一简要概括。

1.tf.nn.depthwise_conv2d

当需要将一个卷积层的输出连接到另一个卷积层的输入时,可使用这种卷积。一种高级用例是利用tf.nn.depthwise_conv2d创建一个遵循Inception架构的网络(参 见https://arxiv.org/abs/1512.00567 )。

2.tf.nn.separable_conv2d

它与tf.nn.conv2d类似,但并非后者的替代品。对于规模较大的模型,它可在不牺牲准确率的前提下实现训练的加速。对于规模较小的模型,它能够快速收敛, 但准确率较低。

3.tf.nn.conv2d_transpose

它将一个卷积核应用于一个新的特征图,后者的每一部分都填充了与卷积核相同的值。当该卷积核遍历新图像时,任何重叠的部分都相加在一起。这就很好地解释了斯坦福大学课程CS231n Winter 2016:Lecture 13中关于如何将tf.nn.conv2d_transpose用于可学习的降采样的问题。

激活函数

这些函数与其他层的输出联合使用可生成特征图。它们用于对某些运算的结果进行平滑(或微分)。其目标是为神经网络引入非线性。非线性意味着输入和输出的关系是一条曲线,而非直线 。曲线能够刻画输入中更为复杂的变化。例如,非线性映射能够描述那些大部分时间值都很小,但在某个单点会周期性地出现极值的输入。为神经网络引入非线性可使其对在数据中发现的复杂模式进行训练。

TensorFlow提供了多种激活函数。在CNN中,人们之所以主要使用tf.nn.relu,是因为它虽然会带来一些信息损失,但性能较为突出。开始设计模型时,推荐使用 tf.nn.relu,但高级用户也可创建自己的激活函数。评价某个激活函数是否有用时,可考虑下列为数不多的几个主要因素。

1)该函数应是单调 的 ,这样输出便会随着输入的增长而增长,从而使利用梯度下降法寻找局部极值点成为可能。

2)该函数应是可微分的 ,以保证该函数定义域内的任意一点上导数都存在,从而使得梯度下降法能够正常使用来自这类激活函数的输出。

任何满足这些条件的函数都可用作激活函数。在TensorFlow中,有少量激活函数值得一提,它们在各种CNN架构中都极为常见。下面给出这些激活函数的简要 介绍,并通过一些示例代码片段来说明其用法。

1.tf.nn.relu

在这里插入图片描述
在某些文档中,修正线性单元也被称为斜坡函数,因为它的图形与滑板的斜坡非常相似。ReLU是分段线性的,当输入为非负时,输出将与输入相同;而当输入 为负时,输出均为0。它的优点在于不受“梯度消失”的影响,且取值范围为:0到正无穷 ;其缺点在于当使用了较大的学习速率时,易受达到饱和的神经元的影响。

features = tf.range(-2,3)
#注意值为负的特征的输出值
sess.run([features,tf,nn,relu(features)])

的得输出:
在这里插入图片描述

2.tf.sigmoid

在这里插入图片描述
sigmoid函数的返回值位于区间[0.0,1.0]中。当输入值较大时,tf.sigmoid将返回一个接近于1.0的值,而输入值较小时,返回值将接近于0.0。对于在那些真实输出位于[0.0,1.0]的样本上训练的神经网络,sigmoid函数可将输出保持在[0.0,1.0]内的能力非常有用。当输入接近饱和或变化剧烈时,对输出范围的这种缩减往往会带来一些不利影响。

features = tf.to_float(tf.range(-1,3))
sess.run([features,tf.sigmoid(features)])

得到输出:
在这里插入图片描述
在本例中,一组整数被转化为浮点类型(1变为1.0),并传入一个sigmoid函数。当输入为0时,sigmoid函数的输出为0.5,即sigmoid函数值域的中间点。

3.tf.tanh

在这里插入图片描述
双曲正切函数(tanh)与tf.sigmoid非常接近,且与后者具有类似的优缺点。tf.sigmoid和tf.tanh的主要区别在于后者的值域为[-1.0,1.0]。在某些特定的网络架构 中,能够输出负值的能力可能会非常有用。

#注意,tf.tanh(tf.nn,tanh)目前只支持浮点类型的输入
features = tf.to_float(tf.range(-1,3))
sess.run([features,tf.tanh(features)])

得到输出:
在这里插入图片描述

4.tf.nn.dropout

依据某个可配置的概率将输出设为0.0。当引入少量随机性有助于训练时,这个层会有很好的表现。一种适合的场景是:当要学习的一些模式与其近邻特征耦合 过强时。这种层会为所学习到的输出添加少量噪声。

注意:这种层应当只在训练阶段使用。如果在测试阶段使用该层,它所引入的随机噪声将对结果产生误导。

features = tf.constant([-0.1,0.0,0.1,0.2])
#注意,每次执行时,输入都应不同。你的数字不会与这些输出匹配
sess.run([features,tf.nn.dropout(features,keep_prob = 0.5)])

得到输出:
在这里插入图片描述

池化层

池化层能够减少过拟合,并通过减小输入的尺寸来提高性能。它们可用于对输入降采样,但会为后续层保留重要的信息。只使用tf.nn.conv2d来减小输入的尺寸 也是可以的,但池化层的效率更高。

1.tf.nnmax_pool

在这里插入图片描述

这个例子也可通过下列示例代码来说明,目标是找到张量中的最大分量。

#输入通常为前一层的输出,而非直接为图像
batch_size= 1
input_height= 3
input_width = 3
input_channels = 1

layer_input = tf.constant([
	[
		[[1.0],[0.2],[1.5]],
		[[0.1],[1.2],[1.4]],
		[[1.1],[0.4],[0.4]]
	]
])
#strides 会使用image_height 和image_width遍历整个输入
kernel 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值