1. Tensorflow知识点

1.1. 张量

在Tensorflow程序中,所有的数据都是通过张量的形式来表示。从功能的角度上看,张量可以简单的理解为多维数组。
(1)占位符Placeholder
可以把占位符看作为函数的未知数。假设函数f(x)=wx,其中w是3行2列的矩阵,
w=[123456]w=\begin{bmatrix} 1 &2 \\ 3 &4 \\ 5 &6 \end{bmatrix}w=⎣⎡​135​246​⎦⎤​
那么x只要满足行数为2,列数不定的矩阵就可以了。
例如,本案例中x = tf.placeholder("float", shape=[None, 160 * 120 * 3]),输入变量的占位符是3个数的乘积57600。
(2)Variable对象
Variable类用于存储随时变化的值,创建Variable对象后,要调用tf.global_variables_initializer(),才可以使用Variable对象的值。
(3)张量基本运算
本案例用到乘法:关于矩阵(二维张量)乘法函数为matmul,例如:tf.matmul(h_pool3_flat, W_fc1)
(4)张量Reduction
TensorFlow提供了几个操作,您可以使用这些操作执行常见的数学计算,以减少张量的各种维。本案例中用到:
reduce_sum(),压缩求和,对于多维数组元素的相加,如果不指定是进行哪一维度的相加,结果是未定义的。tensorflow指定了默认行为:把所有元素全加在一起。
例如:

# 'x' is [[1, 1, 1]]
#         [1, 1, 1]]
tf.reduce_sum(x) ==> 6
tf.reduce_sum(x, 0) ==> [2, 2, 2]
tf.reduce_sum(x, 1) ==> [3, 3]

reduce_mean(), 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。
例如:

# 'x' is [[1., 1. ]]
#         [2., 2.]]
tf.reduce_mean(x) ==> 1.5
tf.reduce_mean(x, 0) ==> [1.5, 1.5]
tf.reduce_mean(x, 1) ==> [1.,  2.]

(5)其他张量函数
argmax(),tf.argmax是tensorflow用numpy的np.argmax实现的,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值,tf.argmax()函数中有个axis参数(轴),该参数能指定按照哪个维度计算。如在矩阵的结构中,axis可被设置为0或1,分别表示:0—按列计算,1—行计算。例如:tf.argmax(y_conv,1)

equal(),比较两个张量是否相等,是逐个元素进行判断,如果相等就是 True,不相等,就是 False。例如:correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))

cast(),把比较结果转换为浮点型,例如:tf.cast(correct_prediction, "float")

1.2. 运行模型——会话

Tensorflow中使用会话(session)来执行定义好的运算。会话拥有并管理程序运行时的所有资源。会话使用有两种模式。
第一种模式:需要明确调用会话生成函数和关闭会话函数,手动管理所有资源。

sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
for i in range(200):batch = mnist.train.next_batch(50)if i%100 == 0:train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0})print ("step {}, training accuracy {}".format(i, train_accuracy))train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
sess.close()

注:参考mnist手写数字识别示例。

第二种模式:通过Python上下文管理器的机制,将所有的计算放到“with”的内部,自行管理所有资源。

with tf.Session() as sess:sess.run(tf.global_variables_initializer())filelist = get_data_filename('mydata')......     if i%50 == 0:train_accuracy = accuracy.eval(feed_dict={x:batch_x, y_: batch_y, keep_prob: 1.0})print ("step {}, training accuracy {}".format(i, train_accuracy))train_step.run(feed_dict={x: batch_x, y_: batch_y, keep_prob: 0.5})

2. 卷积网络模型

2.1. 神经元概述


将上述的神经元结构抽象成数学概念,可以得到如上图所示的神经元模型。

  • 模型的输入是数据里的自变量,比如图中的x1、x2、x3。它们用圆点表示,对应着神经元里的树突。
  • 接收输入变量的是一个线性模型,在图中用正方形表示。这个线性模型对应着神经元的细胞体。对于神经元中的线性模型,用wiw_{i}wi​表示权重,用b表示截距,∑i3wixi+b\sum_{i}^{3}w_{i}x_{i} + b∑i3​wi​xi​+b
  • 接下来是一个非线性的激活函数f()f()f()(activation function),它将控制是否对外发送信号,如图中用三角形表示,对应这神经元里的轴突。在神经网络领域,常常用一个圆圈来概括地表示线性模型和激活函数。
  • 将模型的各个部分联结起来得到最后的输出f(∑i3wixi+b)f(\sum_{i}^{3}w_{i}x_{i} + b)f(∑i3​wi​xi​+b),这个值将传递给下一个神经元模型,在图中用箭头表示,对应着神经元里的突触。

在神经元模型中,非线性的激活函数是整个模型的核心。例如本案例中使用的是激活函数 ReLU。神经元模型代码如下:

# 增加第二层全连接
W_fc2 = weight_variable([512,256])
b_fc2 = bias_variable([256])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)

在深度学习中,常用的激活函数主要有:sigmoid函数,tanh函数,ReLU函数等。例如本案例使用的是ReLU函数。
nn.relu(),函数的作用是计算激活函数 ReLU,即 max(features, 0)。即将矩阵中每行的非最大值置0。例如:h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)

relu(x)=max(x,0)={x,x⩾00x&lt;0relu(x)=max(x,0)= \left\{\begin{matrix} x, &amp; x\geqslant 0\\ 0 &amp; x&lt;0 \end{matrix}\right. relu(x)=max(x,0)={x,0​x⩾0x<0​

2.2. 网络结构

卷积网络模型基于LeNet-5模型,使用3层卷积(卷积层和池化层)和3层全连接层。

序号 输入 输出
1 输入层 输入图像和标签 160×120×3(RGB图像,3个通道)
2 第一卷积层 x=[-1,120,160,3], W=[3, 3, 3, 16], strides=[1, 1, 1, 1], padding=‘SAME’ 160×120×3,3个特征(通道)
3 第一池化层 x=[-1,120,160,3], ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding=‘SAME’ 80×60×16,16个特征(通道)
4 第二卷积层 x=[-1,60,80,16], W=[3, 3, 16, 32], strides=[1, 1, 1, 1], padding=‘SAME’ 80×80×32,32个特征(通道)
5 第二池化层 x=[-1,60,80,16], ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding=‘SAME’ 40×30×32,32个特征(通道)
6 第三卷积层 x=[-1,30,40,32], W=[3, 3, 32, 64], strides=[1, 1, 1, 1], padding=‘SAME’ 40×30×32,32个特征(通道)
7 第三池化层 x=[-1,30,40,32], ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding=‘SAME’) 20×15×64,64个特征(通道)
8 第一全连接层 x=[-1,20×15×64], W=[20×15×64, 512] 512神经元
9 第二全连接层 x=[-1,512], W=[512, 256] 256神经元
10 第三全连接层 x=[-1,256], W=[256, 4] 4个输出值

损失函数,nn.softmax()
如上图所示,全连接最后输出(full3),使用了softmax损失函数,TensorFlow中,Softmax回归参数被去掉,它只是一层额外的处理层,将神经网络的输出变成了一个概率分布。
假设经过第三层(full3)全连接网络输出为y1,y2,...,yny_{1},y_{2},...,y_{n}y1​,y2​,...,yn​,那么经过Softmax回归处理之后的输出为:
softmax(y)i=yi′=eyi∑j=1neyisoftmax(y)_{i}=y_{i}^{'}=\frac{e^{y_{i}}}{\sum_{j=1}^{n}e^{y_{i}}}softmax(y)i​=yi′​=∑j=1n​eyi​eyi​​
从以上公式可以看出,损失函数的输出是概率。本案例的代码如下:
y_conv=tf.nn.softmax(tf.matmul(h_fc2_drop, W_fc3) + b_fc3,name='y_conv')

交叉熵
假设p代表正确答案,q代表预测值,交叉熵用来描述两个概率分布的距离,也就是说交叉熵值越小,两个概率分布越接近,表示为:H=∑i=1nyilog(yi′)H=\sum_{i=1}^{n}y_{i}log(y^{'}_{i})H=∑i=1n​yi​log(yi′​),其中yiy_{i}yi​为真实值,yi′y^{'}_{i}yi′​为预测值。例如本案例中的代码如下:
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))

2.3. 卷积及网络操作

(1)卷积操作

设矩形图像尺寸为W×H,卷积核的尺寸为FxF,步幅为S,图像深度(通道数)为C,Padding使用P,则卷积后输出图像大小:
W1=W0−F+2PS+1W_{1} = \frac{W_{0} - F + 2P}{S} + 1W1​=SW0​−F+2P​+1,H1=H0−F+2PS+1H_{1} = \frac{H_{0} - F + 2P}{S} + 1H1​=SH0​−F+2P​+1

注意:Padding的作用用于解决图像边缘信息损失的问题。
本文案例中,卷积核尺寸为3x3,S(步长)= 1 。

如卷积核为3时 padding 选择1
如卷积核为5时 padding 选择2
如卷积核为7时 padding 选择3

(2)池化操作

设输入图像尺寸为WxH,其中W为图像宽,H为图像高,D:图像深度(通道数),卷积核的尺寸为FxF,S为步长,则池化后输出图像大小:
W1=W0−F+S+1W_{1} = \frac{W_{0} - F +}{S} + 1W1​=SW0​−F+​+1,H1=H0−FS+1H_{1} = \frac{H_{0} - F}{S} + 1H1​=SH0​−F​+1

注:本文案例中,卷积核尺寸为2x2,S(步长)= 2。

3. 模型训练

随着工业互联网高速发展,工业大数据人工智能应运而生,通过探索,发现工业生产中,大量物联网数据形成的工况监控图,存在人工识别标准不统一、学习周期长等情况,先前所开发的极限值、趋势对比等监控软件效果差,需要人工智能技术来提高识别效率和准确率。

3.1. 输入数据

输入是石油工业采油生产工况——示功图,来自物联网采集数据所绘制的示功图。本次实验采用部分数据,分类如下:0-正常,1- 抽油杆断,2- 供液不足,3- 气影响。

3.2. 训练参数

学习率设置为1e-4,batch_size为50。

每个分类样本数为1000,学习率分别是1e-4、5e-5情况下,batch size分别是50、100的情况下,测试准确率接近80%。如果增加样本,优化模型和学习算法,很容易达到90%以上。

3.3. 训练结果

import tensorflow as tf
import cv2
import os
import numpy as np# 创建大量的权重和偏置项。这个模型中的权重在初始化时应该加入少量的噪声来打破对称性以及避免0梯度。
def weight_variable(shape):initial = tf.truncated_normal(shape, stddev=0.01)return tf.Variable(initial)def bias_variable(shape):initial = tf.constant(0.01, shape=shape)return tf.Variable(initial)
# 卷积使用1步长(stride size),0边距(padding size)的模板,保证输出和输入是同一个大小。
# 我们的池化用简单传统的2x2大小的模板做max pooling。为了代码更简洁,我们把这部分抽象成一个函数。
def conv2d(x, W):return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x):return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')batch_size = 10
learning_rate=1e-5 #学习率
#占位符,通过为输入图像和目标输出类别创建节点,来开始构建计算图。
x = tf.placeholder("float", shape=[None, 160 * 120 * 3]) #图片像素160*120
y_ = tf.placeholder("float", shape=[None, 4])
# 输入图片x是一个2维的浮点数张量。这里,分配给它的shape为[None, 160 * 120 * 3],其中160 * 120 * 3是一张展平的图片的维度。
# None表示其值大小不定,在这里作为第一个维度值,用以指代batch的大小,意即x的数量不定。
# 输出类别值y_也是一个2维张量,其中每一行为一个4维的one-hot向量,用于代表对应某一图片的类别。# 第一层卷积,由一个卷积接一个max pooling完成。
# 卷积在每个3x3的patch中算出16个特征。卷积的权重张量形状是[3, 3, 3, 16],前两个维度是patch的大小,接着是输入的通道数目,最后是输出的通道数目。
#  而对于每一个输出通道都有一个对应的偏置量。
W_conv1 = weight_variable([3, 3, 3, 16])
b_conv1 = bias_variable([16])# 把x变成一个4d向量,其第2、第3维对应图片的宽、高,最后一维代表图片的颜色通道数(因为是rgb彩色所以这里是3,如果是灰度图这里的通道数为1)
x_image = tf.reshape(x, [-1,120,160,3])# 把x_image和权值向量进行卷积,加上偏置项,然后应用ReLU激活函数,最后进行max pooling。
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)# 为了构建一个更深的网络,我们会把几个类似的层堆叠起来。第二层中,每个3x3的patch会得到32个特征。
W_conv2 = weight_variable([3, 3, 16, 32])
b_conv2 = bias_variable([32])h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)#第三层卷积
W_conv3 = weight_variable([3, 3, 32, 64])
b_conv3 = bias_variable([64])h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)
h_pool3 = max_pool_2x2(h_conv3)# 现在,图片尺寸减小到15x20,我们加入一个有512个神经元的全连接层,用于处理整个图片。
# 我们把池化层输出的张量reshape成一些向量,乘上权重矩阵,加上偏置,然后对其使用ReLU。
W_fc1 = weight_variable([15 * 20 * 64, 512])
b_fc1 = bias_variable([512]) h_pool3_flat = tf.reshape(h_pool3, [-1, 15*20*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1)# Dropout,为了减少过拟合,我们在输出层之前加入dropout。
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)# 增加第二层全连接
W_fc2 = weight_variable([512,256])
b_fc2 = bias_variable([256])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)h_fc2_drop = tf.nn.dropout(h_fc2,keep_prob)'''softmax层,根据256个特征计算输出标签'''
# 输出层,我们添加一个softmax层,就像前面的单层softmax regression一样。
W_fc3 = weight_variable([256, 4])
b_fc3 = bias_variable([4])y_conv=tf.nn.softmax(tf.matmul(h_fc2_drop, W_fc3) + b_fc3,name='y_conv')  # softmax层,计算输出标签cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
# 使用TensorFlow内置的交叉熵函数避免出现权重消失问题
#cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y_, logits=y_conv))
# tf.reduce_sum :计算tensor指定轴方向上的所有元素的累加和;
# tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))saver = tf.train.Saver()  #定义saverwith tf.Session() as sess:sess.run(tf.global_variables_initializer())print("开始训练!")filelist = get_data_filename('mydata')lenth = len(filelist)k = 0for i in range(int(lenth/3)):# 每个batch为50组数据,梯度下降batch_x,batch_y = get_batch(filelist,k*batch_size,batch_size)k +=1if k*batch_size>=lenth:k = 0 if i%50 == 0:train_accuracy = accuracy.eval(feed_dict={x:batch_x, y_: batch_y, keep_prob: 1.0})print ("step {}, training accuracy {}".format(i, train_accuracy))train_step.run(feed_dict={x: batch_x, y_: batch_y, keep_prob: 0.5})saver.save(sess, 'D:/06Study/Workspace/Python/Machine Learning/SAVE/model.ckpt') #模型储存位置print("开始测试!")filelist = get_data_filename('testdata')lenth = int(len(filelist)/100)for i in range(lenth):x_test_batch,y_test_batch  = get_batch(filelist,i*100,100)print ("test accuracy {}".format(accuracy.eval(feed_dict={x: x_test_batch, y_: y_test_batch, keep_prob: 1.0})))

代码中提到的“get_batch”函数,是需要自行收集图片,组织数据,本文不提供数据。可以参考[2]中人脸数据。关于模型的使用、数据的准备、集成模型等内容,后续再总结。
由于作者水平有限,初入人工智能,欢迎一起讨论、指导。

参考:

[1]《面向机器学习专家的 MNIST 高级教程》 Tensorflow中文社区
[2]《TensorFlow CNN卷积神经网络实现人脸性别检测》 Github, linzhong 2018.12
[3]《使用Python Matplotlib绘制用于CNN训练图片的方法及实践》 CSDN博客, 肖永威 2019.03
[4]《Windows10(64bit)环境下Python3 + Tensorflow安装》 CSDN博客, 肖永威 2018.08
[5]《使用Python Matplotlib绘图并输出图像到文件中的实践》 CSDN博客, 肖永威 2018.04
[6]《Tensorflow卷积神经网络(CNN)手写数字识别示例学习》 CSDN博客, 一颗贪婪的星 2018.05
[7]《TensorFlow实战Google深度学习框架》(第2版)电子工业出版社 郑泽宇 梁博文 顾思宇 著 2018.02
[8]《图解深度学习与神经网络》 电子工业出版社 张平 编著 2018.10
[9]《图像卷积和池化操作后的特征图大小计算方法》 CSDN博客, ZJE_ANDY 2018.12
[10]《神经网络(一):神经元模型与逻辑回归》 简书 tgbaggio 2018.09
[11]《使用Python科学计算包搭建CNN算法实践(1》 CSDN博客, 肖永威 2018.05

TensorFlow CNN卷积神经网络实现工况图分类识别(一)相关推荐

  1. 深度学习之CNN卷积神经网络详解以及猫狗识别实战

    文章目录 CNN 解决了什么问题? 需要处理的数据量太大 图像简单数字化无法保留图像特征 CNN核心思想 局部感知 参数共享 卷积神经网络-CNN 的基本原理 卷积--提取特征 池化层(下采样)--数 ...

  2. (二)Tensorflow搭建卷积神经网络实现MNIST手写字体识别及预测

    1 搭建卷积神经网络 1.0 网络结构 图1.0 卷积网络结构 1.2 网络分析 序号 网络层 描述 1 卷积层 一张原始图像(28, 28, 1),batch=1,经过卷积处理,得到图像特征(28, ...

  3. Tensorflow之 CNN卷积神经网络的MNIST手写数字识别

    点击"阅读原文"直接打开[北京站 | GPU CUDA 进阶课程]报名链接 作者,周乘,华中科技大学电子与信息工程系在读. 前言 tensorflow中文社区对官方文档进行了完整翻 ...

  4. 基于CNN卷积神经网络的minst数据库手写字识别

    up目录 一.理论基础 二.核心程序 三.测试结果 一.理论基础 卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(F ...

  5. 用Keras搭建神经网络 简单模版(三)—— CNN 卷积神经网络(手写数字图片识别)...

    # -*- coding: utf-8 -*- import numpy as np np.random.seed(1337) #for reproducibility再现性 from keras.d ...

  6. python+tensorflow CNN卷积神经网络手写字体识别

    导入所需的库模块: import os import cv2 import numpy as np import tensorflow as tf2 import matplotlib.pyplot ...

  7. cnn 预测过程代码_代码实践 | CNN卷积神经网络之文本分类

    学习目录阿力阿哩哩:深度学习 | 学习目录​zhuanlan.zhihu.com 前面我们介绍了:阿力阿哩哩:一文掌握CNN卷积神经网络​zhuanlan.zhihu.com阿力阿哩哩:代码实践|全连 ...

  8. CNN卷积神经网络十二生肖识别项目(一)数据下载篇

    文章目录 前言 一.前提准备 二.代码部分 1.引入库 2.发送请求,解析数据,并保存到本地 3.全部代码 总结 前言 接触深度学习有一段时间了,我们利用CNN卷积神经网络做一个十二生肖动物图片识别的 ...

  9. 深度学习--TensorFlow(项目)识别自己的手写数字(基于CNN卷积神经网络)

    目录 基础理论 一.训练CNN卷积神经网络 1.载入数据 2.改变数据维度 3.归一化 4.独热编码 5.搭建CNN卷积神经网络 5-1.第一层:第一个卷积层 5-2.第二层:第二个卷积层 5-3.扁 ...

最新文章

  1. JDBC编程:1(使用JDBC连接数据库)
  2. 趣AI | 谁说失去手臂就不能弹琴了,有AI啊
  3. DevExpress Components16.2.6 Source Code 编译
  4. android.mk-编译文件学习(转载)
  5. 软件加密与授权管理的概念
  6. 乾颐堂安德网工认证1000问(持续更新)
  7. spoj Favorite Dice(概率dp+期望)
  8. 比对两个数据库中数据表结构异同
  9. Hyper-V 2016 系列教程49 Windows Server Backup 备份计划的新建备份、修改备份和停止备份...
  10. [Jmeter][基础]Jmeter连接IMPALA
  11. js href的用法
  12. 基于ESP32CAM实现WebSocket服务器实时点灯
  13. 树莓派PICO使用MicroPython + HX1838 接收遥控器数据 NEC解码
  14. css 圆形背景icon_CSS3 各种色彩搭配方案的圆形LOADING动效
  15. linux sub指令,数据处理指令之:SUB减操作指令
  16. LinuxC语言简单实现图片加马赛克-标准IO实现
  17. Cesium:绘制抛物线/散射线
  18. 计算机cpu的主频参数,电脑CPU的参数怎么看?原来这么简单!
  19. 如何在服务器上编辑配置文件
  20. 十六进制字符串转十进制数字

热门文章

  1. Swift 图片加水印
  2. 移动机器人平台常用传感器简介
  3. android 横向头像栏,GitHub - liushiqi0112/android-headimage-cliper: 头像上传图片裁剪,实现仿QQ、微信两种效果...
  4. (网络流)最大流复习
  5. Adobe Air ANE之Admob开发需要的依赖库
  6. java没有指针和析构所以_Java程序员学习C++之构造函数和析构函数调用的时机
  7. NUCLEO开发板 STLINK-V3E体验
  8. Python爬虫实战+数据分析+数据可视化(美团美食信息)
  9. [MTK][FAQ23389] 如何配置AUXADC检测Battery ID或检测其他sensor
  10. FPGA产生2FSK信号(1)