tf一些函數(shù)

對(duì)于 tf.get_variable() vs tf.Variable(),tf.name_scope() vs tf.variable_scope()

最近剛接手tf,有些函數(shù),理解不清楚,做一下筆記。
對(duì)于函數(shù),知道平時(shí)的用法就行了,不用糾結(jié)里面的每一個(gè)參數(shù)的意思,基本用不到,還浪費(fèi)時(shí)間

一、name-scope 和 variable-scope

name-scope 和 variable-scope 都是命名空間,意思就是,定義一個(gè)空間,在這個(gè)空間里面的,定義的變量,基本都會(huì)以這個(gè)命名空間作為其變量名的前綴。(但是也有例外)

比如下圖中,盡管是兩段代碼,但都是在variable-scope定義的名稱(chēng)為“V1”的空間中。而reuse命令,允許共享當(dāng)前scope(同一個(gè)命名空間)下的所有變量,所以a1和a3的變量名都是 V1/a1:0

import tensorflow as tf    
import numpy as np    

with tf.variable_scope('V1'):  
    a1 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))  
  
with tf.variable_scope('V1', reuse=True):  
    a3 = tf.get_variable('a1')  
  • name_scope對(duì) get_variable()創(chuàng)建的變量 的名字不會(huì)有任何影響,而創(chuàng)建的op會(huì)被加上前綴.
  • tf.get_variable_scope() 返回的只是 variable_scope,不管 name_scope.所以以后我們?cè)谑褂胻f.get_variable_scope().reuse_variables() 時(shí)可以無(wú)視name_scope
  • name_scope 是給op_name加前綴, variable_scope是給get_variable()創(chuàng)建的變量的名字加前綴。

二 、tf 的 reduce(降維)操作

1. 基礎(chǔ)理解

1.1 向量的“維”

這里加入基礎(chǔ)理解的意思,是為了防止概念不清晰。
比如若說(shuō)X是一個(gè)n維向量,表示X中,含有n個(gè)元素,可以在n維坐標(biāo)系中表示出來(lái)(原點(diǎn)到X坐標(biāo)的向量)。另外,在機(jī)器學(xué)習(xí)的降維中,是把X從n維降到k維。 ---但這不是tf中的‘‘降維”

n維向量!= n維數(shù)組!!!

1.2 tf中的“維”

在tf中,用constant定義的tensor

  • 0維數(shù)組,表示一個(gè)數(shù),如:6。(可以理解為“點(diǎn)”)
  • 1維數(shù)組,表示一個(gè)a = [1,2,3]。(可以理解為“線(xiàn)”,這也和上面的向量聯(lián)系起來(lái)了。一方面,這是一個(gè)三維向量,另一方面,在n維坐標(biāo)系中,向量是一條直線(xiàn),是“線(xiàn)”)
  • 2維數(shù)組,表示一個(gè)
    b = [[1,2,3],
    [4,5,6]]。(可以理解為“面”,或者矩陣)
  • 3維數(shù)組,表示一個(gè)
    c = [[[1,2,3],[4,5,6]],
    [[7,8,9],[1,1,1]],
    [[2,2,2],[3,3,3]]]
    可以理解為“體”。
1.3 對(duì)數(shù)組進(jìn)行索引

索引,類(lèi)似于Python中的列表索引,0表示第一個(gè)元素,但又不一樣。
比如,對(duì)上面的2維數(shù)組b進(jìn)行索引 ,得到
b[0] = [1,2,3],
c[0] = [[1.2.3].[4.5.6]] (都是數(shù)組里的第一個(gè)元素)

1.4 tf.reduce_xxx操作中的axis

因?yàn)榘姹镜牟煌袝r(shí)參數(shù)axis(軸)等同于參數(shù)reduction_indices(減去索引)
這里所說(shuō)的,應(yīng)該是側(cè)重于axis軸的意思

這里作者就按照坐標(biāo)軸來(lái)理解。比如,上面的三維數(shù)組c,我把它理解為由x,y,z軸組成的坐標(biāo)系中的三個(gè)自變量組成的“體”,c的0維就相當(dāng)于x變量,剩下的由y和z兩個(gè)組成的幾個(gè)平面,也就是剩下的3個(gè)二維數(shù)組。這里的“c的0維”不等于“c[0]”。

那么。去掉c的0維,就相當(dāng)于只剩下y,z兩個(gè)變量組成的三個(gè)平面。

reduc_sum(c,0)那就理解為,先把三個(gè)平面相加,再去掉x自變量。
所以,就相當(dāng)于,先把每個(gè)第0維里面的元素(即三個(gè)二維數(shù)組)按照規(guī)則相加,再去掉最外面的“0維”。于是,最后剩一個(gè)二維數(shù)組。

最外面的中括號(hào)代表了第0維,再往里代表了第1維(比如[[1,2,3],[4,5,6]],第一維里面的元素相加,就是[1,2,3]+[4,5,6]),再往里代表了第2維(比如[1,2,3].)

1.5 代碼

具體別的情況,就看下面代碼。其中,keep_dims表示的意思就是,照常計(jì)算,但不消除該維。

import tensorflow as tf
import numpy as np    

x = [[[1,2,3],[4,5,6]],
[[7,8,9],[1,1,1]],
[[2,2,2],[3,3,3]]]

x = tf.constant(x)

# x 后面沒(méi)有參數(shù),就默認(rèn)為把所有的元素相加
a = tf.reduce_sum(x)

#把所有0維里的元素都按照規(guī)則相加,再消去0維度(即消去代表0維度的中括號(hào))
b = tf.reduce_sum(x,0)

#以下沒(méi)有消去的維度都是保留的
#只舉一個(gè)例子,把目前所有1維里的元素都相加如 ==>得到相加的結(jié)果 ==>再消去1維度
# [1,2,3]+[4,5,6] ==> [5,7,9] ==>5,7,9
c = tf.reduce_sum(x,1)

#只舉一個(gè)例子, 把所有第2維的元素都相加 ==> 得到結(jié)果 ==> 消去2維度
# [1+2+3],[4+5+6] ==> [6],[15] ==> 6,15
d = tf.reduce_sum(x,2)

# 把第1維所有元素相加,得到結(jié)果 ==> 再把第2維所有元素相加,得到結(jié)果 ==>消去1,2維度
# [[[5,7,9]],[[8,9,10]],[[5,5,5]]]==>[[[21]],[[27]],[[15]]]==>[21,27,15]
f = tf.reduce_sum(x,[1,2])

#把0維所有元素相加以后,1維所有元素相加以后,2維所有元素相加以后消去012維
g = tf.reduce_sum(x,[0,1,2])

#把目前所有1維里的元素都相加如 ==>得到相加的結(jié)果 ==>但不消去1維度(即括號(hào)不去掉)== 保留該維度
# [1,2,3]+[4,5,6] ==> [5,7,9] ==>[5,7,9]
h = tf.reduce_sum(x,1,keep_dims=True)

#只舉一個(gè)例子, 把所有第2維的元素都相加 ==> 得到結(jié)果 ==> 但不消去2維度 == 保留該維度
# [1+2+3],[4+5+6] ==> [6],[15] ==> [6],[15]
i = tf.reduce_sum(x,2,keep_dims=True)

with tf.Session() as sess:
   print('a',sess.run(a))
   print('b',sess.run(b))
   print('c',sess.run(c))
   print('d',sess.run(d))
   print('f',sess.run(f))
   print('g',sess.run(g))
   print('h',sess.run(h))
   print('i',sess.run(i))

三、tf.nn.embedding_lookup()函數(shù)

基礎(chǔ)知識(shí)

shape,列表和數(shù)組,

  • 1 shape方法
    shape方法得到的結(jié)果的是一個(gè)tuple,從第一個(gè)元素到最后一個(gè)元素,依次表示的是從數(shù)組第0維里含有元素的個(gè)數(shù),第1維含有元素的個(gè)數(shù),第2維。。。如上面的x數(shù)組,x.shape ==>(3,2,3);再如a=[1,2,3]是一個(gè)列表,那么a.shape ==>(3,)一定有一個(gè)逗號(hào),表示這是一個(gè)元組的數(shù)據(jù)結(jié)構(gòu)

  • 2 列表和數(shù)組
    在運(yùn)用一個(gè)函數(shù)或者方法之前,一定要弄明白,需要傳入的參數(shù)是什么數(shù)據(jù)結(jié)構(gòu)的!!!就比如這個(gè)方法,作者一開(kāi)始定義好x之后,沒(méi)有用np.array設(shè)置成數(shù)組,或者用constant設(shè)置成一個(gè)整體的tensor,結(jié)果x一直是列表形式,最終出現(xiàn)毛病。

def embedding_lookup(params, ids, partition_strategy="mod"),主要講這三個(gè)參數(shù)。

params可以是一個(gè)tensor,也可以是多個(gè)tensor,不過(guò)輸入多個(gè)tensor的時(shí)候,需要用作為params=[a,b,c]的形式進(jìn)行輸入。

當(dāng)系統(tǒng)認(rèn)為,params的長(zhǎng)度等于1時(shí)候,就和平時(shí)的索引一樣,按照ids中的id索引就行。

但是當(dāng)系統(tǒng)認(rèn)為params的長(zhǎng)度大于1的時(shí)候,就會(huì)用第三個(gè)參數(shù)(默認(rèn)是“mod”)的模式,將params去掉里面每個(gè)tensor的中括號(hào)以后所有的元素個(gè)數(shù),按照求余數(shù)相同的方式分成len(params)個(gè)切片,每個(gè)切片里的第i個(gè)id對(duì)應(yīng)該切片里的第i個(gè)元素。
舉個(gè)栗子:
a = [[1,2,3],[4,5,6]]
b = [[7,8,9],[1,1,1]]
c = [[2,2,2],[3,3,3]]
a = tf.constant(a)
b = tf.constant(b)
c = tf.constant(c)

那么傳入params=[a,b,c],此時(shí),系統(tǒng)認(rèn)為params里是多個(gè)量了(3個(gè)tensor),那么去掉每個(gè)tensor的最外面中括號(hào)共有3*2=6個(gè)元素,所以一共可以有6個(gè)id,分別是012345,有3個(gè)tensor,就有3個(gè)切片。按照余數(shù)相同分組,不均勻就前面的分的多。分為[0,3],[1,4],[2,5],對(duì)應(yīng)的分別是 a,b,c。索引id時(shí),id等于3,就相當(dāng)于索引的是a中第二個(gè)元素,所以索引的是[4,5,6].

另外,返回的tensor的shape應(yīng)該是shape(ids) + shape.params[1:]
這里的params指的是被索引的那個(gè)param
比如ids = [3],那么返回的結(jié)果的shape應(yīng)該是shape.[3] + shape.a[1:]=(1,)+(2,3)[1:] = (1,)+(3,) = (1,3),所以結(jié)果應(yīng)該是[[4,5,6]],二維數(shù)組
但這里,這個(gè)函數(shù)是把a(bǔ)作為一個(gè)params了,作為一個(gè)tensor了。

另外需要注意的是,tf中傳入多個(gè)參數(shù),就是用中括號(hào)把參數(shù)作為一個(gè)整體,以列表的方式傳給函數(shù)。所以,有的函數(shù)一旦遇到[a,b,c]這種形式的,就會(huì)認(rèn)為a,b,c是參數(shù)。
所以,若是x一開(kāi)始定義為列表格式的話(huà),那么這個(gè)函數(shù)就會(huì)把這個(gè)‘表示為列表的中括號(hào)’認(rèn)為是類(lèi)似于上面的[a,b,c]這個(gè)傳參的中括號(hào),從而把x認(rèn)為是由三個(gè)tensor組成的。然后就會(huì)啟動(dòng)上面所說(shuō)的切片模式。比如用上面說(shuō)的x,那么就會(huì)認(rèn)為x是三個(gè)[2,3]的數(shù)組。

但是如果用np.array(x)或者用x=tf.constant(x)以后,x就被認(rèn)為是一個(gè)整個(gè)的tensor了,那么這時(shí)候就認(rèn)為x是1個(gè),就不會(huì)啟動(dòng)上面的切片模式,就是正常的索引現(xiàn)象。

以后在遇到的時(shí)候,需要先明確x是列表,還是由constant定義好了的一個(gè)tensor(或者nparray定義的數(shù)組)。自己用的時(shí)候,最好用后者,把x當(dāng)成是一個(gè)整體,若是需要輸入多個(gè),那么就用[a,b,c]的方式輸入。

四、 tf.gather(params,indices,..)

合并 - 索引indices所指示的params中的切片
比如a = tf.gather(x,[0,2]),就是索引x這個(gè)tensor的0維下的元素的位置索引為0,2的兩個(gè)元素 并合并起來(lái),即結(jié)果再放進(jìn)一個(gè)列表中, 即使只有一個(gè)元素也要放進(jìn)列表中

import tensorflow as tf

x = [[[1,2,3],[4,5,6]],
[[7,8,9],[1,1,1]],
[[2,2,2],[3,3,3]]]

a = tf.gather(x,[0,2])

with tf.Session() as sess:
    print('a',sess.run(a))#輸出123,456和222,333

五、tf 的onehot函數(shù)

參考[tf.one_hot()函數(shù)簡(jiǎn)介](http://www.lxweimin.com/writer#/notebooks/17771847/notes/18446692/preview

比如,輸入indices是一維列表,[1,3,5,7,9],depth等于10
那么就會(huì)輸出一個(gè)shape為[5,10]的二維數(shù)組,其中第一行中的索引為1的位置為1,其余為0.第二行中索引為3的位置為1,其余值為0.

如果輸入的indices是一個(gè)shape是[1,5]的二維數(shù)組,[[1,3,5,7,9]],那么輸出就會(huì)使一個(gè)[1,5,10]的三維數(shù)組。其中的onehot形式是一樣的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • TF API數(shù)學(xué)計(jì)算tf...... :math(1)剛開(kāi)始先給一個(gè)運(yùn)行實(shí)例。tf是基于圖(Graph)的計(jì)算系統(tǒng)...
    MachineLP閱讀 3,523評(píng)論 0 1
  • 1. tf函數(shù) tensorflow 封裝的工具類(lèi)函數(shù) | 操作組 | 操作 ||:-------------| ...
    南墻已破閱讀 5,221評(píng)論 0 5
  • 媽媽母親節(jié)快樂(lè)! 一早起來(lái),我就開(kāi)始為寶寶班的孩子們,給媽媽們一個(gè)節(jié)日的驚喜忙碌著,等到寶寶們都被媽媽接走了,才想...
    愛(ài)舞蹈閱讀 333評(píng)論 2 1
  • 人生對(duì)于我們來(lái)說(shuō)到底意味著什么?我覺(jué)得就是一場(chǎng)旅行,一個(gè)人去從來(lái)沒(méi)去過(guò)的遠(yuǎn)方說(shuō)不怕都是騙人的,但我們總要長(zhǎng)大遠(yuǎn)方...
    站在城墻上等我歸來(lái)閱讀 259評(píng)論 0 0
  • 在《歌手》的舞臺(tái)上張杰唱了《你就不要想起我》,最后自己哭了,哭的像個(gè)孩子,而我呢。我聽(tīng)傻了~ 本來(lái)唱的是~你就不要...
    瀟瀟暔閱讀 346評(píng)論 0 0