Auto Byte

专注未来出行及智能汽车科技

微信扫一扫获取更多资讯

Science AI

关注人工智能与其他前沿技术、基础学科的交叉研究与融合发展

微信扫一扫获取更多资讯

Tirmidzi Faizal Aflahi作者韩放 王淑婷编译

如何入手卷积神经网络

卷积神经网络可以算是深度神经网络中很流行的网络了。本文从基础入手,介绍了卷积网络的基本原理以及相关的其它技术,并利用卷积网络做了一个简单项目作为示例参考。想入手 CNN 的朋友不可错过~

首先,我们先看看下面这张照片:

图源:Pix2PixHD

这不是一张真实的照片,你可以新建一个窗口来打开它,放大看看,可以看到马赛克。

实际上,这张照片是由 AI 生成的,是不是看起来很真实?

从 Alex Krizhevsky 及其朋友通过 ImageNet 公布这项技术至今,不过才七年。ImageNet 是一个大规模图像识别竞赛,每年都会举办,识别种类达 1000 多种,从阿拉斯加雪橇犬到厕纸应用尽有。之后,他们又创建了 AlexNet,获得了 ImageNet 竞赛冠军,远超第二名。

这项技术就是卷积神经网络。它是深度神经网络的一个分支,处理图像的效果格外好。

图源:ImageNet

上图是几年来赢得 ImageNet 挑战赛的软件产生的误差率。可以发现,2016 年误差率降到了 5%,已经超越人类水平。

深度学习的引入与其说是改变规则,不如说是在打破规则。

卷积神经网络架构

那么问题来了,卷积神经网络到底是怎么运作的呢?

卷积神经网络之所以优于其它深度神经网络是由于它特殊的操作。相比一次只计算图像中的单个像素,CNN 将多个像素的信息组合在一起(比如上图中计算了 3*3 的像素),因此能够理解时间模式。

另外,CNN 可以「看到」一组像素组合成一条直线或者曲线。由于深度神经网络通常都是多层卷积的堆叠,通过上一层得到了直线或者曲线后,下一层不再组合像素,而是将线组合成形状,一层一层进行下去,直到形成完整的图片。

来自 Mynepalli 的深度卷积神经网络

要想深入理解 CNN,你需要学习很多基础知识,比如什么是核,什么是池化层。但是现在有很多优秀的开源项目,你可以直接在他们的基础上进行研究并加以利用。

这就引入了另一门技术——迁移学习

迁移学习

迁移学习使用训练好的深度学习模型来学习特定的任务。

举个栗子,比如你在火车调度公司工作,你们想在不增加劳动力的情况下,预测火车是否晚点。

你完全可以利用 ImageNet 上的卷积神经网络模型,比如说 2015 年的冠军 ResNet。用火车图片重新训练网络,相信我,结果不会让你失望的。

迁移学习主要有两大优势:

  • 相比于从头开始训练,只需要少量图片就可以得到很好的效果。ImageNet 竞赛提供了一百万张图片用于训练。使用迁移学习,你只需要 1000 甚至 100 张图片就可以训练出一个很好的模型,因为你的预训练模型已经在一百万张图片上训练过了。

  • 较少的训练时间就能实现良好的性能。为了得到和 ImageNet 模型同样好的效果,你可能需要训练数天,这还不包括模型效果不好时对其进行调整所需的时间。然而使用迁移学习,你可能只需要几个小时甚至几分钟就可以完成特定任务的训练,大大节省了时间。

图像分类图像生成

有了迁移学习之后大家产生了许多有趣的想法。既然我们可以处理图像、识别图像中的信息,那我们为什么不自己生成图像呢?

因吹斯汀!

生成对抗网络由此应运而生。

朱俊彦等人提出的 CycleGAN

给定某些输入,这项技术可以生成对应的图片。

如上图所示,CycleGAN 可以根据一幅画生成对应的真实照片,也可以根据草图生成背包的照片,甚至可以进行超分辨率重建。

超分辨率生成对抗网络

很神奇,对吗?

当然,你可以学习构建这些网络。但如何开始呢?

卷积神经网络教程

首先你要知道,入门很简单,但掌握就不是那么容易了。

我们先最基础的开始。

图源:Thomas Verbruggen on Unsplash

航拍仙人掌识别

这是 Kaggle 上的学习项目,你的任务是识别航拍图像中是否有柱状仙人掌。

是不是看起来非常简单?

Kaggle 提供了 17500 张图片,其中 4000 张未标注的作为测试集。如果你的模型能够正确标注 4000 张图片,就会得满分 1 或者 100%。

我找了好久,终于找到下面这个非常适合新手入门的项目。

仙人掌

这张图像与上面的类似。它大小为 32*32,其中包含或者不包含柱状仙人掌。因为是航拍图片所以包含各种不同角度。

所以你需要什么呢?

用 python 构建卷积神经网络

是的,Python——深度学习领域最受欢迎的语言。至于深度学习框架,你有很多种选择,可以自己逐一尝试:

  1. Tensorflow,最受欢迎的深度学习框架,由谷歌工程师构建,并且拥有最多的贡献者和粉丝。由于社群比较庞大,当你有问题时可以很容易找到解决方案。它们的高阶 API keras,在入门者中很受欢迎。

  2. Pytorch,我最喜欢的深度学习框架。纯 Python 实现,因此继承了 Python 的各种优缺点。Python 开发者会很容易上手。它还有 FastAI 库提供抽象,就像 Keras 之于 Tensorflow。

  3. MXNet,Apache 开发的深度学习框架。

  4. Theano,Tensorflow 的前身。

  5. CNTK,微软开发的深度学习框架。

这篇教程中使用的就是我最喜欢的 Pytorch,并且使用 FastAI。

开始之前,你需要安装 Python。浏览 Python 的官网,下载你需要的版本。需要确保的是一定要用 3.6+的版本,否则将不支持你需要用到的一些库。

现在,打开你的命令行或者终端,安装下面这些库:

pip install numpy 
pip install pandas 
pip install jupyter

Numpy 用于存储输入图像,pandas 用于处理 CSV 文件,Jupyter notebook 用于编码。

然后,去 Pytorch 官网下载需要的版本,并且如果你想加速训练的话,要安装 CUDA 版本的 Pytorch,并且版本至少是 1.0 以上。

上面这些搞定之后,安装 torchvision 和 FastAI:

pip install torchvision 
pip install fastai

运行 Jupyter notebook 命令,打开 Jupyter,它将打开一个浏览器窗口。

这样所需环境就配置好了,我们开始吧。

准备数据

导入需要的代码:

import numpy as np
import pandas as pd 
from pathlib import Path 
from fastai import * 
from fastai.vision import * 
import torch 
%matplotlib inline

Numpy 和 Pandas 基本是做什么任务都会需要的。FastAI 和 Torch 是你的深度学习库。Matplotlib Inline 用于显示图表。

下面就可以从 Kaggle 竞赛官网上下载数据了。

解压 zip 文件,并放置于 Jupyter notebook 文件夹中。

假设你的 notebook 被命名为 Cacti。你的文件夹结构会是下面这样:

Train 文件夹里包含所有的训练图片。

Test 文件夹是用于提交的测试图片。

Train CSV 文档里包含训练数据的信息,将图片名与列 has_cactus 映射,如果该列有 cactus,则值为 1,否则为 0。

Sample Submission CSV 中是提交所需的格式。文件名和 Test 文件夹中的图片相对应。

train_df = pd.read_csv("train.csv")

将 Train CSV 文档加载到数据帧中。

data_folder = Path(".") 
train_images = ImageList.from_df(train_df, path=data_folder, folder='train')

利用 ImageList from_df 方法创建加载生成器,以便将 train_df 数据帧和 train 文件夹中的图像进行映射

数据增强

这是一种根据现有数据创建更多数据的技术。一张猫的图片水平翻转之后仍然是猫的图片。但通过这样做,你可以把你的数据扩增至两倍、四倍甚至 16 倍。

如果你数据量比较少,可以尝试这种方法。

transformations = get_transforms(do_flip=True, flip_vert=True, max_rotate=10.0, max_zoom=1.1, max_lighting=0.2, max_warp=0.2, p_affine=0.75, p_lighting=0.75)

FastAI 提供了 get_transform 函数来做这些事情。你可以水平翻转、垂直翻转、旋转、放大、提高光度/亮度或者加仿射变换来增强数据。

你可以用我上边提供的参数试一下图片会变成什么样。或者你可以详细阅读官方文档。

然后,对你的图像序列做上述预处理。

train_img = train_img.transform(transformations, size=128)

参数大小将用于放大或缩小输入,以匹配你将使用的神经网络。我所用的网络是 DenseNet——ImageNet 2017 最佳论文奖的成果,它要输入的图像大小为 128*128。

准备训练

读取数据之后,就到了深度学习最关键的一步——训练。这个过程也是深度学习中学习的由来。网络从你的数据中学习并且依据学习到的结果调整自身参数,直到在数据上得到比较好的效果。

test_df = pd.read_csv("sample_submission.csv") 
test_img = ImageList.from_df(test_df, path=data_folder, folder='test')
train_img = train_img 
          .split_by_rand_pct(0.01) 
          .label_from_df() 
          .add_test(test_img) 
          .databunch(path='.', bs=64, device=torch.device('cuda:0'))             
          .normalize(imagenet_stats)

在训练这一步,你需要把训练数据分出一小部分做验证集。你不可以用这部分数据来训练,因为它们只是用来做验证的。当你的卷积神经网络验证集上效果较好时,很有可能在测试集上也可以提交一个比较好的结果。

FastAI 提供了 split_by_rand_pct 函数,可以很方便地进行以上操作。

databunch 函数可以进行批处理。由于 GPU 内存限制,我的批大小为 64。如果你没有 GPU,忽略 device 参数这一项。

之后,由于你使用的是预训练网络,用 normalize 函数来进行图像归一化。imagenet_stats 函数会根据 ImageNet 预训练模型的训练方式归一化输入图像。

把测试数据也加入训练数据列表里,可以使稍后预测更容易,免得再进行一次预处理。记住,这些图像不能用于训练,也不可以用来做验证。这样做只是为了确保训练图片和测试图片采用了完全相同的预处理方式。

learn = cnn_learner(train_img, models.densenet161, metrics=[error_rate, accuracy])

现在数据准备工作已经做完了。现在,用 cnn_leaner 创建一个训练器。如上所述,我是采用 DenseNet 作为预训练网络的,当然你也可以选择 TorchVision 提供的其他网络。

单周期技术

现在你可以开始训练了。但是,包括卷积神经网络在内,深度学习训练的一大难题就是,如何选择正确的学习率学习率决定了进行梯度下降时更新参数减小误差的幅度。

如上图所示,大一些的学习率使训练过程更快,但更容易错过误差边界,甚至会跳出可控范围,无法收敛。然而,当使用稍微小一点的学习率时,训练过程会更慢,但不会发散。

所以,选择合适的学习率非常重要。我们要找到的是足够大却又不会使训练发散的恰当学习率

但说起来容易做起来难。

所以,一个叫 Leslie Smith 的人提出了单周期策略。

简单来说,就是先暴力查找几个不同的学习率,然后选择一个最接近最小误差但还有进步空间的。代码如下:

learn.lr_find() 
learn.recorder.plot()

你会得到如下输出:

误差最小值在 10^-1 位置,所以我们可以使用略小于这个值的学习率,比如 3*10^-2。

lr = 3e-02 
learn.fit_one_cycle(5, slice(lr))

训练几个 epoch(这里我选择 5,不太大也不太小),然后看看结果。

等等,怎么回事?!

验证集准确率达到了 100%!训练过程实际上是非常高效的,只用了六分钟时间。多么幸运!实际上,你可能需要数次迭代才能找到合适的算法。

我等不及要提交了!哈哈。下面让我们预测并提交测试集结果吧。

preds,_ = learn.get_preds(ds_type=DatasetType.Test) test_df.has_cactus = preds.numpy()[:, 0]

由于之前已经把测试图片放入训练图片列表中了,因此不需要再对测试图片做预处理。

test_df.to_csv('submission.csv', index=False)

上面这行代码会创建一个 CSV 文件,其中包含 4000 张测试图像的名称以及每张图像是否包含仙人掌的 label。

当我尝试提交时,我发现需要通过 Kaggle 核来提交 CSV,这是我之前没有注意到的。

图源:Kaggle

幸运的是,核的操作和 Jupyter notebook 非常相似。你完全可以把 notebook 里创建的东西复制粘贴过来,然后提交。

然后,Duang~完成了!

天呐!得分竟然为 0.9999,这已经非常好了。当然如果第一次尝试就得到这么好的分数,应该还有进步的空间。

所以,我调整了网络结构,又尝试了一次。

得分为 1!我做到了!!所以你也可以,实际上并不是那么困难。

(另外,这个排名是 4 月 13 号的,我的排名现在很有可能已经下降了…)

我学到了什么

这个项目很简单,你在解决任务的过程中也不会遇到什么奇怪的挑战,所以这个项目非常适合入门。

并且由于已经有很多人得满分了,我觉得主办方应该另外创建一个用于提交的测试集,难度最好更高一点。

不管怎么样,从这个项目开始基本没有什么困难。你可以马上尝试并且获得高分。

图源:Mario Mrad on Unsplash

卷积神经网络对各种不同的任务都很有效,不论是图像识别还是图像生成。现在分析图像并不像以前那么难。当然,如果你尝试的话也可以做到。

所以,选择一个好的卷积神经网络项目,准备好高质量的数据,开始吧!

原文链接:https://medium.freecodecamp.org/everything-you-need-to-know-to-master-convolutional-neural-networks-ef98ca3c7655

入门卷积神经网络迁移学习图像分类GAN数据增强
61
相关数据
Microsoft机构

微软是美国一家跨国计算机科技公司,以研发、制造、授权和提供广泛的计算机软件服务为主。总部位于美国华盛顿州的雷德蒙德,最为著名和畅销的产品为Microsoft Windows操作系统和Microsoft Office办公室软件,以及Xbox的游戏业务。微软是美国《财富》杂志2015年评选的世界500强企业排行榜中的第95名。

https://www.microsoft.com/en-us/about
朱俊彦人物

MIT电气工程与计算机科学系计算机科学与人工智能实验室博士后。研究重点:计算机视觉、计算机图形学、机器学习。CycleGAN的作者,曾获得ACM SIGGRAPH 2018最佳博士论文奖。

深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

调度技术

调度在计算机中是分配工作所需资源的方法。资源可以指虚拟的计算资源,如线程、进程或数据流;也可以指硬件资源,如处理器、网络连接或扩展卡。 进行调度工作的程序叫做调度器。调度器通常的实现使得所有计算资源都处于忙碌状态,允许多位用户有效地同时共享系统资源,或达到指定的服务质量。 see planning for more details

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

学习率技术

在使用不同优化器(例如随机梯度下降,Adam)神经网络相关训练中,学习速率作为一个超参数控制了权重更新的幅度,以及训练的速度和精度。学习速率太大容易导致目标(代价)函数波动较大从而难以找到最优,而弱学习速率设置太小,则会导致收敛过慢耗时太长

验证集技术

验证数据集是用于调整分类器超参数(即模型结构)的一组数据集,它有时也被称为开发集(dev set)。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

梯度下降技术

梯度下降是用于查找函数最小值的一阶迭代优化算法。 要使用梯度下降找到函数的局部最小值,可以采用与当前点的函数梯度(或近似梯度)的负值成比例的步骤。 如果采取的步骤与梯度的正值成比例,则接近该函数的局部最大值,被称为梯度上升。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

准确率技术

分类模型的正确预测所占的比例。在多类别分类中,准确率的定义为:正确的预测数/样本总数。 在二元分类中,准确率的定义为:(真正例数+真负例数)/样本总数

映射技术

映射指的是具有某种特殊结构的函数,或泛指类函数思想的范畴论中的态射。 逻辑和图论中也有一些不太常规的用法。其数学定义为:两个非空集合A与B间存在着对应关系f,而且对于A中的每一个元素x,B中总有有唯一的一个元素y与它对应,就这种对应为从A到B的映射,记作f:A→B。其中,y称为元素x在映射f下的象,记作:y=f(x)。x称为y关于映射f的原象*。*集合A中所有元素的象的集合称为映射f的值域,记作f(A)。同样的,在机器学习中,映射就是输入与输出之间的对应关系。

迁移学习技术

迁移学习是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都是为了解决单个任务而设计的,但是促进迁移学习的算法的开发是机器学习社区持续关注的话题。 迁移学习对人类来说很常见,例如,我们可能会发现学习识别苹果可能有助于识别梨,或者学习弹奏电子琴可能有助于学习钢琴。

图像生成技术

图像生成(合成)是从现有数据集生成新图像的任务。

MXNet技术

MXNet是开源的,用来训练部署深层神经网络的深度学习框架。它是可扩展的,允许快速模型训练,并灵活支持多种语言(C ++,Python,Julia,Matlab,JavaScript, Go,R,Scala,Perl,Wolfram语言)

CycleGAN技术

GAN的一个变种

生成对抗网络技术

生成对抗网络是一种无监督学习方法,是一种通过用对抗网络来训练生成模型的架构。它由两个网络组成:用来拟合数据分布的生成网络G,和用来判断输入是否“真实”的判别网络D。在训练过程中,生成网络-G通过接受一个随机的噪声来尽量模仿训练集中的真实图片去“欺骗”D,而D则尽可能的分辨真实数据和生成网络的输出,从而形成两个网络的博弈过程。理想的情况下,博弈的结果会得到一个可以“以假乱真”的生成模型。

图像分类技术

图像分类,根据各自在图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法。它利用计算机对图像进行定量分析,把图像或图像中的每个像元或区域划归为若干个类别中的某一种,以代替人的视觉判读。

堆叠技术

堆叠泛化是一种用于最小化一个或多个泛化器的泛化误差率的方法。它通过推导泛化器相对于所提供的学习集的偏差来发挥其作用。这个推导的过程包括:在第二层中将第一层的原始泛化器对部分学习集的猜测进行泛化,以及尝试对学习集的剩余部分进行猜测,并且输出正确的结果。当与多个泛化器一起使用时,堆叠泛化可以被看作是一个交叉验证的复杂版本,利用比交叉验证更为复杂的策略来组合各个泛化器。当与单个泛化器一起使用时,堆叠泛化是一种用于估计(然后纠正)泛化器的错误的方法,该泛化器已经在特定学习集上进行了训练并被询问了特定问题。

深度神经网络技术

深度神经网络(DNN)是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。

Jupyter技术

Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和 markdown。 用途包括:数据清理和转换,数值模拟,统计建模,机器学习等等 。

仿射变换技术

仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。 一个对向量平移,与旋转放大缩小的仿射映射为 上式在齐次坐标上,等价于下面的式子 在分形的研究里,收缩平移仿射映射可以制造制具有自相似性的分形

推荐文章
这个好像有代码错误