首页 > 编程知识 正文

relu是线性还是非线性,relu为何避免了梯度消失

时间:2023-05-06 11:33:56 阅读:167353 作者:4671

目录SeLu介绍ReLuSeLu比较RELU代码结果RELU BN代码结果SELU BN结果SELU BN lecun_uniform代码结果识别

SeLu介绍SeLu的论文在这里。 从能干的睫毛教授的讲课开始简单概括,就是论文的假设

1 .输入AK的是iid,且平均值为0,标准偏差为1。 (如果有多个feature,则每个feature都满足此条件。)

2 .权重满足平均值0,标准偏差w满足Kw=1。 这里,k是输入的整数。

下图(照片来自上面的讲义)、

根据上面的假设,可以得到输入activation function之前的值,即图中的z已经是normal distribution。 论文假设f的情况(未定系数),希望normal的z进来。 超出范围的值a仍然需要满足平均值为0,标准偏差为1。 这样就可以建立方程求解待定系数。 然后,论文求出了系数。

ReLuSeLu比较老师在课堂上做了几个demo,都是50层全连接的神经网络,除了512个一层的units外,剩下的256个。 看看效果吧。

数据准备如下,作为keras的官方教程的参考

importkerasfromkeras.datasetsimportmnistfromkeras.modelsimportsequentialfromkeras.layersimportdense,Dropout, batchnormalizationfromkeras.optimizersimportrmspropbatch _ size=128 num _ classes=10 epochs=3# the data,shufledandands y_train ),) x_test, y_test )=Mn ist.load _ data./data 784 ) x _ test=x _ test.reshape (10000,784 ) x _ train=x _ train.aaan=255x_type 'train samples ' ) print(x_test.shape[0], ' test samples ' ) convertclassvectorstobinaryclassmatricesy _ train=num _ classes (y _ test=keras.utils.to _ catetes )。

efrun_model(model ) : model.com pile (loss=' categorical _ cross entropy ',optimizer=RMSprop ),metrics=bats

RELU代码def relu _ without _ bn (: model=sequential ) model.add(dense ) 512,activation='relu ', input_Shaang ) for_inrange(50 ) : model.add (batch normalization ) ) model.add (dense ) 256,activation=

Epoch 1/3

15s-loss :2.3016-ACC :1122-val _ loss 33602.3013-val _ ACC :1135

Epoch 2/3

12s-loss :2.3014-ACC :1124-val _ loss 33602.3014-val _ ACC :1135

Epoch 3/3
12s - loss: 2.3014 - acc: 0.1124 - val_loss: 2.3011 - val_acc: 0.1135

可以看到3个EPOCH之后正确率只有可怜的11%左右,说明RELU这样很难训练出好的结果。

RELU & BN

Oh,no!你太土了吧,这年头谁不知道要用个Batch Normalization啦!!
我们加上试试

代码def ReLu_with_BN(): model = Sequential() model.add(Dense(512, activation='relu', input_shape=(784,))) for _ in range(50): model.add(BatchNormalization()) model.add(Dense(256, activation='relu')) model.add(BatchNormalization()) model.add(Dense(num_classes, activation='softmax')) return model结果

Train on 60000 samples, validate on 10000 samples
Epoch 1/3
41s - loss: 2.1168 - acc: 0.2476 - val_loss: 2.8542 - val_acc: 0.2367
Epoch 2/3
30s - loss: 2.0755 - acc: 0.2478 - val_loss: 3.6864 - val_acc: 0.1034
Epoch 3/3
30s - loss: 2.1711 - acc: 0.2054 - val_loss: 2.4536 - val_acc: 0.1241

外向的大雁看起来的确是比不用BN的好,可是看起来第三个Epoch的acc就掉了,不是个好兆头。

SELU

那么SELU呢?!吹了这么多,写了那么长的论文,是骡子是马拉出来溜溜吧。

代码def SeLu_without_BN(): model = Sequential() model.add(Dense(512, activation='relu', input_shape=(784,))) for _ in range(50): model.add(BatchNormalization()) model.add(Dense(256, activation='relu')) model.add(BatchNormalization()) model.add(Dense(num_classes, activation='softmax')) return model结果

Train on 60000 samples, validate on 10000 samples
Epoch 1/3
14s - loss: 2.3017 - acc: 0.1119 - val_loss: 2.3011 - val_acc: 0.1135
Epoch 2/3
12s - loss: 2.3014 - acc: 0.1124 - val_loss: 2.3012 - val_acc: 0.1135
Epoch 3/3
12s - loss: 2.3014 - acc: 0.1124 - val_loss: 2.3012 - val_acc: 0.1135

啧啧啧…喂不要吹牛啊..

SELU & BN

哦不对不对,论文中假设了输入资料的性质:均值是0,标准差是1。好在BatchNormalization可以帮助我们达到这个目的。

def SeLu_with_BN(): model = Sequential() model.add(Dense(512, activation='selu', input_shape=(784,), kernel_initializer="RandomUniform")) for _ in range(50): model.add(BatchNormalization()) model.add(Dense(256, activation='selu', kernel_initializer="RandomUniform")) model.add(BatchNormalization()) model.add(Dense(num_classes, activation='softmax')) return model结果

Train on 60000 samples, validate on 10000 samples
Epoch 1/3
45s - loss: 2.3073 - acc: 0.1559 - val_loss: 2.2522 - val_acc: 0.1403
Epoch 2/3
32s - loss: 2.1674 - acc: 0.1967 - val_loss: 2.6640 - val_acc: 0.1165
Epoch 3/3
32s - loss: 2.0270 - acc: 0.2342 - val_loss: 2.3293 - val_acc: 0.1073

喂喂喂,这个和用BN的ReLu的效果一样吧,不是吧?

SELU & BN & lecun_uniform

啊啊啊,想起来了,论文中还有一个假设:weight也要是均值为0,标准差是1。这个要怎么做呢?好像没有简单的方法可以保证在整个训练过程中都满足这个条件,不过初始的时候用kernel_initializer="lecun_uniform" 可以让初始的weight满足这个条件。

代码def SeLu_with_lecun(): model = Sequential() model.add(Dense(512, activation='selu', input_shape=(784,), kernel_initializer="lecun_uniform")) for _ in range(50): model.add(BatchNormalization()) model.add(Dense(256, activation='selu', kernel_initializer="lecun_uniform")) model.add(BatchNormalization()) model.add(Dense(num_classes, activation='softmax')) return model结果

Train on 60000 samples, validate on 10000 samples
Epoch 1/3
46s - loss: 2.1430 - acc: 0.2284 - val_loss: 5.1081 - val_acc: 0.0996
Epoch 2/3
34s - loss: 1.5847 - acc: 0.4039 - val_loss: 3.8350 - val_acc: 0.1039
Epoch 3/3
34s - loss: 1.4559 - acc: 0.4738 - val_loss: 3.5585 - val_acc: 0.1164
Test loss: 3.55849618073
Test accuracy: 0.1164

哇…服气,可以看到这边的结果明显要好于前面的,论文的工作是很不错的!

感悟

今天听完课非常有感触的,在深度学习特别是NN这一块,由于入门非常容易,并且论文读起来也不困难,所以看的东西多了就以为自己都懂了,结果弄来弄去做出来的模型一塌糊涂还怪自己运气不好2333。

今天领悟到了,根本就是学的不扎实啊。即使简单如SeLu(当然不是说其中的数学推导简单,而是说这只是提出了一个activation function,好像套用就可以了)让我有一种错觉:噢噢keras的话调用这个API就好啦,so easy,又学会了一个新知识我真厉害,结果是疯狂连续的打脸,请我继续扎实努力的学习吧我的天。

共勉!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。