BNNSFilterCreateLayerPooling(_:_:)
Returns a new pooling layer.
Declaration
func BNNSFilterCreateLayerPooling(_ layer_params: UnsafePointer<BNNSLayerParametersPooling>, _ filter_params: UnsafePointer<BNNSFilterParameters>?) -> BNNSFilter?Parameters
- layer_params:
Layer parameters.
- filter_params:
The filter runtime parameters.
Discussion
Use a pooling layer to downsample an input, selecting, for example, the average or the maximum value in a specified kernel size. The following figure illustrates how a 2 x 2 maximum pooling kernel samples each 2 x 2 block of values of 4 x 4 source. The highlighted block contains the values [3, 4, 0, 0], so the maximum value passed to the destination element in output is 4.
[Image]
The following code shows how you apply pooling to the input in the above figure. Note that the input is a 2 x 2 x 1 BNNSDataLayoutImageCHW tensor. Definie x_padding and y_padding as 1 to add zero padding:
let input: [Float] = [1, 2,
3, 4]
var output = [Float](repeating: 0, count: 9)
let inDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
layout: BNNSDataLayoutImageCHW,
size: (2, 2, 1, 0, 0, 0, 0, 0),
stride: (0, 0, 0, 0, 0, 0, 0, 0),
data: nil,
data_type: .float,
table_data: nil,
table_data_type: .float,
data_scale: 0,
data_bias: 0)
let outDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
layout: BNNSDataLayoutImageCHW,
size: (3, 3, 1, 0, 0, 0, 0, 0),
stride: (0, 0, 0, 0, 0, 0, 0, 0),
data: nil,
data_type: .float,
table_data: nil,
table_data_type: .float,
data_scale: 0,
data_bias: 0)
var parameters = BNNSLayerParametersPooling(i_desc: inDescriptor,
o_desc: outDescriptor,
bias: BNNSNDArrayDescriptor(),
activation: .identity,
pooling_function: .max ,
k_width: 2,
k_height: 2,
x_stride: 1,
y_stride: 1,
x_dilation_stride: 0,
y_dilation_stride: 0,
x_padding: 1,
y_padding: 1,
pad: (0, 0, 0, 0))
let filter = BNNSFilterCreateLayerPooling(¶meters, nil)
defer {
BNNSFilterDestroy(filter)
}
BNNSPoolingFilterApplyBatch(filter, 1,
input, input.count,
&output, output.count,
nil, 0)On return, output contains the following values:
[ 1.0, 2.0, 2.0,
3.0, 4.0, 4.0,
3.0, 4.0, 4.0 ]UnMax Pooling
Use BNNSPoolingFunctionUnMax in conjunction with the indices generated by BNNSPoolingFunctionMax to partially recreate the original data of a maximum pooling operation. UnMax pooling is a partial inverse of maximum pooling that sets all non-maximal values to zero.
For example, given the following input data:
let input: [Float] = [1, 1, 1, 9,
1, 9, 9, 1,
1, 1, 1, 1,
1, 9, 1, 9]Use BNNSPoolingFilterApplyBatch(_:_:_:_:_:_:_:_:) to perform the maximum pooling and populate an indices array with positional information of maximum elements in each window:
var output = [Float](repeating: 0, count: 3 * 3)
let inDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
layout: BNNSDataLayoutImageCHW,
size: (4, 4, 1, 0, 0, 0, 0, 0),
stride: (0, 0, 0, 0, 0, 0, 0, 0),
data: nil,
data_type: .float,
table_data: nil,
table_data_type: .float,
data_scale: 0,
data_bias: 0)
let outDescriptor = BNNSNDArrayDescriptor(flags: BNNSNDArrayFlags(0),
layout: BNNSDataLayoutImageCHW,
size: (3, 3, 1, 0, 0, 0, 0, 0),
stride: (0, 0, 0, 0, 0, 0, 0, 0),
data: nil,
data_type: .float,
table_data: nil,
table_data_type: .float,
data_scale: 0,
data_bias: 0)
var parameters = BNNSLayerParametersPooling(i_desc: inDescriptor,
o_desc: outDescriptor,
bias: BNNSNDArrayDescriptor(),
activation: .identity,
pooling_function: .max ,
k_width: 2,
k_height: 2,
x_stride: 1,
y_stride: 1,
x_dilation_stride: 0,
y_dilation_stride: 0,
x_padding: 0,
y_padding: 0,
pad: (0, 0, 0, 0))
let filter = BNNSFilterCreateLayerPooling(¶meters, nil)
defer {
BNNSFilterDestroy(filter)
}
var indices = [Int](repeating: 0, count: input.count)
BNNSPoolingFilterApplyBatch(filter, 1,
input, input.count,
&output, output.count,
&indices, indices.count)To perform the UnMax pooling, reuse the parameters structure, but swap the input and output descriptors:
var recreatedInput = [Float](repeating: 0, count: input.count)
parameters.i_desc = outDescriptor
parameters.o_desc = inDescriptor
parameters.pooling_function = BNNSPoolingFunctionUnMax
let unMaxFilter = BNNSFilterCreateLayerPooling(¶meters, nil)
defer {
BNNSFilterDestroy(unMaxFilter)
}
BNNSPoolingFilterApplyBatch(unMaxFilter, 1,
output, output.count,
&recreatedInput, recreatedInput.count,
&indices, indices.count)On return, recreatedInput is similar to input, but the non-maximal values are zero:
[ 0.0, 0.0, 0.0, 9.0,
0.0, 9.0, 9.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 9.0, 0.0, 9.0 ]See Also
Pooling layers
BNNSPoolingLayerParametersBNNSFilterCreatePoolingLayer(_:_:_:_:)BNNS.PoolingLayerBNNSPoolingFunctionBNNSPoolingFunctionAverageBNNSPoolingFunctionMaxBNNSLayerParametersPoolingBNNSPoolingFilterApplyBatch(_:_:_:_:_:_:_:_:)BNNSPoolingFilterApplyBackwardBatch(_:_:_:_:_:_:_:_:_:_:_:_:_:)BNNSPoolingFilterApplyBatchEx(_:_:_:_:_:_:_:_:_:)BNNSPoolingFilterApplyBackwardBatchEx(_:_:_:_:_:_:_:_:_:_:_:_:_:_:)