|
| 1 | + |
| 2 | +# Adversarial logit pairing |
| 3 | + |
| 4 | +This directory contains implementation of |
| 5 | +[Adversarial logit pairing](https://arxiv.org/abs/1803.06373) paper as well as |
| 6 | +few models pre-trained on ImageNet and Tiny ImageNet. |
| 7 | + |
| 8 | +Please contact [Alexey Kurakin](https://github.com/AlexeyKurakin) regarding |
| 9 | +this code. |
| 10 | + |
| 11 | +## Pre-requesites |
| 12 | + |
| 13 | +Code dependencies: |
| 14 | + |
| 15 | +* TensorFlow 1.8 and Python 2.7 (other versions may work, but were not tested) |
| 16 | +* [Abseil Python](https://github.com/abseil/abseil-py). |
| 17 | +* Script which converts Tiny Imagenet dataset into TFRecord format also |
| 18 | + depends on [Pandas](https://pandas.pydata.org/). |
| 19 | + |
| 20 | +## Datasets |
| 21 | + |
| 22 | +To use this code you need to download datasets. You only need to download |
| 23 | +those datasets which you're going to use. Following list of datasets is |
| 24 | +supported: |
| 25 | + |
| 26 | +* [ImageNet](http://www.image-net.org/). Follow |
| 27 | + [Preparing the datasets](https://github.com/tensorflow/models/tree/master/research/slim#Data) |
| 28 | + instructions in TF-Slim documentation to download and convert ImageNet dataset |
| 29 | + to TFRecord format. |
| 30 | + |
| 31 | +* [Tiny ImageNet](https://tiny-imagenet.herokuapp.com/). |
| 32 | + To obtain Tiny ImageNet dataset do following: |
| 33 | + |
| 34 | + ``` |
| 35 | + # Download zip archive with TinyImagenet |
| 36 | + curl -O http://cs231n.stanford.edu/tiny-imagenet-200.zip |
| 37 | +
|
| 38 | + # Extract archive |
| 39 | + unzip tiny-imagenet-200.zip |
| 40 | +
|
| 41 | + # Convert dataset to TFRecord format |
| 42 | + mkdir tiny-imagenet-tfrecord |
| 43 | + python tiny_imagenet_converter/converter.py \ |
| 44 | + --input_dir=tiny-imagenet-200 \ |
| 45 | + --output_dir=tiny-imagenet-tfrecord |
| 46 | + ``` |
| 47 | + |
| 48 | +## Running the code |
| 49 | + |
| 50 | +NOTE: Provided code supports distributed training on multiple machines, |
| 51 | +and all provided checkpoints were trained in a distributed way. However it is |
| 52 | +beyond the scope of this document to describe how to do distributed training. |
| 53 | +Readed should refer to |
| 54 | +[other material](https://www.tensorflow.org/deploy/distributed) to learn |
| 55 | +about it. |
| 56 | + |
| 57 | +### Training |
| 58 | + |
| 59 | +Following command runs training: |
| 60 | + |
| 61 | +``` |
| 62 | +# Following arguments has to be specified for training: |
| 63 | +# - MAX_NUMBER_OF_TRAINING_STEPS - maximum number of training steps, |
| 64 | +# omit this flag or set it to -1 to have unlimited number of training steps. |
| 65 | +# - MODEL_NAME - name of the model, now only "resnet_v2_50" is supported. |
| 66 | +# - MOVING_AVG_DECAY - decay rate for exponential moving average of the |
| 67 | +# trainable variables. Training with exponential moving average usually |
| 68 | +# leads to better accuracy. Default of 0.9999. -1 disable exponential moving |
| 69 | +# average. Default works well, so typically you set it only if you want |
| 70 | +# to disable this feature. |
| 71 | +# - HYPERPARAMETERS - string with hyperparameters, |
| 72 | +# see model_lib.py for full list of hyperparameters. |
| 73 | +# - DATASET - dataset, either "imagenet" or "tiny_imagenet". |
| 74 | +# - IMAGE_SIZE - size of the image (single number). |
| 75 | +# - OUTPUT_DIRECTORY - directory where to write results. |
| 76 | +# - IMAGENET_DIR - directory with ImageNet dataset in TFRecord format. |
| 77 | +# - TINY_IMAGENET_DIR - directory with Tiny ImageNet dataset in TFRecord format. |
| 78 | +# |
| 79 | +# Note that only one of IMAGENET_DIR or TINY_IMAGENET_DIR has to be provided |
| 80 | +# depending on which dataset you use. |
| 81 | +# |
| 82 | +python train.py \ |
| 83 | + --max_steps="${MAX_NUMBER_OF_TRAINING_STEPS}" \ |
| 84 | + --model_name="${MODEL_NAME}" \ |
| 85 | + --moving_average_decay="${MOVING_AVG_DECAY}" \ |
| 86 | + --hparams="${HYPERPARAMETERS}" \ |
| 87 | + --dataset="${DATASET}" \ |
| 88 | + --dataset_image_size="${IMAGE_SIZE}" \ |
| 89 | + --output_dir="${OUTPUT_DIRECTORY}" \ |
| 90 | + --imagenet_data_dir="${IMAGENET_DIR}" \ |
| 91 | + --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" |
| 92 | +``` |
| 93 | + |
| 94 | +Full list of training hyperparameters could be found in `model_lib.py`. |
| 95 | +These hyperparameters control learning rate schedule, optimizer, weight decay, |
| 96 | +label smoothing and adversarial training. |
| 97 | + |
| 98 | +Adversarial training is controlled by following hyperparameters: |
| 99 | + |
| 100 | +* `train_adv_method` - method which is used to craft adversarial examples during |
| 101 | + training. Could be one of the following: |
| 102 | + |
| 103 | + * `clean` - perform regular training with clean examples; |
| 104 | + * `pgd_EPS_STEP_NITER` - use non targeted PGD with maximum size of |
| 105 | + perturbation equal to `EPS`, step size equal to `STEP` |
| 106 | + and number of iterations equal to `NITER`. Size of perturbation and step |
| 107 | + size are expected to be integers between 1 and 255. |
| 108 | + * `pgdll_EPS_STEP_NITER` - use targeted PGD, where target class is least |
| 109 | + likely prediction of the network. |
| 110 | + * `pgdrnd_EPS_STEP_NITER` - use targeted PGD, where target class is chosen |
| 111 | + randomly. |
| 112 | + |
| 113 | +* `train_lp_weight` - weight of adversarial logit pairing loss. If zero or |
| 114 | + negarive, then no logit pairing is performed and training is done using |
| 115 | + mixed minibatch PGD. If positive then adversarial logit pairing term is added |
| 116 | + to the loss. |
| 117 | + |
| 118 | +Below is example of how to run training with adversarial logit pairing on |
| 119 | +ImageNet 64x64: |
| 120 | + |
| 121 | +``` |
| 122 | +python train.py \ |
| 123 | + --model_name="resnet_v2_50" \ |
| 124 | + --hparams="train_adv_method=pgdll_16_2_10,train_lp_weight=0.5" \ |
| 125 | + --dataset="imagenet" \ |
| 126 | + --dataset_image_size=64 \ |
| 127 | + --output_dir="/tmp/adv_train" \ |
| 128 | + --imagenet_data_dir="${IMAGENET_DIR}" |
| 129 | +``` |
| 130 | + |
| 131 | +### Fine tuning |
| 132 | + |
| 133 | +Provided trainin script could be used to fine tune pre-trained checkpoint. |
| 134 | +Following command does this: |
| 135 | + |
| 136 | +``` |
| 137 | +# Fine tuning adds following additional arguments: |
| 138 | +# - SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT - comma separates list of scopes of |
| 139 | +# variables, which should not be loadeded from checkpoint (and default |
| 140 | +# initialization should be used instead). |
| 141 | +# SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT should be either same or a subset of |
| 142 | +# LIST_OF_SCOPES_OF_TRAINABLE_VARS. |
| 143 | +# - LIST_OF_SCOPES_OF_TRAINABLE_VARS - comma separated list of scopes of |
| 144 | +# trainable variables. Only variables which are prefixed with these scopes |
| 145 | +# will be trained. |
| 146 | +# - PATH_TO_PRETRAINED_CHECKPOINT - directory with pretrained checkpoint which |
| 147 | +# is used as initialization for fine tuning. |
| 148 | +# |
| 149 | +python train.py \ |
| 150 | + --max_steps="${MAX_NUMBER_OF_TRAINING_STEPS}" \ |
| 151 | + --model_name="${MODEL_NAME}" \ |
| 152 | + --moving_average_decay="${MOVING_AVG_DECAY}" \ |
| 153 | + --hparams="${HYPERPARAMETERS}" \ |
| 154 | + --dataset="${DATASET}" \ |
| 155 | + --dataset_image_size="${IMAGE_SIZE}" \ |
| 156 | + --output_dir="${OUTPUT_DIRECTORY}" \ |
| 157 | + --imagenet_data_dir="${IMAGENET_DIR}" \ |
| 158 | + --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" \ |
| 159 | + --finetune_exclude_pretrained_scopes="${SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT}" \ |
| 160 | + --finetune_trainable_scopes="${LIST_OF_SCOPES_OF_TRAINABLE_VARS}" \ |
| 161 | + --finetune_checkpoint_path="${PATH_TO_PRETRAINED_CHECKPOINT}" |
| 162 | +``` |
| 163 | + |
| 164 | +Below is an example of how to fine tune last few layers of the model on |
| 165 | +Tiny Imagenet dataset: |
| 166 | + |
| 167 | +``` |
| 168 | +python train.py \ |
| 169 | + --model_name="resnet_v2_50" \ |
| 170 | + --hparams="train_adv_method=pgdll_16_2_10,train_lp_weight=0.5,learning_rate=0.02" \ |
| 171 | + --dataset="tiny_imagenet" \ |
| 172 | + --dataset_image_size=64 \ |
| 173 | + --output_dir="/tmp/adv_finetune" \ |
| 174 | + --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" \ |
| 175 | + --finetune_exclude_pretrained_scopes="resnet_v2_50/logits" \ |
| 176 | + --finetune_trainable_scopes="resnet_v2_50/logits,resnet_v2_50/postnorm" \ |
| 177 | + --finetune_checkpoint_path="/tmp/adv_train" |
| 178 | +``` |
| 179 | + |
| 180 | +### Evaluation |
| 181 | + |
| 182 | +Following command runs evaluation: |
| 183 | + |
| 184 | +``` |
| 185 | +# Following arguments should be provided for eval: |
| 186 | +# - TRAINING_DIRECTORY - directory where training checkpoints are saved. |
| 187 | +# - TRAINABLE_SCOPES - when loading checkpoint which was obtained by fine tuning |
| 188 | +# this argument should be the same as LIST_OF_SCOPES_OF_TRAINABLE_VARS |
| 189 | +# during training. Otherwise it should be empty. |
| 190 | +# This is needed to properly load exponential moving average variables. |
| 191 | +# If exponential moving averages are disabled then this flag could be |
| 192 | +# omitted. |
| 193 | +# - EVAL_SUBDIR_NAME - name of the subdirectory inside TRAINING_DIRECTORY |
| 194 | +# where evaluation code will be saving event files. |
| 195 | +# - DATASET - name of the dataset. |
| 196 | +# - IMAGE_SIZE - size of the image in the dataset. |
| 197 | +# - DATSET_SPLIT_NAME - name of the split in the dataset, |
| 198 | +# either 'train' or 'validation'. Default is 'validation'. |
| 199 | +# - MODEL_NAME - name of the model. |
| 200 | +# - MOVING_AVG_DECAY - decay rate for exponential moving average. |
| 201 | +# - ADV_METHOD_FOR_EVAL - should be "clean" to evaluate on clean example or |
| 202 | +# description of the adversarial method to evaluate on adversarial examples. |
| 203 | +# - HYPERPARAMETERS - hyperparameters, only "eval_batch_size" matters for eval |
| 204 | +# - NUMBER_OF_EXAMPLES - how many examples from the dataset use for evaluation, |
| 205 | +# specify -1 to use all examples. |
| 206 | +# - EVAL_ONCE - if True then evaluate only once, otherwise keep evaluation |
| 207 | +# running repeatedly on new checkpoints. Repeated evaluation might be useful |
| 208 | +# when running concurrent with training. |
| 209 | +# - IMAGENET_DIR - directory with ImageNet dataset in TFRecord format. |
| 210 | +# - TINY_IMAGENET_DIR - directory with Tiny ImageNet dataset in TFRecord format. |
| 211 | +# |
| 212 | +python eval.py \ |
| 213 | + --train_dir="${TRAINING_DIRECTORY} \ |
| 214 | + --trainable_scopes="${TRAINABLE_SCOPES}" \ |
| 215 | + --eval_name="${EVAL_SUBDIR_NAME}" \ |
| 216 | + --dataset="${DATASET}" \ |
| 217 | + --dataset_image_size="${IMAGE_SIZE}" \ |
| 218 | + --split_name="${DATSET_SPLIT_NAME}" \ |
| 219 | + --model_name="${MODEL_NAME}" \ |
| 220 | + --moving_average_decay="${MOVING_AVG_DECAY}" \ |
| 221 | + --adv_method="${ADV_METHOD_FOR_EVAL}" \ |
| 222 | + --hparams="${HYPERPARAMETERS}" \ |
| 223 | + --num_examples="${NUMBER_OF_EXAMPLES}" \ |
| 224 | + --eval_once="${EVAL_ONCE}" \ |
| 225 | + --imagenet_data_dir="${IMAGENET_DIR}" \ |
| 226 | + --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" |
| 227 | +``` |
| 228 | + |
| 229 | +Example of running evaluation on 10000 of clean examples from ImageNet |
| 230 | +training set: |
| 231 | + |
| 232 | +``` |
| 233 | +python eval.py \ |
| 234 | + --train_dir=/tmp/adv_train \ |
| 235 | + --dataset=imagenet \ |
| 236 | + --dataset_image_size=64 \ |
| 237 | + --split_name=train \ |
| 238 | + --adv_method=clean \ |
| 239 | + --hparams="eval_batch_size=50" \ |
| 240 | + --num_examples=10000 \ |
| 241 | + --eval_once=True \ |
| 242 | + --imagenet_data_dir="${IMAGENET_DIR}" |
| 243 | +``` |
| 244 | + |
| 245 | +Example of running evaluatin on adversarial images generated from Tiny ImageNet |
| 246 | +validation set using fine-tuned checkpoint: |
| 247 | + |
| 248 | +``` |
| 249 | +python eval.py \ |
| 250 | + --train_dir=tmp/adv_finetune \ |
| 251 | + --trainable_scopes="resnet_v2_50/logits,resnet_v2_50/postnorm" \ |
| 252 | + --dataset=tiny_imagenet \ |
| 253 | + --dataset_image_size=64 \ |
| 254 | + --adv_method=pgdrnd_16_2_10 \ |
| 255 | + --hparams="eval_batch_size=50" \ |
| 256 | + --eval_once=True \ |
| 257 | + --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" |
| 258 | +``` |
| 259 | + |
| 260 | +### Pre-trained models |
| 261 | + |
| 262 | +Following set of pre-trained checkpoints released with this code: |
| 263 | + |
| 264 | +| Model | Dataset | Accuracy on<br>clean images | Accuracy on<br>`pgdll_16_1_20` | Accuracy on<br>`pgdll_16_2_10` | |
| 265 | +| ----------- | ------------ | --------------- | --------------------------- | -------------- | |
| 266 | +| [Baseline ResNet-v2-50](http://download.tensorflow.org/models/adversarial_logit_pairing/imagenet64_base_2018_06_26.ckpt.tar.gz) | ImageNet 64x64 | 60.5% | 1.8% | 3.5% | |
| 267 | +| [ALP-trained ResNet-v2-50](http://download.tensorflow.org/models/adversarial_logit_pairing/imagenet64_alp025_2018_06_26.ckpt.tar.gz) | ImageNet 64x64 | 55.7% | 27.5% | 27.8% | |
| 268 | +| [Baseline ResNet-v2-50](http://download.tensorflow.org/models/adversarial_logit_pairing/tiny_imagenet_base_2018_06_26.ckpt.tar.gz) | Tiny ImageNet | 69.2% | 0.1% | 0.3% | |
| 269 | +| [ALP-trained ResNet-v2-50](http://download.tensorflow.org/models/adversarial_logit_pairing/tiny_imagenet_alp05_2018_06_26.ckpt.tar.gz) | Tiny ImageNet | 72.0% | 41.3% | 40.8% | |
| 270 | + |
| 271 | + |
| 272 | +* All provided checkpoints were initially trained with exponential moving |
| 273 | + average. However for ease of use they were re-saved without it. |
| 274 | + So to load and use provided checkpoints you need to specify |
| 275 | + `--moving_average_decay=-1` flag. |
| 276 | +* All ALP models were trained with `pgdll_16_2_10` adversarial examples. |
| 277 | +* All Tiny Imagenet models were obtained by fine tuning corresponding |
| 278 | + ImageNet 64x64 models. ALP-trained models were fine tuned with ALP. |
0 commit comments