bottleNeckChannel = outputChannel / narrowRatio
| 15 | |
| 16 | // bottleNeckChannel = outputChannel / narrowRatio |
| 17 | static VARP shuffleUnit(VARP x, int inputChannel, int outputChannel, |
| 18 | int group, int stride, int narrowRatio) { |
| 19 | int bottleNeckChannel = outputChannel / narrowRatio; |
| 20 | int branchChannel = outputChannel; |
| 21 | if (stride != 1) { |
| 22 | branchChannel = outputChannel - inputChannel; |
| 23 | } |
| 24 | auto y = _Conv(0.0f, 0.0f, x, {inputChannel, bottleNeckChannel}, {1, 1}, VALID, {1, 1}, {1, 1}, group); // Group Conv |
| 25 | y = _ChannelShuffle(y, group); |
| 26 | y = _Conv(0.0f, 0.0f, y, {bottleNeckChannel, bottleNeckChannel}, {3, 3}, SAME, {stride, stride}, {1, 1}, bottleNeckChannel); // Depthwise Conv |
| 27 | y = _Conv(0.0f, 0.0f, y, {bottleNeckChannel, branchChannel}, {1, 1}, VALID, {1, 1}, {1, 1}, group); // Group Conv |
| 28 | if (stride != 1) { |
| 29 | x = _AvePool(x, {3, 3}, {2, 2}, SAME); |
| 30 | y = _Concat({x, y}, 1); // concat on channel axis (NCHW) |
| 31 | } else { |
| 32 | y = _Add(x, y); |
| 33 | } |
| 34 | return y; |
| 35 | } |
| 36 | |
| 37 | static VARP shuffleBlock(VARP x, int inputChannel, int outputChannel, |
| 38 | int group, int stride, int narrowRatio, int number) { |
no test coverage detected