2018-09-25 17:11:22 weixin_42817899 阅读数 272
  • 卷积神经网络与人脸识别系统实战视频教程

    卷积神经网络与人脸识别系统实战视频培训课程概况:本教程从零开始讲解人工神经网络,卷积神经网络等基础内容,然后讲解基于python如何构建一个深度学习模型,后基于CNN,利用keras构建网络结构打造一个人脸识别系统。

    2563 人正在学习 去看看 王而川

【导读】传统的肉眼识别方法是很难直接识别出 NIs (自然图像) 和 CG (计算机生成的图像)。本文中提出了一种高效的、基于卷积神经网络 (CNN) 的图像识别方法。通过大量的实验来评估模型的性能。实验结果表明,该方法优于现有的其他识别方法,与传统方法中采用 CNN 模型来识别图像,此方法还能借助高级可视化工具。

▌ 摘要

考虑到对现有的 CCNs 从头开始训练或微调预训练网络都具有一定的局限性,这个研究提出了一种更合适的想法:设计阶段在 CNN 模型的底部增加了两个级联卷积层。该网络能够根据不同大小的图像输入,进行自适应地调整,同时保持固定的深度,以稳定 CNN 结构并实现良好的识别表现。对于所提出的模型,我们采用一种称为“局部到全局”的策略,即 CNN 能够获取局部图像的识别决策,而全局的识别决策可通过简单的投票方式获得。我们通过大量的实验来评估模型的性能。实验结果表明,该方法优于现有的其他识别方法,且在后处理的图像上也具有较好的鲁棒性。此外,相比于传统方法中采用 CNN 模型来识别图像,我们的方法还能借助高级可视化工具,进一步可视化地了解 NIs 与 CG 之间的差异。

▌简介

当前,对 NIs 和 CG 的图像识别研究已经得到了广泛的关注。解决这个问题的主要挑战在于 NIs 与 CG 有近乎相同的写实性及图像模式。先前的研究通常都是人工设计一些可判别的特征,来区别 NIs 和 CG。但这些方法普遍存在的问题是人为设计的特征对于给定的图像识别问题来说,并不一定是最适合的,特别对于一些复杂的数据库而言,该方法的识别效果更差。

相比于需要先验知识和假设条件的传统方法,卷积神经网络 (CNN) 能够自动地从数据中学习目标的特征及其抽象表征,这使得它能够更广泛适用于一些复杂的数据库。本文,我们提出一种基于 CNN 的框架来识别 NIs 和 CG。这是一种以端到端的方式进行自动特征学习,而无需进行人为设计图像特征的框架。我们的工作主要总结如下:

提出了一种基于 CNN 的 NIs 与 CG 的通用识别框架,通过微调它能够自适应于不同尺寸的图像输入块。
对微调训练后的 CNN 模型,我们针对性地设计了一种改进方案以改进我们的识别表现,这两种基于 CNN 的方案都优于目前最先进的方法。
我们的方法在 Google 和 PRCG 数据库上都表现出良好的识别性能,而且对调整图像大小和压缩 JPEG 等后处理操作有强大的鲁棒性。
利用可视化工具,我们进一步地了解 CNN 模型是如何区分 NIs 和 CG。
▌数据集

我们使用的实验数据包括 Columbia Photo-graphic 与 PRCG 数据库。数据库由三组图像组成:(1) 从40个 3D 图形网站中获取的800张 PRCGs 数据;(2) 我们所采集的800张 NIs;以及 (3) 从 Google 搜索中获取的795张摄影图像。

我们所采集的300张 NIs 是通过小型数码相机拍摄的。先前研究的方法都没有在 Google 与 PRCG 数据库上进行过测试,这是因为 Google中的 NIs 与PRCG中的CG图像起源不同。而我们的研究不仅尝试解决这个问题,而且还将在 Personal 与 PRCG ,以及 Personal+Google 与 PRCG 两种不同数据库组合条件下进行测试。

▌框架

我们将 NIs 与 CG 的图像识别问题视为是一个二元分类问题。针对此问题,提出了两种不同的图像识别标准框架,如图1所示:其中,f 是特征提取器,c 代表一个分类器 (如 SVM) 。我们的框架是一个二阶段模型,其核心在于特征提取器。通常,特征的提取过程不仅需要耗费大量的时间,且提取出来的特征不一定是我们任务所需要的,而我们的 CNN 框架能够以端到端的方式自动学习并提取所需特征,这为解决特征提取问题提供了一种思路。因此,我们提出了一种适用的 CNN 模型,并采用以下三种不同的训练方法:(1) 遵循现有的网络结构,并从头开始训练 CNN 模型;(2) 微调一个预先在其他数据集或另外一个任务中训练好的、现成的 CNN 网络;(3) 设计一个新的网络,并从头开始训练。
在这里插入图片描述
图1 两种不同的图像识别框架

局部到全局策略

考虑到模型的计算成本,图片尺寸的多样性以及图像识别的性能要求,我们采用一种由局部到全局的策略,来对局部图像进行训练并使用简单的投票规则再对全局的图像进行分类。这种由局部到全局的策略是一种基于数据增强的思想,也是扩展训练中的常用技巧,尤其是在深度学习领域。

对于图像分类问题,局部策略 (即高精度的局部图像) 对于图像识别来说是非常重要的;另一方面,从 CG 上裁剪下来的图像本质仍是 CG,而对 Nis 而言也是如此。因此,我们引入数据增强的方法,也就是说,从每次训练中选择一些固定尺寸的图像去增强训练数据集,并且尽可能地去获取更高精度的图像。在实践阶段,我们使用 Maximal Poisson-disk 从每次训练中随机裁剪一定数量的图像来构建新的训练数据集。在测试阶段,从每个测试图像中裁剪一定数量的局部图像,并给每张局部图像加上特定的标签 ( CG 属于0,而 NI 属于1 ),编号较高的标签作为该图像的预测结果。

网络结构

我们所采用的网络结构由 ConvFilter 层,3个卷积层组,2层 FC 层以及1个softmax 分类层组成,模型的输入是二进制的图片格式。其结构如下图2所示:我们的输入是一张233233的 RGB 图像,用绿色方块表示;红色方块代表卷积核,靠近它的数字代表该卷积核的尺寸,左侧的红色方块代表一个77的卷积核;特征图则由阴影部分的长方体所示。
在这里插入图片描述
图2 我们的网络结构

▌实验结果

实验设置与细节

我们使用了双三次插值来调整所有图像的大小,调整后的图片的较短边像素值为512,以此确保所有图像的大小一致性。基于原始数据集,我们以 3:1 的分离率来设置训练集和测试集,并用 MPS 从每张训练数据中裁剪出 200 张,以满足局部到全局策略的需要并达到扩充训练数据的目的。同样地,从每张测试数据中裁剪出 30 张来作为测试集。在训练时,我们采用128的批次大小,学习率设置为0.001,每 30k 次迭代学习率就除以10,直到迭代完 90k 次为止。此外,除了 60×60 和 30×30 图像块大小的正则化设置为 5e-5 和 1e-5 外,其余的正则化权重的默认值为 1e-4。

微调 CaffeNet 和卷积滤波器层的性能分析

微调后的 CaffeNet 的测试结果如下表 1 所示。我们可以看到,微调后网络 (C-1 到 C-7) 的测试性能要优于从头开始训练的网络 (C-S) 实验结果,这可能是由于预训练期间学习大量 NI 对模型的特征学习是有益的。而相比于传统方法 (准确率最高80.65%),通过微调后,我们的网络性能更佳,准确率更高。
在这里插入图片描述
表1 模型的分类精度,其中 C 表示 CaffeNet,”C-S” 表示从头开始训练网络 CaffeNet,”C-N” 表示微调 CaffeNet 后的前 N 层网络,N 从1到7。

此外,我们还对 ConvFilter 层进行了四种不同的配置: (1) 两个级联卷积层;(2) 删除 convFilter 层;(3) convFilter 层之后接 ReLU 激活层;以及(4) convFilter 层中加入高通滤波器。下表2 显示了这四种配置相对应的模型性能,其中使用两个级联卷积层时模型的准确率最高。
在这里插入图片描述
表2 四种不同配置下的 convFilter 的分类精度

不同尺寸图像块上的分类性能

下图 3 展示了我们的方法与三种人工设计特征的方法在不同尺寸图像块上的分类精度。与其他三种方法相比较,我们的方法在任何图像块尺寸上的准确率都更高,且随着图像块尺寸的缩小,网络的分类准确率会降低。
在这里插入图片描述
图3 我们的方法与三种人工设计特征的方法在不同尺寸图像块上的分类精度表现

后处理的鲁棒性分析

有效的图像识别算法不仅能处理原始数据,还应该在后处理数据中具有良好的鲁棒性。本文的研究中,我们针对图像缩放和 JPEG 压缩这两种典型的后处理进行鲁棒性分析。下图 4 展示了四种分类方法在五种后处理中的分类准确率表现 (实线部分)。可以看到,我们的模型对于后处理的数据具有更强的鲁棒性。
在这里插入图片描述
图4 不同分类方法在后处理数据上的分类精度表现

局部到全局策略的分析

进一步地,我们还分析了局部到全局策略在全尺寸图像上的分类精度表现。如下表3所示,实验结果表明在全尺寸图像上的模型精度,比在图像块上的模型精度要高,并且采用图像块投票的方式获得的全尺寸分类精度要高于直接在全尺寸上图像得到的分类精度。而投票准确性对后处理操作的稳健性由上图4中的虚线表示。
在这里插入图片描述
表3 局部到全局策略对六种方法的分类准确率的影响

▌可视化

在计算机视觉任务中,CNN 的训练普遍存在一种现象:即模型在第一层学习的卷积核类似于 Gabor 滤波器和 color blobs。我们在下图 5 展示了模型的卷积可视化结果,其中 (a) 表示我们模型的第一层卷积核的傅里叶变换 (FFT) 结果, (b) 表示预训练的 CaffeNet 的结果,© 是对应于 CaffeNet 中第一层的前96个卷积核的可视化结果,而 (d) 则对应于最后的96个结果。滤波器根据三个颜色通道 B,G 和 R 被分为3个组,而像素越亮则代表所对应的B,G,R的值越高。
在这里插入图片描述
图 5 卷积可视化结果

▌结论

本文,我们提出了一种基于 CNN 的通用框架来区别自然图像 NIs 与计算机生成图像 CG 之间的差异,这种方法不仅能够在 Google 和 PRCG 的数据集中进行测试,而在后处理时也表现出较好的鲁棒性。这些优点对于现实生活中的图像识别任务是非常有效且重要的。

未来的工作中,我们将尝试通过引入语义级别的 CNN 集成模型来进一步改进我们的模型性能。此外,我们还将扩展我们的方法,并应用于视频数据的差异性探索。

有想学习Python的同学可以加一下学习交流扣扣群:862672474

文档与视频资料都已经准备好,欢迎进群一起交流学习!

2017-08-09 13:49:41 CNHK1225 阅读数 989
  • 卷积神经网络与人脸识别系统实战视频教程

    卷积神经网络与人脸识别系统实战视频培训课程概况:本教程从零开始讲解人工神经网络,卷积神经网络等基础内容,然后讲解基于python如何构建一个深度学习模型,后基于CNN,利用keras构建网络结构打造一个人脸识别系统。

    2563 人正在学习 去看看 王而川

对人类来说,描述我们眼睛所看到的事物,即“视觉世界”,看起来太微不足道了,以至于我们根本没有意识到那正是我们时时刻刻在做的事情。在看到某件事物时,不管是汽车、大树,还是一个人,我们通常都不需要过多的思考就能立刻叫出名字。然而对于一台计算机来说,区分识别“人类对象”(比如:在小狗、椅子或是闹钟这些“非人类对象”中识别出奶奶这一“人类对象”)却是相当困难的。

能解决这一问题可以带来非常高的收益。“图像识别”技术,更宽泛地说是“计算机视觉”技术,是许多新兴技术的基础。从无人驾驶汽车和面部识别软件到那些看似简单但十分重要的发展成果——能够监测流水线缺陷和违规的“智能工厂”,以及保险公司用来处理和分类索赔照片的自动化软件。这些新兴科技是离不开“图像识别”的。

在接下来的内容里,我们将要探究“图像识别”所面临的问题和挑战,并分析科学家是如何用一种特殊的神经网络来解决这一挑战的。

学会“看”是一项高难度、高成本的任务

着手解决这个难题,我们可以首先将元数据应用于非结构化数据。在之前的文章里,我们曾描述过在元数据稀缺或元数据不存在的情况下,进行文本内容分类和搜索遇到的一些问题和挑战。让专人来对电影和音乐进行人工分类和标记,确实是一项艰巨的任务。但有些任务不仅艰巨,甚至是几乎不可能完成的。比如训练无人驾驶汽车里的导航系统,让其能够将其他车辆与正在过马路的行人区分开来;或者是每天对社交网站上用户上传的千千万万张的照片和视频进行标记、分类和筛查。

唯一能够解决这一难题的方法就是神经网络。理论上我们可以用常规的神经网络来进行图像分析,但在实际操作中,从计算角度看,使用这种方法的成本非常高。举例来说,一个常规的神经网络,就算是处理一个非常小的图像,假设是30*30像素图像,仍需要900个数据输入和五十多万个参数。这样的处理加工对一个相对强大的机器来说还是可行的;但是,如果需要处理更大的图像,假设是500*500像素的图像,那么机器所需的数据输入和参数数量就会大大增加,增加到难以想象的地步。

除此之外,将神经网络用于“图像识别”还可能会导致另一个问题——过度拟合。简单来说,过度拟合指的是系统训练的数据过于接近定制的数据模型的现象。这不仅会在大体上导致参数数量的增加(也就是进一步计算支出的增加),还将削弱“图像识别”在面临新数据时其他常规功能的正常发挥。

真正的解决方案——卷积

幸运的是,我们发现,只要在神经网络的结构方式上做一个小小的改变,就能使大图像的处理更具可操作性。改造后的神经网络被称作“卷积神经网络”,也叫CNNs或ConvNets。

神经网络的优势之一在于它的普遍适应性。但是,就像我们刚刚看到的,神经网络的这一优势在图像处理上实际上是一种不利因素。而“卷积神经网络”能够对此作出一种有意识的权衡——为了得到一个更可行的解决方案,我们牺牲了神经网络的其他普遍性功能,设计出了一个专门用于图像处理的网络。

在任何一张图像中,接近度与相似度的关联性都是非常强的。准确地说,“卷积神经网络”就是利用了这一原理。具体而言就是,在一张图像中的两个相邻像素,比图像中两个分开的像素更具有关联性。但是,在一个常规的神经网络中,每个像素都被连接到了单独的神经元。这样一来,计算负担自然加重了,而加重的计算负担实际上是在削弱网络的准确程度。

卷积网络通过削减许多不必要的连接来解决这一问题。运用科技术语来说就是,“卷积网络”按照关联程度筛选不必要的连接,进而使图像处理过程在计算上更具有可操作性。“卷积网络”有意地限制了连接,让一个神经元只接受来自之前图层的小分段的输入(假设是3×3或5×5像素),避免了过重的计算负担。因此,每一个神经元只需要负责处理图像的一小部分(这与我们人类大脑皮质层的工作原理十分相似——大脑中的每一个神经元只需要回应整体视觉领域中的一小部分)。

“卷积神经网络”的内在秘密

“卷积神经网络”究竟是如何筛选出不必要的连接的呢?秘密就在于两个新添的新型图层——卷积层和汇聚层。我们接下来将会通过一个实操案例:让网络判断照片中是否有“奶奶”这一对象,把“卷积神经网络”的操作进行分解,逐一描述。

第一步,“卷积层”。“卷积层”本身实际上也包含了几个步骤:

1.首先,我们会将奶奶的照片分解成一些3×3像素的、重叠着的拼接图块。

2.然后,我们把每一个图块运行于一个简单的、单层的神经网络,保持权衡不变。这一操作会使我们的拼接图块变成一个图组。由于我们一开始就将原始图像分解成了小的图像(在这个案例中,我们是将其分解成了3×3像素的图像),所以,用于图像处理的神经网络也是比较好操作的。

3.接下来,我们将会把这些输出值排列在图组中,用数字表示照片中各个区域的内容,数轴分别代表高度、宽度和颜色。那么,我们就得到了每一个图块的三维数值表达。(如果我们讨论的不是奶奶的照片,而是视频,那么我们就会得到一个四维的数值表达了。)

说完“卷积层”,下一步是“汇聚层”。

“汇聚层”是将这个三维(或是四维)图组的空间维度与采样函数结合起来,输出一个仅包含了图像中相对重要的部分的联合数组。这一联合数组不仅能使计算负担最小化,还能有效避免过度拟合的问题。

最后,我们会把从“汇聚层”中得出的采样数组作为常规的、全方位连接的神经网络来使用。通过卷积和汇聚,我们大幅度地缩减了输入的数量,因此,我们这时候得到的数组大小是一个正常普通网络完全能够处理的,不仅如此,这一数组还能保留原始数据中最重要的部分。这最后一步的输出结果将最终显示出系统有多少把握作出“照片中有奶奶”的判断。

以上只是对“卷积神经网络”工作过程的简单描述,现实中,其工作过程是更加复杂的。另外,跟我们这里的案例不同,现实中的“卷积神经网络”处理的内容一般包含了上百个,甚至上千个标签。

“卷积神经网络”的实施

重新开始建立一个“卷积神经网络”是一项非常耗时且昂贵的工作。不过,许多API最近已经实现了——让组织在没有内部计算机视觉或机器学习专家的帮助下,完成图像分析的收集工作。

  • “谷歌云视觉”是谷歌的视觉识别API,它是以开源式TensorFlow框架为基础的,采用了一个REST API。“谷歌云视觉”包含了一组相当全面的标签,能够检测单个的对象和人脸。除此之外,它还具备一些附加功能,包括OCR和“谷歌图像搜索”。

  • “IBM沃森视觉识别”技术是“沃森云开发者”的重要组成部分。它虽然涵盖了大量的内置类集,但实际上,它是根据你所提供的图像来进行定制类集的训练的。与“谷歌云视觉”一样,“IBM沃森视觉识别”也具备许多极好的功能,比如OCR和NSFW检测功能。

  • Clarif.ai是图像识别服务的“后起之秀”,它采用了一个REST API。值得一提的是,Clarif.ai包含了大量的单元,能够根据特定的情境定制不同的算法。像婚礼、旅游甚至食物。

上面的这些API更适用于一些普通的程序,但对于一些特殊的任务,可能还是需要“对症下药”,制定专门的解决方案。不过值得庆幸的是,许多数据库可以处理计算和优化方面的工作,这或多或少地减轻了数据科学家和开发人员的压力,让他们有更多精力关注于模型训练。其中,大部分的数据库,包括TensorFlow,深度学习4J和Theano,都已经得到了广泛、成功的应用。

2016-01-18 00:19:13 taigw 阅读数 90558
  • 卷积神经网络与人脸识别系统实战视频教程

    卷积神经网络与人脸识别系统实战视频培训课程概况:本教程从零开始讲解人工神经网络,卷积神经网络等基础内容,然后讲解基于python如何构建一个深度学习模型,后基于CNN,利用keras构建网络结构打造一个人脸识别系统。

    2563 人正在学习 去看看 王而川

一,前言

卷积神经网络(Constitutional Neural Networks, CNN)是在多层神经网络的基础上发展起来的针对图像分类和识别而特别设计的一种深度学习方法。先回顾一下多层神经网络:
这里写图片描述
多层神经网络包括一个输入层和一个输出层,中间有多个隐藏层。每一层有若干个神经元,相邻的两层之间的后一层的每一个神经元都分别与前一层的每一个神经元连接。在一般的识别问题中,输入层代表特征向量,输入层的每一个神经元代表一个特征值。

在图像识别问题中,输入层的每一个神经元可能代表一个像素的灰度值。但这种神经网络用于图像识别有几个问题,一是没有考虑图像的空间结构,识别性能会受到限制;二是每相邻两层的神经元都是全相连,参数太多,训练速度受到限制。

而卷积神经网络就可以解决这些问题。卷积神经网络使用了针对图像识别的特殊结构,可以快速训练。因为速度快,使得采用多层神经网络变得容易,而多层结构在识别准确率上又很大优势。

二,卷积神经网络的结构

卷积神经网络有三个基本概念:局部感知域(local receptive fields),共享权重(shared weights)和池化(pooling)。

局部感知域: 在上图中的神经网络中输入层是用一列的神经元来表示的,在CNN中,不妨将输入层当做二维矩阵排列的神经元。

与常规神经网络一样,输入层的神经元需要和隐藏层的神经元连接。但是这里不是将每一个输入神经元都与每一个隐藏神经元连接,而是仅仅在一个图像的局部区域创建连接。以大小为28X28的图像为例,假如第一个隐藏层的神经元与输入层的一个5X5的区域连接,如下图所示:
这里写图片描述
这个5X5的区域就叫做局部感知域。该局部感知域的25个神经元与第一个隐藏层的同一个神经元连接,每个连接上有一个权重参数,因此局部感知域共有5X5个权重。如果将局部感知域沿着从左往右,从上往下的顺序滑动,就会得对应隐藏层中不同的神经元,如下图分别展示了第一个隐藏层的前两个神经元与输入层的连接情况。
这里写图片描述
这里写图片描述
如果输入层是尺寸为28X28的图像,局部感知域大小为5X5,那么得到的第一个隐藏层的大小是24X24。

共享权重: 上面得到的第一隐藏层中的24X24个神经元都使用同样的5X5个权重。第j个隐藏层中第k个神经元的输出为:

σ(b+l=04m=04wl,maj+l,k+m)

这里σ是神经元的激励函数(可以是sigmoid函数、thanh函数或者rectified linear unit函数等)。b是该感知域连接的共享偏差。wl,m是个5X5共享权重矩阵。因此这里有26个参数。 ax,y 代表在输入层的x,y处的输入激励。

这就意味着第一个隐藏层中的所有神经元都检测在图像的不同位置处的同一个特征。因此也将从输入层到隐藏层的这种映射称为特征映射。该特征映射的权重称为共享权重,其偏差称为共享偏差。

为了做图像识别,通常需要不止一个的特征映射,因此一个完整的卷积层包含若干个不同的特征映射。下图中是个三个特征映射的例子。
这里写图片描述
在实际应用中CNN可能使用更多的甚至几十个特征映射。以MNIST手写数字识别为例,学习到的一些特征如下:
这里写图片描述
这20幅图像分别对应20个不同的特征映射(或称作filters, kernels)。每一个特征映射由5X5的图像表示,代表了局部感知域中的5X5个权重。亮的像素点代表小的权重,与之对应的图像中的像素产生的影响要小一些。暗的像素点代表的大的权重,也意味着对应的图像中的像素的影响要大一些。可以看出这些特征映射反应了某些特殊的空间结构,因此CNN学习到了一些与空间结构有关的信息用于识别。

池化层(pooling layers) 池化层通常紧随卷积层之后使用,其作用是简化卷积层的输出。例如,池化层中的每一个神经元可能将前一层的一个2X2区域内的神经元求和。而另一个经常使用的max-pooling,该池化单元简单地将一个2X2的输入域中的最大激励输出,如下图所示:
这里写图片描述
如果卷积层的输出包含24X24个神经元,那么在池化后可得到12X12个神经元。每一个特征映射后分别有一个池化处理,前面所述的卷积层池化后的结构为:
这里写图片描述
Max-pooling并不是唯一的池化方法,另一种池化方法是L2pooling,该方法是将卷积层2X2区域中的神经元的输出求平方和的平方根。尽管细节与Max-pooling不一样,但其效果也是简化卷积层输出的信息。

将上述结构连接在一起,再加上一个输出层,得到一个完整的卷积神经网络。在手写数字识别的例子中输出层有十个神经元,分别对应0,1, … ,9的输出。
这里写图片描述
网络中的最后一层是一个全连接层,即该层的每个神经元都与最后一个Max-pooling层的每个神经元连接。

这个结构这是一个特殊的例子,实际CNN中也可在卷积层和池化层之后可再加上一个或多个全连接层。

三,卷积神经网络的应用

3.1 手写数字识别

Michael Nielsen提供了一个关于深度学习和CNN的在线电子书,并且提供了手写数字识别的例子程序,可以在GitHub上下载到。该程序使用Python和Numpy, 可以很方便地设计不同结构的CNN用于手写数字识别,并且使用了一个叫做Theano的机器学习库来实现后向传播算法和随机梯度下降法,以求解CNN的各个参数。Theano可以在GPU上运行,因此可大大缩短训练过程所需要的时间。CNN的代码在network3.py文件中。

作为一个开始的例子,可以试着创建一个仅包含一个隐藏层的神经网络,代码如下:

>>> import network3
>>> from network3 import Network
>>> from network3 import ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer
>>> training_data, validation_data, test_data = network3.load_data_shared()
>>> mini_batch_size = 10
>>> net = Network([
        FullyConnectedLayer(n_in=784, n_out=100),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, 
            validation_data, test_data)

该网络有784个输入神经元,隐藏层有100个神经元,输出层有10个神经元。在测试数据上达到了97.80%的准确率。

如果使用卷积神经网络会不会比它效果好呢?可以试一下包含一个卷积层,一个池化层,和一个额外全连接层的结构,如下图
这里写图片描述
在这个结构中,这样理解:卷积层和池化层学习输入图像中的局部空间结构,而后面的全连接层的作用是在一个更加抽象的层次上学习,包含了整个图像中的更多的全局的信息。

>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2)),
        FullyConnectedLayer(n_in=20*12*12, n_out=100),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, 
            validation_data, test_data)   

这种CNN的结构达到的识别准确率为98.78%。如果想进一步提高准确率,还可以从以下几方面考虑:

  1. 再添加一个或多个卷积-池化层
  2. 再添加一个或多个全连接层
  3. 使用别的激励函数替代sigmoid函数。比如Rectifed Linear Units函数: f(z)=max(0,z). Rectified Linear Units函数相比于sigmoid函数的优势主要是使训练过程更加快速。
  4. 使用更多的训练数据。Deep Learning因为参数多而需要大量的训练数据,如果训练数据少可能无法训练出有效的神经网络。通常可以通过一些算法在已有的训练数据的基础上产生大量的相似的数据用于训练。例如可以将每一个图像平移一个像素,向上平移,向下平移,向左平移和向右平移都可以。
  5. 使用若干个网络的组合。创建若干个相同结构的神经网络,参数随机初始化,训练以后测试时通过他们的输出做一个投票以决定最佳的分类。其实这种Ensemble的方法并不是神经网络特有,其他的机器学习算法也用这种方法以提高算法的鲁棒性,比如Random Forests。

3.2 ImageNet图像分类

Alex Krizhevsky等人2012年的文章“ImageNet classification with deep convolutional neural networks”对ImageNet的一个子数据集进行了分类。ImageNet一共包含1500万张有标记的高分辨率图像,包含22,000个种类。这些图像是从网络上搜集的并且由人工进行标记。从2010年开始,有一个ImageNet的图像识别竞赛叫做ILSVRC(ImageNet Large-Scale Visual Recognition Challenge)。 ILSVRC使用了ImageNet中的1000种图像,每一种大约包含1000个图像。总共有120万张训练图像,5万张验证图像(validation images)和15万张测试图像(testing images)。该文章的方法达到了15.3%的错误率,而第二好的方法错误率是26.2%。
这里写图片描述

这篇文章中使用了7个隐藏层,前5个是卷积层(有些使用了max-pooling),后2个是全连接层。输出层是有1000个单元的softmax层,分别对应1000个图像类别。

该CNN使用了GPU进行计算,但由于单个GPU的容量限制,需要使用2个GPU (GTX 580,分别有3GB显存)才能完成训练。

该文章中为了防止过度拟合,采用了两个方法。一是人工生成更多的训练图像。比如将已有的训练图像进行平移或者水平翻转,根据主成分分析改变其RGB通道的值等。通过这种方法是训练数据扩大了2048倍。二是采用Dropout技术。Dropout将隐藏层中随机选取的一半的神经元的输出设置为0。通过这种方法可以加快训练速度,也可以使结果更稳定。
这里写图片描述
输入图像的大小是224X224X3,感知域的大小是11X11X3。第一层中训练得到的96个卷积核如上图所示。前48个是在第一个GPU上学习到的,后48个是在第二个GPU上学习到的。

3.3 医学图像分割

Adhish Prasoon等人在2013年的文章“Deep feature learning for knee cartilage segmentation using a triplanar convolutional neural network”中,用CNN来做MRI中膝关节软骨的分割。传统的CNN是二维的,如果直接扩展到三维则需要更多的参数,网络更复杂,需要更长的训练时间和更多的训练数据。而单纯使用二维数据则没有利用到三维特征,可能导致准确率下降。为此Adhish采用了一个折中方案:使用xy,yzxz三个2D平面的CNN并把它们结合起来。
这里写图片描述

三个2D CNN分别负责对xy,yzxz平面的处理,它们的输出通过一个softmax层连接在一起,产生最终的输出。该文章中采用了25个病人的图像作为训练数据,每个三维图像中选取4800个体素,一共得到12万个训练体素。相比于传统的从三维图像中人工提取特征的分割方法,该方法在精度上有明显的提高,并且缩短了训练时间。

3.4 谷歌围棋AlphaGo战胜人类

谷歌旗下DeepMind团队使用深度卷积神经网络在电脑围棋上取得了重大突破。早期,IBM的深蓝超级计算机通过强大的计算能力使用穷举法战胜了人类专业象棋选手,但那不算“智能”。

围棋上的计算复杂度远超象棋,即使通过最强大的计算机也无法穷举所有的可能的走法。计算围棋是个极其复杂的问题,比国际象棋要困难得多。围棋最大有3^361 种局面,大致的体量是10^170,而已经观测到的宇宙中,原子的数量才10^80。国际象棋最大只有2^155种局面,称为香农数,大致是10^47。

DeepMind所研究的AlphaGo使用了卷积神经网络来学习人类下棋的方法,最终取得了突破。AlphaGo在没有任何让子的情况下以5:0完胜欧洲冠军,职业围棋二段樊麾。研究者也让AlphaGo和其他的围棋AI进行了较量,在总计495局中只输了一局,胜率是99.8%。它甚至尝试了让4子对阵Crazy Stone,Zen和Pachi三个先进的AI,胜率分别是77%,86%和99%。可见AlphaGo有多强大。

在谷歌团队的论文中,提到“我们用19X19的图像来传递棋盘位置”,来“训练”两种不同的深度神经网络。“策略网络”(policy network)和 “值网络”(value network)。它们的任务在于合作“挑选”出那些比较有前途的棋步,抛弃明显的差棋,从而将计算量控制在计算机可以完成的范围里,本质上和人类棋手所做的一样。

其中,“值网络”负责减少搜索的深度——AI会一边推算一边判断局面,局面明显劣势的时候,就直接抛弃某些路线,不用一条道算到黑;而“策略网络”负责减少搜索的宽度——面对眼前的一盘棋,有些棋步是明显不该走的,比如不该随便送子给别人吃。利用蒙特卡洛拟合,将这些信息放入一个概率函数,AI就不用给每一步以同样的重视程度,而可以重点分析那些有戏的棋着。
这里写图片描述
参考论文:David Silver, et al. “Mastering the game of Go with deep neural networks and tree search.” Nature doi:10.1038/nature16961.
相关链接:http://www.guokr.com/article/441144/

2018-03-09 16:06:48 wrgcon520 阅读数 11082
  • 卷积神经网络与人脸识别系统实战视频教程

    卷积神经网络与人脸识别系统实战视频培训课程概况:本教程从零开始讲解人工神经网络,卷积神经网络等基础内容,然后讲解基于python如何构建一个深度学习模型,后基于CNN,利用keras构建网络结构打造一个人脸识别系统。

    2563 人正在学习 去看看 王而川

TensorFlow实战——卷积神经网络与图像识别

经典的图像识别数据集

在图像识别领域里,经典数据集包括MNIST数据集、Cifar数据集和ImageNet数据集。
在处理上述这些数据集时,全连接神经网络往往无法很好的处理图像数据。因为使用全连接神经网络处理图像的最大问题在于全连接层的参数太多。参数增多除了导致计算速度减慢,还很容易导致过拟合问题。

于是,卷积神经网络CNN应运而来。

卷积神经网络CNN

一个卷积神经网络主要由以下五种结构组成:
1. 输入层。输入层是整个神经网络的输入,在处理图像的卷积神经网络中,它一般代表了一张图片的像素矩阵。比如,三维矩阵就可以代表一张图片。其中三维矩阵的长和宽代表了图像的大小,而三维矩阵的深度代表了图像的色彩通道。比如黑白图片的深度为1,而在RGB色彩模式下,图像的深度为3.
2. 卷积层。卷积层中每一个节点的输入只是上一层神经网络的一小块,这个小块常用的大小有3 × 3或者5 × 5。卷积层试图将神经网络中的每一小块进行更加深入地分析从而得到抽象程度更高的特征。一般来说,通过卷积层处理过的节点矩阵会变得更深。
3. 池化层(Pooling)。池化层神经网络不会改变三维矩阵的深度,但是它可以缩小矩阵的大小。池化操作可以认为是将一张分辨率较高的图片转化为分辨率较低的图片。通过池化层,可以进一步缩小最后全连接层中节点的个数,从而达到减少整个神经网络中参数的目的。
4. 全连接层。在经过多轮卷积层和池化层的处理之后,在卷积神经网络的最后一般会是由1到2个全连接层来给出最后的分类结果。经过几轮卷积层和池化层的处理之后,可以认为图像中的信息已经被抽象成了信息含量更高的特征。我们可以将卷积层和池化层看成自动图像特征提取的过程。在特征提取完成之后,仍然需要使用全连接层来完成分类任务。
5. Softmax层。Softmax层主要用于分类问题。通过Softmax层,可以得到当前样例属于不同种类的概率分布情况。

卷积神经网络常用结构

卷积层

图中显示了卷积层神经网络结构中最重要的部分,这个部分被称之为过滤器filter或者内核kernel。

过滤器可以将当前层神经网络上的一个子节点矩阵转化为下一层神经网络上的一个单位节点矩阵。单位节点矩阵指的是一个长和宽都为1,但深度不限的节点矩阵。
在一个卷积层中,过滤器所处理的节点矩阵的长和宽都是由人工指定的,这个节点矩阵的尺寸也被称之为过滤器的尺寸。常用的过滤器尺寸有3×3或5×5.因为过滤器处理的矩阵深度和当前层神经网络节点矩阵的深度是一致的,所以虽然节点矩阵是三维的,但过滤器的尺寸只需要指定两个维度。过滤器中另外一个需要人工指定的设置是处理得到的单位节点矩阵的深度,这个设置称为过滤器的深度。注意过滤器的尺寸指的是一个过滤器输入节点矩阵的大小,而深度指的是输出单位节点矩阵的深度。
过滤器的前向传播过程就是通过图中左侧小矩阵中的节点计算出右侧单位矩阵中节点的过程。一个具体的样例如下:
通过过滤器将一个2×2×3的节点矩阵变化为一个1×1×5的单位节点矩阵。一个过滤器的前向传播过程和全连接层相似,它总共需要2×2×3×5+5=65个参数,其中最后的+5为偏置项参数的个数。
假设使用wx,y,zi来表示对于输出单位节点矩阵中的第i个节点,过滤器输入节点(x,y,z)的权重,使用bi表示第i个输出节点对应的偏置项参数,那么单位矩阵中的第i个节点的取值g(i)为:

g(i)=f(x=12y=12z=13ax,y,zwx,y,zi+bi)

其中ax,y,z为过滤器中节点(x,y,z)的取值,f为激活函数。

在下图中,展示了在3×3矩阵上使用2×2过滤器的卷积层前向传播过程。在这个过程中,首先将这个过滤器用于左上角子矩阵,然后移动到左下角矩阵,再到右上角矩阵,最后到右下角矩阵。过滤器每移动一次,可以计算得到一个值,将这些数值拼接成一个新的矩阵,就完成了卷积层前向传播的过程。

当过滤器的大小不为1×1时,卷积层前向传播得到的矩阵的尺寸要小于当前层矩阵的尺寸。为了避免尺寸的变化,可以在当前层矩阵的边界上加入全0填充。这样可以使得卷积层前向传播结果矩阵的大小和当前层矩阵保持一致。下图中显示了使用全0填充后卷积层前向传播过程示意图。

除了使用全0填充,还可以通过设置过滤器移动的步长来调整结果矩阵的大小。下图中显示了当移动步长为2且使用全0填充时,卷积层前向传播的结果。

下面的公式给出了在同时使用全0填充时结果矩阵的大小。

如果不使用全0填充,下面公式给出了结果矩阵的大小。

在卷积神经网络中,每一个卷积层中使用的过滤器中的参数都是一样的。这是卷积神经网络一个非常重要的性质。比如,输入层矩阵的维度是32×32×3,第一层卷积层使用尺寸为5×5,深度为16的过滤器,那么这个卷积层的参数个数为5×5×3×16+16=1216个。
共享每一个卷积层中过滤器中的参数可以巨幅减少神经网络上的参数。卷积层的参数个数要远远小于全连接层,而且卷积层的参数个数和图片的大小无关,它只和过滤器的尺寸、深度以及当前层节点矩阵的深度有关,这使得卷积神经网络可以很好的扩展到更大的图像数据上。
下面的程序实现了一个卷积层的前向传播过程

#通过tf.get_variable的方式创建过滤器的权重变量和偏置项变量。上面介绍了卷积层的参数个数只和过滤器的尺寸、深度以及当前层节点矩阵的深度有关,所以这里声明的参数变量是一个四维矩阵,前面两个维度代表了过滤器的尺寸,第三个维度表示当前层的深度,第四个维度表示过滤器的深度。
filter_weight = tf.get_variable('weights', [5, 5, 3, 16], initializer=tf.truncated_normal_initializer(stddev=0.1))
#和卷积层的权重类似,当前层矩阵上不同位置的偏置项也是共享的,所以总共有下一层深度个不同的偏置项。
biases = tf.get_variable('biases', [16], initializer=tf.constant_initializer(0.1))

#tf.nn.conv2d提供了一个非常方便的函数来实现卷积层前向传播的算法。这个函数的第一个输入为当前层的节点矩阵。注意这个矩阵是一个四维矩阵,后面三个维度对应一个节点矩阵,第一维对应一个输入batch。比如在输入层,input[0,:,:,:]表示第一张图片,input[1,:,:,:]表示第二张图片,以此类推。tf.nn.conv2d第二个参数提供了卷积层的权重,第三个参数为不同维度上的步长。虽然第三个参数提供的是一个长度为4的数组,但是第一维和最后一维的数字要求一定是1。这是因为卷积层的步长只对矩阵的长和宽有效。最后一个参数是填充的方法,TensorFlow提供了SAME或VALID两种选择,其中SAME表示添加全0填充,VALID表示不添加
conv = tf.nn.conv2d(input, filter_weight, strides=[1, 1, 1, 1], padding='SAME')
#tf.nn.bias_add提供了一个方便的函数给每一个节点加上偏置项。注意这里不能直接使用加法,因为矩阵上不同位置上的节点都需要加上同样的偏置项。
bias = tf.nn.bias_add(conv, biases)
actived_conv = tf.nn.relu(bias)#将计算结果通过ReLU激活函数完成去线性化

池化层

池化层可以非常有效的缩小矩阵的尺寸,从而减少最后全连接层中的参数。使用池化层既可以加快计算速度也有防止过拟合问题的作用。
池化层前向传播的过程也是通过移动一个类似过滤器的结构完成的。不过池化层过滤器中的计算不是节点的加权和,而是采用更加简单的最大值或者平均值运算。使用最大值操作的池化层被称之为最大池化层max pooling,这是被使用得最多的池化层结构。使用平均值操作的池化层被称之为平均池化层average pooling。
池化层的过滤器也需要人工设定过滤器的尺寸、是否使用全0填充以及过滤器移动的步长等设置。唯一的区别在于卷积层使用的过滤器是横跨整个深度的,而池化层使用的过滤器只影响一个深度上的节点。所以池化层的过滤器除了在长和宽两个维度移动之外,它还需要在深度这个维度移动。

下面的TensorFlow程序实现了最大池化层的前向传播算法

#tf.nn.max_pool实现了最大池化层的前向传播过程,它的参数和tf.nn.conv2d函数类似。ksize提供了过滤器的尺寸,strides提供了步长信息,padding提供了是否使用全0填充。
pool = tf.nn.max_pool(actived_conv, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')

在tfnn.max_pool函数中,首先需要传入当前层的节点矩阵,这个矩阵是一个四维矩阵,格式和tf.nn.conv2d函数中的第一个参数一致。第二个参数为过滤器尺寸。虽然给出的是一个长度为4的一维数组,但这个数组的第一个和最后一个数必须是1.这意味着池化层的过滤器是不可以跨不同输入样例或者节点矩阵深度的。在实际应用中使用得最多的池化层过滤器尺寸为[1,2,2,1]或者[1,3,3,1]。
TensorFlow还提供了tf.nn.avg_pool来实现平均池化层,调用格式和tf.nn.max_pool函数是一致的。

经典卷积网络模型

LeNet-5模型


第一层,卷积层
这一层的输入就是原始的图像像素,LeNet-5模型接收的输入层大小为32×32×1.第一个卷积层过滤器尺寸为5×5,深度为6,不使用全0填充,步长为1。
第二层,池化层
这一层的输入为第一层的输出,是一个28×28×6的节点矩阵。过滤器大小为2×2,长和宽的步长均为2.
第三层,卷积层
本层的输入矩阵大小为14×14×6,使用的过滤器大小为5×5,深度为16,不使用全0填充,步长为1.
第四层,池化层
本层的输入矩阵大小为10×10×16,采用的过滤器大小为2×2,步长为2.
第五层,全连接层
本层的输入矩阵大小为5×5×16,在LeNet5模型的论文中将这一层称为卷积层,但因为过滤器的大小就是5×5,所以和全连接层没有区别。
第六层,全连接层
本层的输入节点个数为120个,输出节点个数为84个。
第七层,全连接层
本层的输入节点个数为84个,输出节点个数为10个。

通过TensorFlow训练卷积神经网络的过程和第五章中介绍的训练全连接神经网络是完全一样的。唯一的区别在于因为卷积神经网络的输入层为一个三维矩阵,所以需要调整一下输入数据的格式:

x = tf.plackholder(tf.float32, [BATCH_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.NUM_CHANNELS], name='x-input')#第一维表示一个batch中样例的个数,第二维和第三维表示图片的尺寸。第四维表示图片的深度,对于RBG格式的图片,深度为5
#类似的将输入的训练数据格式调整为一个四维矩阵,并将这个调整后的数据传入sess.run过程
reshaped_xs = np.reshape(BATCH_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.NUM_CHANNELS))

调整完输入格式后,修改mnist_inference.py程序如下。

# -*- coding: utf-8 -*-
import tensorflow as tf

INPUT_NODE = 784
OUTPUT_NODE = 10
IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10
#第一层卷积层的尺寸和深度
CONV1_DEEP = 32
CONV1_SIZE = 5
#第二层卷积层的尺寸和深度
CONV2_DEPP = 64
CONV2_SIZE = 5
#全连接层的节点个数
FC_SIZE = 512
#定义卷积神经网络的前向传播过程,这里的新的参数train用于区分训练过程和测试过程。在这个程序中将用到dropout方法,dropout可以进一步提升模型可靠性并且防止过拟合,dropout过程只在训练时使用。
def inference(input_tensor, train, regularizer):
    with tf.variable_scope('layer1-conv1'):
        conv1_weights = tf.get_variable("weight", [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP], initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv1_biases = tf.get_variable("bias", [CONV1_DEEP], initializer=tf.constant_initializer(0.0))
        conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))

    with tf.name_scope('layer2-pool1'):
        pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    with tf.variable_scope('layer3-conv2'):
        conv2_weights = tf.get_variable("weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP], initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv2_biases = tf.get_variable("bias", [CONV2_DEEP], initializer=tf.constant_initializer(0.0))
        conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding="SAME")
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, covn2_biases)

    with  tf.name_scope('layer4-pool2'):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    #将第四层池化层的输出转化为第五层全连接层的输入格式。第四层的输出为7×7×64的矩阵,然而第五层全连接层需要的输入格式为向量,所以在这里需要将这个7×7×64的矩阵拉直成一个向量。pool2.get_shape函数可以得到第四层输出矩阵的维度而不需要手工计算。注意因为每一层神经网络的输入输出都为一个batch的矩阵,所以这里得到的维度也包含了一个batch中数据的个数。
    pool_shape = pool2.get_shape().as_list()#把得到的维度变成列表形式
    #计算将矩阵拉直成向量之后的长度,这个长度就是矩阵长宽及深度的乘积,注意这里的pool_shape[0]为一个batch中数据的个数
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    #通过tf.reshape函数将第四层的输出变成一个batch的向量
    reshaped = tf.reshape(pool2, [pool_shape[0], nodes])
    #接下来是第五层全连接层的变量并实现前向传播过程。这一层和之前全连接网络基本一致,唯一的区别就是引入了dropout概念。dropout在训练时会随机将部分节点的输出改为0,可以避免过拟合问题,从而使得模型在测试数据上的效果更好。dropout一般只在全连接层而不是卷积层或者池化层使用。
    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable("weight", [nodes, FC_SIZE], initializer=tf.truncated_normal_initializer(stddev=0.1))
        #只有全连接层的权重需要加入正则化
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc1_weights))
        fc1_biases = tf.get_variable("bias", [FC_SIZE], initializer=tf.constant_initializer(0.1))
        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
        if train:
            fc1 = tf.nn.dropout(tc1, 0.5)

    with tf.variable_scope('layer6-fc2'):
        fc2_weights = tf.get_variable("weight", [FC_SIZE, NUM_LABELS], initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable("bias", [NUM_LABELS], initializer=tf.constant_initializer(0.1))
        logit = tf.matmul(fc1, fc2_weights) + fc2_biases

    return logit

同样的,可以修改全连接网络中的mnist_eval程序的输入部分,就可以测试卷积神经网络在MNIST数据集上的正确率,最终结果大约是99.4%,比全连接的98.4%要好得多。
然而一种卷积神经网络架构不能解决所有问题,比如LeNet5模型就无法很好的处理类似ImageNet这样比较大的图像数据集,下面的正则表达式公式总结了一些经典的用于图片分类问题的卷积神经网络架构:
输入层 ->(卷积层+->池化层?)+ -> 全连接层+
卷积层+ 表示一层或者多层卷积层,大部分卷积神经网络中一般最多连续使用三层卷积层。“池化层?”表示没有或者一层池化层。池化层虽然可以起到减少参数防止过拟合问题,但是在部分论文中也发现可以直接通过调整卷积层步长来完成,所以有些卷积神经网络中没有池化层(但我目前没有找到这种)。在多轮卷积层和池化层之后,卷积神经网络在输出之前一般会经过1-2个全连接层。
在过滤器的深度上,大部分卷积神经网络都采用逐层递增的方式。池化层的配置相对简单,用的最多的是最大池化层。

2016-09-04 17:11:08 TS1130 阅读数 1913
  • 卷积神经网络与人脸识别系统实战视频教程

    卷积神经网络与人脸识别系统实战视频培训课程概况:本教程从零开始讲解人工神经网络,卷积神经网络等基础内容,然后讲解基于python如何构建一个深度学习模型,后基于CNN,利用keras构建网络结构打造一个人脸识别系统。

    2563 人正在学习 去看看 王而川
没有更多推荐了,返回首页