tf.concat()到底怎么接的,看不懂你弄死我

上一篇里详细解释了tf.slice()到底是怎么切的,包括shape和怎么思考这种基于数组的表现方式比较容易理解。这一篇我打算说tf.concat(),然后下一篇讲tf.stack()。这两个容易混淆。而且相比之下,tf.concat()应该对于有计算机背景的人更好理解一点。所以咱们本着由浅入深的原则逐个攻克。


tf.concat()是相对比较好理解的函数,它和python里的numpy.concatenate()函数作用是一样的。都是把多个array沿着某一个维度接在一起。只不过numpy.concatenate()用来处理numpy array,tf.concat()用于处理tensor。他们俩有个共同点,就是得到的结果tensor或者numpy array的维度的数量一定是一样的。(如果忘了shape是什么,请先看上一篇)

方程的signature长这样:

concat( values, axis, name='concat')

来看例1:

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0)  

输出结果是:

[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
shape=[4, 3]

先来分解一下t1和t2。首先t1 = [[1, 2, 3], [4, 5, 6]]可以看成:

t1 = [A, B]
A = [1,2,3]
B = [4,5,6]

t1的shape是[2,3],意思是有2个元素[A, B], 他们每个里面有3个元素。这种类似于代数的思维方式上一篇也有介绍。
那么t2 = [[7, 8, 9], [10, 11, 12]]也照猫画虎:

t2 = [C, D]
C = [7,8,9]
D = [10,11,12]

t2的shape也是[2,3]

这里[2,3]的维度数量是2,也就是2维的。如果是3维的可能是[2,3,什么]。知道tf.concat()不会改变维度数量非常重要。因为tf.concat()只是对对应维度元素数量的叠加。比如tf.concat([t1, t2], 0)意思是对t1和t2在第一维度对接。因为他俩的shape都是[2,3],输出tensor的shape一定是[4,3],因为他俩的第一维度都是2,2+2=4。再比如如果是tf.concat([t1, t2], 1),那么输出shape一定是[2,6],以此类推。


Concatenation

现在再来看例子:

tf.concat([t1, t2], 0)  #后面的0的意思是 axis=0

维度是从0开始算的,也就是沿着第一个维度接起来。(以此类推,axis=1就是第二个维度)
从shape可以看出t1和t2都是只有两个维度。既然是沿着第一个维度对接,那根本就不用看第二个维度
那么什么是第一个维度呢?就可以理解成第一层中括号。t1的第一层中括号是t1 = [A, B], t2 = [C, D](展开A,B,C,D是第二个维度)
对接是什么意思呢?就是把对应的中括号打开,把对应的里面一层的元素放在一起,再用中括号全扩起来。
按步骤是:

  1. 打开中括号:[A,B],[C,D] -> A,B,C,D
  2. 放在一起再扩起来: A,B,C,D -> [A,B,C,D]

这里已经知道了输出的shape是[4,3]。其中的4代表第一维度有4个元素,就是A,B,C,D。t1 = [A, B], t2 = [C, D]各只有一个中括号,所以不用考虑对应,直接放一起就行了。如果t1和t2比如各有2个中括号的话,括回去之后也应该有2个中括号,下面例2有讲到

A,B,C,D都是什么来着?

A = [1,2,3]
B = [4,5,6]
C = [7,8,9]
D = [10,11,12]

每个里面有3个元素,这就是[4,3]的3的含义。
所以输出结果是:

[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], shape = [4,3]

注意t1和t2是有顺序的。如果这行命令是:

tf.concat([t2, t1], 0)

那么结果应该是[[7, 8, 9], [10, 11, 12], [1, 2, 3], [4, 5, 6]]


例2,如果是:

tf.concat([t1, t2], 1)  #1是 axis=1,第二维度的意思

还是按照上面的方法,我们知道了输出结果的shape一定是[2,6]。既然沿着第二维度对接,那么不用看第一维度。
第一维度是:t1 = [A, B], t2 = [C, D](不用动,也就是这一维度的输出结果一定是[x1, x2])
第二维度是:A = [1,2,3] B = [4,5,6] C = [7,8,9] D = [10,11,12]
这里A,B属于t1,C,D属于t2,各有2个中括号。那么按顺序,A对应C,B对应D。

  1. 打开中括号:[1,2,3],[4,5,6],[7,8,9],[10,11,12] -> 1,2,3, 4,5,6, 7,8,9, 10,11,12
  2. 对应的A,C放一起:1,2,3,7,8,9 -> [1,2,3,7,8,9]
  3. 对应的B,D放一起: 4,5,6,10,11,12 -> [4,5,6,10,11,12]

最后在第一维度括起来,结果是:

[[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]], shape = [2,6]

直观方法

我个人还有一种直观的方法去理解上面的对接。
回到例1:

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0)  

其实t1是个2维数组,也就是一个面。形象一点就是:

t1:
-------
|1|2|3|
|-|-|-|
|4|5|6|
-------
t2:
----------
| 7| 8| 9|
|--|--|--|
|10|11|12|
----------

都是2行3列。
我会把第一维度看成,第二维度看成
如果沿着对接,也就是把行数增加为4行,列数还是3列。那么结果就是:

----------
| 1| 2| 3|
|--|--|--|
| 4| 5| 6|
----------
| 7| 8| 9|
|--|--|--|
|10|11|12|
----------

这个矩阵就是:

[[1, 2, 3], 
[4, 5, 6], 
[7, 8, 9], 
[10, 11, 12]]

再看例2:

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1)  

这就是沿着对接,也就是变成6列。行还是3行。也就变成了:

-------------------
| 1| 2| 3| 7| 8| 9|
|--|--|--|--|--|--|
| 4| 5| 6|10|11|12|
-------------------

输出就是

[[1, 2, 3, 7, 8, 9], 
[4, 5, 6, 10, 11, 12]]

如果两个tensor都有第三维的话,比如:

t1 = [[[1], [2], [3]], [[4], [5], [6]]]
t2 = [[[7], [8], [9]], [[10], [11], [12]]]
tf.concat([t1, t2], 2)  

t1和t2的shape都是[2,3,1],沿着第三维对接。结果shape一定是[2,3,2]。
那么用这个直观的方法就是非常好理解,
就可以理解成把t1的2d矩阵放在t2的2d矩阵的前面,形成一个3d矩阵,像这样:

schematic diagram
3d数组这样理解:2行,3列,2层
2行:[A, B]
3列:A = [a,b,c], B = [d, e, f]
2层:a = [1,7], b = [2,8], c = [3, 9], d = [4, 10], e = [5, 11], f = [6, 12]
所以结果是:

[[[1,7], [2,8], [3, 9]], [[4, 10], [5, 11], [6, 12]]], shape = [2,3,2]

这种方法的弊端就是大于3维的数组就不好想了,毕竟我们生活的是3维世界。

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

推荐阅读更多精彩内容