def _make_divisible(v, divisor, min_value=None):
"""
This function is taken from the original tf repo.
It ensures that all layers have a channel number that is divisible by 8
It can be seen here:
https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py
"""
if min_value is None:
min_value = divisor
new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
Make sure that round down does not go down by more than 10%.
import torch import torch.nn as nn import math
all = ['ghost_net']
def _make_divisible(v, divisor, min_value=None): """ This function is taken from the original tf repo. It ensures that all layers have a channel number that is divisible by 8 It can be seen here: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py """ if min_value is None: min_value = divisor new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
Make sure that round down does not go down by more than 10%.
class SELayer(nn.Module): def init(self, channel, reduction=4): super(SELayer, self).init() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, channel // reduction), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel), )
def depthwise_conv(inp, oup, kernel_size=3, stride=1, relu=False): return nn.Sequential( nn.Conv2d(inp, oup, kernel_size, stride, kernel_size//2, groups=inp, bias=False), nn.BatchNorm2d(oup), nn.ReLU(inplace=True) if relu else nn.Sequential(), )
class GhostModule(nn.Module): def init(self, inp, oup, kernel_size=1, ratio=2, dw_size=3, stride=1, relu=True): super(GhostModule, self).init() self.oup = oup init_channels = math.ceil(oup / ratio) new_channels = init_channels*(ratio-1)
class GhostBottleneck(nn.Module): def init(self, inp, hidden_dim, oup, kernel_size, stride, use_se): super(GhostBottleneck, self).init() assert stride in [1, 2]
class GhostNet(nn.Module): def init(self, cfgs, num_classes=1000, width_mult=1.): super(GhostNet, self).init()
setting of inverted residual blocks
def ghost_net(**kwargs): """ Constructs a GhostNet model """ cfgs = [
k, t, c, SE, s
if name=='main': model = ghost_net() model.eval() print(model) input = torch.randn(32,3,224,224) y = model(input) print(y)
python3 of_cnn_train_val.py \ --train_data_dir=$DATA_ROOT/train \ --train_data_part_num=256 \ --val_data_dir=$DATA_ROOT/validation \ --val_data_part_num=256 \ --num_nodes=1 \ --gpu_num_per_node=8 \ --optimizer="rmsprop" \ --decay_rate=0.9 \ --momentum=0.9 \ --learning_rate=0.4 \ --wd=0.00004 \ --lr_decay="exponential" \ --lr_decay_rate=0.94 \ --lr_decay_epochs=2 \ --loss_print_every_n_iter=100 \ --batch_size_per_device=128 \ --val_batch_size_per_device=128 \ --num_epoch=800 \ --warmup_epochs=0 \ --model="ghostnet" \