可以在神经网络的最后一层使用relu吗?

问题描述

我希望找到答案以澄清我的疑问。我这样创建了convolutional-autoencoder

    input_dim = Input((1,200,4))
    x = Conv2D(64,(1,3),activation='relu',padding='same')(input_dim)
    x = MaxPooling2D((1,2),padding='same')(x)
    x = Conv2D(32,padding='same')(x)
    x = MaxPooling2D((1,padding='same')(x)
    encoded = MaxPooling2D((1,padding='same')(x)

    #decoder
    x = Conv2D(32,padding='same')(encoded)
    x = UpSampling2D((1,2))(x)
    x = Conv2D(32,padding='same')(x)
    x = UpSampling2D((1,2))(x)
    x = Conv2D(64,activation='relu')(x)
    x = UpSampling2D((1,2))(x)
    decoded = Conv2D(4,activation='sigmoid',padding='same')(x)
    
    autoencoder = Model(input_layer,decoded) 

    autoencoder.compile(optimizer='adam',loss='mae',metrics=['mean_squared_error'])

但是,当我尝试像上面那样将解码器的最后一次激活为sigmoid来拟合模型时,模型损耗会稍微降低(并且在以后的时期保持不变),mean_square_error也是如此。 (使用认的Adam设置):

autoencoder.fit(train,train,epochs=100,batch_size=256,shuffle=True,validation_data=(test,test),callbacks=callbacks_list)

Epoch 1/100
97/98 [============================>.] - ETA: 0s - loss: 12.3690 - mean_squared_error: 2090.8232
Epoch 00001: loss improved from inf to 12.36328,saving model to weights.best.hdf5
98/98 [==============================] - 6s 65ms/step - loss: 12.3633 - mean_squared_error: 2089.3044 - val_loss: 12.1375 - val_mean_squared_error: 2029.4445
Epoch 2/100
97/98 [============================>.] - ETA: 0s - loss: 12.3444 - mean_squared_error: 2089.8032
Epoch 00002: loss improved from 12.36328 to 12.34172,saving model to weights.best.hdf5
98/98 [==============================] - 6s 64ms/step - loss: 12.3417 - mean_squared_error: 2089.1536 - val_loss: 12.1354 - val_mean_squared_error: 2029.4530
Epoch 3/100
97/98 [============================>.] - ETA: 0s - loss: 12.3461 - mean_squared_error: 2090.5886
Epoch 00003: loss improved from 12.34172 to 12.34068,saving model to weights.best.hdf5
98/98 [==============================] - 6s 63ms/step - loss: 12.3407 - mean_squared_error: 2089.1526 - val_loss: 12.1351 - val_mean_squared_error: 2029.4374
Epoch 4/100
97/98 [============================>.] - ETA: 0s - loss: 12.3320 - mean_squared_error: 2087.0349
Epoch 00004: loss improved from 12.34068 to 12.34050,saving model to weights.best.hdf5
98/98 [==============================] - 6s 63ms/step - loss: 12.3405 - mean_squared_error: 2089.1489 - val_loss: 12.1350 - val_mean_squared_error: 2029.4448

但是当我将解码器的最后一次激活更改为loss时,mean_squared_errorrelu都迅速下降。

Epoch 1/100
97/98 [============================>.] - ETA: 0s - loss: 9.8283 - mean_squared_error: 1267.3282 
Epoch 00001: loss improved from inf to 9.82359,saving model to weights.best.hdf5
98/98 [==============================] - 6s 64ms/step - loss: 9.8236 - mean_squared_error: 1266.0548 - val_loss: 8.4972 - val_mean_squared_error: 971.0208
Epoch 2/100
97/98 [============================>.] - ETA: 0s - loss: 8.1906 - mean_squared_error: 910.6423 
Epoch 00002: loss improved from 9.82359 to 8.19058,saving model to weights.best.hdf5
98/98 [==============================] - 6s 62ms/step - loss: 8.1906 - mean_squared_error: 910.5417 - val_loss: 7.6558 - val_mean_squared_error: 811.6011
Epoch 3/100
97/98 [============================>.] - ETA: 0s - loss: 7.3522 - mean_squared_error: 736.2031
Epoch 00003: loss improved from 8.19058 to 7.35255,saving model to weights.best.hdf5
98/98 [==============================] - 6s 61ms/step - loss: 7.3525 - mean_squared_error: 736.2403 - val_loss: 6.8044 - val_mean_squared_error: 650.5342
Epoch 4/100
97/98 [============================>.] - ETA: 0s - loss: 6.6166 - mean_squared_error: 621.1281
Epoch 00004: loss improved from 7.35255 to 6.61435,saving model to weights.best.hdf5
98/98 [==============================] - 6s 61ms/step - loss: 6.6143 - mean_squared_error: 620.6105 - val_loss: 6.2180 - val_mean_squared_error: 572.2390

我想验证在网络体系结构中使用全部relu函数是否有效。成为深度学习的新手。

解决方法

您可以在最后一层中使用relu功能进行激活。

您可以在TensorFlow官方网站here的自动编码器示例中看到。

在尝试解决标签为类值的分类问题时,请在最终输出层中使用Sigmoid / softmax激活函数。

,

您所提出的问题引出了另一个非常基本的问题。问问自己:“您实际上希望模型做什么?”-预测实际价值?还是值在一定范围内? -您会得到答案的。

但是在此之前,我应该简要介绍一下激活功能以及我们为什么使用它们。

激活功能的主要目标是在模型中引入非线性。由于线性函数的组合也是线性函数,因此,如果没有激活函数,Neural Network就是巨大的线性函数。因此,本身就是线性函数,它根本无法学习任何非线性行为。这是使用激活功能的主要目的。

另一个目的是限制神经元输出的范围。下图显示了SigmoidReLU激活功能(该图像是从here收集的)。

Sigmoid vs ReLU

这两个图准确显示了它们可以对通过它们的值施加什么样的限制。如果您查看Sigmoid函数,它将允许输出位于between 0 to 1中。因此,我们可以认为它就像是基于函数某些输入值的概率映射。那么我们可以在哪里使用它呢?说一下二进制分类,如果我们为两个不同的类别分配01并在输出层中使用Sigmoid函数,那么可以举例说明我们属于某个类别的可能性输入。

现在进入ReLU。它能做什么?它仅允许Non-negative值。如您所见,水平轴上的所有负值都被映射为垂直轴上的0。但是对于正值,45度直线表明它对它们没有任何作用,并保持原样。基本上,它可以帮助我们消除负值并将其设置为0,并且仅允许非负值。数学上:relu(value) = max(0,value)

现在想象一个情况:假设您要预测可能为正,为零甚至为负的实数值!您是否会因为看起来很酷而在输出层中使用ReLU激活功能?不!显然不是。如果这样做,它将永远无法预测任何负值,因为所有负值都被缩小为0。

现在开始处理您的案件,尽管直到现在我还没有和Convolutional Autoencoder一起工作。但是我认为该模型应该预测{strong>不应受0 to 1限制的值。它应该是real valued个预测。

因此,当您使用sigmoid函数时,基本上是迫使模型在0 to 1之间输出,并且在大多数情况下这不是有效的预测,因此该模型会产生较大的{{ 1}}和loss值。由于该模型正在强力预测与实际正确输出不符的东西。

再次使用MSE时,效果会更好。因为ReLU不会更改任何非负值。因此,该模型可以自由地预测任何非负值,并且现在没有边界可以预测接近实际输出的值。

但是我认为(尽管我没有在这个领域工作)该模型想要预测强度值,该强度值可能在0到255之间。因此,您的模型已经没有负值了。因此,从技术上讲,在最后一层不需要使用ReLU激活函数,因为它甚至不会得到任何负值来进行过滤(如果我没记错的话)。但是您可以使用它,因为官方ReLU文档正在使用它。但这只是出于安全目的,不能出现TensorFlow值,而negative不会对ReLU值做任何事情。