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
时,loss
和 mean_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 行为。这是使用激活函数的主要目的。
另一个目的是限制神经元的输出范围。下图显示了 Sigmoid
和 ReLU
激活函数(图像是从 here 收集的)。
这两个图准确地显示了它们可以对通过它们的值施加什么样的限制。如果您查看 Sigmoid
函数,它允许输出在 between 0 to 1
中。所以我们可以将其视为基于函数某些输入值的概率映射。那么我们可以在哪里使用它呢?对于二进制 classification,如果我们为两个不同的 classes 分配 0
和 1
,并在输出层使用 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
之间输出,这在大多数情况下都不是有效预测,因此模型会产生大量loss
和 MSE
值。由于模型正在强行预测与实际正确输出不相符的东西。
同样,当您使用 ReLU
时,它的性能会更好。因为 ReLU
不会更改任何 non-negative 值。因此,该模型可以自由预测任何 non-negative 值,现在没有必要预测接近实际输出的值。
但我认为该模型想要预测可能从 0 到 255 的强度值。因此,您的模型已经没有负值。所以从这个意义上说,技术上不需要在最后一层使用 ReLU
激活函数,因为它甚至不会得到任何负值来过滤掉(如果我没记错的话)。但是您可以使用它,因为 TensorFlow
官方文档正在使用它。但这只是出于安全目的,这样就不会出现 negative
值,并且 ReLU
不会对 non-negative
值做任何事情。
我希望找到一个答案来澄清我的疑问。我这样创建了一个 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
时,loss
和 mean_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 行为。这是使用激活函数的主要目的。
另一个目的是限制神经元的输出范围。下图显示了 Sigmoid
和 ReLU
激活函数(图像是从 here 收集的)。
这两个图准确地显示了它们可以对通过它们的值施加什么样的限制。如果您查看 Sigmoid
函数,它允许输出在 between 0 to 1
中。所以我们可以将其视为基于函数某些输入值的概率映射。那么我们可以在哪里使用它呢?对于二进制 classification,如果我们为两个不同的 classes 分配 0
和 1
,并在输出层使用 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
之间输出,这在大多数情况下都不是有效预测,因此模型会产生大量loss
和 MSE
值。由于模型正在强行预测与实际正确输出不相符的东西。
同样,当您使用 ReLU
时,它的性能会更好。因为 ReLU
不会更改任何 non-negative 值。因此,该模型可以自由预测任何 non-negative 值,现在没有必要预测接近实际输出的值。
但我认为该模型想要预测可能从 0 到 255 的强度值。因此,您的模型已经没有负值。所以从这个意义上说,技术上不需要在最后一层使用 ReLU
激活函数,因为它甚至不会得到任何负值来过滤掉(如果我没记错的话)。但是您可以使用它,因为 TensorFlow
官方文档正在使用它。但这只是出于安全目的,这样就不会出现 negative
值,并且 ReLU
不会对 non-negative
值做任何事情。