致远行的人,自编TensorFlow教程(2)
来源:互联网 发布:海关信息进出口数据 编辑:程序博客网 时间:2024/05/01 03:28
在上一篇文章中,我们介绍了使用TensorFlow框架有两部分组成:构建计算图,用会话启动计算图。今天我们来介绍 tf.placeholder,feed_dict,实现一个 Wx+b 的函数。本文章仍然保持不够专业的传统,只求达到效果,可以实现一些东西;或者说“路子比较野”。同时确实不一定保证章节与章节之间条理清晰。
首先还是上一段可执行的代码。
import tensorflow as tf# 开始构建计算图W = tf.constant( [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])# 注意 x 和 b 是列向量x = tf.placeholder(tf.float32, shape=[3, 1])b = tf.constant([[1.0], [2.0]])result1 = tf.matmul(W, x) + bresult2 = result1 + b# 结束构建计算图init = tf.global_variables_initializer()with tf.Session() as sess: # get_result1 = sess.run(result1, feed_dict={x: [[3.0], [4.0], [5.0]]}) get_result1, get_result2 = sess.run([result1, result2], feed_dict={x: [[3.0], [4.0], [5.0]]}) print(get_result1) print(get_result2)
这段代码中构建计算图的部分比较长,我仍然会细致地讲解。
首先是W矩阵,我把它设为 2 × 3 的矩阵。根据上一节的讲解,它是一个常量。在TensorFlow里,需要特别注意矩阵和向量的shape,即线性代数里学的,2 × 3 的矩阵只能和 3 × n 的矩阵相乘,如果在报错信息里面看到“shape”的字样,十有八九是矩阵的大小搞错了。
讲真,我真的很佩服那些学数学的,是如何记住那些矩阵的shape,保证写出来是对的,当然我确实也记不住大写的是矩阵,小写的是向量这样的规则(Is it right?)。我看公式时总是会想着shape是多少,这样代码跑出来是怎样的效果。
x = tf.placeholder(tf.float32, shape=[3, 1])b = tf.constant([[1.0], [2.0]])
声明 x 是一个placeholder,就是说假设这里有一个矩阵,矩阵的大小是shape决定的。在运行计算图的时候, x 会被填入相应的数据,这个在稍后会说明。总之它是一个 3 × 1 的列向量。同样 b 也是一个 2 × 1 的列向量。
如果你需要 b 是行向量呢?如下所示,自行注意其中的差别。记不住的话,写代码的时候多试几次,调试到正确为止。
b = tf.constant([1.0, 2.0])
然后关于我们希望获得的结果:
result1 = tf.matmul(W, x) + bresult2 = result1 + b
其实写result1这一行就可以了,result2只是为了说明一个技巧。tf.matmul是TensorFlow中的矩阵乘法运算。为什么不直接用“*”呢?我也是写到这边的时候刚刚想到的,然后测试了一下,“*”好像是向量乘法(就是,[1, 2, 3] * [4, 5, 6] = [4, 10, 18]),没有严格测试,欢迎指正。
总之result1就是Wx+b在计算图中的结果。注意计算图中的变量类型都是tensor,必须依靠会话启动计算图才能得到结果。(不信可以试试直接print,啥也看不到)
get_result1, get_result2 = sess.run([result1, result2], feed_dict={x: [[3.0], [4.0], [5.0]]})
我们刚刚说了,构建计算图时假设 x 是一个矩阵,因为我们也没告诉它实际的数值。在这行代码中,我们使用feed_dict这个参数,给 x 传入一个列向量。这样可以一次性得到result1和result2的结果。可以使用构建一个带tensor的list在一行代码中获取所有的tensor在计算后对应的值。这里还有个细节,result2是以来result1的。在获取result2的时候,我觉得,只是个人觉得,计算图只会被计算一次。就是说,获取result2的时候,计算图不会从头计算。(我们能想到的这么简单的优化,TensorFlow团队应该也想得到,除非不可为)只计算一次的好处就是,如果你的计算图流程特别长,那么只计算一次的话可以大大提高计算速度,节约计算资源。虽然只是个人猜测,有机会可以测试一下,但直接写在一行代码里会合适一些。
今天就讲到这儿吧,建议把代码手敲一遍,然后尝试各种改动,调戏一下代码,下一节我们将讲变量和优化器。
- 致远行的人,自编TensorFlow教程(2)
- 致远行的人,自编TensorFlow教程(1)
- 幸福的人不远行
- Python自编教程
- 自编Photoshop简单教程
- 自编Ps教程—我的ps图片欣赏
- 宁哥自编自导自演的《C语言,好爽》第7版(2017年)教程内容
- 宁哥自编自导自演的《C语言,好爽》第7版(2017年)教程内容
- TensorFlow教程:TensorFlow实现自编码器
- 朋友的远行
- 给远行的朋友们
- 我的远行
- linux c中自编的一个进制(2~36进制)转换函数(strtol库函数自带,ltostr自编)
- PPT自编教程第一篇
- 远行
- 远行
- 远行
- 远行
- Java 代码性能优化
- 初学四旋翼之定高
- 条件判断语句
- 浅谈渗透基础总汇
- hdu4348 为 心灵之旅To The Moon 出的 时光穿梭 题。主席树
- 致远行的人,自编TensorFlow教程(2)
- List ,Map ,Set 小记
- Spring MVC Controller配置方式
- 浅谈协议类与句柄类
- 昊昊爱运动 II
- 初入Android
- WUST 1947 联络员(最小生成树+部分连好的点)
- 不能根据方法返回值来确认是否方法重载(Overload)
- dao模式