Python Keras损失始终较低,但精度开始较高,然后下降

Python Keras损失始终较低,但精度开始较高,然后下降,python,machine-learning,keras,loss,cross-entropy,Python,Machine Learning,Keras,Loss,Cross Entropy,首先,我的假设可能是错误的: 损失是指每个训练示例与正确答案之间的距离(然后除以示例数-某种程度上的平均损失) 准确度是指有多少个训练示例是正确的(如果将最高输出作为正确答案,则不管它是否为0.7,这将导致损失0.3,它仍然输出正确答案)。这是以百分比形式给出的 在我看来,这意味着准确率通常将接近100%,而损失将接近0。这不是我所看到的: 10000/10000[==================================================================

首先,我的假设可能是错误的:

  • 损失是指每个训练示例与正确答案之间的距离(然后除以示例数-某种程度上的平均损失)
  • 准确度是指有多少个训练示例是正确的(如果将最高输出作为正确答案,则不管它是否为0.7,这将导致损失0.3,它仍然输出正确答案)。这是以百分比形式给出的
  • 在我看来,这意味着准确率通常将接近100%,而损失将接近0。这不是我所看到的:

    10000/10000[=============================================================================================-1067s-损耗:0.0408-附件:0.9577-损耗:0.0029-附件:0.9995
    纪元2/5
    10000/10000[=========================================================================================================-991s-损耗:0.0021-附件:0.9997-损耗:1.9070e-07-损耗:1.0000
    纪元3/5
    10000/10000[=================================================================================================================================================================================================================================================================================================================================================================================
    
    这是在3个时代,第二次尝试让它工作。这是使用
    train\u dategen
    shuffle=True
    。我有关于
    shuffle=False
    的结果(我最初认为这可能是问题所在),这里:

    10000/10000[====================================================================================-1168s-损耗:0.0079-附件:0.9975-val\u损耗:0.0031-val\u附件:0.9995
    纪元2/5
    10000/10000[==================================================================================================================-1053s-损失:0.0032-会计科目:0.9614-会计科目:1.1921e-07-会计科目:0.2439
    纪元3/5
    10000/10000[=============================================================================================================================================-1029s-损耗:1.1921e-07-损耗:0.2443-损耗:1.1921e-07-损耗:0.2438
    纪元4/5
    10000/10000[==========================================================================================================================================-1017s-损耗:1.1921e-07-附件:0.2438
    纪元5/5
    10000/10000[=====================================================================================================================-1041s-损耗:1.1921e-07-附件:0.2445-val\u损耗:1.1921e-07-val\u附件:0.2435
    
    我用
    categorical\u crossentropy
    表示损失,因为我有3个类。我有比需要更多的数据(大约178000张图片,全部分为三类中的一类)

    我是误解了什么,还是出了什么问题

    以下是我的完整代码:

    # Importing the Keras libraries and packages
    from keras.models import Sequential
    from keras.layers import Conv2D
    from keras.layers import MaxPooling2D
    from keras.layers import Flatten
    from keras.layers import Dense
    
    # Initialising the CNN
    classifier = Sequential()
    # Step 1 - Convolution
    classifier.add(Conv2D(32, (3, 3), input_shape = (200, 200, 3), activation = 'relu'))
    # Step 2 - Pooling
    classifier.add(MaxPooling2D(pool_size = (2, 2)))
    # Adding a second convolutional layer
    classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
    classifier.add(MaxPooling2D(pool_size = (2, 2)))
    # Step 3 - Flattening
    classifier.add(Flatten())
    # Step 4 - Full connection
    classifier.add(Dense(units = 128, activation = 'relu'))
    classifier.add(Dense(units = 3, activation = 'sigmoid'))
    # Compiling the CNN
    classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
    # Part 2 - Fitting the CNN to the images
    from keras.preprocessing.image import ImageDataGenerator
    train_datagen = ImageDataGenerator(rescale = 1./255)
    test_datagen = ImageDataGenerator(rescale = 1./255)
    training_set = train_datagen.flow_from_directory('dataset/training_set',
                    target_size = (200, 200),
                    batch_size = 64,
                    class_mode = 'categorical',
                    shuffle=True)
    
    test_set = test_datagen.flow_from_directory('dataset/test_set',
                    target_size = (200, 200),
                    batch_size = 62,
                    class_mode = 'categorical',
                    shuffle=True)
    
    classifier.fit_generator(training_set,
                    steps_per_epoch = 10000,
                    epochs = 5,
                    validation_data = test_set,
                    validation_steps=1000)
    
    classifier.save("CSGOHeads.h5")
    # Part 3 - Making new predictions
    import numpy as np
    from keras.preprocessing import image
    test_image = image.load_img('dataset/single_prediction/1.bmp', target_size = (200, 200))
    test_image = image.img_to_array(test_image)
    test_image = np.expand_dims(test_image, axis = 0)
    result = classifier.predict(test_image)
    training_set.class_indices
    if result[0][0] == 1:
        prediction = 'head'
    else:
        prediction = 'not'
    

    由于您要将图像分类为三个类别之一(即称为单标签多类别分类:有多个类别,但每个图像只有一个标签),因此应使用
    softmax
    作为最后一层的激活功能,而不是使用
    sigmoid

    classifier.add(密集(单位=3,激活=softmax))#这里不要使用sigmoid
    

    如果您想让我解释更多,请告诉我,我会更新我的答案。

    因为您将图像分为三类之一(即称为单标签多类分类:有多个类,但每个图像只有一个标签)您应该使用
    softmax
    作为最后一层的激活功能,而不是使用
    sigmoid

    classifier.add(密集(单位=3,激活=softmax))#这里不要使用sigmoid
    

    如果你想让我解释更多,让我知道,我会更新我的答案。

    为了补充@today的答案,如果最后一层的激活是
    sigmoid
    ,那么损失应该是
    binary\u crossentropy
    。这是解决多标签分类问题的方法。否则,对于一个标签分类,使用
    softmax
    plus
    categorical\u crossentropy
    。不要将
    sigmoid
    categorical\u crossentropy
    混为一谈来补充@today的答案,如果最后一层的激活是
    sigmoid
    ,那么损失应该是
    binary\u crossentropy
    。这是解决多标签分类问题的方法。否则,对于一个标签分类,使用
    softmax
    plus
    categorical\u crossentropy
    。不要把
    sigmoid
    categorical\u交叉熵混为一谈

    你也可以把你的代码贴出来吗?显然,在培训过程中(假设设置正确),验证和培训损失值都会降低,精度会提高,直到达到稳定期(如果继续培训,可能过一段时间后,验证损失值开始增加,验证精度会下降,这称为过度拟合)。但在您的情况下,一开始的准确率很高,这很奇怪,可能是代码中有bug或错误的迹象。@今天我已经发布了我的全部代码,如果有什么不清楚的地方,请告诉我(我对python还是新手,所以可能看起来很混乱)。谢谢你能把你的密码也发出来吗?显然,在培训过程中(假设设置正确),验证和培训损失值都会降低,精度会提高,直到达到稳定期(如果继续培训,可能过一段时间后,验证损失值开始增加,验证精度会下降,这称为过度拟合)。但在您的情况下,一开始的准确率很高,这很奇怪,可能是代码中有bug或错误的迹象。@今天我已经发布了我的全部代码,如果有什么不清楚的地方,请告诉我(我对python还是新手,所以可能看起来很混乱)。谢谢,谢谢,这很有道理。我将运行代码并在检查问题是否存在后标记为已回答!谢谢,这很有道理。我将运行代码并在检查问题是否存在后标记为已回答!