-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FRONTEND][TENSORFLOW] Add Pad and PadV2 support #1545
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nishi-t thanks for this addition.
@@ -669,6 +669,22 @@ def _impl(inputs, in_state_c, in_state_h, attr, params): | |||
return _impl | |||
|
|||
|
|||
def _pad(name): | |||
def _impl(inputs, attr, params): | |||
padlist = params.pop(inputs[1].list_output_names()[0]).asnumpy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to assert if padlist is not available in params.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please assert for mode not equal to CONSTANT
And the mode string is case-insensitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review.
For the second pointed out, I think that _pad
is called from only CONSTANT
in this PR, because Pad is generated by only tf.pad with CONSTANT
mode without constant_value
. In more detail, tf.pad generates different operators depending on the mode and the option:
- mode is
SYMMETRIC
orREFLECT
=>MirrorPad
- mode is
CONSTANT
withoutconstant_value
=>Pad
- mode is
CONSTANT
withconstant_value
=>PadV2
I confirmed these little strange behavior by following script:
import tensorflow as tf
import nnvm
def main(_):
def check_pad_graph(**kwargs):
print("Pad: args = ", kwargs)
with tf.Graph().as_default() as graph:
sess = tf.InteractiveSession()
a = tf.constant([[1,2,3], [4,5,6]], name='a')
padding = tf.constant([[1, 1], [2,2]])
c = tf.pad(a, padding, **kwargs)
sess.run(tf.global_variables_initializer())
print(sess.run(c))
graph_def = graph.as_graph_def(add_shapes=True)
pad_mode = kwargs['mode']
if pad_mode == 'CONSTANT':
name = "constant"
if 'constant_values' in kwargs:
name += "_with_values"
elif pad_mode == 'REFLECT':
name = "reflect"
elif pad_mode == 'SYMMETRIC':
name = "symmetric"
name += "_pad.pbtxt"
tf.train.write_graph(graph_def, '.', name, as_text=True)
check_pad_graph(mode='CONSTANT')
check_pad_graph(mode='CONSTANT', constant_values=1)
check_pad_graph(mode='SYMMETRIC', constant_values=1)
check_pad_graph(mode='REFLECT')
if __name__ == '__main__':
tf.app.run()
I put the script's result on my gist:
https://gist.github.com/nishi-t/a72c477c5f07812d327a9cb7f06b923d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nishi-t thanks for the details.
I think this PR is good to go with the other cosmetic change in testcase.
Any data about demand for MirrorPad
? we could propose additional attribute to pad operator to support mode
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@srkreddy1238 Sorry for the delay. In terms of wether I have use cases to use MirrorPad
(use tf.pad with symmetric or reflect mode), I don't have any data at the moment. But, since Pad
is required for resnet, I want to add Pad
support for now.
To support MirrorPad
, we will have to add mode
option(attribute?) to pad operator (in nnvm and perhaps tvm) to distinguish behavior of padding(CONSTANT
, REFLECT
, SYMMETRIC
) . Since MirrorPad
has mode
as attribute to distinguish between REFLECT
and SYMMETRIC
, we will be able to pass it to the pad operator.
I might have a misunderstand so please let me if we can give you any other information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nishi-t don't worry about MirrorPad, I just asked about it to know the requirement of it.
padlist = params.pop(inputs[1].list_output_names()[0]).asnumpy() | ||
paddings = tuple([tuple(l) for l in padlist]) | ||
attr['pad_width'] = paddings | ||
attr['pad_value'] = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Pad constant_value should be taken from attributes (should be zero only if not available in attributes.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pad doesn't have constant_value
as attribute and pad_value always should be 0 for Pad. Please check my previous comment.
@@ -704,6 +704,44 @@ def test_forward_resize_bilinear(): | |||
_test_resize_bilinear((4, 16, 32, 32), [50, 50], False) | |||
_test_resize_bilinear((6, 32, 64, 64), [20, 20], True) | |||
|
|||
####################################################################### | |||
# Pad | |||
# ------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underline up to the text size !
pad_values = constant_op.constant(paddings) | ||
pad = tf.pad(in_data, paddings=pad_values, **kwargs) | ||
|
||
if 'constant_values' in kwargs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constant_values could be there for both Pad and PadV2
@@ -669,6 +669,22 @@ def _impl(inputs, in_state_c, in_state_h, attr, params): | |||
return _impl | |||
|
|||
|
|||
def _pad(name): | |||
def _impl(inputs, attr, params): | |||
padlist = params.pop(inputs[1].list_output_names()[0]).asnumpy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nishi-t thanks for the details.
I think this PR is good to go with the other cosmetic change in testcase.
Any data about demand for MirrorPad
? we could propose additional attribute to pad operator to support mode
.
@srkreddy1238 I addressed. Please review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Thanks for contribution and reviewing. This is merged. |
* [FRONTEND][TENSORFLOW] Add Pad and PadV2 support * Add assettion to _pad, and fix testcase for pad.
This PR adds Pad and PadV2 support for tensorflow.
@PariksheetPinjari909 @srkreddy1238 Could you please review?