tensorflow实现谱归一化(Lipschitz stability constraint)


前言

根据(wgan的推导过程)在生成对抗网络的训练中,由于卷积神经网络的权重矩阵应该满足Lipschitz stability constraint,具体的详细了解,因此采用谱归一化,将权重限制在(0,1)之间以代替传统的超过1部分截断等,一般用在生成对抗网络的鉴别器中,这样带来的好处是减少了函数振荡和加速了模型收敛,推导部分可以参照下面这一篇博客,个人觉得这篇博客写的很好,就是最后的谱归一化实现不太清楚,可以参照我写的过程,也可以阅读论文wgan和wgan-gp以及spectral normalization。

对于谱归一化部分的推导和lipschitz稳定性限制可以参照这篇博客

一、实现谱归一化推导过程?

在实际进行谱归一化的过程中会产生大量的计算量,因此采用奇异值分解的方式,用幂迭代法实现卷积神经网络中权重矩阵的谱归一化,W为卷积神经网络的卷积核(权重矩阵)。
在这里插入图片描述

个人认为想要实现谱归一化(可能理解有一些错误,欢迎指正,目前正常学习中)
W = W ∥ W ∥ 2 W=\frac {W}{\left\|W\right\|_2} W=W2W
首先要先进行求得W的谱范数,即||W||,而求二范数通常使用如下两个方式:
1 ) ∥ W ∥ 2 = ∑ i = 1 M ∑ j = 1 N W i , j 2 1)\left\|W\right\|_2 = \sqrt{\sum_{i=1}^M \sum_{j=1}^N W_i,_j^{2}} 1W2=i=1Mj=1NWi,j2

2 ) ∥ W ∥ 2 ′ = sup ⁡ x ∈ R n ( ∣ A x ∣ ∣ x ∣ ) , 其 中 ∣ x ∣ = ( x , x ) 2)\left\|W\right\|_{2^{'}} = \mathop{\sup}\limits_{x\in\R^n}(\frac{|Ax|}{|x|}),其中|x|=\sqrt{(x,x)} 2W2=xRnsup(xAx),x=(x,x)
这两种方式都有较大的计算量,并且对于卷积神经网络中通常有多个卷积核,因此采用幂迭代法先求奇异值,对于奇异值有如下理论,若矩阵A的n个奇异值为

σ 1 , σ 2 , σ 3 , σ 4 , σ 5 . . . . . σ n \sigma_1,\sigma_2,\sigma_3,\sigma_4,\sigma_5.....\sigma_n σ1,σ2,σ3,σ4,σ5.....σn

1 ) ∥ W ∥ 2 = σ 1 2 , σ 2 2 , σ 3 2 , σ 4 2 , σ 5 2 . . . . . σ n 2 1)\left\|W\right\|_2 = \sqrt{\sigma_1^2,\sigma_2^2,\sigma_3^2,\sigma_4^2,\sigma_5^2.....\sigma_n^2} 1W2=σ12,σ22,σ32,σ42,σ52.....σn2
2 ) ∥ W ∥ 2 ′ = m a x ( σ 1 , σ 2 , σ 3 , σ 4 , σ 5 . . . . . σ n ) 2)\left\|W\right\|_{2^{'}}= max(\sigma_1,\sigma_2,\sigma_3,\sigma_4,\sigma_5.....\sigma_n) 2W2=max(σ1,σ2,σ3,σ4,σ5.....σn)

二、tensorflow实现

1.采用幂迭代法进行谱归一化的过程如下(示例):

import tensorflow as tf
def l2_norm(v, eps=1e-12):
    return v / (tf.reduce_sum(v ** 2) ** 0.5 + eps)
def spectral_norm(w, iteration=1):
    w_shape = w.shape.as_list()
    w = tf.reshape(w, [-1, w_shape[-1]])
    # print("w:",w.shape)#w: (48, 64)   #w: (1024, 128)   w: (2048, 256)
    u = tf.get_variable("u", [1, w_shape[-1]], initializer=tf.truncated_normal_initializer(), trainable=False)

    u_hat = u
    v_hat = None
    for i in range(iteration):
        """
        power iteration
        Usually iteration = 1 will be enough
        """
        # print("u_hat:",i,u_hat.shape)#u_hat: 0 (1, 64)   u_hat: 0 (1, 128)   u_hat: 0 (1, 256)
        v_ = tf.matmul(u_hat, tf.transpose(w))
        # print("v_",v_.shape)#v_ (1, 48)   #v_ (1, 1024)   v_ (1, 2048)
        v_hat = l2_norm(v_)
        # print("v_hat:",v_hat.shape)#v_hat: (1, 48)  v_hat: (1, 1024)   v_hat: (1, 2048)
        u_ = tf.matmul(v_hat, w)
        u_hat = l2_norm(u_)
    sigma = tf.matmul(tf.matmul(v_hat, w), tf.transpose(u_hat))
    # print("sigma",sigma.shape)#sigma (1, 1)
    w_norm = w / sigma

    with tf.control_dependencies([u.assign(u_hat)]):
        w_norm = tf.reshape(w_norm, w_shape)
    return w_norm

2.如何使用

对于tensorflow实现的卷积神经网络,只需要对参数中的卷积核调用spectral_norm函数即可代码如下(示例):

tf.nn.conv2d(input_, spectral_norm(kernel), [1, stride, stride, 1], padding=padding

3.在自己的一个模型中的实际使用效果

使用spectral_norm前
在这里插入图片描述

使用spectral_norm后
使用后

总结

在生成对抗网络中,spectral_norm通常使用在鉴别器中,能够带来比较好的效果,觉得用得上的不要忘记点个赞啊。

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值