【问题标题】:How to decrease validation_loss and increase accuracy for age prediction?如何减少验证损失并提高年龄预测的准确性?
【发布时间】:2021-04-09 13:28:49
【问题描述】:

我是机器学习的新手,我尝试训练一个模型来预测图像中人物的年龄。我在 4 个年龄段(0-18、18-40、40-65、65+)上训练了我的模型)。我最大的问题是我不知道如何优化。我把代码和一些结果放在下面。我在 10k 图像上训练了模型,验证集有大约 3.5k 图像,测试集有大约 3k 图像。我使用预学习模型作为基础模型,即“Mobilenet”,批量大小 = 32,时期 = 100,辍学 =.4。我尝试更新学习率,每 10 个时期模型未能减少验证损失,学习率减半(我们从值 0.001 开始)。我希望这种预测的准确性会更好,validation_loss 会低得多(validation_loss 对我来说约为 1)。image with results

欢迎提出任何建议。

if self.model_type == 'Mobilenet':
            base_model = tf.keras.applications.mobilenet.MobileNet(include_top=False, input_shape=img_shape,
                                                                   pooling='max', weights='imagenet', dropout=.4)
        x = base_model.output
        x = keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001)(x)
        x = Dense(self.neurons_a, activation='relu', kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123))(x)
        x = Dropout(rate=dropout, seed=123)(x)
        output = Dense(self.class_count, activation='softmax',
                       kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123))(x)
        model = Model(inputs=base_model.input, outputs=output)
        model.compile(Adamax(lr=self.lr), loss='categorical_crossentropy', metrics=self.metrics)

【问题讨论】:

    标签: tensorflow machine-learning keras


    【解决方案1】:

    看起来您正在使用我创建的代码,我猜可能是从 Kaggle 获得的。该模型似乎表现良好,训练精度非常高,没有过度拟合的迹象。如您的图所示,验证损失通常会稳定在某个值附近。我能想到的唯一另一件事是评估数据集的平衡。我的意思是查看每个类的训练集中的样本数量。我预计您会出现严重的不平衡,65 岁以上的样本很少。在这种情况下,有几种缓解策略。最简单的是使用model.fit中的class_weights参数。为此,您需要创建一个 class_weights 字典。下面概述了执行此操作的过程

    Lets say your class distribution is
     0-18 - 500 samples
     18-40- 2000 samples
     40-65 - 1500 samples
     65+ - 200 samples
    Then your dictionary would be
    class_weights={0: 2000/500, 1:2000/2000, 2: 2000/1500, 3: 2000/200}
    in model.fit set class_weight=class_weights
    

    我的经验是,这通常只会带来轻微的改善。还有其他几种方法,例如使用 cv2 或 PIL 创建“增强”图像并将这些增强图像存储在表示不足的类目录中。如果您有不平衡的数据集,您可能需要使用模块 smote 来提供帮助。一个教程位于here. 如果你创建一个混淆矩阵,你可以告诉更多关于你的模型是如何执行的。如果您没有测试集,则可以使用验证集。您是否使用生成器将数据输入到模型中?下面的代码展示了如何创建混淆矩阵。我假设在您的代码中的某个地方,您可以为您的验证或测试集提供标签。如果您使用生成器并设置 shuffle=False,您可以从 labels-gen.labels 从生成器中获取标签。然后使用下面的代码

    preds=model.predict(test_gen, batch_size=test_batch_size, verbose=0, steps=None)
    labels=test_gen.labels # make sure shuffle=False in the generator
    y_pred=[]
    classes=['0-18', '18-40', '40-65', '65+']
    for i, p in enumerate(preds):
        pred_index=np.argmax(p)
        y_pred.append(pred_index)
    y_true= np.array(labels)        
    y_pred=np.array(y_pred)   
    cm = confusion_matrix(y_true, y_pred )
    plt.figure(figsize=(10, 10))
    sns.heatmap(cm, annot=True, vmin=0, fmt='g', cmap='Blues', cbar=False)       
    plt.xticks(np.arange(length)+.5, classes, rotation= 90)
    plt.yticks(np.arange(length)+.5, classes, rotation=0)
    plt.xlabel("Predicted")
    plt.ylabel("Actual")
    plt.title("Confusion Matrix")
    plt.show()  
    

    【讨论】:

    • 是的,我正在使用来自 kaggle 的代码,我正在尝试了解有关此主题的更多信息。是的,我正在降低学习率,我知道 validation_loss 稳定/趋于一个值,但是这么高是正常的吗?
    • 查看修改后的答案 - 我唯一能想到的就是确定数据集的平衡,即比较每个类中的图像样本数。如果存在严重的不平衡,请使用修改后的答案中的代码。
    • 我正在使用生成器向模型输入数据。我从没想过样本之间的不平衡,现在你这么说我可以说这是一个问题。非常感谢您的建议,我一定会申请的!
    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 2022-01-08
    • 2021-01-06
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2018-12-21
    相关资源
    最近更新 更多