9
$\begingroup$

BlazeFace is a lightweight and well-performing face detector tailored for mobile GPU inference. It runs at a speed of 200-1000+ FPS on flagship devices. How to implement BlazeFace in Mathematica?

enter image description here

$\endgroup$

1 Answer 1

6
$\begingroup$

enter image description here

singleBlazeBlock[ch1_, ch2_, stride_: 1, pad_: 0] := NetGraph[
  <|
   1 -> NetChain[
     {
      ConvolutionLayer[ch1, {5, 5}, "ChannelGroups" -> ch1, 
       "Stride" -> stride, "PaddingSize" -> 2],
      BatchNormalizationLayer[],
      ConvolutionLayer[ch2, {1, 1}],
      BatchNormalizationLayer[]
      }
     ],
   2 -> NetChain[
     {
      PoolingLayer[{stride, stride}, stride],
      PaddingLayer[{{pad, pad}, {0, 0}, {0, 0}}]
      }
     ],
   3 -> ThreadingLayer[Plus],
   4 -> ElementwiseLayer[Ramp]
   |>,
  {
   NetPort["Input"] -> {1, 2} -> 3 -> 4
   }
  ]

doubleBlazeBlock[ch1_, ch2_, ch3_, ch4_, stride_: 1, pad_: 0] := 
 NetGraph[
  <|
   1 -> NetChain[
     {
      ConvolutionLayer[ch1, {5, 5}, "ChannelGroups" -> ch1, 
       "Stride" -> stride, "PaddingSize" -> 2],
      BatchNormalizationLayer[],
      ConvolutionLayer[ch2, {1, 1}],
      BatchNormalizationLayer[],
      ElementwiseLayer[Ramp],
      ConvolutionLayer[ch3, {5, 5}, "ChannelGroups" -> ch3, 
       "Stride" -> 1, "PaddingSize" -> 2],
      BatchNormalizationLayer[],
      ConvolutionLayer[ch4, {1, 1}],
      BatchNormalizationLayer[]
      }
     ],
   2 -> NetChain[
     {
      PoolingLayer[{stride, stride}, stride],
      PaddingLayer[{{pad, pad}, {0, 0}, {0, 0}}]
      }
     ],
   3 -> ThreadingLayer[Plus],
   4 -> ElementwiseLayer[Ramp]
   |>,
  {
   NetPort["Input"] -> {1, 2} -> 3 -> 4
   }
  ]

net = NetGraph[
   <|
    1 -> NetChain[
      {
       ConvolutionLayer[24, {5, 5}, "Stride" -> 2, "PaddingSize" -> 2],
       ElementwiseLayer[Ramp],
       BatchNormalizationLayer[]
       }
      ],
    2 -> singleBlazeBlock[24, 24],
    3 -> singleBlazeBlock[24, 24],
    4 -> singleBlazeBlock[24, 48, 2, 12],
    5 -> singleBlazeBlock[48, 48],
    6 -> singleBlazeBlock[48, 48],
    7 -> doubleBlazeBlock[48, 24, 24, 96, 2, 24],
    8 -> doubleBlazeBlock[96, 24, 24, 96],
    9 -> doubleBlazeBlock[96, 24, 24, 96],
    10 -> doubleBlazeBlock[96, 24, 24, 96, 2],
    11 -> doubleBlazeBlock[96, 24, 24, 96],
    12 -> doubleBlazeBlock[96, 24, 24, 96]
    |>,
   {
    NetPort["Input"] -> 
     1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12
    },
   "Input" -> {3, 128, 128}
   ] // NetInitialize

enter image description here

img = RandomReal[{0, 1}, {3, 128, 128}];

net[img, TargetDevice -> "GPU"]; // AbsoluteTiming
{0.0030011, Null}

net[img, TargetDevice -> "CPU"]; // AbsoluteTiming
{0.0457831, Null}

To be continued...

$\endgroup$
1
  • 1
    $\begingroup$ Would you add all the NetTrain code and data/details to train it? $\endgroup$
    – M.R.
    Feb 29, 2020 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.