SMU: smooth activation function for deep networks using smoothing maximum technique

AI relu激活函数作用_AI relu激活函数作用

1.介绍

尽管ReLU有一些严重的缺点,但由于其简单性,ReLU成为深度学习中最常见的选择。本文在已知激活函数Leaky ReLU近似的基础上,提出了一种新的激活函数,称之为Smooth Maximum Unit(SMU)。用SMU替换ReLU,ShuffleNet V2模型在CIFAR100数据集上得到了6.22%的提升。

神经网络是深度学习的支柱。激活函数是神经网络的大脑,在深度神经网络的有效性和训练中起着核心作用。ReLU由于其简单性而成为深度学习领域的常用选择。尽管它很简单,但ReLU有一个主要的缺点,即ReLU死亡问题,在这种情况下,多达50%的神经元在网络训练期间死亡。

为了克服ReLU的不足,近年来提出了大量的激活方法,其中Leaky ReLU、Parametric ReLU 、ELU、Softplus、随机化Leaky ReLU是其中的几种,它们在一定程度上改善了ReLU的性能。

Swish是谷歌脑组提出的非线性激活函数,对ReLU有一定的改善;GELU是另一种常用的平滑激活函数。可以看出,Swish和GELU都是ReLU的光滑近似。近年来,人们提出了一些提高ReLU、Swish或GELU性能的非线性激活方法,其中一些是ReLU或Leaky ReLU的光滑逼近方法,还有TanhSoft、EIS、Padé激活单元、正交Padé激活单元、Mish、ErfAct等。maximum function在原点处是非光滑的。在本文中,作者将探讨maximum function的平滑逼近如何影响网络的训练和性能。

Maximum Function定义如下:

AI relu激活函数作用_AI relu激活函数作用_02

式1函数|x|在原点是不可微的。因此,从上式可以看出最大值函数在原点处也是不可微的。这里可以用Smooth函数来近似|x|函数。对于本文的其余部分,我们将只考虑两个近似| x, 在深度学习问题中使用这两个函数和近似的结果比其他近似|x|可以得到更好的结果。

注意,从上面平滑地近似|x|,而从下面平滑地近似|x|。这里 是一个平滑参数,当取 无穷大 时,近似函数平滑地逼近|x|。这里erf是高斯误差函数,定义如下:

AI relu激活函数作用_keras_03

现将式(1)中的|x|函数替换为,则最大函数的光滑逼近公式如下:

AI relu激活函数作用_AI relu激活函数作用_04

式2同理,可以推导出的光滑近似公式:

AI relu激活函数作用_keras_05

式3注意,当无穷大,;当, 。对于和的特定值,可以近似已知的激活函数。例如,, ,得到:

AI relu激活函数作用_SMU激活函数_06

式4这是maxout族中的一个简单情况,而通过考虑和的非线性选择可以发现更复杂的情况。对于和的特定值,可以得到ReLU和Leaky ReLU的平滑近似。例如,考虑和,有ReLU的平滑近似:

AI relu激活函数作用_激活函数_07

式5GELU是ReLU的光滑近似。注意,如果方程(5)中取,则可以逼近GELU激活函数,这也表明GELU是ReLU的光滑近似。此外,考虑和α,可以得到Leaky ReLU或Parametric ReLU的光滑逼近,这取决于α是超参数还是可学习参数。

AI relu激活函数作用_SMU激活函数_08

式6请注意,式(5)和式(6)下端近似为ReLU或Leaky ReLU。同样地,可以从式(3)推导出近似函数,它将近似上面的ReLU或Leaky ReLU。

式(6)对输入变量x的相应导数为:

AI relu激活函数作用_AI relu激活函数作用_09

式7其中,

AI relu激活函数作用_激活函数_10

称方程(6)中的函数为Smooth Maximum Unit(SMU)。可以将方程(3)中的和α替换为一个函数,称之为SMU-1。对于所有的实验,将使用SMU和SMU-1作为激活函数。

AI relu激活函数作用_keras_11

 

2. 代码实现:

# coding=utf-8

import tensorflow as tf
import numpy as np

def SMU(x,alpha=0.25):
    mu = tf.get_variable('SMU_mu', shape=(),
                       initializer=tf.constant_initializer(1000000),
                       dtype=tf.float32)
    print("******")
    print(mu)
    print("******")
    return ((1+alpha)*x + (1-alpha)*x*tf.math.erf(mu*(1-alpha)*x))/2

def SMU1(x,alpha=0.25):
    mu = tf.get_variable('SMU1_mu', shape=(),
                       initializer=tf.constant_initializer(4.352665993287951e-9),
                       dtype=tf.float32)# tf.compat.v1.get_variable('SMU_mu', shape=(),
    return ((1+alpha)*x+tf.math.sqrt(tf.math.square(x-alpha*x)+tf.math.square(mu)))/2

from keras.utils.generic_utils import get_custom_objects

get_custom_objects().update({'SMU': Activation(SMU)})
get_custom_objects().update({'SMU1': Activation(SMU1)})

应(调)用:

conv=Convolution1D(10, 1,strides=1,padding="valid", activation='SMU')