问题描述
我希望找到答案以澄清我的疑问。我这样创建了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_error
和relu
都迅速下降。
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
就是巨大的线性函数。因此,本身就是线性函数,它根本无法学习任何非线性行为。这是使用激活功能的主要目的。
另一个目的是限制神经元输出的范围。下图显示了Sigmoid
和ReLU
激活功能(该图像是从here收集的)。
这两个图准确显示了它们可以对通过它们的值施加什么样的限制。如果您查看Sigmoid
函数,它将允许输出位于between 0 to 1
中。因此,我们可以认为它就像是基于函数某些输入值的概率映射。那么我们可以在哪里使用它呢?说一下二进制分类,如果我们为两个不同的类别分配0
和1
并在输出层中使用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
值做任何事情。