From daf106489051eb0ab20838cd369d814ec9f0038f Mon Sep 17 00:00:00 2001 From: huningxin Date: Wed, 30 Oct 2024 07:00:33 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20webmachi?= =?UTF-8?q?nelearning/webnn-samples@77a98b9e4917fb52347272b694a39b4f4fa7bb?= =?UTF-8?q?f7=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- face_recognition/facenet_nchw.js | 11 ++++++---- face_recognition/facenet_nhwc.js | 8 ++++--- .../ssd_mobilenetv2_face_nchw.js | 8 +++++-- .../ssd_mobilenetv2_face_nhwc.js | 7 ++++-- image_classification/mobilenet_nhwc.js | 7 ++++-- image_classification/resnet50v2_nhwc.js | 12 +++++++--- image_classification/squeezenet_nhwc.js | 8 +++++-- nnotepad/js/nnotepad.js | 22 ++++++++++++------- nsnet2/nsnet2.js | 5 +++-- object_detection/ssd_mobilenetv1_nchw.js | 7 ++++-- object_detection/ssd_mobilenetv1_nhwc.js | 7 ++++-- object_detection/tiny_yolov2_nchw.js | 11 +++++++--- object_detection/tiny_yolov2_nhwc.js | 11 +++++++--- semantic_segmentation/deeplabv3_mnv2_nhwc.js | 7 ++++-- style_transfer/fast_style_transfer_net.js | 7 ++++-- 15 files changed, 96 insertions(+), 42 deletions(-) diff --git a/face_recognition/facenet_nchw.js b/face_recognition/facenet_nchw.js index 55de74ca..1fdbea1a 100644 --- a/face_recognition/facenet_nchw.js +++ b/face_recognition/facenet_nchw.js @@ -47,13 +47,15 @@ export class FaceNetNchw { } input = await input; - + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; // WebNN spec drops autoPad support, compute the explicit padding instead. if (options.autoPad == 'same-upper') { options.padding = computePadding2DForAutoPad( - /* nchw */[input.shape()[2], input.shape()[3]], - /* oihw */[weights.shape()[2], weights.shape()[3]], + /* nchw */[inputShape[2], inputShape[3]], + /* oihw */[weightsShape[2], weightsShape[3]], options.strides, options.dilations, options.autoPad); } const conv2d = this.builder_.conv2d(input, weights, options); @@ -266,7 +268,8 @@ export class FaceNetNchw { const averagePool = this.builder_.averagePool2d(await block8_6); // Use reshape to implement squeeze(averagePool, {axes: [2, 3]}); - const squeezed_shape = averagePool.shape(); + const squeezed_shape = typeof averagePool.shape === 'function' ? + averagePool.shape() : averagePool.shape; squeezed_shape.splice(2, 2); const squeeze = this.builder_.reshape(averagePool, squeezed_shape); const gemm = await this.buildGemm_(squeeze); diff --git a/face_recognition/facenet_nhwc.js b/face_recognition/facenet_nhwc.js index 12cf1544..64946d97 100644 --- a/face_recognition/facenet_nhwc.js +++ b/face_recognition/facenet_nhwc.js @@ -49,13 +49,15 @@ export class FaceNetNhwc { } input = await input; - + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; // WebNN spec drops autoPad support, compute the explicit padding instead. if (options.autoPad == 'same-upper') { options.padding = computePadding2DForAutoPad( - /* nwhc */[input.shape()[1], input.shape()[2]], - /* ohwi */[weights.shape()[1], weights.shape()[2]], + /* nwhc */[inputShape[1], inputShape[2]], + /* ohwi */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, options.autoPad); } const conv2d = this.builder_.conv2d(input, weights, options); diff --git a/facial_landmark_detection/ssd_mobilenetv2_face_nchw.js b/facial_landmark_detection/ssd_mobilenetv2_face_nchw.js index 9c146331..76ad51f1 100644 --- a/facial_landmark_detection/ssd_mobilenetv2_face_nchw.js +++ b/facial_landmark_detection/ssd_mobilenetv2_face_nchw.js @@ -69,8 +69,12 @@ ${nameArray[1]}`; const weights = buildConstantByNpy(this.builder_, weightsName); const biasName = prefix + biasSuffix; const bias = buildConstantByNpy(this.builder_, biasName); - const inputShape = (await input).shape(); - const weightsShape = (await weights).shape(); + + const isShapeMethod = typeof (await input).shape === 'function'; + const inputShape = isShapeMethod ? (await input).shape() : + (await input).shape; + const weightsShape = isShapeMethod ? (await weights).shape() : + (await weights).shape; options.padding = computePadding2DForAutoPad( /* nchw */[inputShape[2], inputShape[3]], /* oihw */[weightsShape[2], weightsShape[3]], diff --git a/facial_landmark_detection/ssd_mobilenetv2_face_nhwc.js b/facial_landmark_detection/ssd_mobilenetv2_face_nhwc.js index c2cc6b7f..dadf5a95 100644 --- a/facial_landmark_detection/ssd_mobilenetv2_face_nhwc.js +++ b/facial_landmark_detection/ssd_mobilenetv2_face_nhwc.js @@ -82,8 +82,11 @@ ${nameArray[1]}`; options.filterLayout = 'ihwo'; } options.bias = await bias; - const inputShape = (await input).shape(); - const weightsShape = (await weights).shape(); + const isShapeMethod = typeof (await input).shape === 'function'; + const inputShape = isShapeMethod ? (await input).shape() : + (await input).shape; + const weightsShape = isShapeMethod ? (await weights).shape() : + (await weights).shape; options.padding = computePadding2DForAutoPad( /* nhwc */[inputShape[1], inputShape[2]], /* ohwi or ihwo */[weightsShape[1], weightsShape[2]], diff --git a/image_classification/mobilenet_nhwc.js b/image_classification/mobilenet_nhwc.js index 3fc89bba..ff59d3f2 100644 --- a/image_classification/mobilenet_nhwc.js +++ b/image_classification/mobilenet_nhwc.js @@ -34,10 +34,13 @@ export class MobileNetV2Nhwc { options.bias = await bias; // WebNN spec drops autoPad support, compute the explicit padding instead. if (options.autoPad == 'same-upper') { + const isShapeMethod = typeof weights.shape === 'function'; + const inputShape = isShapeMethod ? (await input).shape() : (await input).shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nwhc */[await input.shape()[1], await input.shape()[2]], - /* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]], + /* nwhc */[inputShape[1], inputShape[2]], + /* ohwi or ihwo */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, options.autoPad); } const conv2d = this.builder_.conv2d(await input, weights, options); diff --git a/image_classification/resnet50v2_nhwc.js b/image_classification/resnet50v2_nhwc.js index 0988e6b2..01af991d 100644 --- a/image_classification/resnet50v2_nhwc.js +++ b/image_classification/resnet50v2_nhwc.js @@ -52,10 +52,14 @@ export class ResNet50V2Nhwc { options.bias = await bias; // WebNN spec drops autoPad support, compute the explicit padding instead. if (options.autoPad == 'same-upper') { + const isShapeMethod = typeof weights.shape === 'function'; + const inputShape = isShapeMethod ? (await input).shape() : + (await input).shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nwhc */[await input.shape()[1], await input.shape()[2]], - /* ohwi */[weights.shape()[1], weights.shape()[2]], + /* nwhc */[inputShape[1], inputShape[2]], + /* ohwi */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, options.autoPad); } const conv2d = this.builder_.conv2d(await input, weights, options); @@ -141,10 +145,12 @@ export class ResNet50V2Nhwc { const conv1 = await this.buildConv_( input, ['', '', '1'], {strides, padding: [3, 3, 3, 3]}, false); const windowDimensions = [3, 3]; + const conv1Shape = typeof conv1.shape === 'function' ? + conv1.shape() : conv1.shape; const pool = this.builder_.maxPool2d( conv1, {windowDimensions, strides, layout, padding: computePadding2DForAutoPad( - /* nhwc */ [conv1.shape()[1], conv1.shape()[2]], + /* nhwc */ [conv1Shape[1], conv1Shape[2]], windowDimensions, strides, /* dilations */ undefined, 'same-upper')}); // Block 1 diff --git a/image_classification/squeezenet_nhwc.js b/image_classification/squeezenet_nhwc.js index f7e50417..44f86668 100644 --- a/image_classification/squeezenet_nhwc.js +++ b/image_classification/squeezenet_nhwc.js @@ -33,10 +33,14 @@ export class SqueezeNetNhwc { options.bias = await bias; // WebNN spec drops autoPad support, compute the explicit padding instead. if (options.autoPad == 'same-upper') { + const isShapeMethod = typeof weights.shape === 'function'; + const inputShape = isShapeMethod ? (await input).shape() : + (await input).shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nwhc */[await input.shape()[1], await input.shape()[2]], - /* ohwi */[weights.shape()[1], weights.shape()[2]], + /* nwhc */[inputShape[1], inputShape[2]], + /* ohwi */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, options.autoPad); } const conv2d = this.builder_.conv2d(await input, weights, options); diff --git a/nnotepad/js/nnotepad.js b/nnotepad/js/nnotepad.js index 38a57c26..315b9f5a 100644 --- a/nnotepad/js/nnotepad.js +++ b/nnotepad/js/nnotepad.js @@ -37,16 +37,21 @@ const kArgTypeOperand = 3; class WebNNUtil { static bufferForOperand(operand) { - const size = [...operand.shape()].reduce((a, b) => a * b, 1); - const ctor = WebNNUtil.dataTypeToBufferType(operand.dataType()); + const isShapeMethod = typeof operand.shape === 'function'; + const operandShape = isShapeMethod ? operand.shape() : operand.shape; + const operandDataType = isShapeMethod ? operand.dataType() : + operand.dataType; + const size = [...operandShape].reduce((a, b) => a * b, 1); + const ctor = WebNNUtil.dataTypeToBufferType(operandDataType); return Reflect.construct(ctor, [size]); } static async tensorForOperand(operand, context) { + const isShapeMethod = typeof operand.shape === 'function'; const desc = { - dataType: operand.dataType(), - dimensions: operand.shape(), - shape: operand.shape(), + dataType: isShapeMethod ? operand.dataType() : operand.dataType, + dimensions: isShapeMethod ? operand.shape() : operand.shape, + shape: isShapeMethod ? operand.shape() : operand.shape, usage: MLTensorUsage.READ, readable: true, }; @@ -613,9 +618,10 @@ export class NNotepad { return outputOperands.map( (op, index) => ({ - dataType: op.dataType(), - dimensions: op.shape(), - shape: op.shape(), + dataType: typeof op.shape === 'function' ? op.dataType() : + op.dataType, + dimensions: typeof op.shape === 'function' ? op.shape() : op.shape, + shape: typeof op.shape === 'function' ? op.shape() : op.shape, buffer: maybeProxyForFloat16Array(outputBuffers[`output-${index}`]), })); } diff --git a/nsnet2/nsnet2.js b/nsnet2/nsnet2.js index f22819b6..401f9dd6 100644 --- a/nsnet2/nsnet2.js +++ b/nsnet2/nsnet2.js @@ -58,7 +58,8 @@ export class NSNet2 { const [gru94, gru93] = this.builder_.gru(transpose31, weight192, recurrentWeight193, frames, this.hiddenSize, {bias: bias194, recurrentBias: recurrentBias194, initialHiddenState: initialState92, returnSequence: true}); // Use reshape to implement squeeze(gru93, {axes: [1]}); - const squeeze95Shape = gru93.shape(); + const isShapeMethod = typeof gru93.shape === 'function'; + const squeeze95Shape = isShapeMethod ? gru93.shape() : gru93.shape; squeeze95Shape.splice(1, 1); const squeeze95 = this.builder_.reshape(gru93, squeeze95Shape); const initialState155 = this.builder_.input('initialState155', initialStateDesc); @@ -89,7 +90,7 @@ export class NSNet2 { const [gru157, gru156] = this.builder_.gru(squeeze95, weight212, recurrentWeight213, frames, this.hiddenSize, {bias: bias214, recurrentBias: recurrentBias214, initialHiddenState: initialState155, returnSequence: true}); // Use reshape to implement squeeze(gru156, {axes: [1]}); - const squeeze158Shape = gru156.shape(); + const squeeze158Shape = isShapeMethod ? gru156.shape() : gru156.shape; squeeze158Shape.splice(1, 1); const squeeze158 = this.builder_.reshape(gru156, squeeze158Shape); const transpose159 = this.builder_.transpose(squeeze158, {permutation: [1, 0, 2]}); diff --git a/object_detection/ssd_mobilenetv1_nchw.js b/object_detection/ssd_mobilenetv1_nchw.js index e5e525da..2f3c53bf 100644 --- a/object_detection/ssd_mobilenetv1_nchw.js +++ b/object_detection/ssd_mobilenetv1_nchw.js @@ -68,9 +68,12 @@ ${nameArray[1]}_BatchNorm_batchnorm`; const biasName = this.biasUrl_ + prefix + biasSuffix; const bias = await buildConstantByNpy( this.builder_, biasName, this.targetDataType_); + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nchw */[input.shape()[2], input.shape()[3]], - /* oihw */[weights.shape()[2], weights.shape()[3]], + /* nchw */[inputShape[2], inputShape[3]], + /* oihw */[weightsShape[2], weightsShape[3]], options.strides, options.dilations, 'same-upper'); options.bias = bias; const conv2d = this.builder_.conv2d(input, weights, options); diff --git a/object_detection/ssd_mobilenetv1_nhwc.js b/object_detection/ssd_mobilenetv1_nhwc.js index 0d44feac..9be23ebd 100644 --- a/object_detection/ssd_mobilenetv1_nhwc.js +++ b/object_detection/ssd_mobilenetv1_nhwc.js @@ -75,9 +75,12 @@ ${nameArray[1]}_BatchNorm_batchnorm`; options.filterLayout = 'ihwo'; } options.bias = bias; + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nhwc */[input.shape()[1], input.shape()[2]], - /* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]], + /* nhwc */[inputShape[1], inputShape[2]], + /* ohwi or ihwo */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, 'same-upper'); const conv2d = this.builder_.conv2d(input, weights, options); if (relu6) { diff --git a/object_detection/tiny_yolov2_nchw.js b/object_detection/tiny_yolov2_nchw.js index 0033212a..db080c14 100644 --- a/object_detection/tiny_yolov2_nchw.js +++ b/object_detection/tiny_yolov2_nchw.js @@ -37,9 +37,12 @@ export class TinyYoloV2Nchw { const weight = await buildConstantByNpy( this.builder_, weightName, this.targetDataType_); const options = {autoPad: 'same-upper'}; + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightShape = isShapeMethod ? weight.shape() : weight.shape; options.padding = computePadding2DForAutoPad( - /* nchw */[input.shape()[2], input.shape()[3]], - /* oihw */[weight.shape()[2], weight.shape()[3]], + /* nchw */[inputShape[2], inputShape[3]], + /* oihw */[weightShape[2], weightShape[3]], options.strides, options.dilations, 'same-upper'); options.bias = await buildConstantByNpy( this.builder_, biasName, this.targetDataType_); @@ -52,8 +55,10 @@ export class TinyYoloV2Nchw { } buildMaxPool2d_(input, options) { + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; options.padding = computePadding2DForAutoPad( - /* nchw */[input.shape()[2], input.shape()[3]], + /* nchw */[inputShape[2], inputShape[3]], options.windowDimensions, options.strides, options.dilations, 'same-upper'); return this.builder_.maxPool2d(input, options); diff --git a/object_detection/tiny_yolov2_nhwc.js b/object_detection/tiny_yolov2_nhwc.js index efeaf706..79c20671 100644 --- a/object_detection/tiny_yolov2_nhwc.js +++ b/object_detection/tiny_yolov2_nhwc.js @@ -34,9 +34,12 @@ export class TinyYoloV2Nhwc { filterLayout: 'ohwi', }; options.bias = bias; + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nhwc */[input.shape()[1], input.shape()[2]], - /* ohwi */[weights.shape()[1], weights.shape()[2]], + /* nhwc */[inputShape[1], inputShape[2]], + /* ohwi */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, 'same-upper'); let conv = this.builder_.conv2d(input, weights, options); if (leakyRelu) { @@ -47,8 +50,10 @@ export class TinyYoloV2Nhwc { } buildMaxPool2d_(input, options) { + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; options.padding = computePadding2DForAutoPad( - /* nhwc */[input.shape()[1], input.shape()[2]], + /* nhwc */[inputShape[1], inputShape[2]], options.windowDimensions, options.strides, options.dilations, 'same-upper'); return this.builder_.maxPool2d(input, options); diff --git a/semantic_segmentation/deeplabv3_mnv2_nhwc.js b/semantic_segmentation/deeplabv3_mnv2_nhwc.js index f4698a46..29e64a5b 100644 --- a/semantic_segmentation/deeplabv3_mnv2_nhwc.js +++ b/semantic_segmentation/deeplabv3_mnv2_nhwc.js @@ -44,9 +44,12 @@ export class DeepLabV3MNV2Nhwc { } else { options.filterLayout = 'ohwi'; } + const isShapeMethod = typeof input.shape === 'function'; + const inputShape = isShapeMethod ? input.shape() : input.shape; + const weightsShape = isShapeMethod ? weights.shape() : weights.shape; options.padding = computePadding2DForAutoPad( - /* nhwc */[input.shape()[1], input.shape()[2]], - /* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]], + /* nhwc */[inputShape[1], inputShape[2]], + /* ohwi or ihwo */[weightsShape[1], weightsShape[2]], options.strides, options.dilations, 'same-upper'); options.bias = bias; const conv2d = this.builder_.conv2d(input, weights, options); diff --git a/style_transfer/fast_style_transfer_net.js b/style_transfer/fast_style_transfer_net.js index 08737229..0f3630db 100644 --- a/style_transfer/fast_style_transfer_net.js +++ b/style_transfer/fast_style_transfer_net.js @@ -25,9 +25,12 @@ export class FastStyleTransferNet { buildInstanceNormalization_(conv2D, variableMul, variableAdd) { if ('instanceNormalization' in this.builder_) { + const isShapeMethod = typeof variableMul.shape === 'function'; + const variableMulShape = isShapeMethod ? variableMul.shape() : variableMul.shape; + const variableAddShape = isShapeMethod ? variableAdd.shape() : variableAdd.shape; // Use reshape to implement squeeze(variableMul); and squeeze(variableAdd); - const mulShape = variableMul.shape().filter((dim) => dim !==1); - const addShape = variableAdd.shape().filter((dim) => dim !==1); + const mulShape = variableMulShape.filter((dim) => dim !==1); + const addShape = variableAddShape.filter((dim) => dim !==1); const mulSqueeze = this.builder_.reshape(variableMul, mulShape); const addSqueeze = this.builder_.reshape(variableAdd, addShape); return this.builder_.instanceNormalization(conv2D, {scale: mulSqueeze, bias: addSqueeze});