激活函数:Softmax 与 Sigmoid

bea*_*hum 3 python conv-neural-network softmax activation-function sigmoid

我一直在尝试用 CNN 构建图像分类器。我的数据集中有 2300 张图像,分为两个类别:男性和女性。这是我使用的模型:

early_stopping = EarlyStopping(min_delta = 0.001, patience = 30, restore_best_weights = True)
model = tf.keras.Sequential()

model.add(tf.keras.layers.Conv2D(256, (3, 3), input_shape=X.shape[1:],  activation = 'relu'))

model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Conv2D(256, (3, 3), input_shape=X.shape[1:], activation = 'relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Flatten())  # this converts our 3D feature maps to 1D feature vectors

model.add(tf.keras.layers.Dense(64))

model.add(tf.keras.layers.Dense(1, activation='softmax'))


model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

h= model.fit(xtrain, ytrain, validation_data=(xval, yval), batch_size=32, epochs=30, callbacks = [early_stopping], verbose = 0)
Run Code Online (Sandbox Code Playgroud)

该模型的准确度为 0.501897,损失为 7.595693(该模型在每个时期都停留在这些数字上),但如果我用 Sigmoid 替换 Softmax 激活,准确度约为 0.98,损失为 0.06。为什么 Softmax 会发生这种奇怪的事情?我能找到的所有信息是这两个激活是相似的,softmax 甚至更好,但我找不到任何关于这种异常的信息。如果有人能解释问题是什么,我会很高兴。

d-x*_*-xa 5

结果摘要:

  • a) 具有 Softmax 激活函数的 CNN -> 准确度 ~ 0.50,损失 ~ 7.60
  • b) 具有 Sigmoid 激活函数的 CNN -> 准确度 ~ 0.98,损失 ~ 0.06

总长DR

更新:

现在我还看到您仅使用 Softmax 的 1 个输出神经元,您将无法捕获二元分类中的第二类。使用 Softmax,您需要在输出层定义 K 个神经元- 其中 K 是您想要预测的类的数量。而对于 Sigmoid:1 个输出神经元足以进行二元分类。

简而言之,当对 2 个类使用 softmax 时,这应该在代码中改变:

#use 2 neurons with softmax
model.add(tf.keras.layers.Dense(2, activation='softmax'))
Run Code Online (Sandbox Code Playgroud)

此外:

在进行二元分类时,sigmoid 函数更合适,因为与更广义的 softmax 函数相比,它在计算上更有效(当您有 K>2 类时,它通常用于多类预测)。


进一步阅读:

选定激活函数的一些属性

如果上面的简短答案对您来说还不够,我可以简单地与您分享一些我从有关神经网络激活函数的研究中学到的东西:

首先,让我们明确术语激活和激活函数

激活(alpha):是神经元的状态。隐藏层或输出层中神经元的状态将通过前一层输入信号的加权和来量化

激活函数 f(alpha):是将激活转换为神经元信号的函数。通常是非线性且可微的函数,例如 sigmoid 函数。许多应用和研究都采用了 sigmoid 函数(参见 Bengio & Courville, 2016, p.67 ff.)。大多数情况下,整个神经网络都使用相同的激活函数,但也可以使用多个激活函数(例如,不同层中的不同激活函数)。

现在来看看激活函数的效果:

激活函数的选择会对神经网络的学习产生巨大影响(正如您在示例中所看到的)。从历史上看,使用 sigmoid 函数很常见,因为它是描述饱和神经元的一个很好的函数。如今,特别是在 CNN 的其他激活函数中,也只有部分线性激活函数(如 relu)比 sigmoid 函数更受青睐。有许多不同的函数,仅举几个例子:sigmoid、tanh、relu、prelu、elu、maxout、max、argmax、softmax 等。

现在我们只比较 sigmoid、relu/maxout 和 softmax:

# pseudo code / formula
sigmoid = f(alpha) = 1 / (1 + exp(-alpha))
relu = f(alpha) = max(0,alpha)
maxout = f(alpha) = max(alpha1, alpha2)
softmax = f(alpha_j) = alpha_j / sum_K(alpha_k)
Run Code Online (Sandbox Code Playgroud)

乙状结肠:

  • 在二元分类中最好用于输出层
  • 值的范围可以在 [0,1] 之间,适合概率解释 (+)
  • 饱和神经元可以消除梯度(-)
  • 不以零为中心 (-)
  • exp() 的计算成本很高 (-)

雷卢:

  • 阳性区域没有饱和神经元 (+)
  • 计算成本较低 (+)
  • 不以零为中心 (-)
  • 负区域中的饱和神经元 (-)

最大输出:

  • relu 的积极属性 (+)
  • 每个神经元的参数数量加倍,通常需要增加学习努力 (-)

软最大:

  • bee 可以看作是 sigmoid 函数的推广
  • 主要用作多类预测问题中的输出激活函数
  • 值范围在 [0,1] 之间,适合概率解释 (+)
  • 由于 exp() 项 (-),计算成本更高

一些可供进一步阅读的好参考: