【最新TensorFlow1.4.0教程03】利用Eager Execution构建和训练卷积神经网络(CNN)

点击上方“专知”关注获取更多AI知识!

【导读】主题链路知识是我们专知的核心功能之一,为用户提供AI领域系统性的知识学习服务,一站式学习人工智能的知识,包含人工智能( 机器学习、自然语言处理、计算机视觉等)、大数据、编程语言、系统架构。使用请访问专知 进行主题搜索查看 - 桌面电脑访问http://www.zhuanzhi.ai, 手机端访问http://www.zhuanzhi.ai 或关注微信公众号后台回复" 专知"进入专知,搜索主题查看。随着TensorFlow 1.4 Eager Execution的出现,TensorFlow的使用出现了革命性的变化。专知为大家推出TensorFlow 1.4系列教程

教程中的代码可以在专知的Github中找到:https://github.com/ZhuanZhiCode/TensorFlow-Eager-Execution-Examples

卷积神经网络简介

卷积神经网络(Convolutional Neural Network, CNN), 最早应用在图像处理领域。从最早的mnist手写体数字识别,到ImageNet大规模图像分类比赛,再到炙手可热的自动驾驶技术,CNN在其中都起到了举足轻重的作用。

最近CNN也被成功的应用到自然语言处理领域(Natural Language Processing),并取得了引人注目的成果。我将在本文中归纳什么是CNN,并以一个简单的文本分类的例子介绍怎样将CNN应用于NLP。CNN背后的直觉知识在计算机视觉的用例里更容易被理解,因此我就先从那里开始,然后慢慢过渡到自然语言处理。

什么是卷积运算

卷积神经网络与之前讲到的常规的神经网络非常相似:它们都是由神经元组成,神经元中有具有学习能力的权重和偏差。每个神经元都得到一些输入数据,进行内积运算后再进行激活函数运算。

那么有哪些地方变化了呢?卷积神经网络的结构基于一个假设,即输入数据是二维的图像,基于该假设,我们就向结构中添加了一些特有的性质。这些特有属性使得前向传播函数实现起来更高效,并且大幅度降低了网络中参数的数量。

上图是常规的全连接网络,我们可以看到这里的输入层就是一维向量,后续的处理方式使用简单的全连接层就可以了。而卷积网络的输入要求是二维向量,这就需要向网络结构中加入一些新的特性来处理,也就是卷积操作

  • 图中绿色为一个二值图像,每个值代表一个像素(0是黑,1是白)。(更典型的是像素值为0-255的灰阶图像)

  • 图中黄色的滑动窗口叫卷积核、过滤器或者特征检测器,也是一个矩阵。

  • 将这个大小是3x3的过滤器中的每个元素(红色小字)与图像中对应位置的值相乘,然后对它们求和,得到右边粉红色特征图矩阵的第一个元素值。

在整个图像矩阵上滑动这个过滤器来得到完整的卷积特征图如下:

什么是卷积神经网络?

知道了卷积运算了吧。那CNN又是什么呢?CNN本质上就是多层卷积运算,外加对每层的输出用非线性激活函数做转换,比如用ReLU和tanh。

  • 常规的神经网络把每个输入神经元与下一层的输出神经元相连接。这种方式也被称作是全连接层。

  • 在CNN中我们不这样做,而是用输入层的卷积结果来计算输出,也就是上图中的(Convolved Feature)。

  • 这相当于是局部连接,每块局部的输入区域与输出的一个神经元相连接。对每一层应用不同的滤波器,往往是如上图所示成百上千个,然后汇总它们的结果。

  • 这里也涉及到池化层(降采样),我会在后文做解释。

  • 在训练阶段,CNN基于你想完成的任务自动学习卷积核的权重值。

  • 举个例子,在图像分类问题中,第一层CNN模型或许能学会从原始像素点检测到一些边缘线条,然后根据边缘线条在第二层检测出一些简单的形状,然后基于这些形状检测出更高级的特征,比如脸部轮廓等。最后一层是利用这些高级特征的一个分类器。

为什么要用卷积神经网络?

图像处理中,往往会将图像看成是一个或者多个二维向量,传统的神经网络采用全联接的方式,即输入层到隐藏层的神经元都是全部连接的,这样做将导致参数量巨大,使得网络训练耗时甚至难以训练,而CNN则通过局部链接、权值共享等方法避免这一困难。

  • 局部连接

对于一个1000 ×1000的输入图像而言,如果下一个隐藏层的神经元数目为10^6个,采用全连接则有1000× 1000 × 10^6 =10^12个权值参数,如此数目巨大的参数几乎难以训练;而采用局部连接,假如局部感受野是10x 10,隐藏层的每个神经元仅与图像中10 × 10的局部图像相连接,那么此时的权值参数数量为10 × 10 × 10^6 = 10^8,将直接减少4个数量级。

  • 权值共享

隐含层每个神经元都连接10 * 10个图像区域,也就是说每一个神经元存在100个连接权值参数。如果我们每个神经元这100个参数相同呢?将这10×10个权值参数共享给剩下的神经元,也就是说隐藏层中10^6个神经元的权值参数相同,那么此时不管隐藏层神经元的数目是多少,需要训练的参数就是这10 × 10个权值参数(也就是卷积核(也称滤波器)的大小)

这大概就是CNN的一个神奇之处,尽管只有这么少的参数,依旧有出色的性能。但是,这样仅提取了图像的一种特征,如果要多提取出一些特征,可以增加多个卷积核,不同的卷积核能够得到图像的不同映射下的特征,称之为Feature Map。如果有100个卷积核,最终的权值参数也仅为100 × 100 =10^4个而已。另外,偏置参数也是共享的,同一种滤波器共享一个。

利用Eager Execution构建和训练卷积神经网络(CNN)

本教程将示范如何使用Eager Execution训练LeNet来分类MNIST数据集中的手写数字图片。

MNIST数据集

MNIST由手写数字图片组成,包含0-9十种数字,常被用作测试机器学习算法性能的基准数据集。MNIST包含了一个有60000张图片的训练集和一个有10000张图片的测试集。深度学习在MNIST上可以达到99.7%的准确率。TensorFlow中直接集成了MNIST数据集,无需自己单独下载。

LeNet

LeNet是一种设计好拓扑的卷积神经网络,大致网络结构如下所示(图中一些具体参数,如卷积核数量,与LeNet有一些差别):

源码

#coding=utf-8
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import tensorflow.contrib.eager as tfe
import numpy as np
tfe.enable_eager_execution()

# 使用TensorFlow自带的MNIST数据集,第一次会自动下载,会花费一定时间
mnist = input_data.read_data_sets("/data/mnist", one_hot=True)

flat_size = 3136
num_class = 10
dim_hidden = 1024

# 展示信息的间隔
verbose_interval = 100

# 定义各种层
layer_cnn0 = tf.layers.Conv2D(32, 5, activation = tf.nn.relu) # 卷积层0
layer_pool0 = tf.layers.MaxPooling2D(2, 2) # pooling0
layer_cnn1 = tf.layers.Conv2D(64, 5, activation = tf.nn.relu) # 卷积层1
layer_pool1 = tf.layers.MaxPooling2D(2, 2) # pooling1
layer_flatten = tf.layers.Flatten() # pooling1的结果flatten
layer_fc0 = tf.layers.Dense(dim_hidden, activation = tf.nn.relu) # 全连接层0
layer_dropout = tf.layers.Dropout(0.75) # DropOut
layer_fc1 = tf.layers.Dense(num_class, activation = None) # 全连接层1


def loss(step, x, y):
   
inputs = tf.constant(x, name = "inputs")
   # 调用各种层进行前向传播
   
cnn0 = layer_cnn0(inputs)
   pool0 = layer_pool0(cnn0)
   cnn1 = layer_cnn1(pool0)
   pool1 = layer_pool1(cnn1)
   flatten = layer_flatten(pool1)
   fc0 = layer_fc0(flatten)
   dropout = layer_dropout(fc0)
   logits = layer_fc1(dropout)

   # 进行softmax,并使用cross entropy计算损失
   
loss = tf.nn.softmax_cross_entropy_with_logits(labels = y, logits = logits)
   loss = tf.reduce_mean(loss)

   # 每隔verbose_interval步显示一下损失和准确率
   
if step % verbose_interval == 0:
       
# 计算准确率
       
predict = tf.argmax(logits, 1).numpy()
       target = np.argmax(y, 1)
       accuracy = np.sum(predict == target)/len(target)

       print("step {}:\tloss = {}\taccuracy = {}".format(step, loss.numpy(), accuracy))

   return loss

optimizer = tf.train.AdamOptimizer(learning_rate = 1e-3)
batch_size = 128
# 训练1000
for step in range(1000):
   
batch_data, batch_label = mnist.train.next_batch(batch_size)
   # 原始batch_datashape[batch_size, 784],需要将其转换为[batch_size, height, weight, channel]
   
batch_data = batch_data.reshape([-1,28,28,1])
   optimizer.minimize(lambda: loss(step, batch_data, batch_label))


运行结果:

step 0: loss = 2.302757740020752   accuracy = 0.1640625
step 100:  loss = 0.17742319405078888 accuracy = 0.9609375
step 200:  loss = 0.056245774030685425    accuracy = 0.9921875
step 300:  loss = 0.11313237249851227 accuracy = 0.9609375
step 400:  loss = 0.016188189387321472    accuracy = 1.0
step 500:  loss = 0.026423435658216476    accuracy = 0.984375
step 600:  loss = 0.08073948323726654 accuracy = 0.984375
step 700:  loss = 0.0532052144408226  accuracy = 0.984375
step 800:  loss = 0.06941711902618408 accuracy = 0.9765625
step 900:  loss = 0.009956443682312965    accuracy = 0.9921875



特注:

电脑版查看体验更佳!获取TensorFlow1.4.0代码最新更新,请登录www.zhuanzhi.ai或者点击阅读原文,顶端搜索“ TensorFlow” 主题,查看获得TensorFlow最新更新代码与知识等资料!如下图所示~ 


欢迎转发到你的微信群和朋友圈,分享专业AI知识!


请加入TensorFlow学习群交流~

请扫描小助手,加入专知人工智能群,交流分享~



此外,请关注专知公众号(扫一扫最下面专知二维码,或者点击上方蓝色专知),获取更多专知荟萃知识资料全集获取,请查看:

【专知荟萃01】深度学习知识资料大全集(入门/进阶/论文/代码/数据/综述/领域专家等)(附pdf下载)

【专知荟萃02】自然语言处理NLP知识资料大全集(入门/进阶/论文/Toolkit/数据/综述/专家等)(附pdf下载)

【专知荟萃03】知识图谱KG知识资料全集(入门/进阶/论文/代码/数据/综述/专家等)(附pdf下载)

【专知荟萃04】自动问答QA知识资料全集(入门/进阶/论文/代码/数据/综述/专家等)(附pdf下载)

【专知荟萃05】聊天机器人Chatbot知识资料全集(入门/进阶/论文/软件/数据/专家等)(附pdf下载)

【教程实战】Google DeepMind David Silver《深度强化学习》公开课教程学习笔记以及实战代码完整版

【GAN货】生成对抗网络知识资料全集(论文/代码/教程/视频/文章等)

【干货】Google GAN之父Ian Goodfellow ICCV2017演讲:解读生成对抗网络的原理与应用

【AlphaGoZero核心技术】深度强化学习知识资料全集(论文/代码/教程/视频/文章等)



请扫描小助手,加入专知人工智能群,交流分享~

获取更多关于机器学习以及人工智能知识资料,请访问www.zhuanzhi.ai,  或者点击阅读原文,即可得到!

-END-

欢迎使用专知

专知,一个新的认知方式!目前聚焦在人工智能领域为AI从业者提供专业可信的知识分发服务, 包括主题定制、主题链路、搜索发现等服务,帮你又好又快找到所需知识。


使用方法>>访问www.zhuanzhi.ai, 或点击文章下方“阅读原文”即可访问专知


中国科学院自动化研究所专知团队

@2017 专知

专 · 知


关注我们的公众号,获取最新关于专知以及人工智能的资讯、技术、算法、深度干货等内容。扫一扫下方关注我们的微信公众号。

点击“阅读原文”,使用专知


展开全文
Top
微信扫码咨询专知VIP会员