TensorFlow 和 NumPy 的 Broadcasting 機制探秘

在使用Tensorflow的過程中置吓,我們經(jīng)常遇到數(shù)組形狀不同的情況斜纪,但有時候發(fā)現(xiàn)二者還能進行加減乘除的運算,在這背后洞就,其實是Tensorflow的broadcast即廣播機制幫了大忙棍厌。而Tensorflow中的廣播機制其實是效仿的numpy中的廣播機制肾胯。本篇,我們就來一同研究下numpy和Tensorflow中的廣播機制耘纱。

1敬肚、numpy廣播原理

1.1 數(shù)組和標量計算時的廣播

標量和數(shù)組合并時就會發(fā)生簡單的廣播,標量會和數(shù)組中的每一個元素進行計算束析。

舉個例子:

arr = np.arange(5)
arr * 4

得到的輸出為:

array([ 0,  4,  8, 12, 16])

這個是很好理解的帘皿,我們重點來研究數(shù)組之間的廣播

1.2 數(shù)組之間計算時的廣播

用書中的話來介紹廣播的規(guī)則:兩個數(shù)組之間廣播的規(guī)則:如果兩個數(shù)組的后緣維度(即從末尾開始算起的維度)的軸長度相等或其中一方的長度為1,則認為他們是廣播兼容的畸陡,廣播會在缺失和(或)長度為1的維度上進行鹰溜。

上面的規(guī)則挺拗口的,我們舉幾個例子吧:

二維的情況
假設有一個二維數(shù)組丁恭,我們想要減去它在0軸和1軸的均值曹动,這時的廣播是什么樣的呢。

我們先來看減去0軸均值的情況:

arr = np.arange(12).reshape(4,3)
arr-arr.mean(0)

輸出的結果為:

array([[-4.5, -4.5, -4.5],
       [-1.5, -1.5, -1.5],
       [ 1.5,  1.5,  1.5],
       [ 4.5,  4.5,  4.5]])

0軸的平均值為[4.5,5.5,6.5]牲览,形狀為(3,)墓陈,而原數(shù)組形狀為(4,3),在進行廣播時第献,從后往前比較兩個數(shù)組的形狀贡必,首先是3=3,滿足條件而繼續(xù)比較庸毫,這時候發(fā)現(xiàn)其中一個數(shù)組的形狀數(shù)組遍歷完成仔拟,因此會在缺失軸即0軸上進行廣播。

可以理解成將均值數(shù)組在0軸上復制4份飒赃,變成形狀(4,3)的數(shù)組利花,再與原數(shù)組進行計算。

書中的圖形象的表示了這個過程(數(shù)據(jù)不一樣請忽略):

我們再來看一下減去1軸平均值的情況载佳,即每行都減去該行的平均值:

arr - arr.mean(1)

此時報錯了:

我們再來念叨一遍我們的廣播規(guī)則炒事,均值數(shù)組的形狀為(4,),而原數(shù)組形狀為(4,3)蔫慧,按照比較規(guī)則挠乳,4 != 3姑躲,因此不符合廣播的條件睡扬,因此報錯。

正確的做法是什么呢肋联,因為原數(shù)組在0軸上的形狀為4威蕉,我們的均值數(shù)組必須要先有一個值能夠跟3比較同時滿足我們的廣播規(guī)則,這個值不用多想橄仍,就是1韧涨。因此我們需要先將均值數(shù)組變成(4,1)的形狀,再去進行運算:

arr-arr.mean(1).reshape((4,1))

得到正確的結果:

array([[-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.],
       [-1.,  0.,  1.]])

三維的情況
理解了二維的情況侮繁,我們也就能很快的理解三維數(shù)組的情況虑粥。

首先看下圖:

根據(jù)廣播原則分析:arr1的shape為(3,4,2),arr2的shape為(4,2),它們的后緣軸長度都為(4,2)宪哩,所以可以在0軸進行廣播娩贷。因此,arr2在0軸上復制三份锁孟,shape變?yōu)?3,4,2)彬祖,再進行計算茁瘦。

不只是0軸,1軸和2軸也都可以進行廣播储笑。但形狀必須滿足一定的條件甜熔。舉個例子來說,我們arr1的shape為(8,5,3)突倍,想要在0軸上廣播的話腔稀,arr2的shape是(1,5,3)或者(5,3),想要在1軸上進行廣播的話羽历,arr2的shape是(8,1,3)焊虏,想要在2軸上廣播的話,arr2的shape必須是(8,5,1)秕磷。

我們來寫幾個例子吧:

arr2 = np.arange(24).reshape((2,3,4))
arr3_0 = np.arange(12).reshape((3,4))
print("0軸廣播")
print(arr2 - arr3_0)

arr3_1 = np.arange(8).reshape((2,1,4))
print("1軸廣播")
print(arr2 - arr3_1)

arr3_2 = np.arange(6).reshape((2,3,1))
print("2軸廣播")
print(arr2 - arr3_2)

輸出為:

0軸廣播
[[[ 0  0  0  0]
  [ 0  0  0  0]
  [ 0  0  0  0]]

 [[12 12 12 12]
  [12 12 12 12]
  [12 12 12 12]]]
1軸廣播
[[[ 0  0  0  0]
  [ 4  4  4  4]
  [ 8  8  8  8]]

 [[ 8  8  8  8]
  [12 12 12 12]
  [16 16 16 16]]]
2軸廣播
[[[ 0  1  2  3]
  [ 3  4  5  6]
  [ 6  7  8  9]]

 [[ 9 10 11 12]
  [12 13 14 15]
  [15 16
 17 18]]]

如果我們想在兩個軸上進行廣播诵闭,那arr2的shape要滿足什么條件呢?

arr1.shape 廣播軸 arr2.shape
(8,5,3) 0,1 (3,),(1,3),(1,1,3)
(8,5,3) 0,2 (5,1),(1,5,1)
(8,5,3) 1,2 (8,1,1)

具體的例子就不給出啦跳夭,嘻嘻涂圆。

2、Tensorflow 廣播舉例

Tensorflow中的廣播機制和numpy是一樣的币叹,因此我們給出一些簡單的舉例:

二維的情況

sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3),0,0.1))
b = tf.Variable(tf.random_normal((2,1),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)

輸出為:

array([[-0.1419442 ,  0.14135399,  0.22752595],
       [ 0.1382471 ,  0.28228047,  0.13102233]], dtype=float32)

三維的情況

sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3,4),0,0.1))
b = tf.Variable(tf.random_normal((2,1,4),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)

輸出為:

array([[[-0.0154749 , -0.02047186, -0.01022427, -0.08932371],
        [-0.12693939, -0.08069084, -0.15459496,  0.09405404],
        [ 0.09730847,  0.06936138,  0.04050628,  0.15374713]],

       [[-0.02691782, -0.26384184,  0.05825682, -0.07617196],
        [-0.02653179, -0.01997554, -0.06522765,  0.03028341],
        [-0.07577246,  0.03199019,  0.0321    , -0.12571403]]], dtype=float32)

錯誤示例

sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3,4),0,0.1))
b = tf.Variable(tf.random_normal((2,4),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)

輸出為:

ValueError: Dimensions must be equal, but are 3 and 2 for 'sub_2' (op: 'Sub') with input shapes: [2,3,4], [2,4].
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末润歉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子颈抚,更是在濱河造成了極大的恐慌踩衩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贩汉,死亡現(xiàn)場離奇詭異驱富,居然都是意外死亡,警方通過查閱死者的電腦和手機匹舞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門褐鸥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赐稽,你說我怎么就攤上這事叫榕。” “怎么了姊舵?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵晰绎,是天一觀的道長。 經(jīng)常有香客問我括丁,道長荞下,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮尖昏,結果婚禮上仰税,老公的妹妹穿的比我還像新娘。我一直安慰自己抽诉,他們只是感情好肖卧,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掸鹅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拦赠。 梳的紋絲不亂的頭發(fā)上巍沙,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音荷鼠,去河邊找鬼句携。 笑死,一個胖子當著我的面吹牛允乐,可吹牛的內(nèi)容都是我干的矮嫉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼牍疏,長吁一口氣:“原來是場噩夢啊……” “哼蠢笋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鳞陨,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤昨寞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厦滤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體援岩,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年掏导,在試婚紗的時候發(fā)現(xiàn)自己被綠了享怀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡趟咆,死狀恐怖添瓷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忍啸,我是刑警寧澤仰坦,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站计雌,受9級特大地震影響悄晃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一妈橄、第九天 我趴在偏房一處隱蔽的房頂上張望庶近。 院中可真熱鬧,春花似錦眷蚓、人聲如沸鼻种。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叉钥。三九已至,卻和暖如春篙贸,著一層夾襖步出監(jiān)牢的瞬間投队,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工爵川, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敷鸦,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓寝贡,卻偏偏與公主長得像扒披,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子圃泡,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361