Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
5b46ddf
Initial implementation of adversarial training callback
dxoigmn Jun 28, 2023
484876c
Merge branch 'main' into adversarial_training_as_callback
dxoigmn Jun 29, 2023
849f071
Make callback work in CPU
dxoigmn Jun 29, 2023
feffbe3
style
dxoigmn Jun 29, 2023
5e6c272
Add and use on_after_batch_transfer hook
dxoigmn Jun 29, 2023
59003c2
Override on_after_batch_transfer in callback setup
dxoigmn Jun 30, 2023
8218f65
Restore on_after_batch_transfer hook in teardown
dxoigmn Jun 30, 2023
226664d
cleanup
dxoigmn Jun 30, 2023
d1187c9
Call original on_after_batch_transfer hook
dxoigmn Jun 30, 2023
9850a78
Move Adversary.attack into callback
dxoigmn Jun 30, 2023
6406485
Merge branch 'main' into generalized_adversary
mzweilin Jul 14, 2023
d71cb43
Use training sequence by default.
mzweilin Jul 14, 2023
83f017e
Assume a simple model interface in adversary.
mzweilin Jul 14, 2023
88a807b
Update configs.
mzweilin Jul 14, 2023
9dfd7f6
Log original gain on progress bar.
mzweilin Jul 14, 2023
2cd7ca8
Hide model in Adversary so that it's not tampered.
mzweilin Jul 14, 2023
e642474
Skip adversary if not defined.
mzweilin Jul 14, 2023
f222aef
Update adversarial experiment on COCO.
mzweilin Jul 14, 2023
1d9b182
Fix test.
mzweilin Jul 14, 2023
45b5bf0
Hide model in adversar's batch.
mzweilin Jul 14, 2023
9a2531f
Fix test.
mzweilin Jul 14, 2023
6feab79
Merge branch 'main' into adversarial_training_as_callback
mzweilin Jul 15, 2023
6250195
Merge branch 'adversarial_training_as_callback' into generalized_adve…
mzweilin Jul 15, 2023
0356993
Merge branch 'main' into adversarial_training_as_callback
mzweilin Jul 15, 2023
39ee397
Merge branch 'adversarial_training_as_callback' into generalized_adve…
mzweilin Jul 15, 2023
704fc01
Hide transform in untransform in this PR.
mzweilin Jul 15, 2023
5bb36e7
Revert changes in gain logging.
mzweilin Jul 15, 2023
c85182d
Add LitModular.attack_step() for adversary to run model.forward() to …
mzweilin Jul 18, 2023
558fc7b
Add batch_converter in Adversary that supports transform/untransform.
mzweilin Jul 19, 2023
7ed32ac
Clean up.
mzweilin Jul 19, 2023
6e43496
Fix adv. visualizer.
mzweilin Jul 19, 2023
254e168
Fix visualizer test.
mzweilin Jul 19, 2023
46b5cb7
Make adversary optional in some phases.
mzweilin Jul 19, 2023
ace60a1
Add a minimal PyTorch wrapper.
mzweilin Jul 21, 2023
f076be1
Add batch_converter for object detection tasks in Armory.
mzweilin Jul 21, 2023
ee9dd36
Fix adversary call.
mzweilin Jul 21, 2023
570a8b5
Implement wrapper MartAttackObjectDetection.
mzweilin Jul 21, 2023
7c52e8c
Make a package.
mzweilin Jul 21, 2023
0ab2170
Add test data.
mzweilin Jul 21, 2023
59bd9d7
Rename as mart_armory.
mzweilin Jul 21, 2023
2445223
Update package.
mzweilin Jul 21, 2023
197016d
Merge branch 'main' into generalized_adversary
mzweilin Jul 21, 2023
e3d4de0
Merge branch 'generalized_adversary' into example_armory_attack
mzweilin Jul 21, 2023
f89f129
Update dependency.
mzweilin Jul 21, 2023
2b8080c
Update README.
mzweilin Jul 21, 2023
b48e85b
Update README
mzweilin Jul 21, 2023
4c05c0f
Update README
mzweilin Jul 21, 2023
7453025
Add an attack config generator.
mzweilin Jul 21, 2023
409f1db
Move configs to package.
mzweilin Jul 22, 2023
9fa464a
Add configs from range01.
mzweilin Jul 22, 2023
b827ef1
Update README.
mzweilin Jul 22, 2023
8f3d725
Update configs.
mzweilin Jul 22, 2023
142b02f
Bugfix.
mzweilin Jul 22, 2023
1c43a3a
Fix Adversary(**kwarg).
mzweilin Jul 22, 2023
b9a055e
Fix device placement.
mzweilin Jul 22, 2023
c29f858
Bugfix.
mzweilin Jul 22, 2023
6622e57
Change lambda to a real wrapper.
mzweilin Jul 22, 2023
2c8ae22
Update README.
mzweilin Jul 22, 2023
8f7570a
Use DualModel and fix bugs.
mzweilin Jul 22, 2023
8e949d3
Bugfix.
mzweilin Jul 22, 2023
3e8f8c9
Comment.
mzweilin Jul 24, 2023
342fef2
Add target_transform in target_untransform.
mzweilin Jul 24, 2023
eaedd2c
Merge branch 'generalized_adversary' into example_armory_attack
mzweilin Jul 24, 2023
08a66e4
Make batch_converter configurable.
mzweilin Jul 24, 2023
a8b2c22
Make transform configurable.
mzweilin Jul 24, 2023
ac3c5e8
Simplify config.
mzweilin Jul 24, 2023
5898fc7
Make target_transofom configurable.
mzweilin Jul 24, 2023
a682d00
Make model_wrapper configurable.
mzweilin Jul 24, 2023
228523a
Clean up.
mzweilin Jul 24, 2023
b6a5149
Update README.
mzweilin Jul 25, 2023
1efd243
Fix typo.
mzweilin Jul 25, 2023
ea7cfce
Rename variable: target -> target_transformed
mzweilin Jul 27, 2023
37c86f2
Merge branch 'generalized_adversary' into example_armory_attack
mzweilin Jul 27, 2023
f187adb
Replace the multimethod package with functools.singledispatch.
mzweilin Jul 27, 2023
bae2345
Fix monkey patch in adv_training callback.
mzweilin Jul 28, 2023
9f1d35d
Fix DictBatchConverter.
mzweilin Jul 28, 2023
2a8505b
Remove recursive adversarial training callback in Adversary.
mzweilin Jul 28, 2023
5d81324
Copy batch before transform().
mzweilin Jul 28, 2023
fb79aa8
Copy original batch in batch_converter(), because tuple batch cannot …
mzweilin Jul 28, 2023
32f72a2
Explicit no_op function in transforms.
mzweilin Jul 31, 2023
840271b
Add batch_transform and batch_untransform in BatchConverter.
mzweilin Jul 31, 2023
8572eef
Make tensor<->array transform configurable as batch_transform.
mzweilin Jul 31, 2023
bb0cecc
Clean up.
mzweilin Jul 31, 2023
fd436c0
Add Adversary.model_transform.
mzweilin Jul 31, 2023
5fc3c4c
Use Adversary.model_transform.
mzweilin Aug 1, 2023
5ebbbc0
Clean up.
mzweilin Aug 1, 2023
58d9983
Update doc.
mzweilin Aug 1, 2023
2b91fe2
Fix import path.
mzweilin Aug 1, 2023
120a127
Explicit no_op function in transforms.
mzweilin Jul 31, 2023
238882e
Add batch_transform and batch_untransform in BatchConverter.
mzweilin Jul 31, 2023
6570285
Add Adversary.model_transform.
mzweilin Jul 31, 2023
5a0c264
Simplify transforms in batch converter.
mzweilin Aug 1, 2023
d410c60
Simplify model_transform.
mzweilin Aug 1, 2023
12d87f4
Merge branch 'generalized_adversary' into example_armory_attack
mzweilin Aug 1, 2023
8dfbbf7
Clean up.
mzweilin Aug 1, 2023
0f51d80
Upgrade dependency to torchmetrics == 1.0.1 (#205)
mzweilin Jul 20, 2023
d068902
Move adversary out of the model sequence.
mzweilin Aug 1, 2023
e81a55a
Make an adversarial training/evaluation callback.
mzweilin Aug 1, 2023
1c716f1
Merge branch 'main' into adversarial_training_as_callback
mzweilin Aug 1, 2023
67544da
Merge branch 'adversarial_training_as_callback' into finish_adv_train…
mzweilin Aug 1, 2023
579d653
Remove stuff that is related to callback entry points.
mzweilin Aug 3, 2023
92f9fe2
Replace model wrapper with a configurable model_transform.
mzweilin Aug 7, 2023
44c9c4b
Add Adversary.batch_converter().
mzweilin Aug 7, 2023
87d41d6
Comment.
mzweilin Aug 7, 2023
878b6f0
Merge branch 'finish_adv_training_callback' into add_adv_batch_converter
mzweilin Aug 7, 2023
90630b3
Merge branch 'add_adv_batch_converter' into example_armory_attack
mzweilin Aug 7, 2023
a0fb559
Update config.
mzweilin Aug 7, 2023
87fca27
Create folder automatically.
mzweilin Aug 7, 2023
55bbda1
Update example.
mzweilin Aug 7, 2023
ccdcf99
Clean up.
mzweilin Aug 7, 2023
aa2b7f8
Clean up.
mzweilin Aug 7, 2023
fbff15a
Clean up.
mzweilin Aug 7, 2023
18c51d4
Merge branch 'main' into example_armory_attack
mzweilin Sep 1, 2023
5b15b6e
Clean up.
mzweilin Sep 1, 2023
5bcd830
Fix parent class.
mzweilin Sep 1, 2023
dceda38
Update to latest Adversary.
mzweilin Sep 1, 2023
c6c8645
Fix typo.
mzweilin Sep 1, 2023
32b3b57
Fix example.
mzweilin Sep 2, 2023
9a81279
Add mart.generate_config.
mzweilin Sep 14, 2023
961313e
Create output folder automatically.
mzweilin Sep 14, 2023
d69f8cd
Simplify config generation.
mzweilin Sep 14, 2023
d9b0a76
Comment.
mzweilin Sep 14, 2023
be5afef
Improve mart.generate_config.
mzweilin Sep 18, 2023
79366b9
Add mart.generate_config
mzweilin Sep 21, 2023
ec13141
Add header.
mzweilin Sep 21, 2023
da814ba
Print yaml to stdout.
mzweilin Sep 21, 2023
8fea0cb
Merge branch 'config_generator' into example_armory_attack
mzweilin Sep 21, 2023
8886b5d
Update mart.generate_config usage.
mzweilin Sep 21, 2023
8acf1c6
Add conversion between PyTorch tensors and Numpy arrays.
mzweilin Sep 21, 2023
45b735b
Add test.
mzweilin Sep 21, 2023
1d44eed
Fix a bug.
mzweilin Sep 21, 2023
0240a10
Merge branch 'convert_array_tensor' into example_armory_attack
mzweilin Sep 21, 2023
03f6dfa
Rename.
mzweilin Sep 21, 2023
050beee
Merge branch 'main' into example_armory_attack
mzweilin Oct 9, 2023
6951a07
Fix batch_c15n in the wrapper.
mzweilin Oct 13, 2023
fbbadd0
Use Adam as the attack optimizer.
mzweilin Oct 13, 2023
5c921d6
Allow trainer.precision options in Adversary.
mzweilin Oct 13, 2023
beb35e1
Use 16bit-mixed precision in attack.
mzweilin Oct 13, 2023
e4c55a7
Remove dependency upon MART during development.
mzweilin Oct 13, 2023
2ff9d82
Add python-fire in MART's dependency.
mzweilin Oct 13, 2023
d76fd15
Update README.
mzweilin Oct 13, 2023
3178003
Merge branch 'main' into example_armory_attack
mzweilin Nov 2, 2023
d6fedcc
Update instructions for ARMORY v0.19.0
mzweilin Nov 2, 2023
8abc8a0
Update attack composition.
mzweilin Nov 7, 2023
ea8c60f
Update mask config.
mzweilin Nov 7, 2023
f14f61d
Update gradient ascent config.
mzweilin Nov 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions examples/mart_armory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
## Introduction

We demonstrate how to configure and run a MART attack against object detection models in ARMORY.

The demo attack here is about 30% faster than the baseline attack implementation in ARMORY, because we specify to use 16bit-mixed-precision in the MART attack configuration.

MART is designed to be modular and configurable. It should empower users to evaluate adversarial robustness of deep learning models more effectively and efficiently.

Please reach out to [Weilin Xu](mailto:[email protected]) if you have any question.

## Installation

Download the code repositories.

```shell
# You can start from any directory other than `~/coder/`, since we always use relative paths in the following commands.
mkdir ~/coder; cd ~/coder

git clone https://github.com/twosixlabs/armory.git
# Make sure we are on the same page.
cd armory; git checkout tags/v0.19.0 -b r0.19.0; cd ..

git clone https://github.com/IntelLabs/MART.git -b example_armory_attack
```

Create and activate a Python virtualen environment.

```shell
cd armory
python -m venv .venv
source .venv/bin/activate
```

Install ARMORY, MART and the glue package mart_armory in editable mode.

```shell
pip install -e .[engine]
pip install tensorflow tensorflow-datasets
# PyTorch 2.0+ is already in the dependency of MART.
pip install -e ../MART
pip install -e ../MART/examples/mart_armory
```

Make sure PyTorch works on CUDA.

```console
$ CUDA_VISIBLE_DEVICES=0 python -c "import torch; print(torch.cuda.is_available())"
True
```

> You may need to install a different PyTorch distribution if your CUDA is not 12.0.

> Here's my `nvidia-smi` output: `| NVIDIA-SMI 525.125.06 Driver Version: 525.125.06 CUDA Version: 12.0 |`

## Usage

1. Generate a YAML configuration of attack, using Adam as the optimizer.

```shell
python -m mart.generate_config \
--config_dir=../MART/examples/mart_armory/mart_armory/configs \
--config_name=assemble_attack.yaml \
batch_converter=object_detection \
batch_c15n=data_coco \
attack=adversary \
[email protected]=sgd \
attack.optimizer.maximize=true \
+attack.optimizer.lr=13 \
+attack.max_iters=500 \
+attack/composer/perturber/projector=mask_range \
+attack/enforcer=default \
+attack/enforcer/constraints=[mask,pixel_range] \
+attack/composer/perturber/initializer=uniform \
attack.composer.perturber.initializer.max=255 \
attack.composer.perturber.initializer.min=0 \
+attack/composer/functions=overlay \
+attack/gradient_modifier=sign \
+attack/gain=rcnn_training_loss \
+attack.precision=16 \
attack.optimizer.optimizer.path=torch.optim.Adam \
~attack.optimizer.momentum \
attack.objective=null \
model_transform=armory_objdet \
> mart_objdet_attack_adam500.yaml
```

2. Run the MART attack on one example.

```shell
cat scenario_configs/eval7/carla_overhead_object_detection/carla_obj_det_adversarialpatch_undefended.json \
| jq 'del(.attack)' \
| jq '.attack.knowledge="white"' \
| jq '.attack.use_label=true' \
| jq '.attack.module="mart_armory"' \
| jq '.attack.name="MartAttack"' \
| jq '.attack.kwargs.mart_adv_config_yaml="mart_objdet_attack_adam500.yaml"' \
| jq '.scenario.export_batches=true' \
| CUDA_VISIBLE_DEVICES=0 armory run - --no-docker --use-gpu --gpus=1 --num-eval-batches 1
```

```
2023-10-13 12:05:33 1m14s METRIC armory.instrument.instrument:_write:743 adversarial_object_detection_mAP_tide on adversarial examples w.r.t. ground truth labels: {'mAP': {0.5: 0.0, 0.55: 0.0, 0.6: 0.0, 0.65: 0.0, 0.7: 0.0, 0.75: 0.0, 0.8: 0.0, 0.85: 0.0, 0.9: 0.0, 0.95: 0.0}, 'errors': {'main': {'dAP': {'Cls': 0.0, 'Loc': 0.0, 'Both': 0.0, 'Dupe': 0.0, 'Bkg': 0.0, 'Miss': 0.0}, 'count': {'Cls': 0, 'Loc': 0, 'Both': 0, 'Dupe': 0, 'Bkg': 100, 'Miss': 21}}, 'special': {'dAP': {'FalsePos': 0.0, 'FalseNeg': 0.0}, 'count': {'FalseNeg': 21}}}}
```

## Comparison

Run the baseline attack on the same example for comparison. The MART attack is ~30% faster due to the 16-bit mixed precision.

```shell
cat scenario_configs/eval7/carla_overhead_object_detection/carla_obj_det_adversarialpatch_undefended.json \
| jq '.scenario.export_batches=true' \
| CUDA_VISIBLE_DEVICES=0 armory run - --no-docker --use-gpu --gpus=1 --num-eval-batches 1
```

```console
2023-10-13 12:11:50 1m33s METRIC armory.instrument.instrument:_write:743 adversarial_object_detection_mAP_tide on adversarial examples w.r.t. ground truth labels: {'mAP': {0.5: 0.0, 0.55: 0.0, 0.6: 0.0, 0.65: 0.0, 0.7: 0.0, 0.75: 0.0, 0.8: 0.0, 0.85: 0.0, 0.9: 0.0, 0.95: 0.0}, 'errors': {'main': {'dAP': {'Cls': 0.0, 'Loc': 0.0, 'Both': 0.0, 'Dupe': 0.0, 'Bkg': 0.0, 'Miss': 0.0}, 'count': {'Cls': 0, 'Loc': 0, 'Both': 0, 'Dupe': 0, 'Bkg': 100, 'Miss': 21}}, 'special': {'dAP': {'FalsePos': 0.0, 'FalseNeg': 0.0}, 'count': {'FalseNeg': 21}}}}
```
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from hydra.core.config_search_path import ConfigSearchPath
from hydra.plugins.search_path_plugin import SearchPathPlugin


class HydraMartSearchPathPlugin(SearchPathPlugin):
def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:
# Add mart.configs to search path
search_path.append("hydra-mart", "pkg://mart_armory.configs")
5 changes: 5 additions & 0 deletions examples/mart_armory/mart_armory/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from importlib import metadata

from mart_armory.attack_wrapper import MartAttack

__version__ = metadata.version(__package__ or __name__)
76 changes: 76 additions & 0 deletions examples/mart_armory/mart_armory/attack_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: BSD-3-Clause
#

from __future__ import annotations

import hydra
from omegaconf import OmegaConf


class MartAttack:
"""A minimal wrapper to run MART adversary in Armory against PyTorch-based models.

1. Instantiate an adversary that runs attack in MART;
2. Instantiate batch_converter that turns Armory's numpy batch into the PyTorch batch;
3. The adversary.model_transform() extracts the PyTorch model from an ART Estimator and makes other changes to easier attack;
4. The adversary returns adversarial examples in the PyTorch format;
5. The batch_converter reverts the adversarial examples into the numpy format.
"""

def __init__(self, model, mart_adv_config_yaml):
"""_summary_

Args:
model (Callable): An ART Estimator that contains a PyTorch model.
mart_adv_config_yaml (str): File path to the adversary configuration.
"""
# Instantiate a MART adversary.
adv_cfg = OmegaConf.load(mart_adv_config_yaml)
adv = hydra.utils.instantiate(adv_cfg)

# Transform the ART estimator to an attackable PyTorch model.
self.model_transform = adv.model_transform

# Convert the Armory batch to a form that is expected by the target PyTorch model.
self.batch_converter = adv.batch_converter

# Canonicalize batches for the Adversary.
self.batch_c15n = adv.batch_c15n

self.adversary = adv.attack

self.device = model.device

# Move adversary to the same device.
self.adversary.to(self.device)

# model_transform
self.model_transformed = self.model_transform(model)

def model(self, input, target):
# Wrap a model for the Adversary which works with the canonical (input, target) format.
batch = self.batch_c15n.revert(input, target)
output = self.model_transformed(*batch)
return output

def generate(self, **batch_armory_np):
# Armory format -> torchvision format
batch_tv_pth = self.batch_converter(batch_armory_np, device=self.device)

# Attack
# Canonicalize input and target for the adversary, and revert it at the end.
input, target = self.batch_c15n(batch_tv_pth)
self.adversary.fit(input, target, model=self.model)
input_adv, target_adv = self.adversary(input, target)
batch_adv_tv_pth = self.batch_c15n.revert(input_adv, target_adv)

# torchvision format -> Armory format
batch_adv_armory_np = self.batch_converter.revert(*batch_adv_tv_pth)

# Only return adversarial input in the original numpy format.
input_key = self.batch_converter.input_key
input_adv_np = batch_adv_armory_np[input_key]
return input_adv_np
88 changes: 88 additions & 0 deletions examples/mart_armory/mart_armory/batch_converter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: BSD-3-Clause
#

from functools import reduce

import torch

from mart.transforms.batch_c15n import BatchC15n


class ObjectDetectionBatchConverter(BatchC15n):
def __init__(
self,
input_key: str = "x",
target_keys: dict = {
"y": ["area", "boxes", "id", "image_id", "is_crowd", "labels"],
"y_patch_metadata": [
"avg_patch_depth",
"gs_coords",
"mask",
"max_depth_perturb_meters",
],
},
**kwargs,
):
super().__init__(**kwargs)
self.input_key = input_key
self.target_keys = target_keys

def _convert(self, batch: dict):
input = batch[self.input_key]

target = []
all_targets = [batch[key] for key in self.target_keys]

# Merge several target keys.
for dicts in zip(*all_targets):
joint_target = reduce(lambda a, b: a | b, dicts)
target.append(joint_target)

target = tuple(target)

return input, target

def _revert(self, input: tuple[torch.Tensor], target: tuple[dict]) -> dict:
batch = {}

batch[self.input_key] = input

# Split target into several self.target_keys
for target_key, sub_keys in self.target_keys.items():
batch[target_key] = []
for target_i_dict in target:
target_key_i = {sub_key: target_i_dict[sub_key] for sub_key in sub_keys}
batch[target_key].append(target_key_i)

return batch


class SelectKeyTransform:
def __init__(self, *, key, transform, rename=None):
self.key = key
self.transform = transform
self.rename = rename

def __call__(self, target: dict):
new_key = self.rename or self.key

target[new_key] = self.transform(target[self.key])
if self.rename is not None:
del target[self.key]

return target


class Method:
def __init__(self, *args, name, **kwargs):
self.name = name
self.args = args
self.kwargs = kwargs

def __call__(self, obj):
method = getattr(obj, self.name)
ret = method(*self.args, **self.kwargs)
return ret
9 changes: 9 additions & 0 deletions examples/mart_armory/mart_armory/configs/assemble_attack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @package _global_

# specify here default training configuration
defaults:
- _self_
- attack: ???
- batch_converter: ???
- batch_c15n: ???
- model_transform: ???
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_target_: mart.nn.CallWith
module:
_target_: mart.nn.Sum
_call_with_args_:
- "training.loss_objectness"
- "training.loss_rpn_box_reg"
- "training.loss_classifier"
- "training.loss_box_reg"
10 changes: 10 additions & 0 deletions examples/mart_armory/mart_armory/configs/batch_c15n/data_coco.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defaults:
- tuple
- [email protected]: pixel_1to255
- [email protected]: pixel_255to1

transform:
_target_: mart.transforms.TupleTransforms

untransform:
_target_: mart.transforms.TupleTransforms
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
_target_: torchvision.transforms.Compose
transforms:
- _target_: mart.transforms.Denormalize
center: 0
scale: 255
# Fix potential numeric error.
- _target_: torch.fake_quantize_per_tensor_affine
_partial_: true
# (x/1+0).round().clamp(0, 255) * 1
scale: 1
zero_point: 0
quant_min: 0
quant_max: 255
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
_target_: torchvision.transforms.Normalize
mean: 0
std: 255
Loading