#ifndef ResNet_H #define ResNet_H #include <dlib/dnn.h> namespace resnet { using namespace dlib; // BN is bn_con or affine layer template<template<typename> class BN> struct def { // the resnet basic block, where BN is bn_con or affine template<long num_filters, int stride, typename SUBNET> using basicblock = BN<con<num_filters, 3, 3, 1, 1, relu<BN<con<num_filters, 3, 3, stride, stride, SUBNET>>>>>; // the resnet bottleneck block template<long num_filters, int stride, typename SUBNET> using bottleneck = BN<con<4 * num_filters, 1, 1, 1, 1, relu<BN<con<num_filters, 3, 3, stride, stride, relu<BN<con<num_filters, 1, 1, 1, 1, SUBNET>>>>>>>>; // the resnet residual, where BLOCK is either basicblock or bottleneck template<template<long, int, typename> class BLOCK, long num_filters, typename SUBNET> using residual = add_prev1<BLOCK<num_filters, 1, tag1<SUBNET>>>; // a resnet residual that does subsampling on both paths template<template<long, int, typename> class BLOCK, long num_filters, typename SUBNET> using residual_down = add_prev2<avg_pool<2, 2, 2, 2, skip1<tag2<BLOCK<num_filters, 2, tag1<SUBNET>>>>>>; // residual block with optional downsampling template< template<template<long, int, typename> class, long, typename> class RESIDUAL, template<long, int, typename> class BLOCK, long num_filters, typename SUBNET > using residual_block = relu<RESIDUAL<BLOCK, num_filters, SUBNET>>; template<long num_filters, typename SUBNET> using resbasicblock_down = residual_block<residual_down, basicblock, num_filters, SUBNET>; template<long num_filters, typename SUBNET> using resbottleneck_down = residual_block<residual_down, bottleneck, num_filters, SUBNET>; // some definitions to allow the use of the repeat layer template<typename SUBNET> using resbasicblock_512 = residual_block<residual, basicblock, 512, SUBNET>; template<typename SUBNET> using resbasicblock_256 = residual_block<residual, basicblock, 256, SUBNET>; template<typename SUBNET> using resbasicblock_128 = residual_block<residual, basicblock, 128, SUBNET>; template<typename SUBNET> using resbasicblock_64 = residual_block<residual, basicblock, 64, SUBNET>; template<typename SUBNET> using resbottleneck_512 = residual_block<residual, bottleneck, 512, SUBNET>; template<typename SUBNET> using resbottleneck_256 = residual_block<residual, bottleneck, 256, SUBNET>; template<typename SUBNET> using resbottleneck_128 = residual_block<residual, bottleneck, 128, SUBNET>; template<typename SUBNET> using resbottleneck_64 = residual_block<residual, bottleneck, 64, SUBNET>; // common processing for standard resnet inputs template<typename INPUT> using input_processing = max_pool<3, 3, 2, 2, relu<BN<con<64, 7, 7, 2, 2, INPUT>>>>; // the resnet backbone with basicblocks template<long nb_512, long nb_256, long nb_128, long nb_64, typename INPUT> using backbone_basicblock = repeat<nb_512, resbasicblock_512, resbasicblock_down<512, repeat<nb_256, resbasicblock_256, resbasicblock_down<256, repeat<nb_128, resbasicblock_128, resbasicblock_down<128, repeat<nb_64, resbasicblock_64, input_processing<INPUT>>>>>>>>; // the resnet backbone with bottlenecks template<long nb_512, long nb_256, long nb_128, long nb_64, typename INPUT> using backbone_bottleneck = repeat<nb_512, resbottleneck_512, resbottleneck_down<512, repeat<nb_256, resbottleneck_256, resbottleneck_down<256, repeat<nb_128, resbottleneck_128, resbottleneck_down<128, repeat<nb_64, resbottleneck_64, input_processing<INPUT>>>>>>>>; // the backbones for the classic architectures template<typename INPUT> using backbone_18 = backbone_basicblock<1, 1, 1, 2, INPUT>; template<typename INPUT> using backbone_34 = backbone_basicblock<2, 5, 3, 3, INPUT>; template<typename INPUT> using backbone_50 = backbone_bottleneck<2, 5, 3, 3, INPUT>; template<typename INPUT> using backbone_101 = backbone_bottleneck<2, 22, 3, 3, INPUT>; template<typename INPUT> using backbone_152 = backbone_bottleneck<2, 35, 7, 3, INPUT>; // the typical classifier models using n18 = loss_multiclass_log<fc<1000, avg_pool_everything<backbone_18<input_rgb_image>>>>; using n34 = loss_multiclass_log<fc<1000, avg_pool_everything<backbone_34<input_rgb_image>>>>; using n50 = loss_multiclass_log<fc<1000, avg_pool_everything<backbone_50<input_rgb_image>>>>; using n101 = loss_multiclass_log<fc<1000, avg_pool_everything<backbone_101<input_rgb_image>>>>; using n152 = loss_multiclass_log<fc<1000, avg_pool_everything<backbone_152<input_rgb_image>>>>; }; using train_18 = def<bn_con>::n18; using train_34 = def<bn_con>::n34; using train_50 = def<bn_con>::n50; using train_101 = def<bn_con>::n101; using train_152 = def<bn_con>::n152; using infer_18 = def<affine>::n18; using infer_34 = def<affine>::n34; using infer_50 = def<affine>::n50; using infer_101 = def<affine>::n101; using infer_152 = def<affine>::n152; } #endif // ResNet_H