TensorFlow入门极简教程(四):Vector

向量

向量在编程语言中就是最常用的一维数组(Vector)。
二维数组叫做矩阵(Matrix),三维以上叫做张量(Tensor)。

向量虽然简单,高效,且容易理解。但是与操作0维的标量数据毕竟还是不同的。比如向量经常用于表示一个序列,生成序列像标量一样一个一个手工写就不划算了。当然可以用循环来写。在向量中这样还好,如果是在矩阵或者是张量中就强烈建议不要用循环来做了。系统提供的函数一般都是经过高度优化的,而且可以使用GPU资源来进行加速。
我们一方面尽可能地多使用系统的函数,另一方面也不要迷信它们,代码优化是一个实践的过程,可以实际比较测量一下。

快速生成向量的方法

range函数生成等差数列

tf.range函数用来快速生成一个等差数列。相当于之前我们讲numpy时的np.arange函数。
原型:

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

例:

b11 = tf.range(1,100,1)
print(b11)
print(sess.run(b11))

Tensor("range:0", shape=(99,), dtype=int32)
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
97 98 99]

linspace生成浮点等差数组

tf.linspace与tf.range的区别在于,数据类型不同。

tf.lin_space(start, stop, num, name=None)

其中,start和stop必须是浮点数,且类型必须相同。num必须是整数。

例:

a2 = tf.linspace(1.0,10.0,4)
print(a2)
print(sess.run(a2))

Tensor("LinSpace:0", shape=(4,), dtype=float32)
[ 1. 4. 7. 10.]

拼瓷砖

就是将一段向量重复若干次。

a10 = tf.range(1,4,1)
print(a10)
print(sess.run(a10))

a11 = tf.tile(a10,[3])
print(a11)
print(sess.run(a11))

Tensor("range_1:0", shape=(3,), dtype=int32)
[1 2 3]
Tensor("Tile:0", shape=(9,), dtype=int32)
[1 2 3 1 2 3 1 2 3]

向量操作

将向量反序

可以使用tf.reverse函数。
原型:

tf.reverse( tensor, axis, name=None)

tensor是向量,axis轴对于向量不重要,给个[-1]就可以了。折腾轴是张量时间的事情,暂时还用不到。

a2 = tf.linspace(1.0,10.0,4)
print(sess.run(a2))

a3 = tf.reverse(a2,[-1])
print(sess.run(a3))

[ 1. 4. 7. 10.]
[10. 7. 4. 1.]

切片

切片也是向量的常用操作之一,就是取数组的一部分。

例:

a5 = tf.linspace(1.0,100.0, 10)
print(sess.run(a5))

a6 = tf.slice(a5, [2],[4])
print(sess.run(a6))

[ 1. 12. 23. 34. 45. 56. 67. 78. 89. 100.]
[23. 34. 45. 56.]

将来处理张量时,我们从一个矩阵切一块,或从一个张量中切一块,就好玩得多了。但是原理跟向量上是一样的。

连接

tf.concat也是需要给定轴信息的。对于两个线性的向量,我们给0或者-1就好。

a20 = tf.linspace(1.0,2.0,10)
print(sess.run(a20))

a21 = tf.linspace(2.0,3.0,5)
print(sess.run(a21))

a23 = tf.concat([a20,a21],-1)
print(sess.run(a23))

[1. 1.1111112 1.2222222 1.3333334 1.4444444 1.5555556 1.6666667
1.7777778 1.8888888 2. ]
[2. 2.25 2.5 2.75 3. ]
[1. 1.1111112 1.2222222 1.3333334 1.4444444 1.5555556 1.6666667
1.7777778 1.8888888 2. 2. 2.25 2.5 2.75 3. ]

向量计算

向量加减法

同样长度的向量之间可以进行加减操作。
例:

a40 = tf.constant([1,1])
a41 = tf.constant([2,2])
a42 = a40 + a41
print(sess.run(a42))

a43 = a40 - a41
print(a43)
print(sess.run(a43))

[3 3]
Tensor("sub:0", shape=(2,), dtype=int32)
[-1 -1]

向量乘除标量

向量乘除标量也非常好理解,就是针对向量中的每个数都做乘除法。
例:

a44 = a40 * 2
print(sess.run(a44))

a45 = a44 / 2
print(sess.run(a45))

print(a44)
print(a45)

[2 2]
[1. 1.]
Tensor("mul:0", shape=(2,), dtype=int32)
Tensor("truediv:0", shape=(2,), dtype=float64)

广播运算

如果针对向量和标量进行加减运算,也是会对向量中的每个数进行加减运算。这种操作称为广播操作。

例:

a46 = a40 + 1
print(sess.run(a46))
print(a46)

[2 2]
Tensor("add_1:0", shape=(2,), dtype=int32)

向量乘法

两个向量相乘,默认的运算是求元素对应乘积(element-wise product),也叫做Hadamard积。

例:

b1 = tf.constant([1, 2])
b2 = tf.constant([2, 1])
b3 = b1 * b2
print(b3)
print(sess.run(b3))

Tensor("mul_1:0", shape=(2,), dtype=int32)
[2 2]

直接调用tf.multiply也是同样的效果,例:

b4 = tf.multiply(b1,b2)
print(b4)
print(sess.run(b4))

Tensor("Mul_2:0", shape=(2,), dtype=int32)
[2 2]

如果要计算点积(dot product)的话,我们得提前剧透一下矩阵的内容了。
首先,用向量是没法做矩阵计算的。
例:

a21 = tf.constant([2,3])
a22 = tf.constant([4,5])
print(a21)
print(a22)

Tensor("Const_8:0", shape=(2,), dtype=int32)
Tensor("Const_9:0", shape=(2,), dtype=int32)

这样(2,)的形状是向量,我们得先把它转换成(2,1)这样的单行矩阵,如下:

a31 = tf.constant(sess.run(tf.reshape(a21,[2,1])))
a32 = tf.constant(sess.run(tf.reshape(a22,[2,1])))

print(a31)
print(a32)

Tensor("Const_10:0", shape=(2, 1), dtype=int32)
Tensor("Const_11:0", shape=(2, 1), dtype=int32)

下面我们终于可以计算点积了,我们知道点积A.B相当于A的转置乘以B,我们可以通过matmul函数来进行矩阵乘法。

a31 = tf.matmul(a31,a32,transpose_a=True)
print(sess.run(a31)) # 也就是2*4+3*5=23

[[23]]

我们也可以用tf.tensordot函数来计算点积。我们刚才为什么没用呢?答案是tensordot要求是浮点型矩阵。
例:
第一步,需要浮点数:

f01 = tf.constant([1,1],dtype=tf.float32)
f02 = tf.constant([1,2],dtype=tf.float32)

第二步,reshape成单行矩阵:

f11 = tf.constant(sess.run(tf.reshape(f01,[2,1])))
f12 = tf.constant(sess.run(tf.reshape(f02,[2,1])))
print(f11)
print(f12)

Tensor("Const_14:0", shape=(2, 1), dtype=float32)
Tensor("Const_15:0", shape=(2, 1), dtype=float32)

第三步,调用tensordot

f13 = tf.tensordot(f11,f12,2)
print(sess.run(f13))

3.0

小结

从上面我们学习的函数我们可以看到,与普通语言中提供的函数多是为一维数组操作不同,Tensorflow中的切片、拼接等操作也是基于张量的。
当我们后面学到张量遇到困难时,不妨回来看下这一节。不管后面张量多么复杂,其实也只是从一维向二维和多维推广而己。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352