上一节中,我们安装 TensorFlow 并运行了最简单的应用,这节我们熟悉 TensorFlow 中的张量。

张量是 TensorFlow 的核心数据类型。数学里面也有张量的概念,但是 TensorFlow 的张量其实不一样,更像是一个 n 维数组。

不能在常规 Python 例程中访问张量,因此 TensorFlow API 提供了很多张量的操作函数。

张量的创建

张量是一个 n 维数组。当 $n=0$ 时它就是标量;当 $n=1$ 时它就是向量;当 $n=2$ 时它就是矩阵。

所有的张量都是 Tensor 类的实例。

张量可以包含数字、字符串和布尔类型。但是一个张量包含的的元素必须是相同类型的。

创建常数

constant 函数签名:

constant(value, dtype=None, shape=None, name='Const', verify_shape=False)

代码示例:

 # 创建常数
t1 = tf.constant('hello world')
t2 = tf.constant([1, 2, 3])
t3 = tf.constant([[1, 2], [3, 4]])
t4 = tf.constant([6, 66, 666], tf.int16, [3], 'very_6', True) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
print(sess.run(t3))
print(sess.run(t4))
b'hello world'
[ ]
[[ ]
[ ]]
[ ]

zeros/ones/fill

zeros 函数签名:

zeros(shape, dtype=tf.float32, name=None)

ones 函数签名:

ones(shape, dtype=tf.float32, name=None)

fill 函数签名:

fill(dims, value, name=None)

代码示例:

 # 创建零值张量
t1 = tf.zeros([2])
# 创建一值张量
t2 = tf.ones([2, 3])
# 填值
t3 = tf.fill([3, 2], 666) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
print(sess.run(t3))
[. .]
[[. . .]
[. . .]]
[[ ]
[ ]
[ ]]

创建序列

linspance 函数签名:

linspace(start, stop, num,  name=None)

range 函数签名:

range(start, limit, delta=, dtype=None, name='range')
range(limit, delta=, dtype=None, name='range')

代码示例:

 # 创建序列
t1 = tf.linspace(0., 1., 10)
t2 = tf.range(-1., 1., delta=0.1)
t3 = tf.range(-2., delta=-0.5) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
print(sess.run(t3))
[.         0.11111111 0.22222222 0.33333334 0.44444445 0.5555556
0.6666667 0.7777778 0.8888889 . ]
[-1.00000000e+00 -8.99999976e-01 -7.99999952e-01 -6.99999928e-01
-5.99999905e-01 -4.99999911e-01 -3.99999917e-01 -2.99999923e-01
-1.99999928e-01 -9.99999270e-02 7.45058060e-08 1.00000076e-01
2.00000077e-01 3.00000072e-01 4.00000066e-01 5.00000060e-01
6.00000083e-01 7.00000107e-01 8.00000131e-01 9.00000155e-01]
[ . -0.5 -. -1.5]

创建随机值:正态分布

很多时候机器学习需要创建随机值。正态分布有两种:random_normal 和 truncated_normal。对于一般意义的正态分布,大约 95.4% 的概率会落在 2 倍标准方差的范围之内。

random_normal 是一般意义的正态分布,有可能有小概率会选择 2 倍标准方差的范围之外。而 truncated_normal 会有截断,保证所有值都落在 2 倍标准方差的范围之内。

函数签名:

random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

代码示例:

 # 创建随机值:正态分布
t1 = tf.random_normal([10], dtype=tf.float64)
t2 = tf.random_normal([20], 0, 2, dtype=tf.float64, seed=60)
t3 = tf.truncated_normal([20], 0, 2, dtype=tf.float32, seed=60) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
print(sess.run(t3))
[-0.30217352 -0.01353907  0.11583214  0.7693184  -2.03386255  0.74505956
-1.57310053 1.16255292 1.87307555 1.1607303 ]
[ 0.43070572 1.78930951 1.90006543 -0.08042026 -2.3744852 1.88272049
1.56724792 1.37002113 -0.12527277 4.5297854 -0.82256769 0.87545214
0.85278266 -0.14404349 0.93608167 -2.59733351 -0.33442825 1.19330448
4.15318877 -3.12805352]
[ 0.74157673 -0.9606577 0.46180212 -3.2753797 0.16152781 -2.189441
-0.09013904 -2.1726682 -1.2061952 0.5147551 -3.3902223 1.843447
-0.83136135 -2.4879968 3.2793632 2.9981675 -3.217487 -0.13496129
1.7222887 -3.1599777 ]

观察第 2 个输出中的 4.15318877,已经超过了 2 倍标准方差(标准方差为 2),这有将近 4.6% 的概率发生。

而对于 truncated_normal 函数,不管输出多少数,也不可能有这样的输出。

创建随机值:均匀分布

random_uniform 创建最大值和最小值之间的均匀分布。

函数签名:

random_uniform(shape, minval=, maxval=None, dtype=tf.float32, seed=None, name=None)

代码示例:

 # 创建随机值:均匀分布
t1 = tf.random_uniform([20], 0, 10, dtype=tf.int32, seed=66) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
[0 7 5 3 2 7 7 5 1 7 9 9 0 3 0 1 4 7 3 4]

随机打乱某张量

random_shuffle 可以对张量沿着一维方向,随机打乱顺序。

函数签名:

random_shuffle(tensor, seed=None, name=None)

代码示例:

 # 随机打乱张量(沿第一维方向)
t1 = tf.constant([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
t2 = tf.random_shuffle(t1, seed=66) # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
[[   ]
[ ]
[ ]
[ ]
[ ]]
[[ ]
[ ]
[ ]
[ ]
[ ]]

设置随机种子

前面的随机函数都有一个 seed 参数,我们其实可以直接设置,让所有随机函数都会用同一个随机种子。

set_random_seed(seed)

代码示例:

 # 随机种子
tf.set_random_seed(66)

创建张量的运算

基本的数学运算

代码示例:

 # 基本的数学运算
x1 = tf.constant([2, 2, 2])
x2 = tf.constant([4, 4, 4])
my_sum1 = tf.add(x1, x2)
my_diff1 = tf.subtract(x1, x2)
my_prod1 = tf.multiply(x1, x2)
my_quot1 = tf.divide(x1, x2)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(my_sum1))
print(sess.run(my_diff1))
print(sess.run(my_prod1))
print(sess.run(my_quot1))
print('-' * 20)
# 还可以使用 Python 运算符
my_sum2 = x1 + x2
my_diff2 = x1 - x2
my_prod2 = x1 * x2
my_quot2 = x1 / x2
# 发起一个会话
with tf.Session() as sess:
print(sess.run(my_sum2))
print(sess.run(my_diff2))
print(sess.run(my_prod2))
print(sess.run(my_quot2))
print('-' * 20)
# 除和整除
my_quot3 = x1 / x2
my_quot4 = x1 // x2
my_quot5 = tf.divide(x1, x2)
my_quot6 = tf.div(x1, x2)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(my_quot3))
print(sess.run(my_quot4))
print(sess.run(my_quot5))
print(sess.run(my_quot6))
[  ]
[- - -]
[ ]
[0.5 0.5 0.5]
--------------------
[ ]
[- - -]
[ ]
[0.5 0.5 0.5]
--------------------
[0.5 0.5 0.5]
[ ]
[0.5 0.5 0.5]
[ ]

凑整和比较运算

代码示例:

 # 凑整和比较运算
# 凑整
t = tf.constant([-1.5, -1.4, 1.4, 1.5])
r1 = tf.round(t)
r2 = tf.rint(t)
r3 = tf.ceil(t)
r4 = tf.floor(t)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(r1))
print(sess.run(r2))
print(sess.run(r3))
print(sess.run(r4))
print('-' * 20)
# 比较
t1 = tf.constant([1., 2.])
t2 = tf.constant([1.5, 3.])
my_max = tf.maximum(t1, t2)
my_min = tf.minimum(t1, t2)
t3 = tf.constant([[6., 2.], [4., -6.]])
min_index = tf.argmin(t3)
max_index = tf.argmax(t3)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(my_max))
print(sess.run(my_min))
print(sess.run(min_index))
print(sess.run(max_index))
[-2. -1.  1.  2.]
[-2. -1. 1. 2.]
[-1. -1. 2. 2.]
[-2. -2. 1. 1.]
--------------------
[1.5 3. ]
[1. 2.]
[1 1]
[0 0]

指数和对数

机器学习经常要用到指数和对数来计算概率。

 # 指数和对数
x = tf.constant([0., 1., 2.])
y = tf.constant([-1., -1., -1.])
t1 = tf.square(x)
t2 = tf.squared_difference(x, y)
t3 = tf.sqrt(x)
t4 = tf.rsqrt(x) # tf.sqrt(x)的倒数
t5 = tf.pow(x, 3)
t6 = tf.exp(x)
t7 = tf.expm1(x) # exp(x)-1
t8 = tf.log(x) # ln(x)
t9 = tf.log1p(x) # log(x+1)
t10 = tf.erf(x) # 误差函数
t11 = tf.erfc(x) # 互补误差函数 # 发起一个会话
with tf.Session() as sess:
print(sess.run(t1))
print(sess.run(t2))
print(sess.run(t3))
print(sess.run(t4))
print(sess.run(t5))
print(sess.run(t6))
print(sess.run(t7))
print(sess.run(t8))
print(sess.run(t9))
print(sess.run(t10))
print(sess.run(t11))
[. . .]
[. . .]
[. . 1.4142135]
[ inf . 0.70710677]
[. . .]
[. 2.7182817 7.389056 ]
[. 1.7182819 6.389056 ]
[ -inf . 0.6931472]
[. 0.6931472 1.0986123]
[. 0.8427008 0.9953223]
[. 0.1572992 0.00467773]

向量和矩阵运算

机器学习中有很多向量(一维张量)和矩阵(二维张量)的运算。

代码示例:

 # 向量和矩阵运算
# 点乘
t1 = tf.constant([0., 1., 2.])
t2 = tf.constant([1., 2., 3.])
dot0 = tf.tensordot(t1, t2, axes=0)
dot1 = tf.tensordot(t1, t2, axes=1)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(dot0))
print(sess.run(dot1))
print('-' * 20)
# 矩阵乘法
t3 = tf.constant([[0., 1., 2.]])
t4 = tf.constant([[1., 2., 3.]])
dot3 = tf.matmul(t3, tf.transpose(t4))
# 交叉内积
cross = tf.cross(t3, t4)
# 对角矩阵
t5 = tf.diag([1, 2, 3])
# 迹
trace = tf.trace(t5)
# 单位矩阵
eye = tf.eye(4)
# 范数
t6 = tf.constant([[1., 2.], [3., 4.]])
norm = tf.norm(t6)
# 求解Ax = b
A = tf.constant([[1., 1.], [2., 3.]])
b = tf.constant([[10.], [23.]])
x = tf.matrix_solve(A, b)
# 特征向量
t7 = tf.constant([[1., 2.], [3., 4.]])
qr = tf.qr(t7)
# 矩阵分解
svd = tf.svd(t7)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(dot3))
print(sess.run(cross))
print(sess.run(t5))
print(sess.run(trace))
print(sess.run(eye))
print(sess.run(norm))
print(sess.run(x))
print(sess.run(qr))
print(sess.run(svd))
print('-' * 20)
# 自定义运算
m1 = tf.constant([[1, 2], [3, 4]])
m2 = tf.constant([[5, 6], [7, 8]])
e1 = tf.einsum('ij->ji', m1)
e2 = tf.einsum('ij,jk->ik', m1, m2)
# 发起一个会话
with tf.Session() as sess:
print(sess.run(e1))
print(sess.run(e2))
[[. . .]
[. . .]
[. . .]]
8.0
--------------------
[[.]]
[[-. . -.]]
[[ ]
[ ]
[ ]] [[. . . .]
[. . . .]
[. . . .]
[. . . .]]
5.477226
[[.]
[.]]
Qr(q=array([[-0.3162278 , -0.9486833 ],
[-0.9486833 , 0.31622773]], dtype=float32), r=array([[-3.1622777 , -4.4271884 ],
[ . , -0.63245535]], dtype=float32))
(array([5.4649854 , 0.36596614], dtype=float32), array([[ 0.4045535, -0.9145143],
[ 0.9145143, 0.4045535]], dtype=float32), array([[ 0.5760484, 0.8174156],
[ 0.8174156, -0.5760484]], dtype=float32))
--------------------
[[ ]
[ ]]
[[ ]
[ ]]

总结

张量是 TensorFlow 中核心的数据类型。本文揭开了 TensorFlow 中张量的神秘面纱,包括张量的创建和张量的运算。

张量类似于 N 维数组。0 维张量就是标量,1 维张量就是向量,2 维张量就是矩阵。

我们只是熟悉了张量基本的创建和运算(很多 API 和我们熟悉的 Numpy 很类似),更多的技巧知识还需要不断在实践中总结和提升。

最新文章

  1. Url和Uri的区别
  2. #pragma once与 #ifndef的区别
  3. C++系列: 如何将十六机制的字符串转成整数
  4. 使用X-UA-Compatible来设置IE8/IE9兼容模式
  5. Java程序员面试失败的5大原因
  6. 【原创】关于Adapter的The content of the adapter has changed问题分析
  7. 使用Core Data应避免的十个错误
  8. zend studio 安装xdebug
  9. hadoo namenode format 异常 java.net.UnknownHostException: localhost.localdomain: localhost.localdomain
  10. Visual format language
  11. IP Editor IP控件(对比一下封装IP控件)
  12. ES入门笔一
  13. crontab 误删恢复
  14. RMQ 字符串 F. Strings and Queries
  15. 杜教BM【转载】
  16. "添加"模态框中某些数据不被清空
  17. linux rsync介绍(八)
  18. js浮点精度问题
  19. Python string常用函数
  20. CSS中float和Clear的使用

热门文章

  1. Idea 设置单击打开文件或者双击打开文件、自动定位文件所在的位置
  2. 【C/C++开发】C++11 并发指南一(C++11 多线程初探)
  3. 那些陌生的C++关键字
  4. kali 触摸板手势之fusuma
  5. sbt 安装
  6. 在myecplice中关联svn
  7. Hbase操作集锦
  8. [转帖]spring基本概念精炼
  9. tornado利用装饰器记录每个http请求
  10. Bootstrap:UI开发平台 sdk