我刚刚开始使用神经网络,并尝试构建一个带有二元标签的基本图像分类网络。根据我对神经网络的理解,我认为在输出层使用Softmax激活函数的目的是将输入信息转换为标签的概率,并预测出概率较高的标签。因此,我的第一个问题是 –
- 为什么以及如何我的模型在输出层没有Softmax激活函数的情况下也能提高准确性并进行合理的预测?(这里没有添加输出图片,但确实如此)
- 其次,当我确实将Softmax作为输出层的激活函数时,我观察到了一种奇怪的行为。我的验证准确率在所有周期中都卡在0.5。(训练准确率卡在0.813)。
我相当确定这是一个关于网络架构和各种超参数的明显问题,但我没有注意到。非常感谢您的帮助!我已经在下面粘贴了我的代码供您查看,我没有放出输出,但如果您也需要,请告诉我。
#Train DataINPUT_FOLDER = '../input/chest-xray-pneumonia/chest_xray/train/NORMAL'images = os.listdir(INPUT_FOLDER)X_train_1 = []for instance in images: image = Image.open('../input/chest-xray-pneumonia/chest_xray/train/NORMAL/' + instance) image_rz = image.resize((100,100)).convert('L') array = np.array(image_rz) X_train_1.append(array)X_train_1 = np.array(X_train_1)print(X_train_1.shape)INPUT_FOLDER = '../input/chest-xray-pneumonia/chest_xray/train/PNEUMONIA'images = os.listdir(INPUT_FOLDER)X_train_2 = []for instance in images: image = Image.open('../input/chest-xray-pneumonia/chest_xray/train/PNEUMONIA/' + instance) image_rz = image.resize((100,100)).convert('L') array = np.array(image_rz) X_train_2.append(array)X_train_2 = np.array(X_train_2)print(X_train_2.shape)X_trn = np.concatenate((X_train_1, X_train_2))print(X_trn.shape)#Make Labelsy_trn = np.zeros(5216, dtype = str)y_trn[:1341] = 'NORMAL'y_trn[1341:] = 'PNEUMONIA'y_trn = y_trn.reshape(5216,1)#Shuffle Labels X_trn, y_trn = shuffle(X_trn, y_trn)#Onehot encode categorical labelsonehot_encoder = OneHotEncoder(sparse=False)y_trn = onehot_encoder.fit_transform(y_trn)#Modelmodel = keras.Sequential([ keras.layers.Flatten(input_shape = (100,100)), keras.layers.Dense(256, activation = 'selu'), keras.layers.Dense(2, activation = 'softmax')])adm = optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)model.compile(optimizer = adm, loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), metrics=['accuracy'])for layer in model.layers: print(layer, layer.trainable)model.fit(X_trn, y_trn, validation_data = (X_val, y_val), epochs=30, shuffle = True)
回答:
秘密在于您的损失函数。当您在损失函数中设置from_logits=True
时:
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True)
它期望值来自没有Softmax激活的层,因此它自己执行Softmax操作。如果您的最后一层已经有Softmax函数,您不应将from_logits
设置为True
,而应设置为False
。
由于这个原因,您的模型在没有Softmax函数的情况下表现良好,而在有Softmax函数的情况下表现不佳。