(l, out_channel, group, stride)
| 50 | |
| 51 | @layer_register() |
| 52 | def shufflenet_unit(l, out_channel, group, stride): |
| 53 | in_shape = l.get_shape().as_list() |
| 54 | in_channel = in_shape[1] |
| 55 | shortcut = l |
| 56 | |
| 57 | # "We do not apply group convolution on the first pointwise layer |
| 58 | # because the number of input channels is relatively small." |
| 59 | first_split = group if in_channel > 24 else 1 |
| 60 | l = Conv2D('conv1', l, out_channel // 4, 1, split=first_split, activation=BNReLU) |
| 61 | l = channel_shuffle(l, group) |
| 62 | l = DepthConv('dconv', l, out_channel // 4, 3, stride=stride) |
| 63 | l = BatchNorm('dconv_bn', l) |
| 64 | |
| 65 | l = Conv2D('conv2', l, |
| 66 | out_channel if stride == 1 else out_channel - in_channel, |
| 67 | 1, split=group) |
| 68 | l = BatchNorm('conv2_bn', l) |
| 69 | if stride == 1: # unit (b) |
| 70 | output = tf.nn.relu(shortcut + l) |
| 71 | else: # unit (c) |
| 72 | shortcut = AvgPooling('avgpool', shortcut, 3, 2, padding='SAME') |
| 73 | output = tf.concat([shortcut, tf.nn.relu(l)], axis=1) |
| 74 | return output |
| 75 | |
| 76 | |
| 77 | @layer_register() |
no test coverage detected