hunk.code_window:     'seresnet101':
           _cfg(url='http://data.lip6.fr/cadene/pretrainedmodels/se_resnet101-7e38fcc6.pth'),
       'seresnet152':
           _cfg(url='http://data.lip6.fr/cadene/pretrainedmodels/se_resnet152-d17c99b7.pth'),
       'seresnext50_32x4d':
           _cfg(url='http://data.lip6.fr/cadene/pretrainedmodels/se_resnext50_32x4d-a260b3a4.pth'),
       'seresnext101_32x4d':
           _cfg(url='http://data.lip6.fr/cadene/pretrainedmodels/se_resnext101_32x4d-3b2fe3d8.pth'),
  
hunk.labels: keep keep keep add keep keep keep keep
hunk.after_edit:     'seresnext26_32x4d':
           _cfg(url='https://www.dropbox.com/s/zaeruz2bejcdhh3/seresnext26_32x4d-65ebdb501.pth?dl=1',
                interpolation='bicubic'),
  
hunk.file_path: models/senet.py
hunk.type: add
file: import torch
  from torchvision import transforms
  from PIL import Image
  import math
  import numpy as np
  from data.random_erasing import RandomErasingNumpy
  
  DEFAULT_CROP_PCT = 0.875
  
  IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
  IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)
  IMAGENET_INCEPTION_MEAN = (0.5, 0.5, 0.5)
  IMAGENET_INCEPTION_STD = (0.5, 0.5, 0.5)
  IMAGENET_DPN_MEAN = (124 / 255, 117 / 255, 104 / 255)
  IMAGENET_DPN_STD = tuple([1 / (.0167 * 255)] * 3)
  
  
  def resolve_data_config(model, args, default_cfg={}, verbose=True):
      new_config = {}
      default_cfg = default_cfg
      if not default_cfg and hasattr(model, 'default_cfg'):
          default_cfg = model.default_cfg
  
      # Resolve input/image size
      # FIXME grayscale/chans arg to use different # channels?
      in_chans = 3
      input_size = (in_chans, 224, 224)
      if args.img_size is not None:
          # FIXME support passing img_size as tuple, non-square
          assert isinstance(args.img_size, int)
          input_size = (in_chans, args.img_size, args.img_size)
      elif 'input_size' in default_cfg:
          input_size = default_cfg['input_size']
      new_config['input_size'] = input_size
  
      # resolve interpolation method
      new_config['interpolation'] = 'bilinear'
      if args.interpolation:
          new_config['interpolation'] = args.interpolation
      elif 'interpolation' in default_cfg:
          new_config['interpolation'] = default_cfg['interpolation']
  
      # resolve dataset + model mean for normalization
      new_config['mean'] = get_mean_by_model(args.model)
      if args.mean is not None:
          mean = tuple(args.mean)
          if len(mean) == 1:
              mean = tuple(list(mean) * in_chans)
          else:
              assert len(mean) == in_chans
          new_config['mean'] = mean
      elif 'mean' in default_cfg:
          new_config['mean'] = default_cfg['mean']
  
      # resolve dataset + model std deviation for normalization
      new_config['std'] = get_std_by_model(args.model)
      if args.std is not None:
          std = tuple(args.std)
          if len(std) == 1:
              std = tuple(list(std) * in_chans)
          else:
              assert len(std) == in_chans
          new_config['std'] = std
      else:
          new_config['std'] = default_cfg['std']
  
      # resolve default crop percentage
      new_config['crop_pct'] = DEFAULT_CROP_PCT
      if 'crop_pct' in default_cfg:
          new_config['crop_pct'] = default_cfg['crop_pct']
  
      if verbose:
          print('Data processing configuration for current model + dataset:')
          for n, v in new_config.items():
              print('\t%s: %s' % (n, str(v)))
  
      return new_config
  
  
  def get_mean_by_name(name):
      if name == 'dpn':
          return IMAGENET_DPN_MEAN
      elif name == 'inception' or name == 'le':
          return IMAGENET_INCEPTION_MEAN
      else:
          return IMAGENET_DEFAULT_MEAN
  
  
  def get_std_by_name(name):
      if name == 'dpn':
          return IMAGENET_DPN_STD
      elif name == 'inception' or name == 'le':
          return IMAGENET_INCEPTION_STD
      else:
          return IMAGENET_DEFAULT_STD
  
  
  def get_mean_by_model(model_name):
      model_name = model_name.lower()
      if 'dpn' in model_name:
          return IMAGENET_DPN_STD
      elif 'ception' in model_name or 'nasnet' in model_name:
          return IMAGENET_INCEPTION_MEAN
      else:
          return IMAGENET_DEFAULT_MEAN
  
  
  def get_std_by_model(model_name):
      model_name = model_name.lower()
      if 'dpn' in model_name:
          return IMAGENET_DEFAULT_STD
      elif 'ception' in model_name or 'nasnet' in model_name:
          return IMAGENET_INCEPTION_STD
      else:
          return IMAGENET_DEFAULT_STD
  
  
  class ToNumpy:
  
      def __call__(self, pil_img):
          np_img = np.array(pil_img, dtype=np.uint8)
          if np_img.ndim < 3:
              np_img = np.expand_dims(np_img, axis=-1)
          np_img = np.rollaxis(np_img, 2)  # HWC to CHW
          return np_img
  
  
  class ToTensor:
  
      def __init__(self, dtype=torch.float32):
          self.dtype = dtype
  
      def __call__(self, pil_img):
          np_img = np.array(pil_img, dtype=np.uint8)
          if np_img.ndim < 3:
              np_img = np.expand_dims(np_img, axis=-1)
          np_img = np.rollaxis(np_img, 2)  # HWC to CHW
          return torch.from_numpy(np_img).to(dtype=self.dtype)
  
  
  def transforms_imagenet_train(
          img_size=224,
          scale=(0.1, 1.0),
          color_jitter=(0.4, 0.4, 0.4),
          interpolation='bilinear',
          random_erasing=0.4,
          use_prefetcher=False,
          mean=IMAGENET_DEFAULT_MEAN,
          std=IMAGENET_DEFAULT_STD
  ):
  
      tfl = [
          transforms.RandomResizedCrop(
              img_size, scale=scale,
              interpolation=Image.BILINEAR if interpolation == 'bilinear' else Image.BICUBIC),
          transforms.RandomHorizontalFlip(),
          transforms.ColorJitter(*color_jitter),
      ]
  
      if use_prefetcher:
          # prefetcher and collate will handle tensor conversion and norm
          tfl += [ToNumpy()]
      else:
          tfl += [
              ToTensor(),
              transforms.Normalize(
                  mean=torch.tensor(mean),
                  std=torch.tensor(std))
          ]
          if random_erasing > 0.:
              tfl.append(RandomErasingNumpy(random_erasing, per_pixel=True))
      return transforms.Compose(tfl)
  
  
  def transforms_imagenet_eval(
          img_size=224,
          crop_pct=None,
          interpolation='bilinear',
          use_prefetcher=False,
          mean=IMAGENET_DEFAULT_MEAN,
          std=IMAGENET_DEFAULT_STD):
      crop_pct = crop_pct or DEFAULT_CROP_PCT
  
      if isinstance(img_size, tuple):
          assert len(img_size) == 2
          if img_size[-1] == img_size[-2]:
              # fall-back to older behaviour so Resize scales to shortest edge if target is square
              scale_size = int(math.floor(img_size[0] / crop_pct))
          else:
              scale_size = tuple([int(x / crop_pct) for x in img_size])
      else:
          scale_size = int(math.floor(img_size / crop_pct))
  
      tfl = [
          transforms.Resize(scale_size, Image.BILINEAR if interpolation == 'bilinear' else Image.BICUBIC),
          transforms.CenterCrop(img_size),
      ]
      if use_prefetcher:
          # prefetcher and collate will handle tensor conversion and norm
          tfl += [ToNumpy()]
      else:
          tfl += [
              transforms.ToTensor(),
              transforms.Normalize(
                       mean=torch.tensor(mean),
                       std=torch.tensor(std))
          ]
  
      return transforms.Compose(tfl)
  