Skip to content

Commit 50b0de9

Browse files
authored
Merge pull request #134 from lukemelas/advprop
Add advprop and b8 model
2 parents dbb58b1 + 396b06b commit 50b0de9

File tree

15 files changed

+894
-201
lines changed

15 files changed

+894
-201
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Custom
2+
tmp
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# EfficientNet PyTorch
22

3+
4+
_IMPORTANT NOTE_: In the latest update, I switched hosting providers for the pretrained models, as the previous models were becoming extremely expensive to host. This _will_ break old versions of the library. I apologize, but I cannot afford to keep serving the models on the old provider. Everything should work properly if you update the library:
5+
```
6+
pip install --upgrade efficientnet-pytorch
7+
```
8+
9+
### Update (January 23, 2020)
10+
11+
This update adds a new category of pre-trained model based on adversarial training, called _advprop_. It is important to note that the preprocessing required for the advprop pretrained models is slightly different from normal ImageNet preprocessing. As a result, by default, advprop models are not used. To load a model with advprop, use:
12+
```
13+
model = EfficientNet.from_pretrained("efficientnet-b0", advprop=True)
14+
```
15+
There is also a new, large `efficientnet-b8` pretrained model that is only available in advprop form. When using these models, replace ImageNet preprocessing code as follows:
16+
```
17+
if advprop: # for models using advprop pretrained weights
18+
normalize = transforms.Lambda(lambda img: img * 2.0 - 1.0)
19+
else:
20+
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
21+
std=[0.229, 0.224, 0.225])
22+
23+
```
24+
This update also addresses multiple other issues ([#115](https://github.com/lukemelas/EfficientNet-PyTorch/issues/115), [#128](https://github.com/lukemelas/EfficientNet-PyTorch/issues/128)).
25+
326
### Update (October 15, 2019)
427

528
This update allows you to choose whether to use a memory-efficient Swish activation. The memory-efficient version is chosen by default, but it cannot be used when exporting using PyTorch JIT. For this purpose, we have also included a standard (export-friendly) swish activation function. To switch to the export-friendly version, simply call `model.set_swish(memory_efficient=False)` after loading your desired model. This update addresses issues [#88](https://github.com/lukemelas/EfficientNet-PyTorch/pull/88) and [#89](https://github.com/lukemelas/EfficientNet-PyTorch/pull/89).

efficientnet_pytorch/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.5.1"
1+
__version__ = "0.6.0"
22
from .model import EfficientNet
33
from .utils import (
44
GlobalParams,

efficientnet_pytorch/model.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,33 +206,24 @@ def from_name(cls, model_name, override_params=None):
206206
return cls(blocks_args, global_params)
207207

208208
@classmethod
209-
def from_pretrained(cls, model_name, num_classes=1000, in_channels = 3):
209+
def from_pretrained(cls, model_name, advprop=False, num_classes=1000, in_channels=3):
210210
model = cls.from_name(model_name, override_params={'num_classes': num_classes})
211-
load_pretrained_weights(model, model_name, load_fc=(num_classes == 1000))
211+
load_pretrained_weights(model, model_name, load_fc=(num_classes == 1000), advprop=advprop)
212212
if in_channels != 3:
213213
Conv2d = get_same_padding_conv2d(image_size = model._global_params.image_size)
214214
out_channels = round_filters(32, model._global_params)
215215
model._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False)
216216
return model
217217

218-
@classmethod
219-
def from_pretrained(cls, model_name, num_classes=1000):
220-
model = cls.from_name(model_name, override_params={'num_classes': num_classes})
221-
load_pretrained_weights(model, model_name, load_fc=(num_classes == 1000))
222-
223-
return model
224-
225218
@classmethod
226219
def get_image_size(cls, model_name):
227220
cls._check_model_name_is_valid(model_name)
228221
_, _, res, _ = efficientnet_params(model_name)
229222
return res
230223

231224
@classmethod
232-
def _check_model_name_is_valid(cls, model_name, also_need_pretrained_weights=False):
233-
""" Validates model name. None that pretrained weights are only available for
234-
the first four models (efficientnet-b{i} for i in 0,1,2,3) at the moment. """
235-
num_models = 4 if also_need_pretrained_weights else 8
236-
valid_models = ['efficientnet-b'+str(i) for i in range(num_models)]
225+
def _check_model_name_is_valid(cls, model_name):
226+
""" Validates model name. """
227+
valid_models = ['efficientnet-b'+str(i) for i in range(9)]
237228
if model_name not in valid_models:
238229
raise ValueError('model_name should be one of: ' + ', '.join(valid_models))

efficientnet_pytorch/utils.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ def efficientnet_params(model_name):
170170
'efficientnet-b5': (1.6, 2.2, 456, 0.4),
171171
'efficientnet-b6': (1.8, 2.6, 528, 0.5),
172172
'efficientnet-b7': (2.0, 3.1, 600, 0.5),
173+
'efficientnet-b8': (2.2, 3.6, 672, 0.5),
174+
'efficientnet-l2': (4.3, 5.3, 800, 0.5),
173175
}
174176
return params_dict[model_name]
175177

@@ -293,20 +295,35 @@ def get_model_params(model_name, override_params):
293295
return blocks_args, global_params
294296

295297

296-
url_map = {
297-
'efficientnet-b0': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b0-355c32eb.pth',
298-
'efficientnet-b1': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b1-f1951068.pth',
299-
'efficientnet-b2': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b2-8bb594d6.pth',
300-
'efficientnet-b3': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b3-5fb5a3c3.pth',
301-
'efficientnet-b4': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b4-6ed6700e.pth',
302-
'efficientnet-b5': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b5-b6417697.pth',
303-
'efficientnet-b6': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b6-c76e70fd.pth',
304-
'efficientnet-b7': 'http://storage.googleapis.com/public-models/efficientnet/efficientnet-b7-dcc49843.pth',
298+
url_map_aa = {
299+
'efficientnet-b0': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b0-355c32eb.pth',
300+
'efficientnet-b1': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b1-f1951068.pth',
301+
'efficientnet-b2': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b2-8bb594d6.pth',
302+
'efficientnet-b3': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b3-5fb5a3c3.pth',
303+
'efficientnet-b4': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b4-6ed6700e.pth',
304+
'efficientnet-b5': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b5-b6417697.pth',
305+
'efficientnet-b6': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b6-c76e70fd.pth',
306+
'efficientnet-b7': 'https://publicmodels.blob.core.windows.net/container/aa/efficientnet-b7-dcc49843.pth',
305307
}
306308

307309

308-
def load_pretrained_weights(model, model_name, load_fc=True):
310+
url_map_advprop = {
311+
'efficientnet-b0': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b0-b64d5a18.pth',
312+
'efficientnet-b1': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b1-0f3ce85a.pth',
313+
'efficientnet-b2': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b2-6e9d97e5.pth',
314+
'efficientnet-b3': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b3-cdd7c0f4.pth',
315+
'efficientnet-b4': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b4-44fb3a87.pth',
316+
'efficientnet-b5': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b5-86493f6b.pth',
317+
'efficientnet-b6': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b6-ac80338e.pth',
318+
'efficientnet-b7': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b7-4652b6dd.pth',
319+
'efficientnet-b8': 'https://publicmodels.blob.core.windows.net/container/advprop/efficientnet-b8-22a8fe65.pth',
320+
}
321+
322+
323+
def load_pretrained_weights(model, model_name, load_fc=True, advprop=False):
309324
""" Loads pretrained weights, and downloads if loading for the first time. """
325+
# AutoAugment or Advprop (different preprocessing)
326+
url_map = url_map_advprop if advprop else url_map_aa
310327
state_dict = model_zoo.load_url(url_map[model_name])
311328
if load_fc:
312329
model.load_state_dict(state_dict)

examples/imagenet/main.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
help='GPU id to use.')
7272
parser.add_argument('--image_size', default=224, type=int,
7373
help='image size')
74+
parser.add_argument('--advprop', default=False, action='store_true',
75+
help='use advprop or not')
7476
parser.add_argument('--multiprocessing-distributed', action='store_true',
7577
help='Use multi-processing distributed training to launch '
7678
'N processes per node, which has N GPUs. This is the '
@@ -134,7 +136,7 @@ def main_worker(gpu, ngpus_per_node, args):
134136
# create model
135137
if 'efficientnet' in args.arch: # NEW
136138
if args.pretrained:
137-
model = EfficientNet.from_pretrained(args.arch)
139+
model = EfficientNet.from_pretrained(args.arch, advprop=args.advprop)
138140
print("=> using pre-trained model '{}'".format(args.arch))
139141
else:
140142
print("=> creating model '{}'".format(args.arch))
@@ -206,8 +208,11 @@ def main_worker(gpu, ngpus_per_node, args):
206208
# Data loading code
207209
traindir = os.path.join(args.data, 'train')
208210
valdir = os.path.join(args.data, 'val')
209-
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
210-
std=[0.229, 0.224, 0.225])
211+
if args.advprop:
212+
normalize = transforms.Lambda(lambda img: img * 2.0 - 1.0)
213+
else:
214+
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
215+
std=[0.229, 0.224, 0.225])
211216

212217
train_dataset = datasets.ImageFolder(
213218
traindir,

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
1919
AUTHOR = 'Luke'
2020
REQUIRES_PYTHON = '>=3.5.0'
21-
VERSION = '0.5.1'
21+
VERSION = '0.6.0'
2222

2323
# What packages are required for this module to be executed?
2424
REQUIRED = [

tf_to_pytorch/convert_tf_to_pt/load_tf_weights.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def load_and_save_temporary_tensorflow_model(model_name, model_ckpt, example_img
149149
parser = argparse.ArgumentParser(
150150
description='Convert TF model to PyTorch model and save for easier future loading')
151151
parser.add_argument('--model_name', type=str, default='efficientnet-b0',
152-
help='efficientnet-b{N}, where N is an integer 0 <= N <= 7')
152+
help='efficientnet-b{N}, where N is an integer 0 <= N <= 8')
153153
parser.add_argument('--tf_checkpoint', type=str, default='pretrained_tensorflow/efficientnet-b0/',
154154
help='checkpoint file path')
155155
parser.add_argument('--output_file', type=str, default='pretrained_pytorch/efficientnet-b0.pth',

0 commit comments

Comments
 (0)