掌握卷积神经网络,从一个简单项目开始

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

图源:Pix2PixHD
这不是一张真实的照片,你可以新建一个窗口来打开它,放大看看,可以看到马赛克。
实际上,这张照片是由 AI 生成的,是不是看起来很真实?
这项技术就是卷积神经网络。它是深度神经网络的一个分支,处理图像的效果格外好。

图源: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——深度学习领域最受欢迎的语言。至于深度学习框架,你有很多种选择,可以自己逐一尝试:

Tensorflow,最受欢迎的深度学习框架,由谷歌工程师构建,并且拥有最多的贡献者和粉丝。由于社群比较庞大,当你有问题时可以很容易找到解决方案。它们的高阶 API keras,在入门者中很受欢迎。
Pytorch,我最喜欢的深度学习框架。纯 Python 实现,因此继承了 Python 的各种优缺点。Python 开发者会很容易上手。它还有 FastAI 库提供抽象,就像 Keras 之于 Tensorflow。
MXNet,Apache 开发的深度学习框架。
Theano,Tensorflow 的前身。
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
卷积神经网络对各种不同的任务都很有效,不论是图像识别还是图像生成。现在分析图像并不像以前那么难。当然,如果你尝试的话也可以做到。
所以,选择一个好的卷积神经网络项目,准备好高质量的数据,开始吧!

原价799,现在限时只要388。
点击深度学习,助您推开AI的大门,掌握深度学习
加微:hcgx0904(备注“深度学习”),了解更多详情

原文地址:https://blog.51cto.com/14352303/2410394

时间: 2024-10-08 16:46:50

掌握卷积神经网络,从一个简单项目开始的相关文章

Windows 8.1 应用再出发 (WinJS) - 创建一个简单项目

原文:Windows 8.1 应用再出发 (WinJS) - 创建一个简单项目 前面几篇我们介绍了如何利用 C# + XAML 完成Windows Store App 功能的实现,接下来的几篇我们来看看如何利用 Html + WinJS 来完成这些功能. 本篇我们使用WinJS 来创建一个简单的项目,来看看项目的构成是怎样的,与C#,XAML 的项目有哪些异同. 首先我们在Visual Studio 2013中选择模板 -> JavaScript -> Windows 应用商店来创建一个空白应

卷积神经网络(CNN)的简单实现(MNIST)

卷积神经网络(CNN)的基础介绍见http://blog.csdn.net/fengbingchun/article/details/50529500,这里主要以代码实现为主. CNN是一个多层的神经网络,每层由多个二维平面组成,而每个平面由多个独立神经元组成. 以MNIST作为数据库,仿照LeNet-5和tiny-cnn( http://blog.csdn.net/fengbingchun/article/details/50573841 ) 设计一个简单的7层CNN结构如下: 输入层Inpu

Vue安装并创建一个简单项目

1.nodejs安装 下载地址:https://nodejs.org/en/download/ 安装完之后cmd 下输入:node -v 查看是否安装成功. 2.查看npm版本 cmd下输入命令:npm -v 如果低于3.0版本需要进行升级 升级方法: 在cmd命令下cd到nodejs安装目录,然后输入以下命令:npm update npm 这里要等待一下.更新完成后再使用:npm -v检查一下版本 3.cnpm安装 cnpm是淘宝的一个镜像,安装之后可以使用cnpm安装命令工具,安装速度会加快

SpringMVC+Hibernate框架整合,构建一个简单项目

SpringMVC:简单易用,上手快,项目配置部分很少,注重代码开发层面 Hibernate:ORM(对象关系映射,英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping)框架,轻量级的数据库封装 下面直接上项目: 1.创建Dynamic Web Project项目,命名:SpringMVC_Hibernate ? 如图,缺少web.xml文件,如下图示,加入: ? 2.导入SpringMVC相关jar包 下载地址:SpringMVC下载 ? 3.

创建一个简单项目的开发步骤

理解NLP中的卷积神经网络(CNN)

此篇文章是Denny Britz关于CNN在NLP中应用的理解,他本人也曾在Google Brain项目中参与多项关于NLP的项目. · 翻译不周到的地方请大家见谅. 阅读完本文大概需要7分钟左右的时间,如果您有收获,请点赞关注 :) 一.理解NLP中的卷积神经网络(CNN) 现在当我们听到神经网络(CNN)的时候,一般都会想到它在计算机视觉上的应用,尤其是CNN使图像分类取得了巨大突破,而且从Facebook的图像自动标注到自动驾驶汽车系统,CNN已经成为了核心. 最近,将CNN应用于NLP也

卷积神经网络(CNN)

1. 概述 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面,一方面它的神经元间的连接是非全连接的, 另一方面同一层中某些神经元之间的连接的权重是共享的(即相同的).它的非全连接和权值共享的网络结构使之更类似于生物 神经网络,降低了网络模型的复杂度(对于很难学习的深层结构来说,这是非常重要的),减少了权值的数量. 卷积网络最初是受视觉神经机制的启发而设计的,是为识别二维形状而设计的一个多层感知器,这种网络结构对平移.比例缩放.倾斜或者共他 形式的变形具有高度不变性.1962年

(转载)Convolutional Neural Networks卷积神经网络

Convolutional Neural Networks卷积神经网络 Contents 一:前导 Back Propagation反向传播算法 网络结构 学习算法 二:Convolutional Neural Networks卷积神经网络 三:LeCun的LeNet-5 四:CNNs的训练过程 五:总结 本文是我在20140822的周报,其中部分参照了以下博文或论文,如果在文中有一些没说明白的地方,可以查阅他们.对Yann LeCun前辈,和celerychen2009.zouxy09表示感谢

卷积神经网络

1. 概述 回想一下BP神经网络.BP网络每一层节点是一个线性的一维排列状态,层与层的网络节点之间是全连接的.这样设想一下,如果BP网络中层与层之间的节点连接不再是全连接,而是局部连接的.这样,就是一种最简单的一维卷积网络.如果我们把上述这个思路扩展到二维,这就是我们在大多数参考资料上看到的卷积神经网络.具体参看下图: 上图左:全连接网络.如果我们有1000x1000像素的图像,有1百万个隐层神经元,每个隐层神经元都连接图像的每一个像素点,就有1000x1000x1000000=10^12个连接