今天和大家一起来看下基于TensorFlow实现CNN的代码示例,源码参见Convolutional_netWork。使用MNIST数据集进行训练和预测,下面开始代码注解。
'''
这里从源码的角度详细说明使用TensorFlow如何简单的实现卷积神经网络
使用MNIST数据集进行卷积神经网络的实现
使用MNIST数据集
数据集参见:http://yann.lecun.com/exdb/mnist/)
源码地址:
https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/convolutional_network.py
'''12345678910111213141234567891011121314
导入相关方法和模块
from __future__ import print_function
import tensorflow as tf
# 导入 MNIST 数据
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
1234567812345678
基本参数设置
# 参数设置
#学习速率(也有称为步长的)
learning_rate = 0.001
#迭代的次数
training_iters = 200000
#每个批次的数据大小(这里表示每个批次使用128张图片)
batch_size = 128
#每10次进行一次结果输出
display_step = 10
#网络相关参数
#输入数据,每个待处理图片是28*28的矩阵,可以理解为将其拉平则变为一个长度为784的数组
n_input = 784
#分类数量,最终是解决分类问题,这里分为10类,卷积神经网络也只是替代传统机器学习中特征提取的这个过程
n_classes = 10
#随机失活概率,也有叫留存率的,即在dropout层,以这个概率进行随机失活,进而减少过拟合
dropout = 0.75
123456789101112131415161718123456789101112131415161718
基本输入的占位
# 图的输入参数定义,TensorFlow中会将各个Option编排成一个DAG(有向无环图)
# 这里定义输入,可以理解为采用占位符进行站位,待实际运行时进行具体填充,这里None表示运行时指定
# [参见]tf.placeholder使用
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
#失活概率
keep_prob = tf.placeholder(tf.float32)
1234567812345678
定义卷积神经网络
# 该函数实现卷基层的定义
# 在卷积神经网络中,往往存在多层卷基层,这里将卷积的定义当初抽出来
# 实现很简单,即采用卷积核(或者理解成滤波器)W对待处理数据x进行卷积计算(理解成在图像上平移过滤,当然也会处理深度的问题)
# 在每个窗口都可以理解成进行窗口内的WX+b这样的计算(这里的X是窗口内的数据,W是卷积核)
def conv2d(x, W, b, strides=1):
#进行卷积计算,padding = 'SAME'表示处理后输出图像大小不变,如果valid则是变动的
#一般在多层卷积中,往往会控制图像大小不变,否则处理起来比较困难,每层处理都要考虑图像大小
#[参见]卷积计算
x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x, b)
#对结果进行非线性激活
#[参见]激活函数
return tf.nn.relu(x)
12345678910111213141234567891011121314
定义池化操作
# 进行池化操作,这里进行最大池化
# 池化可以达到降低数据量、利用更过的局部信息的目的
# 这里k默认为2,移动的步长是2,那么图像处理后相当于减小一半
# [参见]池化操作
def maxpool2d(x, k=2):
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME')
1234567812345678
构建卷积神经网络
# 进行卷积神经网络的构建
# 这里的网络层级关系为:卷积(Conv)->池化(Pooling)->卷积(Conv)->池化(Pooling)->全连接(包含非线性激活,FullConnect)->随机失活(Dropout)->(Class Pre)分类
def conv_net(x, weights, biases, dropout):
#可以简单理解为,将输入数据还原为28*28的矩阵
#输入x为[128,784] 经过reshape后变为 [128,28,28,1]的tensor(依次为[batchSize,width,height,channel])
x = tf.reshape(x, shape=[-1, 28, 28, 1])
#卷积层1
#卷积核为[5,5,1,32]([width,height,input_channel,out_channel])即采用5*5的卷积核,输入图像的通道是1,输出通道是32
#[128,28,28,1]的输入,采用[5,5,1,32]的filter,得到[128,28,28,32]输出
conv1 = conv2d(x, weights['wc1'], biases['bc1'])
#池化层 池化后得到[128,14,14,32]的输出
conv1 = maxpool2d(conv1, k=2)
#卷积层2
#上面的结果是32通道的,所以这里的卷积核采用[5,5,32,64],输出通道是64
#卷积计算后输出[128,14,14,64]
conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
#池化层 输出[128,7,7,64]
conv2 = maxpool2d(conv2, k=2)
# 全连接层
# reshape后数据变成[128,7*7*64]
fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
#矩阵乘法 [128,7*7*64] X [7*7*64,1024] -> [128,1024]
fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
#非线性激活,这里采用relu
fc1 = tf.nn.relu(fc1)
#失活层
#对结果进行随机失活
fc1 = tf.nn.dropout(fc1, dropout)
# 分类 实际上就是做WX+b 这个运算
#[128,1024]X[1024,10] ->[128,10] 即得到每个图片在10个分类中的得分
# 如某个图片分类结果是[0.1, 0.0, 0.01, 0.3, 0.8, 0.2, 0.1, 0.1, 0.0, 0.2],那么最大的0.8这一列表示的类别即为预测类别
out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
return out
12345678910111213141516171819202122232425262728293031323334353637383940411234567891011121314151617181920212223242526272829303132333435363738394041
权重等相关参数
weights = {
# 第一层的过滤器,采用[5,5,1,32]的filter输出通道是32
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 第二层的过滤器,输入通道是32,输出通道是64
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# 全连接层,输入数据是7*7*64,输出是1024
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 分类,权重矩阵是[1024,10],输出10个分类
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
biases = {
'bc1': tf.Variable(tf.random_normal([32])),
'bc2': tf.Variable(tf.random_normal([64])),
'bd1': tf.Variable(tf.random_normal([1024])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
宁波最好的整形医院www.iyestar.com