我一直在尝试使用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甚至更好,但是我找不到关于这种异常的任何信息。如果有人可以解释问题所在,我会很高兴。
结果摘要:
TLDR
更新:
现在,我还看到您仅在Softmax中使用1个输出神经元,因此您将无法捕获二进制分类中的第二类。使用Softmax,您需要在输出层中定义K个神经元-其中K是您要预测的类数。而对于Sigmoid:1个输出神经元足以进行二进制分类。
简而言之,当将softmax用于2个类时,这应该在您的代码中进行更改:
#use 2 neurons with softmax
model.add(tf.keras.layers.Dense(2, activation='softmax'))
另外:
当进行二进制分类时,与更广义的softmax函数(通常在K> 2类时用于多类预测)相比,S型函数在计算上更有效,因此它更适合于S型函数。
进一步阅读:
选定激活功能的一些属性
如果上面的简短答案对您来说还不够,我可以与您分享一些我从关于NN的激活函数的研究中学到的东西:
首先,让我们先了解一下激活和激活功能这两个术语
激活(alpha):是神经元的状态。隐藏层或输出层中神经元的状态将通过来自上一层的输入信号的加权总和来量化
激活函数f(alpha):是将激活转换为神经元信号的函数。通常是非线性和可微函数,例如S形函数。乙状结肠功能已经应用了很多应用和研究(参见Bengio&Courville,2016,p.67 ff。)。通常,整个神经网络都使用相同的激活函数,但也可以使用多个激活函数(例如,不同层中的不同激活函数)。
现在来看激活功能的效果:
激活函数的选择会对神经网络的学习产生巨大影响(如您在示例中所看到的)。从历史上看,通常会使用S型功能,因为它是描绘饱和神经元的良好功能。如今,尤其是在CNN中,其他激活函数中,仅部分线性激活函数(如relu)优于S型函数。有很多不同的功能,仅举几例:S型,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)
乙状结肠:
重读:
maxout:
softmax:
一些很好的参考资料供进一步阅读:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句