-
-
Save fpgaminer/57232ab085b8be1decb0906c4eb03356 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_dataloaders(size, woof, bs, sh=0., workers=None): | |
if size<=224: path = URLs.IMAGEWOOF_320 if woof else URLs.IMAGENETTE_320 | |
else : path = URLs.IMAGEWOOF if woof else URLs.IMAGENETTE | |
source = untar_data(path) | |
if workers is None: workers = min(8, num_cpus()) | |
batch_tfms = [Normalize.from_stats(*imagenet_stats)] | |
if sh: batch_tfms.append(RandomErasing(p=0.3, max_count=3, sh=sh)) | |
dblock = DataBlock(blocks=(ImageBlock, CategoryBlock), | |
splitter=GrandparentSplitter(valid_name='val'), | |
get_items=get_image_files, get_y=parent_label, | |
item_tfms=[RandomResizedCrop(size, min_scale=0.35), FlipItem(0.5)], | |
batch_tfms=batch_tfms) | |
return dblock.dataloaders(source, path=source, bs=bs, num_workers=workers) | |
def main( | |
woof=True, | |
lr=1e-2, | |
size=128, | |
sqrmom=0.99, | |
mom=0.9, | |
eps=1e-6, | |
epochs=5, | |
bs=64, | |
mixup=0., | |
opt=ranger, | |
arch=xresnet18, | |
sh=0., | |
sa=0, | |
sym=0, | |
beta=0., | |
act_fn=Mish, | |
pool=MaxPool, | |
dump=0, | |
dump_learned=False, | |
runs=1, | |
wd=1e-2, | |
act_classes=None | |
): | |
if opt == Adam: opt_func = partial(Adam, mom=mom, sqr_mom=sqrmom, eps=eps) | |
elif opt == ranger: opt_func = partial(ranger, mom=mom, sqr_mom=sqrmom, eps=eps, beta=beta) | |
dls = get_dataloaders(size, woof, bs, sh=sh) | |
summed_accuracy = 0 | |
accuracies = [] | |
for run in range(runs): | |
print(f'Run: {run}') | |
if act_classes is None: | |
learn = Learner(dls, arch(n_out=10, act_cls=act_fn, sa=sa, sym=sym, pool=pool), opt_func=opt_func, \ | |
metrics=[accuracy,top_k_accuracy], loss_func=LabelSmoothingCrossEntropy()) | |
else: | |
learn = Learner(dls, arch(n_out=10, act_cls=act_fn, sa=sa, sym=sym, pool=pool, act_classes=act_classes), opt_func=opt_func, \ | |
metrics=[accuracy,top_k_accuracy], loss_func=LabelSmoothingCrossEntropy()) | |
if dump: return learn | |
cbs = MixUp(mixup) if mixup else [] | |
learn.fit_flat_cos(epochs, lr, wd=wd, cbs=cbs) | |
max_accuracy = max(L(learn.recorder.values).itemgot(2)) | |
accuracies.append(max_accuracy) | |
if dump_learned: | |
return learn | |
gc.collect() | |
torch.cuda.empty_cache() | |
return (sum(accuracies) / len(accuracies), accuracies) | |
class CustomResNet(nn.Sequential): | |
@delegates(ResBlock) | |
def __init__(self, p=0.0, c_in=3, n_out=10, act_cls=defaults.activation, act_classes=None, **kwargs): | |
self.act_classes = act_classes | |
stem = [ | |
ConvLayer(c_in, 32, stride=2, act_cls=act_classes.stem), | |
ConvLayer(32, 32, stride=1, act_cls=act_classes.stem), | |
ConvLayer(32, 64, stride=1, act_cls=act_classes.stem_final), | |
] | |
block_sizes = [64, 64, 128, 256, 512] | |
blocks = [] | |
for i in range(len(block_sizes)-1): | |
ni = block_sizes[i] | |
nf = block_sizes[i+1] | |
stride = 1 if i == 0 else 2 | |
blocks.append(self._make_layer(ni, nf, stride=stride, **kwargs)) | |
super().__init__( | |
*stem, nn.MaxPool2d(kernel_size=3, stride=2, padding=1), | |
act_classes.stem_pool_after(), | |
*blocks, | |
act_classes.after_blocks(), | |
nn.AdaptiveAvgPool2d(1), Flatten(), nn.Dropout(p), | |
nn.Linear(block_sizes[-1], n_out), | |
) | |
init_cnn(self) | |
def _make_layer(self, ni, nf, stride, sa, **kwargs): | |
return nn.Sequential( | |
CustomResBlock(ni, nf, stride=stride, act_classes=self.act_classes, **kwargs), | |
CustomResBlock(nf, nf, stride=1, act_classes=self.act_classes, **kwargs) | |
) | |
class CustomResBlock(Module): | |
def __init__(self, ni, nf, stride=1, sym=False, norm_type=NormType.Batch, act_classes=None, | |
pool=AvgPool, ks=3, **kwargs): | |
norm2 = (NormType.BatchZero if norm_type==NormType.Batch else | |
NormType.InstanceZero if norm_type==NormType.Instance else norm_type) | |
convpath = [ | |
act_classes.block_conv_before(), | |
ConvLayer(ni, nf, ks, stride=stride, groups=1, norm_type=norm_type, act_cls=act_classes.block_conv1, ndim=2, **kwargs), | |
ConvLayer(nf, nf, ks, groups=1, norm_type=norm2, act_cls=act_classes.block_conv2, ndim=2, **kwargs) | |
] | |
self.convpath = nn.Sequential(*convpath) | |
# FYI: In CustomResNet the blocks are either stride=1 && ni==nf, or stride=2 && ni!=nf, so this code is | |
# a little hacky and doesn't do anything complicated to handle other cases. | |
idpath = [act_classes.block_id_before()] | |
if stride != 1: | |
idpath.append(act_classes.block_idpool_before()) | |
idpath.append(pool(stride, ndim=2, ceil_mode=True)) | |
if ni != nf: | |
idpath.append(act_classes.block_idpool_after()) | |
idpath.append(ConvLayer(ni, nf, 1, act_cls=act_classes.block_idconv, ndim=2, **kwargs)) | |
self.idpath = nn.Sequential(*idpath) | |
self.act = act_classes.block_act() | |
def forward(self, x): | |
return self.act(self.convpath(x) + self.idpath(x)) | |
class DoubleMish(Module): | |
def forward(self, x): return mish(mish(x)) | |
ResNetActivations = namedtuple('ResNetActivations', ['stem', 'stem_final', 'stem_pool_after', 'after_blocks', 'block_conv_before', 'block_conv1', 'block_conv2', 'block_id_before', 'block_idpool_before', 'block_idpool_after', 'block_idconv', 'block_act']) | |
ResNetActivationsDefaults = ResNetActivations( | |
stem = Mish, | |
stem_final = Mish, | |
stem_pool_after = nn.Sequential, | |
after_blocks = nn.Sequential, | |
block_conv_before = nn.Sequential, | |
block_conv1 = Mish, | |
block_conv2 = None, | |
block_id_before = nn.Sequential, | |
block_idpool_before = nn.Sequential, | |
block_idpool_after = nn.Sequential, | |
block_idconv = None, | |
block_act = Mish, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment