[FFmpeg-devel] [PATCH V2 1/2] dnn/native: add native support for avg_pool

Fu, Ting ting.fu at intel.com
Thu Jul 30 04:43:23 EEST 2020



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces at ffmpeg.org> On Behalf Of Ting Fu
> Sent: Wednesday, July 29, 2020 10:11 PM
> To: ffmpeg-devel at ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH V2 1/2] dnn/native: add native support for
> avg_pool
> 
> Not support pooling strides in channel dimension now.
> It can be tested with the model generated with below python script:
> 
> import tensorflow as tf
> import numpy as np
> import imageio
> 
> in_img = imageio.imread('input_odd.jpg') in_img =
> in_img.astype(np.float32)/255.0 in_data = in_img[np.newaxis, :]
> 
> x = tf.placeholder(tf.float32, shape=[1, None, None, 3], name='dnn_in') x_pool
> = tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME') #please
> alter the params as needed y = tf.identity(x_pool, name='dnn_out')
> 
> sess=tf.Session()
> sess.run(tf.global_variables_initializer())
> 
> graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def,
> ['dnn_out']) tf.train.write_graph(graph_def, '.', 'image_process.pb',
> as_text=False)
> 
> print("image_process.pb generated, please use \
> path_to_ffmpeg/tools/python/convert.py to generate image_process.model\n")
> 
> output = sess.run(y, feed_dict={x: in_data}) imageio.imsave("out.jpg",
> np.squeeze(output))
> 
> Signed-off-by: Ting Fu <ting.fu at intel.com>
> ---
>  libavfilter/dnn/Makefile                      |   1 +
>  libavfilter/dnn/dnn_backend_native.h          |   2 +
>  .../dnn/dnn_backend_native_layer_avgpool.c    | 147 ++++++++++++++++++
>  .../dnn/dnn_backend_native_layer_avgpool.h    |  35 +++++
>  .../dnn/dnn_backend_native_layer_conv2d.h     |   3 +-
>  libavfilter/dnn/dnn_backend_native_layers.c   |   2 +
>  tools/python/convert_from_tensorflow.py       |  35 ++++-
>  7 files changed, 222 insertions(+), 3 deletions(-)  create mode 100644
> libavfilter/dnn/dnn_backend_native_layer_avgpool.c
>  create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.h
> 
> diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index
> d90137ec42..e0957073ee 100644
> --- a/libavfilter/dnn/Makefile
> +++ b/libavfilter/dnn/Makefile
> @@ -1,6 +1,7 @@
>  OBJS-$(CONFIG_DNN)                           += dnn/dnn_interface.o
>  OBJS-$(CONFIG_DNN)                           += dnn/dnn_backend_native.o
>  OBJS-$(CONFIG_DNN)                           += dnn/dnn_backend_native_layers.o
> +OBJS-$(CONFIG_DNN)                           +=
> dnn/dnn_backend_native_layer_avgpool.o
>  OBJS-$(CONFIG_DNN)                           += dnn/dnn_backend_native_layer_pad.o
>  OBJS-$(CONFIG_DNN)                           +=
> dnn/dnn_backend_native_layer_conv2d.o
>  OBJS-$(CONFIG_DNN)                           +=
> dnn/dnn_backend_native_layer_depth2space.o
[...]
> 
> 
> +    def dump_avg_pool_to_file(self, node, f):
> +        assert(node.op == 'AvgPool')
> +        self.layer_number = self.layer_number + 1
> +        self.converted_nodes.add(node.name)
> +        node0 = self.name_node_dict[node.input[0]]
> +        strides = node.attr['strides']
> +        assert(strides.list.i[1]==strides.list.i[2])
> +        assert(strides.list.i[0]==1)
> +        assert(strides.list.i[3]==1)

Since the tensorflow do not support pooling strides in batch dimension, and current do not support pooling in channel dimension,
added two assert here.

> +        strides = strides.list.i[1]
> +        filter_node = node.attr['ksize']
> +        input_name = node.input[0]
> +
> +        assert(filter_node.list.i[0]==1)
> +        assert(filter_node.list.i[3]==1)

Same as above, the tensorflow do not support pooling ksize in both batch dimension and channel dimension.

> +        filter_height = filter_node.list.i[1]
> +        filter_width = filter_node.list.i[2]
> +
> +        in_channels = node0.attr['shape'].shape.dim[3].size
> +        out_channels = in_channels
> +        padding = node.attr['padding'].s.decode("utf-8")
> +        np.array([self.op2code[node.op], strides, self.pool_paddings[padding],
> in_channels, out_channels,
> +                  filter_height],dtype=np.uint32).tofile(f)
> +
> +        input_operand_index = self.add_operand(input_name,
> Operand.IOTYPE_INPUT)
> +        output_operand_index = self.add_operand(node.name,
> Operand.IOTYPE_OUTPUT)
> +        np.array([input_operand_index,
> + output_operand_index],dtype=np.uint32).tofile(f)
> +
> +
>      def dump_layers_to_file(self, f):
>          for node in self.nodes:
>              if node.name in self.converted_nodes:
> @@ -311,6 +342,8 @@ class TFConverter:
> 
>              if node.op == 'Conv2D':
>                  self.dump_simple_conv2d_to_file(node, f)
> +            if node.op == 'AvgPool':
> +                self.dump_avg_pool_to_file(node, f)
>              elif node.op == 'DepthToSpace':
>                  self.dump_depth2space_to_file(node, f)
>              elif node.op == 'MirrorPad':
> --
> 2.17.1
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email ffmpeg-devel-request at ffmpeg.org
> with subject "unsubscribe".


More information about the ffmpeg-devel mailing list