只有光头才能变强。python
文本已收录至个人GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3ygit
回顾前面:github
TensorFlow是什么意思?Tensor?Flow?这篇文章介绍TensorFlow一些最基础的知识。算法
在介绍以前,首先要记住一个结论:TensorFlow使用Tensor来表示数据编程
接着咱们来看看什么是Tensor,在官网的文档中,Tensor被翻译成”张量“。其中也给出了一个定义:api
张量是对矢量和矩阵向潜在的更高维度的泛化,TensorFlow 在内部将张量表示为基本数据类型的n维数组。数组
不知道大家看完这句话有啥感觉,反正我当时就看不懂,啥是”张量“?。因而,我就跑去知乎里边用关键字搜了一下:”张量是什么“。果然给我搜到了相关的问题:《怎么通俗地理解张量?》session
我本觉得经过知乎,就能够通俗易懂地理解什么是张量,能给我一个清晰的认识。却不知,大多数答主都在回答在物理和数学中张量的定义,随后贴出了一堆我看不懂的公式。其中,也看到了一种相对通俗易懂的定义:数据结构
一个量, 在不一样的参考系下按照某种特定的法则进行变换, 就是张量.dom
把全部答主的回答都阅读了一遍,看完就更加抽象了。再回到官方文档中,看看官方介绍张量的例子,貌似有点懂了。
目前为止咱们有两个结论:
我再翻译一下上面的两句话:在TensorFlow全部的数据都是一个n维的数组,只是咱们给它起了个名字叫作张量(Tensor)
中间折腾了一大堆,实际上仍是将最开头的结论和官方的定义再翻译成本身以为好理解的话...但不少时候,学习就这么一个过程。
从上面咱们已经得知,Tensor(张量)实际上就是一个n维的数组。这就延伸了几个的术语:
其实上,阶就是平时咱们所说的维数。
之前在写Java的时候,可能通常接触到的都是二维的,但在机器学习上就极可能有很高的维度,那维数咱们怎么数?很简单,咱们数括号就好了。举个例子,咱们可能会看到有下面的一个数组输出形式:
[[[9 6] [6 9] [8 8] [7 9]] [[6 1] [3 5] [1 7] [9 4]]]
咱们直接看第一个括号到第一个数字,有多少个括号就知道了。[[[9
能够发现有3个括号,那这个就是一个三维的数组,它的阶(秩)就是3
张量的形状可让咱们看到每一个维度中元素的数量。
好比咱们在Java中建立出一个二维的数组:int [][] array = new int[3][4]
,咱们就能够知道这个数组有三行有四列。但若是咱们建立出一个多维的数组,单单只用行和列就描述不清了。因此,在TensorFlow通常咱们会这样描述:
若是咱们要打印上面数组的形状时,咱们能够获得这样的结果:shape = (3,4)
。咱们再看看第一篇写”机器学习HelloWorld“的时候,再来看看当时打印的结果:shape = (60000, 28, 28)
。经过shape咱们就能够获得一些信息:
那咱们若是拿到一个数组,怎么经过肉眼看他的shape呢?
好比说:m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
,这个很简单,一眼就能够看出这个是一个二维数组(矩阵),有三行三列。因此shape的结果应该是(3,3)
再来看一个:t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]]
,从多个括号上咱们能够看出,这是三维的。咱们先把最外层括号去掉获得的结果是[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]
Ok,到这一步,咱们能够理解成有三个子数组,因而咱们的shape能够先写成shape(3,?,?)
(?,?,?)
的。从“子数组”的个数咱们将第一个“?”号填充为3随后,咱们继续把外层的括号去除,获得这样的结果:[2], [4], [6]
,也是有三个元素,因而咱们的shape就能够填成shape(3,3,?)
最后,再把括号去掉,咱们能够发现只有一个元素,因而最后的结果就是shape(3,3,1)
咱们能够看下图来巩固一下上面所说的概念:
TensorFlow 在内部将张量表示为基本数据类型的 n维数组,没错的。在一个数组里边,咱们总得知道咱们的存进去的数据到底是什么类型。
Tensor的数据类型以下所示:
特殊的张量由一下几种:
tf.Variable
— 变量tf.constant
— 常量tf.placeholder
—占位符tf.SparseTensor
—稀疏张量此次,咱们先来说讲前三种(比较好理解),分别是变量、常量和占位符。
常量就是常量的意思,一经建立就不会被改变。(相信你们仍是可以理解的)
在TensorFlow中,建立常量的方式十分简单:
a = tf.constant(2) b = tf.constant(3)
变量也挺好理解的(就将编程语言的概念跟这里类比就行了)。通常来讲,咱们在训练过程当中的参数通常用变量进行存储起来,由于咱们的参数会不停的变化。
在TensorFlow建立变量有两种方式:
# 1.使用Variable类来建立 # 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") # 2.使用get_variable的方式来建立 my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3], dtype=tf.int32, initializer=tf.zeros_initializer)
值得注意的是:当咱们建立完变量之后,咱们每次使用以前,都须要为其进行初始化!
tf.global_variables_initializer()
我最先接触占位符这个概念的时候是在JDBC的时候。由于SQL须要传入的参数才能肯定下来,因此咱们可能会写出这样的SQL语句:select * from user where id =?
一样地,在TensorFlow占位符也是这么一个概念,可能须要等到运行的时候才把某些变量肯定下来,因而咱们就有了占位符。
在TensorFlow使用占位符也很简单:
# 文件名须要等到运行的时候才肯定下来 train_filenames = tf.placeholder(tf.string, shape=[None]) # ..省略一堆细节 # 运行的时候,经过feed_dict将占位符具体的值给肯定下来 feed_dict={train_filenames: training_filenames}
上面的东西说白了在编程语言中都是有的,只是语法变了而已。
咱们将Flow翻译成中文:流,因此如今是Tensor流?
其实,在TensorFlow中,使用图 (graph) 来表示计算任务。其实TensorFlow默认会给咱们一张空白的图,通常咱们会叫这个为”数据流图“。数据流图由有向边和节点组成,在使用TensorFlow的时候咱们会在图中建立各类的节点,而Tensor会在这些节点中流通。因此,就叫作TensorFlow
那有人就会好奇,咱们执行什么操做会建立节点呢?在TensorFlow中,节点的类型能够分为三种:
看到这里的同窗,可能就反应过来了:原来在上面建立的变量、常量和占位符在TensorFlow中都会生成一个节点!对于这类的操做Operation(行为)通常你们会简说成op
因此,op就是在TensorFlow中所执行的一个操做统称而已(有多是建立变量的操做、也有多是计算的操做)。在TensorFlow的常见的op有如下:
其实说白了就是TensorFlow会给咱们一张空白的数据流图,咱们往这张数据流图填充(建立节点),从而实现想要效果。
咱们来看看官方的给出数据流图的gif,加深下印象。
TensorFlow程序一般被组织成一个构建阶段和执行阶段. 在构建阶段, op的执行步骤被描述成一个图. 在执行阶段, 使用会话执行执行图中的op。
说白了,就是当咱们在编写代码的时候,实际上就是在将TensorFlow给咱们的空白图描述成一张咱们想要的图。但咱们想要运行出图的结果,那就必须经过session来执行。
举个小例子:
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 # =========若是不使用session来运行,那上面的代码只是一张图。咱们经过session运行这张图,获得想要的结果 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
Fetch就时候能够在session.run
的时候传入多个op(tensor),而后返回多个tensor(若是只传入一个tensor的话,那就是返回一个tensor)
有的同窗在查阅资料的时候,发现可能调用的不是session.run
,而是tensor.eval()和Operation.run()
。其实,他们最后的调用的仍是session.run
。不一样的是session.run
能够一次返回多个tensor(经过Fetch)。
曾经看到一段话总结得不错:
变量 (Variable)
维护状态.TensorFlow 是一个编程系统, 使用图来表示计算任务. 图中的节点被称之为 op (operation 的缩写). 一个 op 得到 0 个或多个
Tensor
, 执行计算, 产生 0 个或多个Tensor
. 每一个 Tensor 是一个类型化的多维数组.
这篇文章简单讲了TensorFlow是啥意思以及一些基础的概念。但我也只是简单以个人理解方式来讲了一些常见概念。里头的知识点仍是比较多的(好比建立变量的时候通常咱们会指定哪些参数….),这些就交由你们去官网、博客、书籍去学习了。
我相信,只要了解了这些概念,那学习必定能够事半功倍!
下一篇TensorFlow文章敬请期待~
参考资料:
乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!
以为个人文章写得不错,不妨点一下赞!