Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 02e295a

Browse files
Merge branch 'master' into patch-1
2 parents 8f22066 + 1b181b1 commit 02e295a

File tree

7 files changed

+70
-31
lines changed

7 files changed

+70
-31
lines changed

‎.github/workflows/main.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Workflow
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
pypi-job:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- name: Install twine
14+
run: pip install twine
15+
- name: Build package
16+
run: python setup.py sdist
17+
- name: Publish a Python distribution to PyPI
18+
uses: pypa/gh-action-pypi-publish@release/v1
19+
with:
20+
user: __token__
21+
password: ${{ secrets.PYPI_API_TOKEN }}

‎README.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ model = EfficientNet.from_pretrained('efficientnet-b0')
1010

1111
### Updates
1212

13+
#### Update (April 2, 2021)
14+
15+
The [EfficientNetV2 paper](https://arxiv.org/abs/2104.00298) has been released! I am working on implementing it as you read this :)
16+
17+
About EfficientNetV2:
18+
> EfficientNetV2 is a new family of convolutional networks that have faster training speed and better parameter efficiency than previous models. To develop this family of models, we use a combination of training-aware neural architecture search and scaling, to jointly optimize training speed and parameter efficiency. The models were searched from the search space enriched with new ops such as Fused-MBConv.
19+
20+
Here is a comparison:
21+
> <img src="https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnetv2-image.png" width="100%" />
22+
23+
1324
#### Update (Aug 25, 2020)
1425

1526
This update adds:

‎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.7.0"
1+
__version__ = "0.7.1"
22
from .model import EfficientNet, VALID_MODELS
33
from .utils import (
44
GlobalParams,

‎efficientnet_pytorch/model.py‎

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class MBConvBlock(nn.Module):
5050
def __init__(self, block_args, global_params, image_size=None):
5151
super().__init__()
5252
self._block_args = block_args
53-
self._bn_mom = 1 - global_params.batch_norm_momentum # pytorch's difference from tensorflow
53+
self._bn_mom = 1 - global_params.batch_norm_momentum # pytorch's difference from tensorflow
5454
self._bn_eps = global_params.batch_norm_epsilon
5555
self.has_se = (self._block_args.se_ratio is not None) and (0 < self._block_args.se_ratio <= 1)
5656
self.id_skip = block_args.id_skip # whether to use skip connection and drop connect
@@ -152,9 +152,7 @@ class EfficientNet(nn.Module):
152152
[1] https://arxiv.org/abs/1905.11946 (EfficientNet)
153153
154154
Example:
155-
156-
157-
import torch
155+
>>> import torch
158156
>>> from efficientnet.model import EfficientNet
159157
>>> inputs = torch.rand(1, 3, 224, 224)
160158
>>> model = EfficientNet.from_pretrained('efficientnet-b0')
@@ -198,7 +196,7 @@ def __init__(self, blocks_args=None, global_params=None):
198196
# The first block needs to take care of stride and filter size increase.
199197
self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size))
200198
image_size = calculate_output_image_size(image_size, block_args.stride)
201-
if block_args.num_repeat > 1: # modify block_args to keep same output size
199+
if block_args.num_repeat > 1: # modify block_args to keep same output size
202200
block_args = block_args._replace(input_filters=block_args.output_filters, stride=1)
203201
for _ in range(block_args.num_repeat - 1):
204202
self._blocks.append(MBConvBlock(block_args, self._global_params, image_size=image_size))
@@ -213,16 +211,18 @@ def __init__(self, blocks_args=None, global_params=None):
213211

214212
# Final linear layer
215213
self._avg_pooling = nn.AdaptiveAvgPool2d(1)
216-
self._dropout = nn.Dropout(self._global_params.dropout_rate)
217-
self._fc = nn.Linear(out_channels, self._global_params.num_classes)
214+
if self._global_params.include_top:
215+
self._dropout = nn.Dropout(self._global_params.dropout_rate)
216+
self._fc = nn.Linear(out_channels, self._global_params.num_classes)
217+
218+
# set activation to memory efficient swish by default
218219
self._swish = MemoryEfficientSwish()
219220

220221
def set_swish(self, memory_efficient=True):
221222
"""Sets swish function as memory efficient (for training) or standard (for export).
222223
223224
Args:
224225
memory_efficient (bool): Whether to use memory-efficient version of swish.
225-
226226
"""
227227
self._swish = MemoryEfficientSwish() if memory_efficient else Swish()
228228
for block in self._blocks:
@@ -261,17 +261,17 @@ def extract_endpoints(self, inputs):
261261
for idx, block in enumerate(self._blocks):
262262
drop_connect_rate = self._global_params.drop_connect_rate
263263
if drop_connect_rate:
264-
drop_connect_rate *= float(idx) / len(self._blocks) # scale drop connect_rate
264+
drop_connect_rate *= float(idx) / len(self._blocks) # scale drop connect_rate
265265
x = block(x, drop_connect_rate=drop_connect_rate)
266266
if prev_x.size(2) > x.size(2):
267-
endpoints['reduction_{}'.format(len(endpoints)+1)] = prev_x
267+
endpoints['reduction_{}'.format(len(endpoints)+1)] = prev_x
268268
elif idx == len(self._blocks) - 1:
269-
endpoints['reduction_{}'.format(len(endpoints)+1)] = x
269+
endpoints['reduction_{}'.format(len(endpoints)+1)] = x
270270
prev_x = x
271271

272272
# Head
273273
x = self._swish(self._bn1(self._conv_head(x)))
274-
endpoints['reduction_{}'.format(len(endpoints)+1)] = x
274+
endpoints['reduction_{}'.format(len(endpoints)+1)] = x
275275

276276
return endpoints
277277

@@ -292,7 +292,7 @@ def extract_features(self, inputs):
292292
for idx, block in enumerate(self._blocks):
293293
drop_connect_rate = self._global_params.drop_connect_rate
294294
if drop_connect_rate:
295-
drop_connect_rate *= float(idx) / len(self._blocks) # scale drop connect_rate
295+
drop_connect_rate *= float(idx) / len(self._blocks) # scale drop connect_rate
296296
x = block(x, drop_connect_rate=drop_connect_rate)
297297

298298
# Head
@@ -322,7 +322,7 @@ def forward(self, inputs):
322322

323323
@classmethod
324324
def from_name(cls, model_name, in_channels=3, **override_params):
325-
"""create an efficientnet model according to name.
325+
"""Create an efficientnet model according to name.
326326
327327
Args:
328328
model_name (str): Name for efficientnet.
@@ -348,7 +348,7 @@ def from_name(cls, model_name, in_channels=3, **override_params):
348348
@classmethod
349349
def from_pretrained(cls, model_name, weights_path=None, advprop=False,
350350
in_channels=3, num_classes=1000, **override_params):
351-
"""create an efficientnet model according to name.
351+
"""Create an efficientnet model according to name.
352352
353353
Args:
354354
model_name (str): Name for efficientnet.
@@ -375,7 +375,8 @@ def from_pretrained(cls, model_name, weights_path=None, advprop=False,
375375
A pretrained efficientnet model.
376376
"""
377377
model = cls.from_name(model_name, num_classes=num_classes, **override_params)
378-
load_pretrained_weights(model, model_name, weights_path=weights_path, load_fc=(num_classes == 1000), advprop=advprop)
378+
load_pretrained_weights(model, model_name, weights_path=weights_path,
379+
load_fc=(num_classes == 1000), advprop=advprop)
379380
model._change_in_channels(in_channels)
380381
return model
381382

‎efficientnet_pytorch/utils.py‎

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
################################################################################
20-
### Help functions for model architecture
20+
# Help functions for model architecture
2121
################################################################################
2222

2323
# GlobalParams and BlockArgs: Two namedtuples
@@ -50,11 +50,14 @@
5050
GlobalParams.__new__.__defaults__ = (None,) * len(GlobalParams._fields)
5151
BlockArgs.__new__.__defaults__ = (None,) * len(BlockArgs._fields)
5252

53-
54-
# An ordinary implementation of Swish function
55-
class Swish(nn.Module):
56-
def forward(self, x):
57-
return x * torch.sigmoid(x)
53+
# Swish activation function
54+
if hasattr(nn, 'SiLU'):
55+
Swish = nn.SiLU
56+
else:
57+
# For compatibility with old PyTorch versions
58+
class Swish(nn.Module):
59+
def forward(self, x):
60+
return x * torch.sigmoid(x)
5861

5962

6063
# A memory-efficient implementation of Swish function
@@ -71,6 +74,7 @@ def backward(ctx, grad_output):
7174
sigmoid_i = torch.sigmoid(i)
7275
return grad_output * (sigmoid_i * (1 + i * (1 - sigmoid_i)))
7376

77+
7478
class MemoryEfficientSwish(nn.Module):
7579
def forward(self, x):
7680
return SwishImplementation.apply(x)
@@ -96,10 +100,10 @@ def round_filters(filters, global_params):
96100
divisor = global_params.depth_divisor
97101
min_depth = global_params.min_depth
98102
filters *= multiplier
99-
min_depth = min_depth or divisor # pay attention to this line when using min_depth
103+
min_depth = min_depth or divisor # pay attention to this line when using min_depth
100104
# follow the formula transferred from official TensorFlow implementation
101105
new_filters = max(min_depth, int(filters + divisor / 2) // divisor * divisor)
102-
if new_filters < 0.9 * filters: # prevent rounding by more than 10%
106+
if new_filters < 0.9 * filters: # prevent rounding by more than 10%
103107
new_filters += divisor
104108
return int(new_filters)
105109

@@ -233,7 +237,7 @@ def forward(self, x):
233237
ih, iw = x.size()[-2:]
234238
kh, kw = self.weight.size()[-2:]
235239
sh, sw = self.stride
236-
oh, ow = math.ceil(ih / sh), math.ceil(iw / sw) # change the output size according to stride ! ! !
240+
oh, ow = math.ceil(ih / sh), math.ceil(iw / sw) # change the output size according to stride ! ! !
237241
pad_h = max((oh - 1) * self.stride[0] + (kh - 1) * self.dilation[0] + 1 - ih, 0)
238242
pad_w = max((ow - 1) * self.stride[1] + (kw - 1) * self.dilation[1] + 1 - iw, 0)
239243
if pad_h > 0 or pad_w > 0:
@@ -311,6 +315,7 @@ def forward(self, x):
311315
return F.max_pool2d(x, self.kernel_size, self.stride, self.padding,
312316
self.dilation, self.ceil_mode, self.return_indices)
313317

318+
314319
class MaxPool2dStaticSamePadding(nn.MaxPool2d):
315320
"""2D MaxPooling like TensorFlow's 'SAME' mode, with the given input image size.
316321
The padding mudule is calculated in construction function, then used in forward.
@@ -343,7 +348,7 @@ def forward(self, x):
343348

344349

345350
################################################################################
346-
### Helper functions for loading model params
351+
# Helper functions for loading model params
347352
################################################################################
348353

349354
# BlockDecoder: A Class for encoding and decoding BlockArgs
@@ -576,7 +581,7 @@ def get_model_params(model_name, override_params):
576581
# TODO: add the petrained weights url map of 'efficientnet-l2'
577582

578583

579-
def load_pretrained_weights(model, model_name, weights_path=None, load_fc=True, advprop=False):
584+
def load_pretrained_weights(model, model_name, weights_path=None, load_fc=True, advprop=False, verbose=True):
580585
"""Loads pretrained weights from weights path or download using url.
581586
582587
Args:
@@ -607,4 +612,5 @@ def load_pretrained_weights(model, model_name, weights_path=None, load_fc=True,
607612
['_fc.weight', '_fc.bias']), 'Missing keys when loading pretrained weights: {}'.format(ret.missing_keys)
608613
assert not ret.unexpected_keys, 'Missing keys when loading pretrained weights: {}'.format(ret.unexpected_keys)
609614

610-
print('Loaded pretrained weights for {}'.format(model_name))
615+
if verbose:
616+
print('Loaded pretrained weights for {}'.format(model_name))

‎examples/imagenet/main.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def accuracy(output, target, topk=(1,)):
434434

435435
res = []
436436
for k in topk:
437-
correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
437+
correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)
438438
res.append(correct_k.mul_(100.0 / batch_size))
439439
return res
440440

‎setup.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
EMAIL = 'lmelaskyriazi@college.harvard.edu'
1919
AUTHOR = 'Luke'
2020
REQUIRES_PYTHON = '>=3.5.0'
21-
VERSION = '0.7.0'
21+
VERSION = '0.7.1'
2222

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

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /