激活函数Swish

激活函数Swish

      • pytorch实现
      • 系列文章:

  Swish函数先对来说是比较新的一些激活函数,算是由之前的激活函数复合而成出来的。也是由Google提出的,毕竟资力雄厚,承担的起搜索的任务。而且这个算法感觉曝光率还算比较高,就在这里整理一下,同时后面的文章也会再次提到这个函数。
  对前面的激活函数有了一定的基础之后,理解Swish激活就容易很多了,Swish函数的表达式是 f ( x ) = x ⋅ σ ( x ) f(x)=x·\sigma(x) f(x)=xσ(x) σ ( x ) \sigma(x) σ(x)就是sigmoid函数。因为sigmoid函数的饱和性容易导致梯度消失,借鉴ReLU的效果,当 x x x非常大的时候,这个时候有 f ( x ) f(x) f(x)趋近于 x x x,但是当 x → − ∞ , 则 f ( x ) → 0 x→-∞,则f(x)→0 xf(x)0,函数的大致走势和ReLU比较相似,但是又比ReLU复杂。
  但是呢,为了让自己理论看起来更厉害一些,所以通常就把自己的想法抽象成一个框架,以囊括更多的东西进去。通常在函数上体现就是加几个超参数进去,然后呈现出更多的特性。在Swish中,加了一个超参数使得函数表达式变成了 f ( x ) = x ⋅ σ ( β x ) f(x)=x·\sigma(\beta x) f(x)=xσ(βx),然后说这个 β \beta β可以是常量,或者是可训练参数。函数的图像如下。
激活函数Swish_第1张图片
  接下来就是考虑这个激活函数的反向传播了,核心步骤就是求导。显然这里就是复合求导。 f ( x ) = x ⋅ σ ( β x ) f(x)=x·\sigma(\beta x) f(x)=xσ(βx)则有
激活函数Swish_第2张图片
激活函数Swish_第3张图片
  上面已经提到过 x → ± ∞ x→±∞ x±的情况,容易明白在 x > 0 x>0 x>0的时候,同样是不存在梯度消失的情况。而在 x < 0 x<0 x<0的时候,神经元也不会像ReLU一样出现死亡的情况。同时Swish相比于ReLU导数不是一成不变的,这也是一种优势。而且Swish处处可导,连续光滑。另外还有一个特点就是Swish并非一个单调的函数。但是swish也并非没有任何缺点,最大的缺点就是计算量大,本来sigmoid函数就不容易计算。
  在Swish之上,后面有人提出了一种激活函数叫h-swish,这个h代表hard(硬)的意思。大概是想让激活函数硬起来。我说的是边界,sigmoid函数取值位于[0,1]之间,两侧边界都是趋近于0或者1,这个趋近于就是soft的意思,如果直接就是常量,这就是hard。
  找到一个sigmoid函数的近似,但是两边边界是hard的。这个函数就是 f ( x ) = r e l u 6 ( x + 3 ) 6 f(x)=\frac{relu6(x+3)}{6} f(x)=6relu6(x+3),relu6代表着什么,因为relu函数无上界,给relu函数加一个上界,如果大于6,就让relu函数的值等于6,就是relu6。图像如下。
激活函数Swish_第4张图片
  显然如果对relu6再除6再向左平移三个单位,就会得到一条类似于sigmoid函数的图像。对比图如下。
激活函数Swish_第5张图片
  可以看到swish中使用到了sigmoid函数,如果我们使用h-sigmoid来构造swish函数,就得到了h-swish函数。这样一近似,计算量也变小了。
激活函数Swish_第6张图片
  这个激活后函数基本就是这样了,不知道以后是否会变成一种范式,彻底撼动ReLU的地位。

pytorch实现

class SwishImplementation(torch.autograd.Function):
    @staticmethod
    def forward(ctx, i):
        ctx.save_for_backward(i)
        return i * torch.sigmoid(i)

    @staticmethod
    def backward(ctx, grad_output):
        sigmoid_i = torch.sigmoid(ctx.saved_variables[0])
        return grad_output * (sigmoid_i * (1 + ctx.saved_variables[0] * (1 - sigmoid_i)))
    
class Swish(nn.Module):
    def forward(self, x):
        return SwishImplementation.apply(x)

系列文章:

神经网络中的激活函数总述
sigmoid激活函数
tanh激活函数
ReLU系列激活函数
maxout激活函数
Swish激活函数
激活函数发展的新里程——EvoNorms

你可能感兴趣的:(深度学习)