File size: 11,785 Bytes
0b8359d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
![No Maintenance Intended](https://img.shields.io/badge/No%20Maintenance%20Intended-%E2%9C%95-red.svg)
![TensorFlow Requirement: 1.x](https://img.shields.io/badge/TensorFlow%20Requirement-1.x-brightgreen)
![TensorFlow 2 Not Supported](https://img.shields.io/badge/TensorFlow%202%20Not%20Supported-%E2%9C%95-red.svg)

# Adversarial logit pairing

This directory contains implementation of
[Adversarial logit pairing](https://arxiv.org/abs/1803.06373) paper as well as
few models pre-trained on ImageNet and Tiny ImageNet.

Please contact [Alexey Kurakin](https://github.com/AlexeyKurakin) regarding
this code.

## Pre-requesites

Code dependencies:

* TensorFlow 1.8 and Python 2.7 (other versions may work, but were not tested)
* [Abseil Python](https://github.com/abseil/abseil-py).
* Script which converts Tiny Imagenet dataset into TFRecord format also
  depends on [Pandas](https://pandas.pydata.org/).

## Datasets

To use this code you need to download datasets. You only need to download
those datasets which you're going to use. Following list of datasets is
supported:

* [ImageNet](http://www.image-net.org/). Follow
  [Preparing the datasets](https://github.com/tensorflow/models/tree/master/research/slim#Data)
  instructions in TF-Slim documentation to download and convert ImageNet dataset
  to TFRecord format.

* [Tiny ImageNet](https://tiny-imagenet.herokuapp.com/).
  To obtain Tiny ImageNet dataset do following:

  ```
  # Download zip archive with TinyImagenet
  curl -O http://cs231n.stanford.edu/tiny-imagenet-200.zip

  # Extract archive
  unzip tiny-imagenet-200.zip

  # Convert dataset to TFRecord format
  mkdir tiny-imagenet-tfrecord
  python tiny_imagenet_converter/converter.py \
    --input_dir=tiny-imagenet-200 \
    --output_dir=tiny-imagenet-tfrecord
  ```

## Running the code

NOTE: Provided code supports distributed training on multiple machines,
and all provided checkpoints were trained in a distributed way. However it is
beyond the scope of this document to describe how to do distributed training.
Readed should refer to
[other material](https://www.tensorflow.org/deploy/distributed) to learn
about it.

### Training

Following command runs training:

```
# Following arguments has to be specified for training:
# - MAX_NUMBER_OF_TRAINING_STEPS - maximum number of training steps,
#     omit this flag or set it to -1 to have unlimited number of training steps.
# - MODEL_NAME - name of the model, now only "resnet_v2_50" is supported.
# - MOVING_AVG_DECAY - decay rate for exponential moving average of the
#     trainable variables. Training with exponential moving average usually
#     leads to better accuracy. Default of 0.9999. -1 disable exponential moving
#     average. Default works well, so typically you set it only if you want
#     to disable this feature.
# - HYPERPARAMETERS - string with hyperparameters,
#     see model_lib.py for full list of hyperparameters.
# - DATASET - dataset, either "imagenet" or "tiny_imagenet".
# - IMAGE_SIZE - size of the image (single number).
# - OUTPUT_DIRECTORY - directory where to write results.
# - IMAGENET_DIR - directory with ImageNet dataset in TFRecord format.
# - TINY_IMAGENET_DIR - directory with Tiny ImageNet dataset in TFRecord format.
#
# Note that only one of IMAGENET_DIR or TINY_IMAGENET_DIR has to be provided
# depending on which dataset you use.
#
python train.py \
  --max_steps="${MAX_NUMBER_OF_TRAINING_STEPS}" \
  --model_name="${MODEL_NAME}" \
  --moving_average_decay="${MOVING_AVG_DECAY}" \
  --hparams="${HYPERPARAMETERS}" \
  --dataset="${DATASET}" \
  --dataset_image_size="${IMAGE_SIZE}" \
  --output_dir="${OUTPUT_DIRECTORY}" \
  --imagenet_data_dir="${IMAGENET_DIR}" \
  --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}"
```

Full list of training hyperparameters could be found in `model_lib.py`.
These hyperparameters control learning rate schedule, optimizer, weight decay,
label smoothing and adversarial training.

Adversarial training is controlled by following hyperparameters:

* `train_adv_method` - method which is used to craft adversarial examples during
  training. Could be one of the following:

  * `clean` - perform regular training with clean examples;
  * `pgd_EPS_STEP_NITER` - use non targeted PGD with maximum size of
    perturbation equal to `EPS`, step size equal to `STEP`
    and number of iterations equal to `NITER`. Size of perturbation and step
    size are expected to be integers between 1 and 255.
  * `pgdll_EPS_STEP_NITER` - use targeted PGD, where target class is least
    likely prediction of the network.
  * `pgdrnd_EPS_STEP_NITER` - use targeted PGD, where target class is chosen
    randomly.

* `train_lp_weight` - weight of adversarial logit pairing loss. If zero or
  negarive, then no logit pairing is performed and training is done using
  mixed minibatch PGD. If positive then adversarial logit pairing term is added
  to the loss.

Below is example of how to run training with adversarial logit pairing on
ImageNet 64x64:

```
python train.py \
  --model_name="resnet_v2_50" \
  --hparams="train_adv_method=pgdll_16_2_10,train_lp_weight=0.5" \
  --dataset="imagenet" \
  --dataset_image_size=64 \
  --output_dir="/tmp/adv_train" \
  --imagenet_data_dir="${IMAGENET_DIR}"
```

### Fine tuning

Provided trainin script could be used to fine tune pre-trained checkpoint.
Following command does this:

```
# Fine tuning adds following additional arguments:
# - SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT - comma separates list of scopes of
#     variables, which should not be loadeded from checkpoint (and default
#     initialization should be used instead).
#     SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT should be either same or a subset of
#     LIST_OF_SCOPES_OF_TRAINABLE_VARS.
# - LIST_OF_SCOPES_OF_TRAINABLE_VARS - comma separated list of scopes of
#     trainable variables. Only variables which are prefixed with these scopes
#     will be trained.
# - PATH_TO_PRETRAINED_CHECKPOINT - directory with pretrained checkpoint which
#     is used as initialization for fine tuning.
#
python train.py \
  --max_steps="${MAX_NUMBER_OF_TRAINING_STEPS}" \
  --model_name="${MODEL_NAME}" \
  --moving_average_decay="${MOVING_AVG_DECAY}" \
  --hparams="${HYPERPARAMETERS}" \
  --dataset="${DATASET}" \
  --dataset_image_size="${IMAGE_SIZE}" \
  --output_dir="${OUTPUT_DIRECTORY}" \
  --imagenet_data_dir="${IMAGENET_DIR}" \
  --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" \
  --finetune_exclude_pretrained_scopes="${SCOPES_DO_NOT_LOAD_FROM_CHECKPOINT}" \
  --finetune_trainable_scopes="${LIST_OF_SCOPES_OF_TRAINABLE_VARS}" \
  --finetune_checkpoint_path="${PATH_TO_PRETRAINED_CHECKPOINT}"
```

Below is an example of how to fine tune last few layers of the model on
Tiny Imagenet dataset:

```
python train.py \
  --model_name="resnet_v2_50" \
  --hparams="train_adv_method=pgdll_16_2_10,train_lp_weight=0.5,learning_rate=0.02" \
  --dataset="tiny_imagenet" \
  --dataset_image_size=64 \
  --output_dir="/tmp/adv_finetune" \
  --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}" \
  --finetune_exclude_pretrained_scopes="resnet_v2_50/logits" \
  --finetune_trainable_scopes="resnet_v2_50/logits,resnet_v2_50/postnorm" \
  --finetune_checkpoint_path="/tmp/adv_train"
```

### Evaluation

Following command runs evaluation:

```
# Following arguments should be provided for eval:
# - TRAINING_DIRECTORY - directory where training checkpoints are saved.
# - TRAINABLE_SCOPES - when loading checkpoint which was obtained by fine tuning
#     this argument should be the same as LIST_OF_SCOPES_OF_TRAINABLE_VARS
#     during training. Otherwise it should be empty.
#     This is needed to properly load exponential moving average variables.
#     If exponential moving averages are disabled then this flag could be
#     omitted.
# - EVAL_SUBDIR_NAME - name of the subdirectory inside TRAINING_DIRECTORY
#     where evaluation code will be saving event files.
# - DATASET - name of the dataset.
# - IMAGE_SIZE - size of the image in the dataset.
# - DATSET_SPLIT_NAME - name of the split in the dataset,
#     either 'train' or 'validation'. Default is 'validation'.
# - MODEL_NAME - name of the model.
# - MOVING_AVG_DECAY - decay rate for exponential moving average.
# - ADV_METHOD_FOR_EVAL - should be "clean" to evaluate on clean example or
#     description of the adversarial method to evaluate on adversarial examples.
# - HYPERPARAMETERS - hyperparameters, only "eval_batch_size" matters for eval
# - NUMBER_OF_EXAMPLES - how many examples from the dataset use for evaluation,
#     specify -1 to use all examples.
# - EVAL_ONCE - if True then evaluate only once, otherwise keep evaluation
#     running repeatedly on new checkpoints. Repeated evaluation might be useful
#     when running concurrent with training.
# - IMAGENET_DIR - directory with ImageNet dataset in TFRecord format.
# - TINY_IMAGENET_DIR - directory with Tiny ImageNet dataset in TFRecord format.
#
python eval.py \
  --train_dir="${TRAINING_DIRECTORY} \
  --trainable_scopes="${TRAINABLE_SCOPES}" \
  --eval_name="${EVAL_SUBDIR_NAME}" \
  --dataset="${DATASET}" \
  --dataset_image_size="${IMAGE_SIZE}" \
  --split_name="${DATSET_SPLIT_NAME}" \
  --model_name="${MODEL_NAME}" \
  --moving_average_decay="${MOVING_AVG_DECAY}" \
  --adv_method="${ADV_METHOD_FOR_EVAL}" \
  --hparams="${HYPERPARAMETERS}" \
  --num_examples="${NUMBER_OF_EXAMPLES}" \
  --eval_once="${EVAL_ONCE}" \
  --imagenet_data_dir="${IMAGENET_DIR}" \
  --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}"
```

Example of running evaluation on 10000 of clean examples from ImageNet
training set:

```
python eval.py \
  --train_dir=/tmp/adv_train \
  --dataset=imagenet \
  --dataset_image_size=64 \
  --split_name=train \
  --adv_method=clean \
  --hparams="eval_batch_size=50" \
  --num_examples=10000 \
  --eval_once=True \
  --imagenet_data_dir="${IMAGENET_DIR}"
```

Example of running evaluatin on adversarial images generated from Tiny ImageNet
validation set using fine-tuned checkpoint:

```
python eval.py \
  --train_dir=tmp/adv_finetune \
  --trainable_scopes="resnet_v2_50/logits,resnet_v2_50/postnorm" \
  --dataset=tiny_imagenet \
  --dataset_image_size=64 \
  --adv_method=pgdrnd_16_2_10 \
  --hparams="eval_batch_size=50" \
  --eval_once=True \
  --tiny_imagenet_data_dir="${TINY_IMAGENET_DIR}"
```

### Pre-trained models

Following set of pre-trained checkpoints released with this code:

| Model       |    Dataset   |  Accuracy on<br>clean images | Accuracy on<br>`pgdll_16_1_20` | Accuracy on<br>`pgdll_16_2_10` |
| ----------- | ------------ | --------------- | --------------------------- | -------------- |
| [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% |
| [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% |
| [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% |
| [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% |


* All provided checkpoints were initially trained with exponential moving
  average. However for ease of use they were re-saved without it.
  So to load and use provided checkpoints you need to specify
  `--moving_average_decay=-1` flag.
* All ALP models were trained with `pgdll_16_2_10` adversarial examples.
* All Tiny Imagenet models were obtained by fine tuning corresponding
  ImageNet 64x64 models. ALP-trained models were fine tuned with ALP.