我一直在尝试用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)该模型的精度为0.501897,损失为7.595693(模型在每一个时代都被这些数字所束缚),但如果用Sigmoid代替Softmax激活,精度约为0.98,损失约为0.06。为什么这样奇怪的事情会发生在Softmax上?我能找到的所有信息是,这两种激活是相似的,而softmax甚至更好,但是我没有发现任何关于这种异常的东西。如果有人能解释一下是什么问题,我会很高兴的。
发布于 2020-12-11 23:31:20
结果摘要:
TLDR
更新:
现在我也看到您是,只使用一个输出神经元和Softmax,您将无法捕获二进制分类中的第二类。和Softmax,您需要在输出层中定义K神经元,其中K是您想要预测的类的数量。而对于Sigmoid: 1输出神经元则足以进行二值分类。
因此,简单地说,当对两个类使用softmax时,这应该会在代码中发生变化:
#use 2 neurons with softmax
model.add(tf.keras.layers.Dense(2, activation='softmax'))此外:
当执行二进制分类时,sigmoid函数更适合于,因为与更广义的softmax函数相比,计算效率更高(通常用于多类预测,当有K>2类时)。
继续阅读:
所选激活函数的一些属性
如果上面的简短回答对你来说还不够的话,我可以和你分享一些我从NNs关于激活函数的研究中学到的东西--简而言之:
首先,让我们弄清楚激活和激活函数的术语
激活(alpha):是神经元的状态。隐层或输出层中神经元的状态将通过来自前一层激活函数f(Alpha)的输入信号的加权和来量化。f(Alpha)是将激活转换为神经元信号的函数。通常是一个非线性和可微的函数,例如乙状结肠函数。许多应用和研究已经应用于sigmoid函数(见Bengio & Courville,2016,p.67 ff.)。在整个神经网络中,大部分都使用相同的激活函数,但可以使用多个(例如,不同层中的不同激活函数)。
现在谈谈激活函数的影响:
激活函数的选择会对神经网络的学习产生巨大的影响(正如你在你的例子中所看到的)。历史上使用乙状结肠功能是常见的,因为它是一个很好的功能来描绘一个饱和的神经元。今天,特别是在CNN的其他激活函数中,也只有部分线性激活函数(如relu)比乙状结肠功能更好。它有许多不同的功能,例如: sigmoid、tanh、relu、prelu、elu、maxout、max、argmax、softmax等。
现在,我们只比较乙状结肠、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)乙状体:
(+)
F 241
雷鲁:
(+)
中不以零为中心
最大限度:
softmax:
function
而更昂贵的概率解释(+)
一些好的参考资料供进一步阅读:
)
发布于 2020-12-11 23:47:44
你看到这些不同结果的原因是你的输出层的大小--它是一个神经元。
根据定义,Softmax需要超过1个输出神经元才有意义。1 Softmax神经元总是输出1(查找公式并考虑一下)。这就是为什么你看到~50%的准确性,因为你的网络总是预测1级。
Sigmoid没有这个问题,可以输出任何东西,这就是它训练的原因。
如果您想要测试softmax,您必须为每个类创建一个输出神经元,然后对您的ytrain和yval进行“一次热编码”(查找一次热编码以获得更多解释)。在您的例子中,这意味着: label 0 -> 1,0,label 1 -> 0,1。我不确定,但在这种情况下,我相信你会使用绝对交叉熵。我无法从文档中确切地分辨出来,但在我看来,二进制交叉熵需要一个输出神经元,要么是0,要么是1(其中Sigmoid是正确使用的激活),而分类交叉熵则要求每个类都有一个输出神经元,而Softmax是有意义的。即使在多输出情况下也可以使用Sigmoid,但这并不常见。
所以简单地说,在我看来,二进制X熵是由1神经元的值编码的类,而分类x熵则是输出神经元最活跃的编码类。(简化用语)
https://stackoverflow.com/questions/65258468
复制相似问题