feature_learning.md 4.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
# 特征学习

此部分主要是针对`RecModel`的训练模式进行说明。`RecModel`的训练模式,主要是为了支持车辆识别(车辆细分类、ReID)、Logo识别、动漫人物识别、商品识别等特征学习的应用。与在`ImageNet`上训练普通的分类网络不同的是,此训练模式,主要有以下特征

- 支持对`backbone`的输出进行截断,即支持提取任意中间层的特征信息
- 支持在`backbone`的feature输出层后,添加可配置的网络层,即`Neck`部分
- 支持`ArcMargin``metric learning` 相关loss函数,提升特征学习能力

## yaml文件说明

`RecModel`的训练模式与普通分类训练的配置类似,配置文件主要分为以下几个部分:

### 全局设置部分

```yaml
Global:
  # 如为null则从头开始训练。若指定中间训练保存的状态地址,则继续训练
  checkpoints: null
  # pretrained model路径或者 bool类型
  pretrained_model: null
  # 模型保存路径
  output_dir: "./output/"
  device: "gpu"
  class_num: 30671
  # 保存模型的粒度,每个epoch保存一次
  save_interval: 1
  eval_during_train: True
  eval_interval: 1
  # 训练的epoch数
  epochs: 160
  # log输出频率
  print_batch_step: 10
  # 是否使用visualdl库
  use_visualdl: False
  # used for static mode and model export
  image_shape: [3, 224, 224]
  save_inference_dir: "./inference"
  # 使用retrival的方式进行评测
  eval_mode: "retrieval"
```

### 数据部分

```yaml
DataLoader:
  Train:
    dataset:
        # 具体使用的Dataset的的名称
        name: "VeriWild"
        # 使用此数据集的具体参数
        image_root: "/work/dataset/VeRI-Wild/images/"
        cls_label_path: "/work/dataset/VeRI-Wild/train_test_split/train_list_start0.txt"
        # 图像增广策略:ResizeImage、RandFlipImage等
        transform_ops:
          - ResizeImage:
              size: 224
          - RandFlipImage:
              flip_code: 1
          - AugMix:
              prob: 0.5
          - NormalizeImage:
              scale: 0.00392157
              mean: [0.485, 0.456, 0.406]
              std: [0.229, 0.224, 0.225]
              order: ''
          - RandomErasing:
              EPSILON: 0.5
              sl: 0.02
              sh: 0.4
              r1: 0.3
              mean: [0., 0., 0.]
    sampler:
        name: DistributedRandomIdentitySampler
        batch_size: 128
        num_instances: 2
        drop_last: False
        shuffle: True
    loader:
        num_workers: 6
        use_shared_memory: False
```

`val dataset`设置与`train dataset`除图像增广策略外,设置基本一致

### Backbone的具体设置

```yaml
Arch:
  # 使用RecModel模式进行训练
  name: "RecModel"
  # 导出inference model的具体配置
  infer_output_key: "features"
  infer_add_softmax: False
  # 使用的Backbone
  Backbone:
    name: "ResNet50"
    pretrained: True
  # 使用此层作为Backbone的feature输出,name为ResNet50的full_name
  BackboneStopLayer:
    name: "adaptive_avg_pool2d_0"
  # Backbone的基础上,新增网络层。此模型添加1x1的卷积层(embedding)
  Neck:
    name: "VehicleNeck"
    in_channels: 2048
    out_channels: 512
  # 增加ArcMargin, 即ArcLoss的具体实现
  Head:
    name: "ArcMargin"  
    embedding_size: 512
    class_num: 431
    margin: 0.15
    scale: 32
```

`Neck`部分为在`bacbone`基础上,添加的网络层,可根据需求添加。 如在ReID任务中,添加一个输出长度为512的`embedding`层,可由此部分实现。需注意的是,`Neck`部分需对应好`BackboneStopLayer`层的输出维度。一般来说,`Neck`部分为网络的最终特征输出层。

`Head`部分主要是为了支持`metric learning`等具体loss函数,如`ArcMargin`([ArcFace Loss](https://arxiv.org/abs/1801.07698)的fc层的具体实现),在完成训练后,一般将此部分剔除。

### Loss的设置

```yaml
Loss:
  Train:
    - CELoss:
        weight: 1.0
    - SupConLoss:
        weight: 1.0
        # SupConLoss的具体参数
        views: 2
  Eval:
    - CELoss:
        weight: 1.0
```

训练时同时使用`CELoss``SupConLoss`,权重比例为`1:1`,测试时只使用`CELoss`

### 优化器设置

```yaml
Optimizer:
  # 使用的优化器名称
  name: Momentum
  # 优化器具体参数
  momentum: 0.9
  lr:
    # 使用的学习率调节具体名称
    name: MultiStepDecay
    # 学习率调节算法具体参数
    learning_rate: 0.01
    milestones: [30, 60, 70, 80, 90, 100, 120, 140]
    gamma: 0.5
    verbose: False
    last_epoch: -1
  regularizer:
    name: 'L2'
    coeff: 0.0005
```

### Eval Metric设置

```yaml
Metric:
  Eval:
    # 使用Recallk和mAP两种评价指标
    - Recallk:
        topk: [1, 5]
    - mAP: {}
```