快捷搜索:  汽车  科技

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)学Python近八年,认识了很多大佬和朋友,感恩。作者的本意是帮助更多初学者入门,因此在github开源了所有代码,也在公众号同步更新。深知自己很菜,得拼命努力前行,编程也没有什么捷径,干就对了。希望未来能更透彻学习和撰写文章,也能在读博几年里学会真正的独立科研。同时非常感谢参考文献中的大佬们的文章和分享。代码下载地址(欢迎大家关注点赞):前一篇文章介绍什么是过拟合,并采用droput解决神经网络中过拟合的问题,以tensorflow和sklearn的load_digits为案例讲解;本篇文章详细讲解了卷积神经网络CNN原理,并通过TensorFlow编写CNN实现了MNIST分类学习案例。本专栏主要结合作者之前的博客、AI经验和"莫烦大神"的视频介绍,后面随着深入会讲解更多的Python人工智能应用。基础性文章,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作


也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大

少走了弯路,也就错过了风景,无论如何,感谢经历


更多关于Android安全的知识,可前往:https://blog.csdn.net/ananasorangey/category11955914.html

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(1)

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(2)

本篇文章转载自公众号[娜璋AI安全之家]


前一篇文章介绍什么是过拟合,并采用droput解决神经网络中过拟合的问题,以tensorflow和sklearn的load_digits为案例讲解;本篇文章详细讲解了卷积神经网络CNN原理,并通过TensorFlow编写CNN实现了MNIST分类学习案例。本专栏主要结合作者之前的博客、AI经验和"莫烦大神"的视频介绍,后面随着深入会讲解更多的Python人工智能应用。

基础性文章,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作者作为人工智能的菜鸟,希望大家能与我在这一笔一划的博客中成长起来。写了这么多年博客,尝试第一个付费专栏,但更多博客尤其基础性文章,还是会继续免费分享,但该专栏也会用心撰写,望对得起读者,共勉!

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(3)

文章目录:

  • 一.卷积神经网络原理
  • 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

一.卷积神经网络原理

1.什么是CNN

一般的神经网络在理解图片信息的时候还是有不足之处,这时卷积神经网络就成为了计算机处理图片的助推器。卷积神经网络的英文是Convolutional Neural Network,简称CNN。它通常应用于图像识别和语音识等领域,并能给出更优秀的结果,也可以应用于视频分析、机器翻译、自然语言处理、药物发现等领域。著名的阿尔法狗让计算机看懂围棋就是基于卷积神经网络的。

神经网络是由很多神经层组成,每一层神经层中存在很多神经元,这些神经元是识别事物的关键,当输入是图片时,其实就是一堆数字。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(4)

首先,卷积是什么意思呢?卷积是指不在对每个像素做处理,而是对图片区域进行处理,这种做法加强了图片的连续性,看到的是一个图形而不是一个点,也加深了神经网络对图片的理解。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(5)

卷积神经网络批量过滤器,持续不断在图片上滚动搜集信息,每一次搜索都是一小块信息,整理这一小块信息之后得到边缘信息。比如第一次得出眼睛鼻子轮廓等,再经过一次过滤,将脸部信息总结出来,再将这些信息放到全神经网络中进行训练,反复扫描最终得出的分类结果。如下图所示,猫的一张照片需要转换为数学的形式,这里采用长宽高存储,其中黑白照片的高度为1,彩色照片的高度为3(RGB)。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(6)

过滤器搜集这些信息,将得到一个更小的图片,再经过压缩增高信息嵌入到普通神经层上,最终得到分类的结果,这个过程即是卷积。Convnets是一种在空间上共享参数的神经网络,如下图所示,它将一张RGB图片进行压缩增高,得到一个很长的结果。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(7)

近几年神经网络飞速发展,其中一个很重要的原因就是CNN卷积神经网络的提出,这也是计算机视觉处理的飞跃提升。关于TensorFlow中的CNN,Google公司也出了一个非常精彩的视频教程,也推荐大家去学习。

Google官方卷积神经网络介绍视频 - 优达学城


2.CNN原理

本文主要讲解如何去应用CNN,下面我们先简单看看CNN是如何处理信息的。这里参考Google官方视频介绍,强烈推荐大家学习。

假设你有一张小猫咪的照片,如下图所示,它可以被表示为一个博饼,它有宽度(width)和高度(height),并且由于天然存在红绿蓝三色,它还拥有RGB厚度(depth),此时你的输入深度为3。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(8)

假设我们现在拿出图片的一小块,运行一个具有K个输出的小神经网络,像图中一样把输出表示为垂直的一小列。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(9)

在不改变权重的情况下,通过小神经网络滑动扫遍整个图片,就像我们拿着刷子刷墙一样水平垂直的滑动。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(10)

此时,输出端画出了另一幅图像,如下图中红色区域所示。它与之前的宽度和高度不同,更重要的是它跟之前的深度不同,而不是仅仅只有红绿蓝,现在你得到了K个颜色通道,这种操作称为——卷积。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(11)

如果你的块大小是整张图片,那它跟普通的神经网络层没有任何区别,正是由于我们使用了小块,我们有很多小块在空间中共享较少的权重。卷积不在对每个像素做处理,而是对图片区域进行处理,这种做法加强了图片的连续性,也加深了神经网络对图片的理解。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(12)

一个卷积网络是组成深度网络的基础,我们将使用数层卷积而不是数层的矩阵相乘。如下图所示,让它形成金字塔形状,金字塔底是一个非常大而浅的图片,仅包括红绿蓝,通过卷积操作逐渐挤压空间的维度,同时不断增加深度,使深度信息基本上可以表示出复杂的语义。同时,你可以在金字塔的顶端实现一个分类器,所有空间信息都被压缩成一个标识,只有把图片映射到不同类的信息保留,这就是CNN的总体思想。

上图的具体流程如下:

  • 首先,这是有一张彩色图片,它包括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通过不断压缩图片的长度和宽度,增加厚度,最终会变成了一个很厚的分类器,从而进行分类预测。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(13)

如果你想实现它,必须还要正确实现很多细节。此时,你已经接触到了块和深度的概念,块(PATCH)有时也叫做核(KERNEL),如下图所示,你堆栈的每个薄饼都被叫做特征图(Feature Map),这里把三个特性映射到K个特征图中,PATCH/KERNEL的功能是从图片中抽离一小部分进行分析,每次抽离的小部分都会变成一个长度、一个宽度、K个厚度的数列。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(14)

另一个你需要知道的概念是——步幅(STRIDE)。它是当你移动滤波器或抽离时平移的像素的数量,每一次跨多少步去抽离图片中的像素点。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(15)

如果步幅STRIDE等于1,表示每跨1个像素点抽离一次,得到的尺寸基本上和输入相同。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(16)

如果步幅STRIDE等于2,表示每次跨2个像素点抽离,意味着变为一半的尺寸。它收集到的信息就会被缩减,图片的长度和宽度被压缩了,压缩合并成更小的一块立方体。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(17)

压缩完之后再合并成一个立方体,它就是更小的一块立方体,包含了图片中的所有信息。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(18)

抽离图片信息的方式称为PADDING(填充),一般分为两种:

  • VALID PADDING: 抽出来这层比原先那层图片宽和长裁剪了一点,抽取的内容全部是图片内的。
  • SAME PADDING: 抽离出的那层与之前的图片一样的长和宽,抽取的内容部分再图片外,图片外的值用0来填充。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(19)

研究发现,卷积过程会丢失一些信息,比如现在想跨2步去抽离原始图片的重要信息,形成长宽更小的图片,该过程中可能会丢失重要的图片信息。为了解决这个问题,通过POOLING(持化)可以避免。其方法是:卷积时不再压缩长宽,尽量保证更多信息,压缩工作交给POOLING。经过图片到卷积,持化处理卷积信息,再卷积再持化,将结果传入两层全连接神经层,最终通过分类器识别猫或狗。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(20)

总结:整个CNN从下往上依次经历“图片->卷积->持化->卷积->持化->结果传入两层全连接神经层->分类器”的过程,最终实现一个CNN的分类处理。

  • IMAGE 图片
  • CONVOLUTION 图层
  • MAX POOLING 更好地保存原图片的信息
  • CONVOLUTION 图层
  • MAX POOLING 更好地保存原图片的信息
  • FULLY CONNECTED 神经网络隐藏层
  • FULLY CONNECTED 神经网络隐藏层
  • CLASSIFIER 分类器

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(21)

写到这里,CNN的基本原理讲解完毕,希望大家对CNN有一个初步的理解。同时建议大家处理神经网络时,先用一般的神经网络去训练它,如果得到的结果非常好,就没必要去使用CNN,因为CNN结构比较复杂。


二.TensorFlow实现CNN

接着我们讲解如何在TensorFlow代码中编写CNN。之前我们用一般的神经网络来预测MNIST手写数字时,其准确率能达到87.78%。但该准确率相对目前的技术来说,是非常低的,我们需要编写CNN来实现,它能提升到96%左右。

第一步,打开Anaconda,然后选择已经搭建好的“tensorflow”环境,运行Spyder。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(22)

第二步,导入扩展包。

import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data

第三步,下载数据集。
由于MNIST数据集是TensorFlow的示例数据,所以我们只需要下面一行代码,即可实现数据集的读取工作。如果数据集不存在它会在线下载,如果数据集已经被下载,它会被直接调用。

# 下载数据集 数字1到10 mnist = input_data.read_data_sets('MNIST_data' one_hot=True)

获取的数据如下图所示:

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(23)

第四步,定义compute_accuracy()函数,输出的准确度result为该函数返回的结果。
mnist分为train data(训练数据集)和test data(测试数据集),如果整个数据集拿去训练,会造成人为的误差,分好成两个独立的事件效果会更好。这里定义compute_accuracy()函数计算准确度,代码如下:

#-------------------------------定义计算准确度函数------------------------------ # 参数:预测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

接着我们需要编写定义weight、bias、conv2d、max_pool_2x2等函数。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(24)


第五步,定义权重和误差变量。

#---------------------------------定义权重和误差变量------------------------------ # 输入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')

抽离图片信息的方式成为PADDING,这里使用“SAME PADDING”,抽离出的那层与之前的图片一样的长和宽。

第七步,为了防止跨度太大,丢失东西太多,这里添加了POOLING处理,减小跨度。最终得到结果的形状都一样,但它能保留更多的图片信息。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(25)

conv2d()函数和max_pool_2x2()比较类似,但是con2d阶段保留了原始长度和宽度(strides=[1 1 1 1]),而在pooling阶段减小长度和宽度(strides=[1 2 2 1])。

#------------------------------------定义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和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。

小方块的长度和宽度是5,in size为1是图片的厚度,输出的高度是32。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(26)

h_conv1输出的大小为282832,因为padding采用“SAME”的形式,W_conv1输出值为32,故厚度也为32,长度和宽度相同为28。而由于POOLING处理设置的strides步长为2,故其输出大小也有变化,其结果为141432。核心代码如下:

#-------------------------------增加神经层 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定义的patch为5*5,传入大小为32,传出大小为64,不断将其变厚,类似于下图所示。图片最早的厚度为1(MNIST数据集是黑白图片,如果是彩色则为3),接着第一层厚度变成32,第三层厚度增长为64。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(27)

此时h_conv2的输出结果为141464,第二层POOLING处理会继续缩小一半,h_pool2输出结果为7764,高度不变。

#-------------------------------增加神经层 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和func2layer。


第十一步,定义func1 layer,即第一个全连接神经层。

定义权重,输入值为conv2 layer的输出值7764,输出值为1024,让其变得更高更厚。

#-------------------------------增加神经层 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)

第十二步,进行最后一层的Layer处理。

#-------------------------------增加神经层 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

第十三步,定义误差loss和训练。
这里使用的优化器是AdamOptimizer()函数,其学习效率比GradientDescentOptimizer()更高,学习效率设置为0.0001。

# 预测值与真实值误差 平均值->求和->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))

接着运行代码,CPU基本上满负荷运转。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(28)

最终输出结果如下图所示,可以看到,最早预测的准确度结果非常低为6.78%,最后提升到了96.92%,其结果高于之前的一般神经网络的结果87.79%(第六篇博客),由此可见TensorFlow CNN的分类学习效果还不错。

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(29)

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 三.总结

写到这里,这篇文章就结束了。本文详细介绍了卷积神经网络CNN的基本原理,并通过TensorFlow实现CNN卷积神经网络,结合MNIST手写体识别数据集进行分类学习。

最后,希望这篇基础性文章对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作为人工智能的菜鸟,我希望自己能不断进步并深入,后续将它应用于图像识别、网络安全、对抗样本等领域,指导大家撰写简单的学术论文,一起加油!

读博不易,但深夜总喜欢挤时间写上一篇文章,算是对自己这么多年分享的鼓励,也希望自己能坚持,感谢家人的支持,小珞珞太可爱了。如果您也是从事Python数据分析、图像处理、人工智能、网络安全的朋友,我们可以深入探讨,尤其是做研究的同学,共同进步~

pythoncnn识别(Python人工智能九.卷积神经网络CNN原理详解及TensorFlow编写CNN)(30)

前文分享(可以点击喔):

  • 一.白话神经网络和AI概念入门普及
  • 二.TensorFlow环境搭建、学习路线及入门案例
  • 三.TensorFlow基础及一元直线预测案例
  • 四.TensorFlow基础之Session、变量、传入值和激励函数
  • 五.TensorFlow创建回归神经网络及Optimizer优化器
  • 六.Tensorboard可视化基本用法及神经网络绘制
  • 七.TensorFlow实现分类学习及MNIST手写体识别案例
  • 八.什么是过拟合及dropout解决神经网络中的过拟合问题
  • 九.卷积神经网络CNN原理详解及TensorFlow编写CNN

天行健,君子以自强不息。
地势坤,君子以厚德载物。

真诚地感谢您关注“娜璋之家”公众号,也希望我的文章能陪伴你成长,希望在技术路上不断前行。文章如果对你有帮助、有感悟,就是对我最好的回报,且看且珍惜!再次感谢您的关注,也请帮忙宣传下“娜璋之家”,初来乍到,还请多指教。

(By:Eastmount 2021-11-09 夜于东西湖)


参考文献:

  • [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官方卷积神经网络介绍视频

你以为你有很多路可以选择,其实你只有一条路可以走


猜您喜欢: