首页 > 编程知识 正文

tensorflow卷积神经网络(tensorflow神经网络代码)

时间:2023-05-03 22:04:57 阅读:97193 作者:4318

深度学习最令人兴奋的领域之一是计算机视觉。通过卷积神经网络的最新发展,我们已经能够创建自动驾驶汽车、人脸检测系统和自动医学图像分析,这些都是专家的专长。在这篇文章中,我将向您展示卷积神经网络的基本知识,以及如何创建一个来对手写数字进行分类。

与深度学习的许多领域不同,卷积神经网络非常接近人脑的生物功能。早在1959年,David Hubel和Torsten Wiesel就对猫和猴子进行了研究,揭示了视觉皮层的功能。他们发现许多神经元有一个小的局部感受区,它只对整个视野中有限的小区域做出反应。他们发现,一些神经元会对水平线、垂直线和其他圆形图案等低级图案做出反应。他们还意识到,其他神经元有更大的感受区,并受到更复杂模式的刺激,这些模式是低级神经元收集的信息的组合。这些发现为我们现在所说的卷积神经网络奠定了基础。让我们一个一个地分解组成单位。

1.卷积层

每个卷积层由几个特征图组成,这些特征图通过过滤器提供信息,过滤器检测水平或垂直线等特征。您可以将每个过滤器描述为一个窗口,该窗口根据图像的大小滑动并检测属性。滤镜在图像上移动的量称为步幅。步幅为1意味着过滤器一次移动一个像素,因为步幅为2将跳过2个像素。

在上面的例子中,我们有一个垂直线探测器。原始图像为6x6,由步长为1的3x3滤波器扫描,从而产生4x4输出。过滤器只对其视野的左列和右列感兴趣。通过将图像的输入乘以3x3滤波器的配置,我们得到3 1 2 -1 -7-5=-7。然后过滤器向右移动一步,然后计算1 0 3 -2-3-1=-2。-2,然后输入-7右侧的位置。这个过程将持续到4x4网格完成。然后,下一个特征图将使用它自己唯一的滤波器/核矩阵来计算它自己的值。

00-1010汇集层的目标是通过汇集卷积层或所谓的二次采样收集的值来进一步降低维数。这将减少计算负荷,并为机器学习模型提供一些正则化,以避免过度拟合。他们遵循与conv层相同的滑动窗口思想,而不是计算他们选择输入的最大值或平均值的所有值。这分别称为最大池化和平均池化。

这两个组件是卷积层的关键构件。然后,您通常会重复此方法,以进一步减小要素地图的大小,但增加其深度。每个要素地图将明确标识其独特的形状。在卷积结束时,您将放置一个具有激活功能的完全连接的层,例如Relu或卢瑟,以将大小刷新为适合分类器的向量。例如,如果您的最终转换层输出3x128矩阵,但您只预测了10个不同的类,则需要将其刷新为1x1152向量,并在将其输入分类器之前逐渐减小其大小。完全连接的层也学习自己的功能,就像典型的深度神经网络一样。

现在让我们看看MNIST手写数字数据集在Tensorflow中的实现。首先,我们将加载我们的Python库。使用sklearn中的fetch_mldata,我们加载mnist数据集,并为X和Y变量分配图像和标签。然后我们将创建我们的训练/测试数据集。最后,我们将给出一些例子来理解未来的任务。

on">

正如您所看到的,有一些具有挑战性的例子。右侧都是1。

接下来,我们将进行一些数据扩充,这是提高模型性能的可靠方法。通过创建训练图像的轻微变化,您实际上可以为模型创建正则化。我们将使用scipy的ndimage模块将图像向右,向左,向上和向下移动1个像素。这不仅提供了更多种类的例子,而且还会大大增加我们训练集的大小,这通常总是一件好事。

我将向您展示的最后一种数据扩充形式是使用cv2库创建图像的水平翻转。我们还需要为这些翻转图像创建新标签,这与复制原始标签一样简单。

设置“flipCode = 0”将产生垂直翻转。

接下来,我们将创建一个辅助函数,将随机的小批量输入到我们的神经网络输入中。由于卷积层的性质,它们在向前和向后遍历步骤中需要大量的内存。考虑一个带有4x4过滤器的层,输出128个具有1步长和相同填充的feature map, RGB图像输入的尺寸为299x299。参数的数量将相等(4x4x3 + 1)x 128 = 6272.现在考虑这128个特征图中的每一个都计算299x299个神经元,并且这些神经元中的每一个都计算4x4x3输入的加权和。现在是4x4x3x299x299x150 = 643,687,200次计算。这只是一个训练的例子。你可以想象这很快就会失控。解决这一问题的方法是,使用python生成器一次向网络提供小批量的内容,这种生成器本质上是在需要项之前将其保存在内存之外。

我们准备开始创建我们的神经网络架构。首先,我们为我们的训练数据/标签创建占位符。我们将需要将它们reshape为(-1,28,28,1)矩阵,因为tensorflow conv2d层需要4维输入。我们将第一个维度设置为“无”,以允许将任意批量大小提供给占位符。

现在我们将设计我们的卷积层。我将从Le-NET5(由Yann LeCun开创)网络架构中获取灵感,该架构因其在手写数字分类方面的成功而闻名。然而,有很多事情我做了不同的事情。我建议您研究Le-NET5以及其他经过验证的模型,以了解哪种卷积网络适用于不同的任务。

第一层由12个特征图组成,使用3x3 filter,步幅为1.我们选择了SAME填充,通过在输入周围添加一个零填充来保持图像的尺寸。然后,我们应用最大池化层与另一个3x3 filter和步长为2,将输出13x13x12矩阵。所以我们从一个28x28x1的图像开始,并且生成的filter maps 的尺寸小于其尺寸的一半但深度更深。然后我们将这个矩阵传递给第二个conv 层,它具有深度为16,3x3 filter,stride = 1和padding SAME ,与之前相同的最大池化层。这输出一个6 * 6 * 16维矩阵。您可以看到我们正在缩小特征图的维度空间,但要更深入。这是我们学习的地方,在第一层把较低层次的图组合起来,在第二层形成更复杂的图。接下来,我们通过将其reshape为由6x6x16 = 576值组成的1维行向量来准备全连接层的输出。我们使用Selu激活的两个dense 层来减少每层输入的数量大约一半,直到最终将它们输入我们的logits,这将输出10个预测。

我们创建了我们的损失函数,在这种情况下,它将是softmax交叉熵,它将输出多类概率。您可以将交叉熵视为各种数据点之间距离的度量。我们选择AdamOptimizer,当它向下移动梯度时自动调整它的学习率。最后,我们创建了一种评估结果的方法。in_top_k将计算我们的logits并选择最高分。然后我们使用我们的准确度变量输出0-1之间的值。

现在我们已经为训练阶段做好了准备。首先,我将训练模型。让我们看看我们的机器学习模型表现得如何。

在第19 epoch,我们达到最高百分比正确在0.9907。这已经比任何机器学习算法的结果更好,因此卷积已经取得了领先。现在让我们尝试使用我们的移位特征/翻转特征,并为我们的网络添加两个新元素。dropout和批归一化。

我们使用placeholder_with_default节点修改现有占位符,这些节点将保存批归一化和Dropout层生成的值。在训练期间,我们将这些值设置为True,在测试期间,我们将通过设置为False将其关闭。

批归一化只是简单地对每批次的数据进行中心化和归一化。我们指定了0.9的momentum 。Drop out正则化指定概率(在我们的情况下为1 -0.5)以在训练期间完全随机地关闭节点。想象一下,一家公司决定每周随机选择50名员工留在家里。其余的工作人员将不得不有效地处理额外的工作,提高他们在其他领域的技能。不确定这会在现实生活中起作用,但在深度学习中它已被证明是有效的。

我们像以前一样创建我们的损失,训练和评估步骤,然后对我们的执行阶段进行一些修改。通过批归一化化执行的计算在每次迭代期间保存为更新操作。为了访问这些,我们分配一个变量extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)。在我们的训练操作期间,我们将其作为列表项与training_op一起提供给sess.run。最后,在执行验证/测试预测时,我们通过feed_dict为占位符分配False值。我们不会在预测阶段进行任何随机化。为了获得输出,我们使用我们的测试集运行logits操作。让我们看看这个模型现在表现得如何,我们已经添加了正则化/归一化并且正在使用增强特征。

在29 epoch,我们在10,000个数字的测试集上达到了99.5%的准确率。正如你所看到的那样,只有第二个epoch的模型精确度达到了99%,而之前的模型只有16个精度。虽然0.05%听起来可能不是很多,但在处理大量数据时这是一个重大改进。最后,我将向您展示如何在logits输出上使用np.argmax提取预测。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。