赞
踩
Hello!大家好!欢迎大家加入到TensorFlow框架的学习,也欢迎大家进入人工智能领域。这是我的第一篇博客,在这篇以及之后的几篇博文中,我将从一个初学者的角度来带领大家入门TensorFlow与深度学习。希望大家有所收获,加油!
首先给大家看张图,这是人工智能的发展历程。
1956年,几个计算机科学家相聚在达特茅斯会议(Dartmouth Conferences),提出了“人工智能”的概念。1959年美国的塞缪尔(Samuel)设计了一个下棋程序,这个程序具有学习能力,它可以在不断的对弈中改善自己的棋艺。达特茅斯会议之后,人工智能研究进入了20年的黄金时代。4年后,这个程序战胜了设计者本人。又过了3年,这个程序战胜了美国一个保持8年之久的常胜不败的冠军。这是最早的人工智能的出现。1964到1966年期间,诞生了世界上第一个聊天程序ELIZA,它是由麻省理工学院的人工智能学院创造的。不过由于当时计算机的计算能力有限,缺乏大量的训练数据,再加上人们当时对人工智能的期待过高,使得人工智能的发展在70年代进入了寒冬。
幸运的是,1980年卡耐基梅隆大学研发的XCON(根据顾客需求自动选配计算机组件的专家系统软件程序)正式投入使用,这成为一个新时期的里程碑,专家系统开始在特定领域发挥威力,也带动整个人工智能技术进入了一个繁荣阶段。就在这个时候神经网络又有了新的研究进展,尤其是1982年英国科学家霍普菲尔德几乎同时与杰弗里·辛顿发现了具有学习能力的神经网络算法,这使得神经网络一路发展,在后面的90年代开始商业化,被用于文字图像识别和语音识别。1988年,美国科学家朱迪亚·皮尔将概率统计方法引入人工智能的推理过程中,这也是机器学习的开始。
再后来随着深度神经网络的发展,2006年,杰弗里辛顿出版了《Learning Multiple Layers of Representation》奠定了后来神经网络的全新的架构,至今仍然是人工智能深度学习的核心技术。华裔科学家吴恩达及其团队在2009年开始研究使用图形处理器(GPU而不是CPU)进行大规模无监督式机器学习工作,尝试让人工智能程序完全自主的识别图形中的内容。在这段期间深度学习技术飞速发展,出现了kearas、caffe、tensorflow等开源深度学习框架。
TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。它灵活的架构让你可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU、GPU、TPU,服务器,移动设备等等。TensorFlow 最初由Google大脑小组(隶属于Google机器智能研究机构)的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但这个系统的通用性使其也可广泛用于其他计算领域。Google于2015年将该框架开源,使其得以广泛应用。
大家看张图,首先是顶层api,分别是keras和estimators,keras是在tensorflow出现前就有了的学习算法框架,tensorflow出现后很好的对接了keras,使得keras成为一个高层的接口,可以根据需要调用。而estimators则是Google团队推出的另一款针对模型设计推出的框架,主要用于模型设计、估算以及模型指标。而中层api中layers用来进行卷积、池化等运算,datasets用来处理输入输出数据,metrics用于设定模型指标。
底层的api为tensorflow支持的语言,如:Python、C++、Java、Go等,他们只是在应用层进行封装,只是制定了一个运行的法则或者流程,在tensorflow真正的处理会话中并不采用命令式编程范式而是采用声明式编程范式(这点后面会提到)。所以如果用编python的思维方式去编tensorflow会出现错误。
最下面的api是程序执行的分布式执行引擎或者是本地执行引擎。
上图为tensorflow的架构,tensorflow采用了非常合理的架构,即模块化、分层式。高层模块可以调用低层模块,低层模块也可以以接口的形式向上层提供调用逻辑。
TensorFlow 的名字中己经说明了它最重要的两个概念一一Tensor 和Flow 。Tensor 就是张量。张量是一种数学上常用的数据结构,可以理解为多维数组。如果说TensorFlow 的第一个词Tensor 表明了它的数据结构,那么Flow 则体现了它的计算模型。Flow 翻译成中文就是“流”,它直观地表达了张量之间通过计算相互转化的过程。
数据流图用“结点”(nodes)和“线”(edges)的有向图来描述数学计算。“节点” 一般用来表示施加的数学操作,但也可以表示数据输入(feed in)的起点/输出(push out)的终点,或者是读取/写入持久变量(persistent variable)的终点。“线”表示“节点”之间的输入/输出关系。这些数据“线”可以输运“size可动态调整”的多维数据数组,即“张量”(tensor)。一旦输入端的所有张量准备好,节点将被分配到各种计算设备完成异步并行地执行运算。
TensorFlow变量主要作用是维护节点的状态的,如学习过程中的模型参数。所调用的操作是tf.Variable(value,type,name),三个参数分别为变量值、变量类型、变量名(注意此处不要和操作名混淆),返回值是变量。通过该方法创建的变量与张量一样,可以作为操作的输入输出。
注意:张量的生命周期通常依赖计算完成而结束,内存随之释放;变量则不然,变量常驻内存在每一次运行时都会更新,以实现模型参数的更新。(下面会有实例介绍)
a1 = tf.Variable([[7],[11]], tf.int16,name='a1')
a2 = tf.Variable([[False, True],[True, False]], tf.bool,name='a2')
a3 = tf.Variable([[4], [9], [16], [25]], tf.int32,name='a3')
a4 = tf.Variable([ [4, 9], [16, 25] ], tf.int32,name='a4')
a5 = tf.Variable([[7],[11]], tf.int32,name='a5')
[a1,a2,a3,a4,a5]
运行结果:
[<tf.Variable ‘a1:0’ shape=(2, 1) dtype=int32_ref>,
<tf.Variable ‘a2:0’ shape=(2, 2) dtype=bool_ref>,
<tf.Variable ‘a3:0’ shape=(4, 1) dtype=int32_ref>,
<tf.Variable ‘a4:0’ shape=(2, 2) dtype=int32_ref>,
<tf.Variable ‘a5:0’ shape=(2, 1) dtype=int32_ref>]
大家可以看到返回的结果都是tf.Valuable这个操作,其中tf.Variable为类型,a1为变量名,如果在写这个方法时没有写这个参数,系统将自动为其分配变量名,dtype=int32_ref为变量类型。
TensorFlow中对常量的初始化,不管是对数值、向量还是对矩阵的初始化,都是通过调用tf.constant(value,name,dtype,shapeverify_shape)操作实现的。value为常量的具体值,可以是一个数字,一维向量或是多维矩阵,name是常量的名字,用于区别其它常量,dtype是常量的类型,shape是指常量的维度,我们可以自行定义常量的维度。
Tensorflow还提供了一些常见常量的初始化,如:tf.zeros、tf.ones、tf.fill、tf.linspace、tf.range等,均可以快速初始化一些常量。例如:我们想要快速初始化N维全0的矩阵,我们可以利用tf.zeros进行初始化。
tf.placeholder是一个数据初始化的容器,它与变量最大的不同在于它定义的是一个模板,这样我们就可以session运行阶段,利用feed_dict的字典结构给placeholder填充具体的内容,而无需每次都提前定义好变量的值,这样我们就可以让占位符作为图的输入节点,因为输入节点的入度为零。
import tensorflow as tf
# 创建数据流图:y = W * x + b,其中W和b为存储节点,x为数据节点。
x = tf.placeholder(tf.float32)
W = tf.Variable(1.0)
b = tf.Variable(1.0)
y = W * x + b
with tf.Session() as sess:
tf.global_variables_initializer().run() # Operation.run
fetch = y.eval(feed_dict={x: 3.0}) # Tensor.eval
print(fetch) # fetch = 1.0 * 3.0 + 1.0
以上程序使用了占位符x,在声明阶段并没有,只是用来占位在会话中才通过feed_dict添加了输入值。
以下示例可以帮助大家熟悉本部分过程:
import tensorflow as tf # 创建变量 # tf.random_normal 方法返回形状为(1,4)的张量。它的4个元素符合均值为100、标准差为0.35的正态分布。 W = tf.Variable(initial_value=tf.random_normal(shape=(1, 4), mean=100, stddev=0.35), name="W") b = tf.Variable(tf.zeros([4]), name="b") # 初始化变量 # 创建会话(之后介绍) sess = tf.Session() # 使用 global_variables_initializer 方法初始化全局变量 W 和 b sess.run(tf.global_variables_initializer()) # 执行操作,获取变量值 sess.run([W, b]) # 执行更新变量 b 的操作 sess.run(tf.assign_add(b, [1, 1, 1, 1])) # 查看变量 b 是否更新成功 sess.run(b)
大家有些地方需要注意:如下图(交互环境jupyter notebook),为我点四次运行后的结果,要知道b是[0,0,0,0],在add[1,1,1,1]之后应该会为[1,1,1,1],在训练过程中会话前面的过程只是为了设定计算法则,在会话中一旦数据更新,将写入内存,下次训练将在这次的基础上训练。
TensorFlow会话提供了估算张量和执行操作的运行环境,是发起计算任务的客户端,所有计算任务都有它来凝结的执行引擎完成。通常会话分为以下三步:
#1.创建会话
sess = tf.Session(target=...,graph=...,config=...)
#target为会话连接的执行引擎,graph为会话加载的数据流图,config为启动配置项
#2.估算张量或执行操作
sess.run(...)
#3.关闭会话
sess.close()
下面让我们看下会话的执行过程:
通过改图可以看出,我们为你所使用的sess.run()只是会话的最后结果,我们略去了中间过程,所以执行会话还有一种方式:
with tf.Session() as sess:
tf.global_variables_initializer().run()
tensor.eval()
对比一下段两代码看出所使用的两种会话方式:
#方法一: import tensorflow as tf # 创建数据流图:y = W * x + b,其中W和b为存储节点,x为数据节点。 x = tf.placeholder(tf.float32) W = tf.Variable(1.0) b = tf.Variable(1.0) y = W * x + b with tf.Session() as sess: tf.global_variables_initializer().run() # Operation.run fetch = y.eval(feed_dict={x: 3.0}) # Tensor.eval print(fetch) # fetch = 1.0 * 3.0 + 1.0 #方法二: import tensorflow as tf # 创建数据流图:y = W * x + b,其中W和b为存储节点,x为数据节点。 x = tf.placeholder(tf.float32) W = tf.Variable(1.0) b = tf.Variable(1.0) y = W * x + b sess=tf.Session() sess.run(tf.global_variables_initializer()) print(sess.run(y,feed_dict={x: 3.0})) # Tensor.eval sess.close()
输出结果均为:4.0
想知道TensorFlow所以函数及操作,请查阅TensorFlow官方文档。
未完待续。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。