【学习笔记】GAN模型的学习(3)------quantizer部分
1 引言
通过前半个月的学习,感觉学习到了不少的知识,也非常享受这个过程,下面将开始quantizer的部分。
2 quantizer部分
@staticmethod
def quantizer(w, config, reuse=False, temperature=1, L=5, scope='image'):
"""
Quantize feature map over L centers to obtain discrete $\hat{w}$
+ Centers: {-2,-1,0,1,2}
+ TODO: Toggle learnable centers?
"""
with tf.variable_scope('quantizer_{}'.format(scope, reuse=reuse)):
centers = tf.cast(tf.range(-2,3), tf.float32)
# Partition W into the Voronoi tesellation over the centers
w_stack = tf.stack([w for _ in range(L)], axis=-1)
w_hard = tf.cast(tf.argmin(tf.abs(w_stack - centers), axis=-1), tf.float32) + tf.reduce_min(centers)
smx = tf.nn.softmax(-1.0/temperature * tf.abs(w_stack - centers), dim=-1)
# Contract last dimension
w_soft = tf.einsum('ijklm,m->ijkl', smx, centers) # w_soft = tf.tensordot(smx, centers, axes=((-1),(0)))
# Treat quantization as differentiable for optimization
w_bar = tf.round(tf.stop_gradient(w_hard - w_soft) + w_soft)
return w_bar
量化器的作用是吧feature map的L个中心上的特征映射进行量化得到离散的w_bar
参数
w
:输入feature mapreuse
:temperature
:L
:中心点的个数scope
:是一个字符串,在这里定义为“image”、
(1)tf.cast的作用是将张量转化为一个新的数据类型
def cast(x, dtype, name=None):
参数
x
:待转化的数据(张量)dtype
: 目标数据类型name
: 可选择参数,定义参数名称(可选)
参考:tf.cast()数据类型转换
(2)tf.range
tf.range(limit, delta=1, dtype=None, name='range')
tf.range(start, limit, delta=1, dtype=None, name='range')
参数:
start
:开始limit
:结束(不包括limit的值)delta
:步长,默认为1
故tf.range(-2,3)
表示[-2,-1,0,1,2],以这五个值为中心
**Voronoi tesellation:**泰森多边形图
在数学上,它是根据到平面上一些点的距离而将平面进行划分的分区。这些点是事先已经规定好的,对每个点来说,它所对应的区域里的任何一个点到它的距离都比到其他点的距离要短。为了得到这样的区域,在操作时,我们可以连接每个点和它近邻的一些点,对得到的线段做垂直平分线,这些垂直平分线就能够包围起一块区域。
下面要根据中心点将feature map按照森泰多边形的方式来进行划分区域
(3)tf.stack
函数的作用是将一个秩为’ R ‘的张量堆成一个秩为’ (R+1) '张量.通过沿着“轴”维度打包张量,将“值”中的张量打包成一个比“值”中的每个张量高1级的张量。
Given a list of lengthN
of tensors of shape(A, B, C)
;if
axis == 0
then theoutput
tensor will have the shape(N, A, B, C)
.
ifaxis == 1
then theoutput
tensor will have the shape(A, N, B, C)
.
Etc.
参数
values
:具有相同形状和类型的张量对象列表axis
: 一个整型数。要堆叠的轴。默认为第一个维度。负值环绕,所以有效范围是[-(R+1), R+1)]name
:此操作的名称(可选)
参考文章 : tf.stack
例如:
x = tf.constant([1, 4])
y = tf.constant([2, 5])
z = tf.constant([3, 6])
tf.stack([x, y, z]) # [[1, 4], [2, 5], [3, 6]] (Pack along first dim.)
tf.stack([x, y, z], axis=1) # [[1, 2, 3], [4, 5, 6]]
示例为length=3 shape为(2, )
,axis == 0
,输出的shape为(3,2)
,axis == 1
,输出的shape为(2,3)
(4)tf.argmin:返回矩阵横列或者纵列的最小值的坐标
tf.argmin(
input,
axis=None,//0是纵列 1是横列
name=None,
dimension=None,
output_type=tf.int64
)
自己测试了一下函数的功能
import tensorflow as tf
x = tf.constant([[2, 3, 4, 2, 1],[2, 0, 4, 2, 0],[2, 0, 4, 0, 1]])
sess = tf.Session()
print(sess.run(x))
print(sess.run(tf.argmin(x, 0)))
print(sess.run(tf.argmin(x, 1)))
输出如下:
[[2 3 4 2 1]
[2 0 4 2 0]
[2 0 4 0 1]]
[0 1 0 2 1]
[4 1 1]
当axis==0
时候在一个纵列内比较,可以看出第一列都是2所以记录第一个的坐标为0,第二列是3,0,0所以记录第一个的坐标为1,以此类推
当axis==1
时候在一个行内比较,第一行1最小其坐标为1,第二行0最小,其坐标为1,以此类推
(5)tf.reduce_min:按照axis给定的维度减少input_tensor
def reduce_min(input_tensor,
axis=None,
keepdims=None,
name=None,
reduction_indices=None,
keep_dims=None):
参数
input_tensor
:输入需要减少的数字张量axis
:指定需要减少的维度(0 表示 列,1 表示行,-1 表示最后一个维度)keepdims
:如果这个参数为True,被删去的维度在结果矩阵中就被设置为1,举例:如果一个234的三维矩阵,axis=0,keepdims默认为False,则结果矩阵被降维至34(二维矩阵) 是不是一下子明白了!! 参考:Python NumPy中sum()函数详解 axis与keepdims图解
如果keepdims=True, 则矩阵维度保持不变,还是三维,只是第零个维度由2变为1,即13*4的三维矩阵name
:可选reduction_indices
:已废弃名称
参考文章: tf.reduce_max 与 reduce 系列 API
(6)tf.nn.softmax()