reid-strong-baseline 中的tricks

目录

Warmup:

Random Erasing Data Augmentation:


以config/defaults.py为例

  • Warmup:

学习率的变化:上升--平稳--下降

【开始训练以很小的学习率训练,随着训练学习率慢慢上升,再以一定的学习率平稳训练,最后在减小学习率】

# warm up factor
_C.SOLVER.WARMUP_FACTOR = 1.0 / 3
# iterations of warm up
_C.SOLVER.WARMUP_ITERS = 500
# method of warm up, option: 'constant','linear'
_C.SOLVER.WARMUP_METHOD = "linear"


softmax_triplet_with_center.yml中:

  WARMUP_FACTOR: 0.01
  WARMUP_ITERS: 10
  WARMUP_METHOD: 'linear'

WarmupMultiStepLR( )函数

# encoding: utf-8
"""
@author:  liaoxingyu
@contact: [email protected]
"""
from bisect import bisect_right
import torch


# FIXME ideally this would be achieved with a CombinedLRScheduler,
# separating MultiStepLR with WarmupLR
# but the current LRScheduler design doesn't allow it

class WarmupMultiStepLR(torch.optim.lr_scheduler._LRScheduler):
    def __init__(
        self,
        optimizer,
        milestones,
        gamma=0.1,
        warmup_factor=1.0 / 3,
        warmup_iters=500,
        warmup_method="linear",
        last_epoch=-1,
    ):
        if not list(milestones) == sorted(milestones):
            raise ValueError(
                "Milestones should be a list of" " increasing integers. Got {}",
                milestones,
            )

        if warmup_method not in ("constant", "linear"):
            raise ValueError(
                "Only 'constant' or 'linear' warmup_method accepted"
                "got {}".format(warmup_method)
            )
        self.milestones = milestones
        self.gamma = gamma
        self.warmup_factor = warmup_factor #初始学习率
        self.warmup_iters = warmup_iters #停止epoch
        self.warmup_method = warmup_method
        super(WarmupMultiStepLR, self).__init__(optimizer, last_epoch)

    def get_lr(self):
        warmup_factor = 1
        if self.last_epoch < self.warmup_iters: #当还在使用warmup方法epoch范围内
            if self.warmup_method == "constant": #constant
                warmup_factor = self.warmup_factor #学习率在使用warmup之内保持恒定warmup_factor 
            elif self.warmup_method == "linear": #linear
                alpha = self.last_epoch / self.warmup_iters #相当于计算线性变化的斜率
                warmup_factor = self.warmup_factor * (1 - alpha) + alpha #计算新的warmup_factor 
        return [
            base_lr
            * warmup_factor
            * self.gamma ** bisect_right(self.milestones, self.last_epoch)
            for base_lr in self.base_lrs
        ]
  • Random Erasing Data Augmentation:

利用随机擦除的方式,将原数据集中的一部分样本随机擦除一个矩形区域。

INPUT:
  SIZE_TRAIN: [384, 384]
  SIZE_TEST:  [384, 384]
  PROB: 0.5 # random horizontal flip
  RE_PROB: 0.5 # random erasing 随机擦除的概率 一半一半
  PADDING: 10
# encoding: utf-8
"""
@author:  liaoxingyu
@contact: [email protected]
"""

import math
import random


class RandomErasing(object):
    """ Randomly selects a rectangle region in an image and erases its pixels.
        'Random Erasing Data Augmentation' by Zhong et al.
        See https://arxiv.org/pdf/1708.04896.pdf
    Args:
         probability: The probability that the Random Erasing operation will be performed.
         sl: Minimum proportion of erased area against input image.
         sh: Maximum proportion of erased area against input image.
         r1: Minimum aspect ratio of erased area.
         mean: Erasing value.
    """

    def __init__(self, probability=0.5, sl=0.02, sh=0.4, r1=0.3, mean=(0.4914, 0.4822, 0.4465)):
        self.probability = probability
        self.mean = mean
        self.sl = sl
        self.sh = sh
        self.r1 = r1

    def __call__(self, img):

        if random.uniform(0, 1) >= self.probability:#随机选择样本
            return img

        for attempt in range(100):
            area = img.size()[1] * img.size()[2]#图像的区域大小

            target_area = random.uniform(self.sl, self.sh) * area #擦除面积的比率
            aspect_ratio = random.uniform(self.r1, 1 / self.r1) #长宽比的上下界
            #求长宽area=wh,ar=h/w,所以:area*ar=h*h;area/ar=w*w
            h = int(round(math.sqrt(target_area * aspect_ratio)))
            w = int(round(math.sqrt(target_area / aspect_ratio)))
            #如果长宽满足要求,就设置为均值
            if w < img.size()[2] and h < img.size()[1]:
                #找到随机的一个矩形区域的左上角坐标,定矩形位置
                x1 = random.randint(0, img.size()[1] - h)
                y1 = random.randint(0, img.size()[2] - w)
                #根据通道数设置区域像素值
                if img.size()[0] == 3:
                    img[0, x1:x1 + h, y1:y1 + w] = self.mean[0]
                    img[1, x1:x1 + h, y1:y1 + w] = self.mean[1]
                    img[2, x1:x1 + h, y1:y1 + w] = self.mean[2]
                else:
                    img[0, x1:x1 + h, y1:y1 + w] = self.mean[0]
                return img

        return img

 

你可能感兴趣的:(代码实战,reid,深度学习)