用于做网站的软件,学做网站基础知识,最近一周的时政热点新闻,网站建设成都哪家公司好文章目录 12.1 TensorFlow 12.1.1 TensorFlow 是什么 12.1.2 TensorFlow的设计理念是什么 12.1.3 TensorFlow特点有哪些 12.1.4 TensorFlow的系统架构是怎样的 12.1.5 TensorFlow编程模型是怎样的 12.1.6 如何基于TensorFlow搭建VGG16 12.1 TensorFlow
12.1.1 TensorFlow 是什…文章目录 12.1 TensorFlow 12.1.1 TensorFlow 是什么 12.1.2 TensorFlow的设计理念是什么 12.1.3 TensorFlow特点有哪些 12.1.4 TensorFlow的系统架构是怎样的 12.1.5 TensorFlow编程模型是怎样的 12.1.6 如何基于TensorFlow搭建VGG16 12.1 TensorFlow
12.1.1 TensorFlow 是什么
TensorFlow支持各种异构平台支持多CPU/GPU、服务器、移动设备具有良好的跨平台的特性TensorFlow架构灵活能够支持各种网络模型具有良好的通用性此外TensorFlow架构i具有良好的可扩展性对OP的扩展支持Kernel特化方面表现出众。
TensorFlow最初由Google大脑的研究员和工程师开发出来用于机器学习和神经网络方面的研究于2015.10宣布开源在众多深度学习框架中脱颖而出在Github上获得了最多的Star量。
12.1.2 TensorFlow的设计理念是什么
TensorFlow的设计理念主要体现在两个方面
1将图定义和图运算完全分开。TensorFlow 被认为是一个“符号主义”的库。我们知道编程模式通常分为命令式编程imperative style programming和符号式编程symbolic style 皮肉gramming。命令式编程就是编写我们理解的通常意义上的程序很容易理解和调试按照原有逻辑执行。符号式编程涉及很多的嵌入和优化不容易理解和调试但运行速度相对有所提升。现有的深度学习框架中Torch是典型的命令式的Caffe、MXNet采用了两种编程模式混合的方法而TensorFlow完全采用符号式编程。
符号式计算一般是先定义各种变量然后建立一个数据流图在数据流图中规定各个变量间的计算关系最后需要对数据流图进行编译但此时的数据流图还是一个空壳里面没有任何实际数据只有把需要运算的输入放进去后才能在整个模型中形成数据流从而形成输出值。 例如
t 8 9
print(t) 在传统的程序操作中定义了 t 的运算在运行时就执行了并输出 17。而在 TensorFlow中数据流图中的节点实际上对应的是 TensorFlow API 中的一个操作并没有真正去运行
import tensorflow as tf
t tf.add(8,9)
print(t)#输出 Tensor{Add_1:0,shape{},dtypeint32}
2TensorFlow 中涉及的运算都要放在图中而图的运行只发生在会话session中。开启会话后就可以用数据去填充节点进行运算关闭会话后就不能进行计算了。因此会话提供了操作运行和 Tensor 求值的环境。 例如
import tensorflow as tf
#创建图
a tf.constant([4.0,5.0])
b tf.constant([6.0,7.0])
c a * b
#创建会话
sess tf.Session()
#计算c
print(sess.run(c)) #进行矩阵乘法输出[24.,35.]
sess.close()12.1.3 TensorFlow特点有哪些
1. 高度的灵活性 TensorFlow并不仅仅是一个深度学习库只要可以把你的计算过程表示成一个数据流图的过程我们就可以使用TensorFlow来进行计算。TensorFlow允许我们用计算图的方式建立计算网络同时又可以很方便的对网络进行操作。用户可以基于TensorFlow的基础上用Python编写自己的上层结构和库如果TensorFlow没有提供我们需要的API的我们也可以自己编写底层的C代码通过自定义操作将新编写的功能添加到TensorFlow中。
2. 真正的移植性 TensorFlow 可以在 CPU 和 GPU 上运行可以在台式机、服务器、移动设备上运行。你想在你的笔记本上跑一下深度学习的训练或者又不想修改代码想把你的模型在多个CPU上运行 亦或想将训练好的模型放到移动设备上跑一下这些TensorFlow都可以帮你做到。
3. 多语言支持 TensorFlow采用非常易用的python来构建和执行我们的计算图同时也支持 C 的语言。我们可以直接写python和C的程序来执行TensorFlow也可以采用交互式的ipython来方便的尝试我们的想法。当然这只是一个开始后续会支持更多流行的语言比如LuaJavaScript 或者R语言。
4. 丰富的算法库 TensorFlow提供了所有开源的深度学习框架里最全的算法库并且在不断的添加新的算法库。这些算法库基本上已经满足了大部分的需求对于普通的应用基本上不用自己再去自定义实现基本的算法库了。
5. 完善的文档
TensorFlow的官方网站提供了非常详细的文档介绍内容包括各种API的使用介绍和各种基础应用的使用例子也包括一部分深度学习的基础理论。 自从宣布开源以来大量人员对TensorFlow做出贡献其中包括Google员工外部研究人员和独立程序员全球各地的工程师对TensorFlow的完善已经让TensorFlow社区变成了Github上最活跃的深度学习框架。
12.1.4 TensorFlow的系统架构是怎样的
整个系统从底层到上层可分为七层
设备层硬件计算资源支持CPU、GPU
网络层支持两种通信协议
数值计算层提供最基础的计算有线性计算、卷积计算
高维计算层数据的计算都是以数组的形式参与计算
计算图层用来设计神经网络的结构
工作流层提供轻量级的框架调用
构造层最后构造的深度学习网络可以通过TensorBoard服务端可视化
12.1.5 TensorFlow编程模型是怎样的
TensorFlow 的编程模型让向量数据在计算图里流动。那么在编程时至少有这几个过程1、构建图2、启动图3、给图输入数据并获取结果。
1. 构建图
TensorFlow 的图的类型是 tf.FGraph它包含着计算节点和tensor的集合。
这里引用了两个新概念tensor和计算节点。我们先介绍tensor一开始我们就介绍了我们需要把数据输入给启动的图才能获取计算结果。那么问题来了在构建图时用什么表示中间计算结果这个时候tensor的概念就需要引入了。类型是 tf.Tensor代表某个计算节点的输出一定要看清楚是“代表”。它主要有两个作用
1构建不同计算节点直接的数据流
2在启动图时可以设置某些tensor的值然后获取指定tensor的值。这样就完成了计算的输入输出功能。
如下代码所示
inImage tf.placeholder(tf.float32,[32,32,3],inputImage)
processedImage tf.image.per_image_standardization(inImage,processedImage) 这里inImage和processedImage都是tensor类型。它们代表着计算节点输出的数据数据的值具体是多少在启动图的时候才知道。上面两个方法调用都传递了一个字符串它是计算节点的名字最好给节点命名这样我们可以在图上调用get_tensor_by_name(name)获取对应的tensor对象十分方便。tensor名字为“计算节点名字:tensor索引” 创建tensor时需要指定类型和shape。对不同tensor进行计算时要求类型相同可以使用 tf.cast 进行类型转换。同时也要求 shape (向量维度)满足运算的条件我们可以使用 tf.reshape 改变shape。 现在了解计算节点的概念其功能是对tensor进行计算、创建tensor或进行其他操作类型是tf.Operation。获取节点对象的方法为get_operation_by_name(name)。
构建图如下代码
gtf.Graph()with g.as_default():input_datatf.placeholder(tf.float32,[None,2],input_data)input_labeltf.placeholder(tf.float32,[None,2],input_label)W1tf.Variable(tf.truncated_normal([2,2]),nameW1)B1tf.Variable(tf.zeros([2]),nameB1)outputtf.add(tf.matmul(input_data,W1),B1,nameoutput)cross_entropytf.nn.softmax_cross_entropy_with_logits(logitsoutput,labelsinput_label)train_steptf.train.AdamOptimizer().minimize(cross_entropy,nametrain_step)initertf.global_variables_initializer()
上面的代码中我们创建了一个图并在上面添加了很多节点。我们可以通过调用get_default_graph()获取默认的图。 Input_datainput_labelW1B1outputcross_entropy都是tensor类型train_stepiniter是节点类型。
有几类tensor或节点比较重要下面介绍一下
1placeholder
Tensorflow顾名思义 tensor代表张量数据flow代表流其最初的设计理念就是构建一张静态的数据流图。图是有各个计算节点连接而成计算节点之间流动的便是中间的张量数据。要想让张量数据在我们构建的静态计算图中流动起来就必须有最初的输入数据流。而placeholder翻译过来叫做占位符顾名思义是给我们的输入数据提供一个接口也就是说我们的一切输入数据例如训练样本数据超参数数据等都可以通过占位符接口输送到数据流图之中。使用实例如下代码
import tensorflow as tf
x tf.placeholder(dtypetf.float32,shape[],namex)
y tf.placeholder(dtpetf.float32,shape[],nmaey)
z x*y
with tf.Session() as sess:prod sess.run(z,feed_dict{x:1.,y:5.2})print(prod)
[out]:5.2
2variable
无论是传统的机器学习算法例如线性支持向量机Support Vector Machine, SVM)其数学模型为y w,x b还是更先进的深度学习算法例如卷积神经网络Convolutional Neural Network CNN单个神经元输出的模型y w*x b。可以看到w和b就是我们要求的模型模型的求解是通过优化算法对于SVM使用 SMO[1]算法对于CNN一般基于梯度下降法来一步一步更新w和b的值直到满足停止条件。因此大多数机器学习的模型中的w和b实际上是以变量的形式出现在代码中的这就要求我们在代码中定义模型变量。
import tensorflow as tf
a tf.Variable(2.)
b tf.Variable(3.)
with tf.Session() as sess:sess.run(tf.global_variables_initializer()) #变量初始化print(sess.run(a*b))
[out]:6.
[1] Platt, John. Sequential minimal optimization: A fast algorithm for training support vector machines. (1998).
3initializer
由于tensorflow构建的是静态的计算流图在开启会话之前所有的操作都不会被执行。因此为了执行在计算图中所构建的赋值初始化计算节点需要在开启会话之后在会话环境下运行初始化。如果计算图中定义了变量而会话环境下为执行初始化命令则程序报错代码如下
import tensorflow as tf
a tf.Variable(2.)
b tf.Variable(3.)
with tf.Session() as sess:#sess.run(tf.global_variables_initializer()) #注释掉初始化命令print(sess.run(a*b))
[Error]: Attempting to use uninitialized value Variable
2. 启动图
先了解session的概念然后才能更好的理解图的启动。 图的每个运行实例都必须在一个session里session为图的运行提供环境。Session的类型是tf.Session在实例化session对象时我们需要给它传递一个图对象如果不显示给出将使用默认的图。Session有一个graph属性我们可以通过它获取session对应的图。
代码如下
numOfBatch5
datasnp.zeros([numOfBatch,2],np.float32)
labelsnp.zeros([numOfBatch,2],np.float32)sesstf.Session(graphg)
graphsess.graph
sess.run([graph.get_operation_by_name(initer)])dataHoldergraph.get_tensor_by_name(input_data:0)
labelHoldergraph.get_tensor_by_name(input_label:0)
traingraph.get_operation_by_name(train_step)
outgraph.get_tensor_by_name(output:0)for i inrange(200):resultsess.run([out,train],feed_dict{dataHolder:datas,labelHolder:labels})if i%1000:saver.save(sess,./moules)sess.close()
代码都比较简单就不介绍了。不过要注意2点1.别忘记运行初始化节点2.别忘记close掉session对象以释放资源。
3. 给图输入数据并获取结果
代码
for i inrange(200):resultsess.run([out,train],feed_dict{dataHolder:datas,labelHolder:labels}) 这里主要用到了session对象的run方法它用来运行某个节点或tensor并获取对应的值。我们一般会一次传递一小部分数据进行mini-batch梯度下降来优化模型。 我们需要把我们需要运行的节点或tensor放入一个列表然后作为第一个参数(不考虑self)传递给run方法run方法会返回一个计算结果的列表与我们传递的参数一一对应。 如果我们运行的节点依赖某个placeholder那我们必须给这个placeholder指定值怎么指定代码里面很清楚给关键字参数feed_dict传递一个字典即可字典里的元素的key是placeholder对象value是我们指定的值。值的数据的类型必须和placeholder一致包括shape。值本身的类型是numpy数组。
这里再解释一个细节在定义placeholder时代码如下
input_datatf.placeholder(tf.float32,[None,2],input_data)
input_labeltf.placeholder(tf.float32,[None,2],input_label)shape为[None,2]说明数据第一个维度是不确定的然后TensorFlow会根据我们传递的数据动态推断第一个维度这样我们就可以在运行时改变batch的大小。比如一个数据是2维一次传递10个数据对应的tensor的shape就是[10,2]。可不可以把多个维度指定为None理论上不可以
12.1.6 如何基于TensorFlow搭建VGG16
介绍完关于tensorflow的基础知识是时候来一波网络搭建实战了。虽然网上有很多相关教程但我想从最标准的tensorflow代码和语法出发而不是调用更高级的API失去了原来的味道向大家展示如何搭建其标准的VGG16网络架构。话不多说上代码
import numpy as np
import tensorflow as tfdef get_weight_variable(shape):return tf.get_variable(weight, shapeshape, initializertf.truncated_normal_initializer(stddev0.1))def get_bias_variable(shape):return tf.get_variable(bias, shapeshape, initializertf.constant_initializer(0))def conv2d(x, w, padding SAME, s1):x tf.nn.conv2d(x, w, strides[1, s, s, 1], padding padding)return xdef maxPoolLayer(x):return tf.nn.max_pool(x, ksize [1, 2, 2, 1],strides [1, 2, 2, 1], padding SAME)def conv2d_layer(x,in_chs, out_chs, ksize, layer_name):with tf.variable_scope(layer_name):w get_weight_variable([ksize, ksize, in_chs, out_chs])b get_bias_variable([out_chs])y tf.nn.relu(tf.bias_add(conv2d(x,w,padding SAME, s1), b))return ydef fc_layer(x,in_kernels, out_kernels, layer_name):with tf.variable_scope(layer_name):w get_weight_variable([in_kernels,out_kernels])b get_bias_variable([out_kernels])y tf.nn.relu(tf.bias_add(tf.matmul(x,w),b))return ydef VGG16(x):conv1_1 conv2d_layer(x,tf.get_shape(x).as_list()[-1], 64, 3, conv1_1)conv1_2 conv2d_layer(conv1_1,64, 64, 3, conv1_2)pool_1 maxPoolLayer(conv1_2)conv2_1 conv2d_layer(pool1,64, 128, 3, conv2_1)conv2_2 conv2d_layer(conv2_1,128, 128, 3, conv2_2)pool2 maxPoolLayer(conv2_2)conv3_1 conv2d_layer(pool2,128, 256, 3, conv3_1)conv3_2 conv2d_layer(conv3_1,256, 256, 3, conv3_2)conv3_3 conv2d_layer(conv3_2,256, 256, 3, conv3_3)pool3 maxPoolLayer(conv3_3)conv4_1 conv2d_layer(pool3,256, 512, 3, conv4_1)conv4_2 conv2d_layer(conv4_1,512, 512, 3, conv4_2)conv4_3 conv2d_layer(conv4_2,512, 512, 3, conv4_3)pool4 maxPoolLayer(conv4_3)conv5_1 conv2d_layer(pool4,512, 512, 3, conv5_1)conv5_2 conv2d_layer(conv5_1,512, 512, 3, conv5_2)conv5_3 conv2d_layer(conv5_1,512, 512, 3, conv5_3)pool5 maxPoolLayer(conv5_3)pool5_flatten_dims int(np.prod(pool5.get_shape().as_list()[1:]))pool5_flatten tf.reshape(pool5,[-1,pool5_flatten_dims])fc_6 fc_layer(pool5_flatten, pool5_flatten_dims, 4096, fc6)fc_7 fc_layer(fc_6, 4096, 4096, fc7)fc_8 fc_layer(fc_7, 4096, 10, fc8)return fc_8