文章目录:
一.卷积神经网络原理
1.什么是CNN
2.CNN原理
二.TensorFlow实现CNN
三.总结
https://github.com/eastmountyxz/
AI-for-TensorFlow
https://github.com/eastmountyxz/
AI-for-Keras
学Python近八年,认识了很多大佬和朋友,感恩。作者的本意是帮助更多初学者入门,因此在github开源了所有代码,也在公众号同步更新。深知自己很菜,得拼命努力前行,编程也没有什么捷径,干就对了。希望未来能更透彻学习和撰写文章,也能在读博几年里学会真正的独立科研。同时非常感谢参考文献中的大佬们的文章和分享。
- https://blog.csdn.net/eastmount
首先,这是有一张彩色图片,它包括RGB三原色分量,图像的长和宽为256*256,三个层面分别对应红(R)、绿(G)、蓝(B)三个图层,也可以看作像素点的厚度。
其次,CNN将图片的长度和宽度进行压缩,变成12812816的方块,压缩的方法是把图片的长度和宽度压小,从而增高厚度。
再次,继续压缩至646464,直至3232256,此时它变成了一个很厚的长条方块,我们这里称之为分类器Classifier。该分类器能够将我们的分类结果进行预测,MNIST手写体数据集预测结果是10个数字,比如[0,0,0,1,0,0,0,0,0,0]表示预测的结果是数字3,Classifier在这里就相当于这10个序列。
最后,CNN通过不断压缩图片的长度和宽度,增加厚度,最终会变成了一个很厚的分类器,从而进行分类预测。
VALID PADDING: 抽出来这层比原先那层图片宽和长裁剪了一点,抽取的内容全部是图片内的。
SAME PADDING: 抽离出的那层与之前的图片一样的长和宽,抽取的内容部分再图片外,图片外的值用0来填充。
IMAGE 图片
CONVOLUTION 图层
MAX POOLING 更好地保存原图片的信息
CONVOLUTION 图层
MAX POOLING 更好地保存原图片的信息
FULLY CONNECTED 神经网络隐藏层
FULLY CONNECTED 神经网络隐藏层
CLASSIFIER 分类器
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 下载数据集 数字1到10
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
#-------------------------------定义计算准确度函数------------------------------
# 参数:预测xs和预测ys
def compute_accuracy(v_xs, v_ys):
# 定义全局变量
global prediction
# v_xs数据填充到prediction变量中 生成预测值0到1之间的概率
y_pre = sess.run(prediction, feed_dict={xs:v_xs,keep_prob: 1})
# 比较预测最大值(y_pre)和真实最大值(v_ys)的差别 如果等于就是预测正确,否则错误
correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
# 计算正确的数量
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 输出结果为百分比 百分比越高越准确
result = sess.run(accuracy, feed_dict={xs:v_xs, ys:v_ys, keep_prob:1})
return result
#---------------------------------定义权重和误差变量------------------------------
# 输入shape返回变量定义的参数
def weight_variable(shape):
# 产生截断正态分布随机数
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
# 误差初始值定义为0.1
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
#---------------------------------定义卷积神经网络层------------------------------
# 定义二维CNN x表示输入值或图片的值 W表示权重
def conv2d(x, W):
# 输入x表示整张图片的信息 权重W strides表示步长跨度 [1,x_movement,y_movement,1]
# strides:一个长度为4的列表 第一个和最后一个元素为1 第二个为元素是水平x方向的跨度 第三个元素为垂直y方向跨度
# padding包括两种形式 VALID和SAME
return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
#------------------------------------定义POOLING---------------------------------
def max_pool_2x2(x):
# Must have strides[0] = striders[3] = 1
# x_movement和y_movement隔两个步长移动一次 从而压缩整幅图片的长和宽
return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# 设置传入的值xs和ys
xs = tf.placeholder(tf.float32, [None, 784]) #每张图片28*28=784个点
ys = tf.placeholder(tf.float32, [None, 10]) #每个样本有10个输出
# keeping probability
keep_prob = tf.placeholder(tf.float32)
# 形状修改
# xs包括了所有的图片样本 -1表示图片个数维度暂时不管(后续补充)
# 28*28表示像素点 1表示信道(该案例图片黑白为1,彩色为3)
x_image = tf.reshape(xs, [-1,28,28,1])
print(x_image.shape) #[n_samples,28,28,1]
#-------------------------------增加神经层 conv1 layer------------------------------
# 定义权重
W_conv1 = weight_variable([5,5,1,32]) #patch 5*5, input size 1, output size 32
# 定义bias
b_conv1 = bias_variable([32]) #32个长度
# 搭建CNN的第一层
# 嵌套一个relu非线性化激励处理 计算 = x_image输入*权重 + 误差
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # output size 28*28*32
# POOLING处理
h_pool1 = max_pool_2x2(h_conv1) # output size 14*14*32
#-------------------------------增加神经层 conv2 layer------------------------------
# 定义权重
W_conv2 = weight_variable([5,5,32,64]) #patch 5*5, input size 32, output size 64
# 定义bias
b_conv2 = bias_variable([64]) #64个长度
# 搭建CNN的第二层
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 14*14*64
# POOLING处理
h_pool2 = max_pool_2x2(h_conv2) # output size 7*7*64
#-------------------------------增加神经层 func1 layer------------------------------
# 定义权重 输入值为conv2 layer的输出值7*7*64 输出为1024
W_fc1 = weight_variable([7*7*64, 1024])
# 定义bias
b_fc1 = bias_variable([1024]) #1024个长度
# 将h_pool2输出值7*7*64转换为一维数据 [n_samples,7,7,64]->>[n_samples,7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) #-1表示样本数
# 乘法
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# 解决过拟合
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
#-------------------------------增加神经层 func2 layer------------------------------
# 定义权重 输入值为1024 输出为10对应10个数字
W_fc2 = weight_variable([1024, 10])
# 定义bias
b_fc2 = bias_variable([10])
# 预测 使用softmax计算概率
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
conv1 layer:经过卷积和POOLING处理,最终输出141432
conv2 layer:经过卷积和POOLING处理,最终输出7764
func1 layer:平常使用的神经网络,输入7764,最终输出1024
func2 layer:平常使用的神经网络,输入1024,最终输出10,代表10个数字,即为prediction
# 预测值与真实值误差 平均值->求和->ys*log(prediction)
cross_entropyloss = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
reduction_indices=[1])) #loss
# 训练学习 学习效率设置为0.0001
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropyloss) #减小误差
# 定义Session
sess = tf.Session()
# 初始化
init = tf.initialize_all_variables()
sess.run(init)
for i in range(1000):
# 提取一部分的xs和ys
batch_xs, batch_ys = mnist.train.next_batch(100) #从下载好的数据集提取100个样本
# 训练
sess.run(train_step, feed_dict={xs:batch_xs, ys:batch_ys})
# 每隔50步输出一次结果
if i % 50 == 0:
# 计算准确度
print(compute_accuracy(
mnist.test.images, mnist.test.labels))
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 20 14:27:01 2019
@author: xiuzhang Eastmount CSDN
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 下载数据集 数字1到10
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
#-------------------------------定义计算准确度函数------------------------------
# 参数:预测xs和预测ys
def compute_accuracy(v_xs, v_ys):
# 定义全局变量
global prediction
# v_xs数据填充到prediction变量中 生成预测值0到1之间的概率
y_pre = sess.run(prediction, feed_dict={xs:v_xs,keep_prob: 1})
# 比较预测最大值(y_pre)和真实最大值(v_ys)的差别 如果等于就是预测正确,否则错误
correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
# 计算正确的数量
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 输出结果为百分比 百分比越高越准确
result = sess.run(accuracy, feed_dict={xs:v_xs, ys:v_ys, keep_prob:1})
return result
#---------------------------------定义权重和误差变量------------------------------
# 输入shape返回变量定义的参数
def weight_variable(shape):
# 产生截断正态分布随机数
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
# 误差初始值定义为0.1
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
#---------------------------------定义卷积神经网络层------------------------------
# 定义二维CNN x表示输入值或图片的值 W表示权重
def conv2d(x, W):
# 输入x表示整张图片的信息 权重W strides表示步长跨度 [1,x_movement,y_movement,1]
# strides:一个长度为4的列表 第一个和最后一个元素为1 第二个为元素是水平x方向的跨度 第三个元素为垂直y方向跨度
# padding包括两种形式 VALID和SAME
return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
#------------------------------------定义POOLING---------------------------------
def max_pool_2x2(x):
# Must have strides[0] = striders[3] = 1
# x_movement和y_movement隔两个步长移动一次 从而压缩整幅图片的长和宽
return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
#-----------------------------定义placeholder输入至神经网络-------------------------
# 设置传入的值xs和ys
xs = tf.placeholder(tf.float32, [None, 784]) #每张图片28*28=784个点
ys = tf.placeholder(tf.float32, [None, 10]) #每个样本有10个输出
# keeping probability
keep_prob = tf.placeholder(tf.float32)
# 形状修改
# xs包括了所有的图片样本 -1表示图片个数维度暂时不管(后续补充)
# 28*28表示像素点 1表示信道(该案例图片黑白为1,彩色为3)
x_image = tf.reshape(xs, [-1,28,28,1])
print(x_image.shape) #[n_samples,28,28,1]
#-------------------------------增加神经层 conv1 layer------------------------------
# 定义权重
W_conv1 = weight_variable([5,5,1,32]) #patch 5*5, input size 1, output size 32
# 定义bias
b_conv1 = bias_variable([32]) #32个长度
# 搭建CNN的第一层
# 嵌套一个relu非线性化激励处理 计算 = x_image输入*权重 + 误差
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # output size 28*28*32
# POOLING处理
h_pool1 = max_pool_2x2(h_conv1) # output size 14*14*32
#-------------------------------增加神经层 conv2 layer------------------------------
# 定义权重
W_conv2 = weight_variable([5,5,32,64]) #patch 5*5, input size 32, output size 64
# 定义bias
b_conv2 = bias_variable([64]) #64个长度
# 搭建CNN的第二层
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 14*14*64
# POOLING处理
h_pool2 = max_pool_2x2(h_conv2) # output size 7*7*64
#-------------------------------增加神经层 func1 layer------------------------------
# 定义权重 输入值为conv2 layer的输出值7*7*64 输出为1024
W_fc1 = weight_variable([7*7*64, 1024])
# 定义bias
b_fc1 = bias_variable([1024]) #1024个长度
# 将h_pool2输出值7*7*64转换为一维数据 [n_samples,7,7,64]->>[n_samples,7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) #-1表示样本数
# 乘法
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# 解决过拟合
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
#-------------------------------增加神经层 func2 layer------------------------------
# 定义权重 输入值为1024 输出为10对应10个数字
W_fc2 = weight_variable([1024, 10])
# 定义bias
b_fc2 = bias_variable([10])
# 预测 使用softmax计算概率
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
#------------------------------定义loss和训练-------------------------------
# 预测值与真实值误差 平均值->求和->ys*log(prediction)
cross_entropyloss = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
reduction_indices=[1])) #loss
# 训练学习 学习效率设置为0.0001
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropyloss) #减小误差
#-----------------------------------初始化-----------------------------------
# 定义Session
sess = tf.Session()
# 初始化
init = tf.initialize_all_variables()
sess.run(init)
#---------------------------------神经网络学习---------------------------------
for i in range(1000):
# 提取一部分的xs和ys
batch_xs, batch_ys = mnist.train.next_batch(100) #从下载好的数据集提取100个样本
# 训练
sess.run(train_step, feed_dict={xs:batch_xs, ys:batch_ys, keep_prob:0.5})
# 每隔50步输出一次结果
if i % 50 == 0:
# 计算准确度
print(compute_accuracy(
mnist.test.images, mnist.test.labels))
0.0678
0.8096
0.8839
0.9119
0.9266
0.9361
0.9441
0.9496
0.9505
0.9561
0.9566
0.9616
0.9625
0.9644
0.9648
0.9668
0.9689
0.9698
0.9709
0.9692
天行健,君子以自强不息。
地势坤,君子以厚德载物。
[1] 神经网络和机器学习基础入门分享 - 作者的文章
[2] 斯坦福机器学习视频NG教授:https://class.coursera.org/ml/class/index
[3] 书籍《游戏开发中的人工智能》、《游戏编程中的人工智能技术》
[4] 网易云莫烦老师视频(强推 我付费支持老师一波):https://study.163.com/course/courseLearn.htm?courseId=1003209007
[5] 神经网络激励函数 - deeplearning
[6] tensorflow架构 - NoMorningstar
[7] Tensorflow实现CNN用于MNIST识别 - siucaan
[8] MNIST手写体识别任务 - chen645096127
[9] https://github.com/siucaan/CNN_MNIST
[10] https://github.com/eastmountyxz/AI-for-TensorFlow
[11] Google官方卷积神经网络介绍视频