欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

tf.nn.moments()函数解析(最清晰的解释)

程序员文章站 2022-04-02 21:08:50
...

tf.nn.moments()函数用于计算均值和方差。

# 用于在指定维度计算均值与方差
tf.nn.moments(
    x,
    axes,
    shift=None,	# pylint: disable=unused-argument
    name=None,
    keep_dims=False)

参数:

  • x:一个Tensor,可以理解为我们输出的数据,形如 [batchsize, height, width, kernels]。

  • axes:整数数组,用于指定计算均值和方差的轴。如果x是1-D向量且axes=[0] 那么该函数就是计算整个向量的均值与方差。

  • shift:未在当前实现中使用。

  • name:用于计算moment的操作范围的名称。

  • keep_dims:产生与输入具有相同维度的moment,通俗点说就是是否保持维度。

返回:

Two Tensor objects: mean and variance.

两个Tensor对象:mean和variance.

解释如下:

  • mean 就是均值
  • variance 就是方差

例子1:

计算3 * 3维向量的mean和variance,程序如下:

import tensorflow as tf

img = tf.Variable(tf.random_normal([3, 3]))
axis = list(range(len(img.get_shape()) - 1))
mean, variance = tf.nn.moments(img, axis)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(img))
    print(axis)
    resultMean = sess.run(mean)
    print('resultMean',resultMean)
    resultVar = sess.run(variance)
    print('resultVar',resultVar)

> [[ 0.9398157   1.1222504  -0.6046098 ]
   [ 1.4187386  -0.298682    1.033441  ]
   [ 0.64805275  0.40496045  1.4371132 ]]
> [0]
> resultMean [1.0022024  0.40950966 0.62198144]
> # (0.9398157 + 1.4187386 + 0.64805275)/3=1.0022024
> resultVar [0.10093883 0.33651853 0.77942157]
> # ((0.9398157-1.0022024)**2+(1.4187386-1.0022024)**2+(0.64805275-1.0022024)**2)/3=0.10093883

根据上面的代码,很容易可以看出axis=[0],那么tf.moments()函数就是在 [0] 维度上求了个均值和方差。(**[0] ** 表示行,所以每次要取每一行其中的一个元素)

Note:不写1,表示计算以列为单位计算(就是是axis=[0], 不是axis=[0, 1])

而针对3 * 3的矩阵,其实可以这么理解,当axis=[0]时,那么我们3 * 3的矩阵就可以看成三个长度为3的一维向量,然后就是三个向量的均值和方差计算,也就是对应三个向量的对应第一个数进行一次计算,对应第二个数进行一次计算,对应第三个数进行一次计算,这么说的就非常的通俗了。这是一个非常简单的例子,如果换做形如

例子2:

计算卷积神经网络某层的的mean和variance,程序如下:

import tensorflow as tf

img = tf.Variable(tf.random_normal([128, 32, 32, 64]))
axis = list(range(len(img.get_shape()) - 1))  # axis=[0, 1, 2]
mean, variance = tf.nn.moments(img, axis)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
#     print(sess.run(img))
    print(axis)
    resultMean = sess.run(mean)
    print('resultMean',resultMean)
    resultVar = sess.run(variance)
    print('resultVar',resultVar)

形如[128, 32, 32, 64]的数据在CNN的中间层非常常见,为了给出一个直观的认识,函数的输出结果如下,可能输出的数字比较多。

> [0, 1, 2]
> resultMean [ 2.6853075e-03 -3.0257576e-03  2.3035323e-03 -2.6062224e-03
 			  -3.2305701e-03  2.1037455e-03  6.7329779e-03 -2.2388114e-04
  			   2.6253066e-03 -6.7248638e-03  2.3191441e-04 -5.8187090e-04
			  -9.0473756e-04 -1.6551851e-03 -1.1362392e-03 -1.9381186e-03
			  -1.2468656e-03 -3.5813404e-03  7.0505054e-04  5.0926261e-04
			  -3.4001360e-03 -2.2198933e-03 -1.8291552e-04 -2.9487342e-03
			   2.8003550e-03  2.0361040e-03  7.5038348e-04  1.1216532e-03
			   1.1721103e-03  4.0136781e-03 -1.3581098e-03 -1.9081675e-03
			  -5.7506924e-03  1.4085017e-04  9.2261989e-04  3.6248637e-03
			  -3.4064866e-04 -1.7123687e-03  2.8599303e-03  3.3247408e-03
			  -3.0919732e-04 -2.5428729e-03 -1.8558424e-03  6.8022363e-04
			  -2.3567205e-04  2.0230825e-03 -5.6563923e-03 -4.9449857e-03
			  -1.5591505e-03  5.4281385e-04  3.4175792e-03  3.4342592e-03
			  -2.2981209e-03 -1.1064336e-03 -2.4347606e-03 -8.7688277e-03
			   4.2153443e-03  1.8990067e-03 -1.7339690e-03 -4.1099632e-04
  			   2.9905797e-05 -2.2589187e-03  1.3317640e-03 -1.0637580e-03]
> resultVar [0.99827653 0.99892205 1.0023996  1.0008711  1.0027382  1.0062183
		 	 1.0062574  0.9907291  1.0007423  1.0074934  0.9987777  0.99734586
			 0.99948376 0.9996146  0.9981512  0.9992911  1.0065222  0.9959912
			 0.99847895 0.9947184  1.0043     1.004565   0.9955365  1.0063928
			 0.9991787  0.99631685 1.0008278  1.0084031  1.0019135  1.0009897
			 1.0022242  1.0076597  1.0040829  0.9944737  1.0008909  0.9962167
			 1.002177   1.0043476  1.0003107  1.0018493  1.0021918  1.0038664
			 0.9958006  0.99403363 1.0066489  1.001033   0.9994988  0.9943808
			 0.9973529  0.9969688  1.0023019  1.004277   1.0000937  1.0009365
			 1.0067816  1.0005956  0.9942864  1.0030564  0.99745005 0.9908926
			 1.0037254  0.9974016  0.99849343 1.0066065 ]

对于 [128, 32, 32, 64] 这样的4维矩阵来说,一个batch里的128个图,经过一个64kernels卷积层处理,得到了128 * 64个图,再针对每一个kernel所对应的128个图,求它们所有像素的mean和variance,因为总共有64个kernels,输出的结果就是一个一维长度64的数组。
Note:不写4,表示计算以kernel为单位计算(就是是axis=[0, 1, 2], 不是axis=[0, 1, 2, 3])
以kernel为单位,64个kernel,表示计算会得到64个均值和64个方差。
具体怎么计算呢?
举个例子
比如第一个kernel,均值为:128个样本,它们的第一个通道得到的feature map,即128个feature map,求均值,方差同理。可以看下图,解释的比较清晰。

tf.nn.moments()函数解析(最清晰的解释)