From 9adb02b9580cea501f0b6e7e50a71e903e211e5b Mon Sep 17 00:00:00 2001 From: BruceDai Date: Mon, 31 Mar 2025 17:30:11 +0800 Subject: [PATCH 1/2] Fixed wrong result for l2Pool2d when sliding window having two valid elements --- src/reduce.js | 9 +++++---- test/l2pool2d_test.js | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/reduce.js b/src/reduce.js index 8c72aae..56db30a 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -166,13 +166,14 @@ export function reduceL1(input, options = {}) { /* The l2 reducer */ export function l2Reducer(previousValue, currentValue, currentIndex, array) { + let sumOfSquares; if (currentIndex == 1) { - const sumOfSquares = previousValue * previousValue + currentValue * currentValue; - return sumOfSquares; + sumOfSquares = previousValue * previousValue + currentValue * currentValue; } else { - const sumOfSquares = previousValue + currentValue * currentValue; - return (currentIndex === array.length - 1) ? Math.sqrt(sumOfSquares) :sumOfSquares; + sumOfSquares = previousValue + currentValue * currentValue; } + + return (currentIndex === array.length - 1) ? Math.sqrt(sumOfSquares) : sumOfSquares; } /** diff --git a/test/l2pool2d_test.js b/test/l2pool2d_test.js index cc9e06a..ea82e26 100644 --- a/test/l2pool2d_test.js +++ b/test/l2pool2d_test.js @@ -199,4 +199,22 @@ describe('test pool2d', function() { ]; utils.checkValue(y, expected); }); + + it('l2Pool2d pads roundingType=ceil', function() { + const x = new Tensor([1, 1, 5, 5], [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + ]); + const windowDimensions = [3, 3]; + const padding = [1, 0, 0, 1]; + const strides = [2, 2]; + const y = l2Pool2d(x, {windowDimensions, padding, strides, roundingType: 'ceil'}); + utils.checkShape(y, [1, 1, 3, 3]); + const expected = [ + 12.767145334803704, 17.175564037317667, 11.180339887498949, + 38.1051177665153, 43.81780460041329, 26.92582403567252, + 48.19751030914356, 53.056573579529235, 32.01562118716424, + ]; + utils.checkValue(y, expected); + }); }); From 0f894b88f484b9361444cac06cbd1bb578913777 Mon Sep 17 00:00:00 2001 From: BruceDai Date: Mon, 7 Apr 2025 14:14:37 +0800 Subject: [PATCH 2/2] optimize l2Pool2d implementation by introduced sumReducer method --- src/pool2d.js | 10 +++++++--- src/reduce.js | 20 ++++++-------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/pool2d.js b/src/pool2d.js index 7ed740b..73798bc 100644 --- a/src/pool2d.js +++ b/src/pool2d.js @@ -1,8 +1,10 @@ 'use strict'; -import {Tensor} from './lib/tensor.js'; +import {Tensor, Scalar} from './lib/tensor.js'; import {transpose} from './transpose.js'; -import {l2Reducer, meanReducer, maxReducer} from './reduce.js'; +import {pow} from './binary.js'; +import {sqrt} from './unary.js'; +import {maxReducer, meanReducer, sumReducer} from './reduce.js'; import {validatePool2dParams} from './lib/validate-input.js'; /** @@ -120,5 +122,7 @@ export function maxPool2d(input, options = {}) { * @return {Tensor} */ export function l2Pool2d(input, options = {}) { - return pool2d(input, l2Reducer, options); + const squaredInput = pow(input, new Scalar(2)); + const pooledInput = pool2d(squaredInput, sumReducer, options); + return sqrt(pooledInput); } diff --git a/src/reduce.js b/src/reduce.js index 56db30a..c989917 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -101,6 +101,11 @@ export function meanReducer(previousValue, currentValue, currentIndex, array) { } } +/* The sum reducer */ +export function sumReducer(previousValue, currentValue) { + return previousValue + currentValue; +} + /** * Compute the average value of all the input values along the axes. * @param {Tensor} input @@ -140,8 +145,7 @@ export function reduceProduct(input, options = {}) { * @return {Tensor} */ export function reduceSum(input, options = {}) { - return reduce(input, - (previousValue, currentValue) => previousValue + currentValue, options); + return reduce(input, sumReducer, options); } /** @@ -164,18 +168,6 @@ export function reduceL1(input, options = {}) { return reduceSum(abs(input), options); } -/* The l2 reducer */ -export function l2Reducer(previousValue, currentValue, currentIndex, array) { - let sumOfSquares; - if (currentIndex == 1) { - sumOfSquares = previousValue * previousValue + currentValue * currentValue; - } else { - sumOfSquares = previousValue + currentValue * currentValue; - } - - return (currentIndex === array.length - 1) ? Math.sqrt(sumOfSquares) : sumOfSquares; -} - /** * Compute the L2 norm of all the input values along the axes. * @param {Tensor} input