计算机一级电子表格TF函数,tf一些函数

对于 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')

name_scope对 get_variable()创建的变量 的名字不会有任何影响,而创建的op会被加上前缀.

tf.get_variable_scope() 返回的只是 variable_scope,不管 name_scope.所以以后我们在使用tf.get_variable_scope().reuse_variables() 时可以无视name_scope

name_scope 是给op_name加前缀, variable_scope是给get_variable()创建的变量的名字加前缀。

二 、tf 的 reduce(降维)操作

1. 基础理解

1.1 向量的“维”

这里加入基础理解的意思,是为了防止概念不清晰。

比如若说X是一个n维向量,表示X中,含有n个元素,可以在n维坐标系中表示出来(原点到X坐标的向量)。另外,在机器学习的降维中,是把X从n维降到k维。 ---但这不是tf中的‘‘降维”

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

1.2 tf中的“维”

在tf中,用constant定义的tensor

0维数组,表示一个数,如:6。(可以理解为“点”)

1维数组,表示一个a = [1,2,3]。(可以理解为“线”,这也和上面的向量联系起来了。一方面,这是一个三维向量,另一方面,在n维坐标系中,向量是一条直线,是“线”)

2维数组,表示一个

b = [[1,2,3],

[4,5,6]]。(可以理解为“面”,或者矩阵)

3维数组,表示一个

c = [[[1,2,3],[4,5,6]],

[[7,8,9],[1,1,1]],

[[2,2,2],[3,3,3]]]

可以理解为“体”。

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,列表和数组,

1 shape方法

shape方法得到的结果的是一个tuple,从第一个元素到最后一个元素,依次表示的是从数组第0维里含有元素的个数,第1维含有元素的个数,第2维。。。如上面的x数组,x.shape ==>(3,2,3);再如a=[1,2,3]是一个列表,那么a.shape ==>(3,)一定有一个逗号,表示这是一个元组的数据结构

2 列表和数组

在运用一个函数或者方法之前,一定要弄明白,需要传入的参数是什么数据结构的!!!就比如这个方法,作者一开始定义好x之后,没有用np.array设置成数组,或者用constant设置成一个整体的tensor,结果x一直是列表形式,最终出现毛病。

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

40ad96a33af6c8f6f87cd3f156897a4e.png

五、tf 的onehot函数

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

92ff42f10e2fbe03a1c8d763b41bbbc8.png

比如,输入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形式是一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值