TensorFlow Layers module 为容易的创建一个神经网络提供了高水平的API接口。它提供了很多方法帮助创建dense(全连接)层和卷积层,增加激活函数和应用dropout做归一化。在这个教程中,你会学到如何用layers
构建一个卷积神经网络用于识别手写体数字,基于MNIST数据集。
MNIST 数据集包括手写体数字0~9的6万个训练数据和1万个测试数据,并格式化为28*28像素单色图片。
开端
让我们先创建一个TensorFlow程序 的主框架。创建一个文件命名为:cnn_mnist.py,并书写如下代码:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
# Imports
import numpy as np
import tensorflow as tf
from tensorflow.contrib import learn
from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib
tf.logging.set_verbosity(tf.logging.INFO)
# Our application logic will be added here
if __name__ == "__main__":
tf.app.run()
阅读完这段教程,学习相应代码就能完成构建,训练和验证一个卷积神经网络,完成代码可以从这里获取
卷积神经网络介绍
卷积神经网络(CNNs)介绍是现在图片分类任务的一个理想模型。CNN通过一系列的过滤器从图片的原始像素数据上抽取和学习更高层次的特征,这些特征用于模型进行分类。CNN包含三部分:
- 卷积层(Convolutional layers):这层会应用一定数量的卷积器到图片上。对于每个子区域,该层用一套数学运算产生一个单独的值在输出特征映射中。卷积层特别的应用了一个ReLU activation function 到输出数据上用于引用非线性到模型中。
- 池化层(Pooling layers):这层下采样图片数据抽取操作,来减少特征维度以减少处理时间。池算法中最大池算法通常被使用,最大池算法抽取特征图的子区域(例如:2*2像素块)
- 全连接层(Dense (fully connected) layers):Fully Connected 也叫 Dense,因为全连接权重密度很大。其实就是个卷积核宽高等于输入数据宽高的特殊卷积层。卷积层和全连接层可以等效转换。该层用于前面卷积层和池化层的下采样进行 的特征抽取后的分类任务。这层的每个节点都被前一层的每个节点连接。
通常,一个CNN由一系列的卷积模块组成,这些模块完成每步的特征抽取。每个模块由一个卷积层和紧跟的一个池化层组成,最后一个卷积模块由一个或多个全连接层组成,完成分类任务。在CNN的最后一个全连接层对模型的的每个目标类别(模型预测的所有可能类别)都包含着一个单独的节点,这个全连接层有一个softmax激活函数用于为每个节点产生一个0-1之间的值(所有这些softmax值的总和等于1)。我们能够把softmax值对应到一个给定的图片,而这些图片都是对应每个目标类别。CNN网络示例如下:
- 想更全面的了解CNN的架构,可以看斯坦福的CNN用于视觉识别课程材料
构建CNN的MNIST分类器
让我们用下面的CNN架构构建一个模型用于对MNIST数据集图片进行分类。
1. 卷积层1:用32个 的5*5的卷积核(抽取5*5像素的子区域),使用ReLu激活函数。
2. 池化层1:用一个2*2的过滤器进行最大池化,步长为2(保证池化区域不重叠)。
3. 卷积层2:用于64个 的5*5的卷积核,使用ReLu激活函数。
4. 池化层2:再次用一个2*2的过滤器进行最大池化,步长为2
5. 全连接层1:1024个神经元节点,每个节点有0.4的的概率会正则化丢弃(每个给定的元素点在训练时有0.4的概率被丢弃,防止过拟合)。
6. 全连接层2:10个神经元节点,每一个对应一个数字目标类(0-9)
tf.layers
模块包含了创建上面三种层的方法:
- conv2d():构建一个二维的卷积层。参数有:卷积核数(filters)、卷积和尺寸、填充(padding)、激活函数。
- max_pooling2d():构建一个二维的池化层,使用最大池算法。参数有:池化核尺寸,步长。
- dense():构建一个全连接层。参数有:神经元节点数、激活函数。
上面的每一个函数都接收一个张量(tensor)作为输入,并且返回一个变换过的张量作为输出。这样能够容易的连接一层到另一层:某一层的输出作为下一层的输入。
将下面的cnn_model_fn
函数添加到cnn_mnist.py
中,这符合TensorFlow’s Estimator API期待的接口。cnn_mnist.py
将MNIST特征数据,标签集合模型模式(TRAIN, EVAL, INFER)作为参数。配置CNN网络,并且返回预测值,损失值和训练操作。
def cnn_model_fn(features, labels, mode):
"""Model function for CNN."""
# Input Layer
input_layer = tf.reshape(features, [-1, 28, 28, 1])
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
# Pooling Layer #1
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strid