Skip to content
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

Fix avgPool3d #7133

Merged
merged 23 commits into from Dec 6, 2022
Merged

Fix avgPool3d #7133

merged 23 commits into from Dec 6, 2022

Conversation

Linchenn
Copy link
Collaborator

@Linchenn Linchenn commented Dec 1, 2022

This PR fixes a couple of issues for avgPool3d for Core, CPU-backend and GPU-backend:

  1. Avoid dividing zero when computing averages in CPU-backend and GPU-backend. Fixed When setting the pad to a number, the result of tf.avgPool3d is abnormal. #7122
  2. Changes the logics for computing the shape of avgPool3d's output. Fixed Error in tf.avgPool3d: The shape of the output tensor is [1,0,2,-1,1] when run on WebGL and CPU backend while [ 0, 2, 0, 1 ] on tensorflow backend #7130
  3. Adds strides check to make sure they are positive. Fixed When strides contains 0, the tf.avgPool3d occurred Crash #7129

To see the logs from the Cloud Build CI, please join either our discussion or announcement mailing list.


This change is Reviewable

}
setOutput(${returnValue});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setOutput(${returnValue}); should happen out of all loops and just before main returns. Originally, it is within for (int wD = 0; wD < ${effectiveFilterDepth};'s loop

roundingMode);
}
}
return outShape;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds two changes in computeOutputShape4D function:

  1. add a if-branch to make sure all dimensions of outShape are non-negative.
  2. outputDepths, outputRows, outputCols should be computed from the corresponding strides and filterSize respectfully.

@@ -496,6 +495,10 @@ function get3DPadAndOutInfo(
let outHeight: number;
let outWidth: number;

if (pad === 'valid') {
pad = 0;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If pad is 'valid', it should have the same result as pad = 0.

By the way, the roundingMode for this case is supposed to be 'truncate', instead of 'ceil', referring to tensorflow.

Copy link
Collaborator

@pyu10055 pyu10055 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great work, thank you Lin!

Reviewable status: :shipit: complete! 2 of 1 approvals obtained (waiting on @Linchenn)


tfjs-backend-webgl/src/pool_gpu.ts line 455 at r1 (raw file):

Previously, Linchenn wrote…

setOutput(${returnValue}); should happen out of all loops and just before main returns. Originally, it is within for (int wD = 0; wD < ${effectiveFilterDepth};'s loop

good catch!


tfjs-core/src/ops/avg_pool_3d.ts line 91 at r7 (raw file):

  util.assert(
      (typeof strides === 'number' && strides > 0) ||
          (typeof strides === 'object' && strides[0] > 0 && strides[1] > 0 &&

should we use Arrays.isArray()?


tfjs-core/src/ops/conv_util.ts line 500 at r6 (raw file):

Previously, Linchenn wrote…

If pad is 'valid', it should have the same result as pad = 0.

By the way, the roundingMode for this case is supposed to be 'truncate', instead of 'ceil', referring to tensorflow.

thanks for checking TF implementation.

Copy link
Collaborator Author

@Linchenn Linchenn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Reviewable status: :shipit: complete! 2 of 1 approvals obtained (waiting on @pyu10055)


tfjs-core/src/ops/avg_pool_3d.ts line 91 at r7 (raw file):

Previously, pyu10055 (Ping Yu) wrote…

should we use Arrays.isArray()?

Done.

// Use `max(count, 1.0)` instead of `count` in case count === 0.0.
// If count === 0.0, `avgValue` is always 0.0 and we change `count`'s
// value to avoid dividing zero.
returnValue = `avgValue / max(count, 1.0)`;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @qjia7 @xhcao , WebGPU may have the same issue,

returnValue = `resultValue / count`;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Linchenn . Just curious, is L124 returnValue = avgValue / count; missed for change?

And another question is that it seems that it's not possible to happen that count is zero in

returnValue = `resultValue / count`;
since updateSnippet will increase count. Will there be a situation that the filter window is totally no overlap with the input window?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, thanks!

If padding >= filter size, this would happen, as #7122.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for your explanation.
Can you help to cover the webgpu change in this PR since you already find the right place? :) And it will be great if you add a similar case as #7122 to file avg_pool_3d_test.ts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you!

@Linchenn Linchenn requested a review from qjia7 December 5, 2022 20:26
Copy link
Collaborator

@qjia7 qjia7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@Linchenn Linchenn merged commit cd8c668 into tensorflow:master Dec 6, 2022
@Linchenn Linchenn deleted the fixAvgPool branch December 6, 2022 00:55
Linchenn added a commit to Linchenn/tfjs that referenced this pull request Jan 9, 2023
BUG

* fix webgl

* rename

* add strides check

* Update conv_util.ts

* reduce valid

* lint

* reduce

* add tests

* isArray

* Update pool_gpu.ts

* Update pool2d_webgpu.ts

* Update avg_pool_3d_test.ts

* Update avg_pool_3d_test.ts

* skip tests for node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants