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

Can relu be used at the last layer of a neural network?

我希望找到一个答案来澄清我的疑问。我这样创建了一个 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, (1,3), activation='relu', padding='same')(x)
    x = MaxPooling2D((1,2), padding='same')(x)
    x = Conv2D(32, (1,3), activation='relu', padding='same')(x)
    encoded = MaxPooling2D((1,2), padding='same')(x)

    #decoder
    x = Conv2D(32, (1,3), activation='relu', padding='same')(encoded)
    x = UpSampling2D((1,2))(x)
    x = Conv2D(32, (1,3), activation='relu', padding='same')(x)
    x = UpSampling2D((1,2))(x)
    x = Conv2D(64, (1,3), activation='relu')(x)
    x = UpSampling2D((1,2))(x)
    decoded = Conv2D(4, (1,3), 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

但是当我将解码器的最后激活更改为 relu 时,lossmean_squared_error 都迅速减少。

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

我想验证在网络架构中使用an-all relu函数是否有效。作为深度学习的新手。

你可以在最后一层使用relu函数作为激活。

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

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

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

但在此之前,我觉得我应该简要介绍一下激活函数的全部内容以及我们使用它们的原因。

激活函数的主要目标是在您的模型中引入 non-linearity。由于线性函数的组合也是线性函数,因此,如果没有激活函数,Neural Network 只不过是一个巨大的线性函数。因此,作为一个线性函数本身,它根本无法学习任何 non-linear 行为。这是使用激活函数的主要目的。

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

这两个图准确地显示了它们可以对通过它们的值施加什么样的限制。如果您查看 Sigmoid 函数,它允许输出在 between 0 to 1 中。所以我们可以将其视为基于函数某些输入值的概率映射。那么我们可以在哪里使用它呢?对于二进制 classification,如果我们为两个不同的 classes 分配 01,并在输出层使用 Sigmoid 函数,它可以给我们对于示例输入,属于某个 class 的概率。

现在来到 ReLU。它能做什么?它只允许 Non-negative 值。如您所见,水平轴中的所有负值都映射到垂直轴中的 0。但对于正值,45 度直线表明它对它们没有任何作用,并保持原样。基本上它可以帮助我们摆脱负值并使它们为 0 并仅允许 non-negative 值。数学上:relu(value) = max(0, value).

现在设想一个情况:假设您要预测可以为正、零甚至负的实数值!你会因为看起来很酷就在输出层使用ReLU激活函数吗?没有!明显不是。如果这样做,它将永远无法预测任何负值,因为所有负值都被削减为 0。

现在来看你的情况,我相信这个模型应该预测 不应 受限于 0 to 1 的值。应该是 real valued 预测。

因此,当您使用 sigmoid 函数时,它基本上是在强制模型在 0 to 1 之间输出,这在大多数情况下都不是有效预测,因此模型会产生大量lossMSE 值。由于模型正在强行预测与实际正确输出不相符的东西。

同样,当您使用 ReLU 时,它的性能会更好。因为 ReLU 不会更改任何 non-negative 值。因此,该模型可以自由预测任何 non-negative 值,现在没有必要预测接近实际输出的值。

但我认为该模型想要预测可能从 0 到 255 的强度值。因此,您的模型已经没有负值。所以从这个意义上说,技术上不需要在最后一层使用 ReLU 激活函数,因为它甚至不会得到任何负值来过滤掉(如果我没记错的话)。但是您可以使用它,因为 TensorFlow 官方文档正在使用它。但这只是出于安全目的,这样就不会出现 negative 值,并且 ReLU 不会对 non-negative 值做任何事情。