深度学习基础

tf一些函数

2017-10-19  本文已影响835人  小碧小琳

对于 tf.get_variable() vs tf.Variable(),tf.name_scope() vs tf.variable_scope()

最近刚接手tf,有些函数,理解不清楚,做一下笔记。
对于函数,知道平时的用法就行了,不用纠结里面的每一个参数的意思,基本用不到,还浪费时间

一、name-scope 和 variable-scope

name-scope 和 variable-scope 都是命名空间,意思就是,定义一个空间,在这个空间里面的,定义的变量,基本都会以这个命名空间作为其变量名的前缀。(但是也有例外)

比如下图中,尽管是两段代码,但都是在variable-scope定义的名称为“V1”的空间中。而reuse命令,允许共享当前scope(同一个命名空间)下的所有变量,所以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')  

二 、tf 的 reduce(降维)操作

1. 基础理解

1.1 向量的“维”

这里加入基础理解的意思,是为了防止概念不清晰。
比如若说X是一个n维向量,表示X中,含有n个元素,可以在n维坐标系中表示出来(原点到X坐标的向量)。另外,在机器学习的降维中,是把X从n维降到k维。 ---但这不是tf中的‘‘降维”

n维向量!= n维数组!!!

1.2 tf中的“维”

在tf中,用constant定义的tensor

1.3 对数组进行索引

索引,类似于Python中的列表索引,0表示第一个元素,但又不一样。
比如,对上面的2维数组b进行索引 ,得到
b[0] = [1,2,3],
c[0] = [[1.2.3].[4.5.6]] (都是数组里的第一个元素)

1.4 tf.reduce_xxx操作中的axis

因为版本的不同,有时参数axis(轴)等同于参数reduction_indices(减去索引)
这里所说的,应该是侧重于axis轴的意思

这里作者就按照坐标轴来理解。比如,上面的三维数组c,我把它理解为由x,y,z轴组成的坐标系中的三个自变量组成的“体”,c的0维就相当于x变量,剩下的由y和z两个组成的几个平面,也就是剩下的3个二维数组。这里的“c的0维”不等于“c[0]”。

那么。去掉c的0维,就相当于只剩下y,z两个变量组成的三个平面。

reduc_sum(c,0)那就理解为,先把三个平面相加,再去掉x自变量。
所以,就相当于,先把每个第0维里面的元素(即三个二维数组)按照规则相加,再去掉最外面的“0维”。于是,最后剩一个二维数组。

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

1.5 代码

具体别的情况,就看下面代码。其中,keep_dims表示的意思就是,照常计算,但不消除该维。

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 后面没有参数,就默认为把所有的元素相加
a = tf.reduce_sum(x)

#把所有0维里的元素都按照规则相加,再消去0维度(即消去代表0维度的中括号)
b = tf.reduce_sum(x,0)

#以下没有消去的维度都是保留的
#只举一个例子,把目前所有1维里的元素都相加如 ==>得到相加的结果 ==>再消去1维度
# [1,2,3]+[4,5,6] ==> [5,7,9] ==>5,7,9
c = tf.reduce_sum(x,1)

#只举一个例子, 把所有第2维的元素都相加 ==> 得到结果 ==> 消去2维度
# [1+2+3],[4+5+6] ==> [6],[15] ==> 6,15
d = tf.reduce_sum(x,2)

# 把第1维所有元素相加,得到结果 ==> 再把第2维所有元素相加,得到结果 ==>消去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维里的元素都相加如 ==>得到相加的结果 ==>但不消去1维度(即括号不去掉)== 保留该维度
# [1,2,3]+[4,5,6] ==> [5,7,9] ==>[5,7,9]
h = tf.reduce_sum(x,1,keep_dims=True)

#只举一个例子, 把所有第2维的元素都相加 ==> 得到结果 ==> 但不消去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()函数

基础知识

shape,列表和数组,

def embedding_lookup(params, ids, partition_strategy="mod"),主要讲这三个参数。

params可以是一个tensor,也可以是多个tensor,不过输入多个tensor的时候,需要用作为params=[a,b,c]的形式进行输入。

当系统认为,params的长度等于1时候,就和平时的索引一样,按照ids中的id索引就行。

但是当系统认为params的长度大于1的时候,就会用第三个参数(默认是“mod”)的模式,将params去掉里面每个tensor的中括号以后所有的元素个数,按照求余数相同的方式分成len(params)个切片,每个切片里的第i个id对应该切片里的第i个元素。
举个栗子:
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],此时,系统认为params里是多个量了(3个tensor),那么去掉每个tensor的最外面中括号共有3*2=6个元素,所以一共可以有6个id,分别是012345,有3个tensor,就有3个切片。按照余数相同分组,不均匀就前面的分的多。分为[0,3],[1,4],[2,5],对应的分别是 a,b,c。索引id时,id等于3,就相当于索引的是a中第二个元素,所以索引的是[4,5,6].

另外,返回的tensor的shape应该是shape(ids) + shape.params[1:]
这里的params指的是被索引的那个param
比如ids = [3],那么返回的结果的shape应该是shape.[3] + shape.a[1:]=(1,)+(2,3)[1:] = (1,)+(3,) = (1,3),所以结果应该是[[4,5,6]],二维数组
但这里,这个函数是把a作为一个params了,作为一个tensor了。

另外需要注意的是,tf中传入多个参数,就是用中括号把参数作为一个整体,以列表的方式传给函数。所以,有的函数一旦遇到[a,b,c]这种形式的,就会认为a,b,c是参数。
所以,若是x一开始定义为列表格式的话,那么这个函数就会把这个‘表示为列表的中括号’认为是类似于上面的[a,b,c]这个传参的中括号,从而把x认为是由三个tensor组成的。然后就会启动上面所说的切片模式。比如用上面说的x,那么就会认为x是三个[2,3]的数组。

但是如果用np.array(x)或者用x=tf.constant(x)以后,x就被认为是一个整个的tensor了,那么这时候就认为x是1个,就不会启动上面的切片模式,就是正常的索引现象。

以后在遇到的时候,需要先明确x是列表,还是由constant定义好了的一个tensor(或者nparray定义的数组)。自己用的时候,最好用后者,把x当成是一个整体,若是需要输入多个,那么就用[a,b,c]的方式输入。

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

合并 - 索引indices所指示的params中的切片
比如a = tf.gather(x,[0,2]),就是索引x这个tensor的0维下的元素的位置索引为0,2的两个元素 并合并起来,即结果再放进一个列表中, 即使只有一个元素也要放进列表中

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函数

参考[tf.one_hot()函数简介](https://www.jianshu.com/writer#/notebooks/17771847/notes/18446692/preview

比如,输入indices是一维列表,[1,3,5,7,9],depth等于10
那么就会输出一个shape为[5,10]的二维数组,其中第一行中的索引为1的位置为1,其余为0.第二行中索引为3的位置为1,其余值为0.

如果输入的indices是一个shape是[1,5]的二维数组,[[1,3,5,7,9]],那么输出就会使一个[1,5,10]的三维数组。其中的onehot形式是一样的。

上一篇下一篇

猜你喜欢

热点阅读