×

签到

分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

[经验分享] 将ReLU变成LeakyReLU的一种方法 吴吴吴三群2022-07-12 11:50:29 回复 查看 技术答疑 经验交流 干货资源
[经验分享] 将ReLU变成LeakyReLU的一种方法
分享到:

本次课程最重要的内容就是理解深度学习应用的开发过程、其中最有难度的就是对深度学习处理器架构、其指令集已经指令集如何运用再TensorFlow当中,为其提供加速的全栈过程。


所以就分享以下自己将ReLU改成LeakyReLU的方法和代码。


ReLU是一种能够有效缓解梯度消失的激活函数,其在现在的深度学习中有广泛的应用。

但是由于ReLU对待小于零的数值非常严苛,直接将其赋值为零(如下图所示),所以ReLU也有其局限性。

image.png


为了给小于零的前向传播值一个机会,所以ReLU出现了一个变种------LeakyReLU(如下图)

image.png


从图中可以看到LeakyReLU并不会将小于零的值直接赋零,而是用一个小于1的a来作为惩罚。


所以他的前向函数应该如下图实现:


class ReLU ( ):
    def __init__(self):
        self.LeakyReLU = 0.2
        print('\tReLU  .')
    def forward(self, input, LeakyReLU=0.2):  # 前向传播的计算
        start_time = time.time()
        self.input = input
        # TODO:ReLU层的前向传播,计算输出结果
        # output = ________________
        output = np.maximum(self.input * LeakyReLU, self.input)
        return output


其中: output = np.maximum(self.input * LeakyReLU, self.input) 最为核心

也就是x * a 和 x进行比较,取其中最大的数。若x>0,则 y = x, 若x < 0,则 y = a*x  (公式如下图)

image.png


其次有了前向传播,反向传播的实现更为重要:

def backward(self, top_diff):  # 反向传播的计算
    # TODO:ReLU层的反向传播,计算本层损失
    bottom_diff_1 = top_diff * (self.input >= 0.)
    bottom_diff_2 = top_diff * self.LeakyReLU * (self.input < 0.)
    bottom_diff = bottom_diff_1 + bottom_diff_2
    return bottom_diff

反向传播公式如下图:

image.png


因此最终的代码为:

class ReLU ( ):
    def __init__(self):
        self.LeakyReLU = 0.2
        print('\tReLU  .')
    def forward(self, input, LeakyReLU=0.2):  # 前向传播的计算
        start_time = time.time()
        self.input = input
        # TODO:ReLU层的前向传播,计算输出结果
        # output = ________________
        output = np.maximum(self.input * LeakyReLU, self.input)
        return output
    def backward(self, top_diff):  # 反向传播的计算
        # TODO:ReLU层的反向传播,计算本层损失
        bottom_diff_1 = top_diff * (self.input >= 0.)
        bottom_diff_2 = top_diff * self.LeakyReLU * (self.input < 0.)
        bottom_diff = bottom_diff_1 + bottom_diff_2
        return bottom_diff


PS:在本程序中,为了使其他代码不被本次修改影响,所以就没有修改激活函数的类名,并且为了方便LeakyReLU的a值直接赋值为0.2,如果读者有需要也可以讲参数调整为__init__()函数的参数,在声明对象时进行确认a的值。


欢迎指正错误。




版权所有 © 2024 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭