diff --git a/index.bs b/index.bs index 35ee539c..ccec0054 100644 --- a/index.bs +++ b/index.bs @@ -395,7 +395,7 @@ th, td { Introduction {#intro} ===================== -The Web Neural Network API defines a web-friendly hardware-agnostic abstraction layer that makes use of Machine Learning capabilities of operating systems and underlying hardware platforms without being tied to platform-specific capabilities. The abstraction layer addresses the requirements of key Machine Learning JavaScript frameworks and also allows web developers familiar with the ML domain to write custom code without the help of libraries. A complementary Model Loader API defines a higher-level abstraction targeting primarily web developers. +The Web Neural Network API defines a web-friendly hardware-agnostic abstraction layer that makes use of Machine Learning capabilities of operating systems and underlying hardware platforms without being tied to platform-specific capabilities. The abstraction layer addresses the requirements of key Machine Learning JavaScript frameworks and also allows web developers familiar with the ML domain to write custom code without the help of libraries. For an illustrated introduction, please see the explainer. @@ -671,8 +671,8 @@ array data (such as its shape). As mentioned above, the operations have a functional semantics. This allows the implementation to potentially share the array data between multiple tensors. For example, the implementation -of operations such as reshape, or slice, or squeeze may return a view of its input tensor -that shares the same buffer as the input tensor. (In the case of reshape or squeeze, +of operations such as reshape, or slice may return a view of its input tensor +that shares the same buffer as the input tensor. (In the case of reshape, the entire data is shared, while in the case of slice, a part of the input data is shared.) The implementation may use views, as above, for intermediate values. @@ -738,7 +738,7 @@ Navigator includes NavigatorML; WorkerNavigator includes NavigatorML; -## The ML interface ## {#api-ml} +## {{ML}} interface ## {#api-ml} -
+ const shape = [1,null,1,1]; + return builder.relu( + builder.add( + builder.mul( + builder.reshape(options.scale, shape), + builder.div( + builder.sub(input, builder.reshape(mean, shape)), + builder.sqrt(builder.add(builder.reshape(variance, shape), builder.constant(options.epsilon))) + )), + builder.reshape(options.bias, shape))); ++
- const shape = [1,null,1,1]; - return builder.relu( - builder.add( - builder.mul( - builder.reshape(options.scale, shape), - builder.div( - builder.sub(input, builder.reshape(mean, shape)), - builder.pow( - builder.add(builder.reshape(variance, shape), builder.constant(options.epsilon)), - builder.constant(0.5)) - )), - builder.reshape(options.bias, shape))); --
if (options.minValue === undefined) { if (options.maxValue === undefined) { - return operand; + return input; } else { - return builder.min(operand, builder.constant(options.maxValue)); + return builder.min(input, builder.constant(options.maxValue)); } } else { if (options.maxValue === undefined) { - return builder.max(operand, builder.constant(options.minValue)); + return builder.max(input, builder.constant(options.minValue)); } else { return builder.min( - builder.max(operand, builder.constant(options.minValue)), + builder.max(input, builder.constant(options.minValue)), builder.constant(options.maxValue)); } } @@ -1901,10 +1776,10 @@ partial interface MLGraphBuilder { -#### The {{MLGraphBuilder/clamp(operand, options)}} method #### {#api-mlgraphbuilder-clamp-operand-options} +#### {{MLGraphBuilder/clamp(input, options)}} #### {#api-mlgraphbuilder-clamp-operand-options}**Arguments:** - - *operand*: an {{MLOperand}}. The input tensor. + - *input*: an {{MLOperand}}. The input tensor. - *options*: an optional {{MLClampOptions}}. The optional parameters of the operation. - *minValue*: a {{float}} scalar. Specifies the minimum value of the range. When it is not specified, the clamping is not performed on the lower limit of the range. - *maxValue*: a {{float}} scalar. Specifies the maximum value of the range. When it is not specified, the clamping is not performed on the upper limit of the range. @@ -1913,27 +1788,26 @@ partial interface MLGraphBuilder {--#### The {{MLGraphBuilder/clamp(options)}} method #### {#api-mlgraphbuilder-clamp-options} +#### {{MLGraphBuilder/clamp(options)}} #### {#api-mlgraphbuilder-clamp-options}- The clamp(|operand|, |options|) method steps are: + The clamp(|input|, |options|) method steps are:
- 1. [=Assert=]: the type of |operand| is {{MLOperand}}. + 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If running the check clamp options steps given |options| returns false, then [=exception/throw=] a {{TypeError}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |operand|. + 1. Let |output| be the result of copying an MLOperand given |input|. 1. Make a request to the underlying platform to: 1. Create an [=implementation-defined=] platform operator |clampImpl| for this method, given |options|.{{MLClampOptions/minValue}} and |options|.{{MLClampOptions/maxValue}}. 1. Store a reference of |clampImpl| in |output|.{{MLOperand/[[operator]]}}. 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent clamp output, given |output| and |clampImpl|. 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |operand|.{{MLOperand/[[operand]]}} as input to |clampImpl|. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |clampImpl|. 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |clampImpl|. 1. Return |output|.**Arguments:** - *options*: an optional {{MLClampOptions}}. The optional parameters of the operation. @@ -1956,7 +1830,7 @@ partial interface MLGraphBuilder {-### The concat() method ### {#api-mlgraphbuilder-concat} +### concat ### {#api-mlgraphbuilder-concat} Concatenates the input tensors along a given axis. + ++ **Arguments:** + - *a*: an {{MLOperand}}. The first input tensor. + - *b*: an {{MLOperand}}. The second input tensor when specified. + + **Returns:** an {{MLOperand}}. The output tensor that contains the result of element-wise comparison of the two input tensors. +++ **Operation types:** + - *equal*: Compare if the values of the two input tensors are equal, element-wise. + - *greater*: Compare if the values of the first input tensor is greater, element-wise. + - *greaterOrEqual*: Compare if the values of the first input tensor is greater or equal, element-wise. + - *lesser*: Compare if the values of the first input tensor is lesser, element-wise. + - *lesserOrEqual*: Compare if the values of the first input tensor is lesser or equal, element-wise. + - *not*: Invert the values of the input tensor to values 0 or 1, element-wise. Specifically, when the input value is non-zero, invert it to a {{boolean}} value 0. Conversely, for a zero input value, invert it to a {{boolean}} value 1. ++ ++Although operations *greaterOrEqual* and *lesserOrEqual* can each be implemented in terms of operations *not*, *lesser*, and *greater* in other words `greater-or-equal(a, b)` is `not(lesser(a, b))`, they are specifically defined to handle NaN cases and for performance reason to avoid double comparisons. ++ +++ To create element-wise logical operation given |op|, |a| and |b|, run the following steps: +
++ 1. [=Assert=]: |op| is one of "equal", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "not". + 1. [=Assert=]: the type of |a| and |b| if available is {{MLOperand}}. + 1. If |op| is "not". + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} isn't "uint8", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |op| is anything else but "not". + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to "uint8". + 1. Let |descriptor|.{{MLOperandDescriptor/dimensions}} be the result of running the [=MLGraphBuilder/broadcast-shapes=] steps given |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of creating an MLOperand given [=this=] and |descriptor|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the binary operation |op|, given |a| and |b|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|.- The element-wise binary operation algorithms invoke the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] steps as follows. + The element-wise logical operation algorithms invoke the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] steps as follows.
+- The add(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "add", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -- -- The sub(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "sub", |a| and |b|. + The equal(|a|, |b|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "equal", |a| and |b|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.- The mul(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "mul", |a| and |b|. + The greater(|a|, |b|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "greater", |a| and |b|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.- The div(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "div", |a| and |b|. + The greaterOrEqual(|a|, |b|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "greaterOrEqual", |a| and |b|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.- The max(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "max", |a| and |b|. + The lesser(|a|, |b|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "lesser", |a| and |b|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.- The min(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "min", |a| and |b|. + The lesserOrEqual(|a|, |b|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "lesserOrEqual", |a| and |b|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.- The pow(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "pow", |a| and |b|. + The not(|a|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-logical-op | create element-wise logical operation=] given "not" and |a|. 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. 1. Return |output|.@@ -2506,11 +2610,15 @@ partial interface MLGraphBuilder { MLOperand abs(MLOperand input); MLOperand ceil(MLOperand input); MLOperand cos(MLOperand input); + MLOperand erf(MLOperand input); MLOperand exp(MLOperand input); MLOperand floor(MLOperand input); + MLOperand identity(MLOperand input); MLOperand log(MLOperand input); MLOperand neg(MLOperand input); + MLOperand reciprocal(MLOperand input); MLOperand sin(MLOperand input); + MLOperand sqrt(MLOperand input); MLOperand tan(MLOperand input); }; @@ -2523,26 +2631,30 @@ partial interface MLGraphBuilder { element-wise unary operation of the input tensor. The shape of the output tensor is the same as the shape of input tensor.**Operation types:** - *abs*: Compute the absolute value of the input tensor, element-wise. - *ceil*: Compute the ceiling of the input tensor, element-wise. - *cos*: Compute the cosine of the input tensor, element-wise. + - *erf*: Compute the error function [[Error-Function]] of the input tensor, element-wise. - *exp*: Compute the exponential of the input tensor, element-wise. - *floor*: Compute the floor of the input tensor, element-wise. + - *identity*: Copy the value of the input tensor to the output tensor, element-wise. - *log*: Compute the natural logarithm of the input tensor, element-wise. - *neg*: Compute the numerical negative value of the input tensor, element-wise. + - *reciprocal*: Compute the reciprocal of the input tensor, element-wise. - *sin*: Compute the sine of the input tensor, element-wise. + - *sqrt*: Compute the square root of the input tensor, element-wise. - *tan*: Compute the tangent of the input tensor, element-wise.--To create element-wise unary operation given |op| and |input|, run the following steps:
- 1. [=Assert=]: |op| is one of "abs", "ceil", "cos", "exp", "floor", "log", "neg", "sin", "tan". + 1. [=Assert=]: |op| is one of "abs", "ceil", "cos", "erf", "exp", "floor", "identity", "log", "neg", "reciprocal", "sin", "sqrt", "tan". 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |output| be the result of copying an MLOperand given |input|. @@ -2556,7 +2668,6 @@ partial interface MLGraphBuilder { 1. Return |output|.-### The elu() method ### {#api-mlgraphbuilder-elu} +### elu ### {#api-mlgraphbuilder-elu} Calculate the exponential linear unit function (ELU) on the input tensor element-wise. The calculation follows the expression `max(0, x) + alpha * (exp(min(0, x)) - 1)`. +The element-wise unary operation algorithms invoke the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] steps as follows. @@ -2583,6 +2694,13 @@ partial interface MLGraphBuilder { 1. Return |output|. +
+ The erf(|input|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "erf" and |input|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. ++The exp(|input|) method steps are: 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "exp" and |input|. @@ -2597,6 +2715,13 @@ partial interface MLGraphBuilder { 1. Return |output|.++ The identity(|input|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "identity" and |input|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. ++The log(|input|) method steps are: 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "log" and |input|. @@ -2611,6 +2736,13 @@ partial interface MLGraphBuilder { 1. Return |output|.++ The reciprocal(|input|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "reciprocal" and |input|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. ++The sin(|input|) method steps are: 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "sin" and |input|. @@ -2618,6 +2750,13 @@ partial interface MLGraphBuilder { 1. Return |output|.++ The sqrt(|input|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "sqrt" and |input|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. ++The tan(|input|) method steps are: 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "tan" and |input|. @@ -2627,7 +2766,7 @@ partial interface MLGraphBuilder {+ **Arguments:** + - *input*: an {{MLOperand}}. An input tensor + - *newShape*: a sequence of {{unsigned long}}. The new shape the input tensor is expanded to. + + **Returns:** an {{MLOperand}}. The tensor with expanded size dimensions. ++ +++ +### gather ### {#api-mlgraphbuilder-gather} +Gather values of the input tensor along an axis according to the indices. + + +{{MLGatherOptions}} has the following members: ++ The expand(|input|, |newShape|) method steps are: +
++++ The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. ++ 1. [=Assert=]: the type of |input| is {{MLOperand}} object. + 1. [=Assert=]: the type of |newShape| is a `sequence of unsigned long`. + 1. If any of the following steps fail, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |inputDesc| be |input|.{{MLOperand/[[descriptor]]}}. + 1. If the sequence length of |newShape| is not equal to the [=rank=] of |inputDesc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |outputDesc| be a copy of |inputDesc|. + 1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive: + 1. Let |size| be the |input|.{{MLOperand/shape()}}[|index|]. + 1. If |size| is not equal to 1 and not equal to |newShape|[index], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |size| is equal to 1, then let |outputDesc|.{{MLOperandDescriptor/dimensions}}[|index|] be |newShape|[|index|]. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of creating an MLOperand given [=this=] and |outputDesc|. + 1. Make a request to the underlying platform to: + 1. Create an [=implementation-defined=] platform operator |expandImpl| for this method, given |input| and |newShape|. + 1. Store a reference of |expandImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent output,given |output| and |expandImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input| as input to |expandImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |expandImpl|. + 1. Return |output|. ++ : axis + :: + An {{unsigned long}} scalar specifying the axis along which the gathered values are obtained. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensor. +
+ ++ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor from which the values are gathered. + - *indices*: an {{MLOperand}}. The indices N-D tensor of the input values to gather. The values must be of type "uint32" or "int64" in the range [0, N-1] where N is the size of the input dimension indexed by *options.axis*. + - *options*: an optional {{MLGatherOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output N-D tensor of [=rank=] equal to the [=rank=] of *input* + the [=rank=] of *indices* - 1. ++ +++ ++ The gather(|input|, |indices|, |options|) method steps are: +
++ 1. [=Assert=]: the type of |input| and |indices| is {{MLOperand}}. + 1. If |indices|.{{MLOperand/dataType()}} is neither "uint32" nor "int64", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |shapeInput| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |rankInput| be the [=list/size=] of |shapeInput|. + 1. Let |shapeIndices| be |indices|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Let |axis| be |options|.{{MLGatherOptions/axis}}. + 1. Let |axisSize| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|axis|] + 1. If |axis| is greater than or equal to |rankInput|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=map/For each=] |index| → |value| of |indices|: + 1. If |index| is greater than or equal to |axisSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |dimCount| be zero. + 1. Let |rankOutput| be zero. + 1. Let |shapeOutput| be an empty list. + 1. [=map/For each=] |size| → |value| of |shapeInput|: + 1. If |dimCount| is equal to |axis| then [=break=]. + 1. Set |shapeOutput|[|dimCount|] to |size|. + 1. Increment |dimCount| by one. + 1. Set |rankOutput| to |dimCount|. + 1. Let |dimCount| be zero. + 1. [=map/For each=] |size| → |value| of |shapeIndices|: + 1. Set |shapeOutput|[|rankOutput| + |dimCount|] to |size|. + 1. Increment |dimCount| by one. + 1. Set |rankOutput| to |rankOutput| + |dimCount|. + 1. Let |dimCount| be zero. + 1. [=map/For each=] |size| → |value| of |shapeInput|: + 1. If |dimCount| is less than or equal to |axis| then [=continue=]. + 1. Set |shapeOutput|[|rankOutput| + |dimCount| - |axis| - 1] to |size|. + 1. Increment |dimCount| by one. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |shapeOutput|. + 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of creating an MLOperand given |desc|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the Gather operation, given |input|, |indices|, and |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} and |indices|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. ++++ +### gemm ### {#api-mlgraphbuilder-gemm} Calculate the [general matrix multiplication of the Basic Linear Algebra Subprograms](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3). The calculation follows the expression `alpha * A * B + beta * C`, where `A` is a 2-D tensor with shape [M, K] or [K, M], `B` is a 2-D tensor with shape [K, N] or [N, K], and `C` is broadcastable to the shape [M, N]. `A` and `B` may optionally be transposed prior to the calculation. + +The {{MLLayerNormalizationOptions}} members are: ++++ Examples of how gather works in different slicing schemes. +
++ // input of shape [4,3]: + // [[ 0, 1, 2], + // [10, 11, 12], + // [20, 21, 22], + // [30, 31, 32]] + const input = builder.constant( + { dimensions: [4,3] }, new Float32Array([0,1,2,10,11,12,20,21,22,30,31,32])); + + const indices1 = builder.constant( + { dataType: 'uint32', dimensions: [2] }, new Uint32Array([3,1])); + + const indices2 = builder.constant( + { dataType: 'uint32', dimensions: [3] }, new Uint32Array([2,1,1])); + + const indices3 = builder.constant( + { dataType: 'uint32', dimensions: [2,2] }, new Uint32Array([0,1,1,2])); + + // axis = 0 (default) + // indices of shape [2]: + // [3,1] + // output of shape [2,3]: + // [[30, 31, 32], + // [10, 11, 12]] + const output1 = builder.gather(input, indices1); + + // axis = 1 + // indices of shape [3]: + // [2,1,1] + // output of shape [4,3]: + // [[ 2, 1, 1], + // [12, 11, 11], + // [22, 21, 21], + // [32, 31, 31]] + const output2 = builder.gather(input, indices2, { axis: 1 }); + + // axis = 1 + // indices of shape [2,2]: + // [[0, 1], + // [1, 2]] + // output of shape [4,2,2]: + // [[[ 0, 1], [ 1, 2]], + // [[10, 11], [11, 12]], + // [[20, 21], [21, 22]], + // [[30, 31], [31, 32]]] + const output3 = builder.gather(input, indices3, { axis: 1 }); +++ : scale + :: + An {{MLOperand}}. Specifies the N-D tensor of the scaling values whose shape is determined by the |axes| member in that each value in |axes| indicates the dimension of the input tensor with scaling values. For example, for an |axes| values of [1,2,3], the shape of this tensor is the list of the corresponding sizes of the input dimension 1, 2 and 3. When this member is not present, the scaling value is assumed to be 1. + + : bias + :: + An {{MLOperand}}. Specifies the N-D tensor of the bias values whose shape is determined by the |axes| member in that each value in |axes| indicates the dimension of the input tensor with bias values. For example, for an |axes| values of [1,2,3], the shape of this tensor is the list of the corresponding sizes of the input dimension 1, 2 and 3. When this member is not present, the bias value is assumed to be 0. + + : axes + :: + A sequence of {{unsigned long}}. The indices to the input dimensions to reduce. When this member is not present, it is assumed to be [1,2,3] that is, the reduction for the mean and variance values are calculated across all the input features for each individual sample in the batch. + + : epsilon + :: + A {{float}} scalar. Specifies a small value to prevent computational error due to divide-by-zero. +
+ ++ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor. + - *options*: an optional {{MLLayerNormalizationOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The layer-normalized N-D tensor of the same shape as *input*. ++ +++ ++ The layerNormalization(|input|, |options|) method steps are: +
++ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. [=Assert=]: the type of |options|.{{MLLayerNormalizationOptions/scale}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/scale}} is not equal to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=Assert=]: the type of |options|.{{MLLayerNormalizationOptions/bias}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/bias}} is not equal to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=map/For each=] |index| in [=the range=] 0 to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, exclusive: + 1. Let |axis| be |options|.{{MLLayerNormalizationOptions/axes}}[|index|]. + 1. If |axis| is greater or equal to the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |size| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|axis|]. + 1. If |options|.{{MLLayerNormalizationOptions/scale}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|index|] is not equal to |size|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLayerNormalizationOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|index|] is not equal to |size|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the instance normalization operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. ++++ +### leakyRelu ### {#api-mlgraphbuilder-leakyrelu} Calculate the leaky version of rectified linear function on the input tensor element-wise. The calculation follows the expression `max(0, x) + alpha ∗ min(0, x)`. - -+++ The behavior of this operation when the axes parameter is set to [1,2,3] can be generically emulated from + the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, + therefore its usage is encouraged from the performance standpoint. +
++ // The reduction of the mean and variance values happens over the spatial dimensions + // across all the input features (i.e. all channels) of the input tensor. + const reduceOptions = { axes: [1,2,3], keepDimensions: true }; + const mean = builder.reduceMean(input, reduceOptions); + const variance = builder.reduceMean( + builder.pow( + builder.sub(input, mean), + buider.constant(2)), + reduceOptions + ); + + // The scale and bias tensors are of the shape of the input dimensions specified + // by the values in the axes parameter (i.e. [1,2,3]). + return builder.add( + builder.mul( + options.scale, + builder.div( + builder.sub(input, mean), + buidler.sqrt(builder.add(variance, options.epsilon)) + ) + ), + options.bias + ); ++- **Arguments:** - - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape - is interpreted according to the value of *options.layout*. - - *options*: an optional {{MLPool2dOptions}}. The optional parameters of the operation. - - **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the - result of the reduction. The logical shape is interpreted according to the - value of *layout*. More specifically, if the *options.roundingType* is *"floor"*, the spatial dimensions of the output tensor can be calculated as follow: - - *output size = floor(1 + (input size - filter size + beginning padding + ending padding) / stride)* - - or if *options.roundingType* is *"ceil"*: - - *output size = ceil(1 + (input size - filter size + beginning padding + ending padding) / stride)* -+ sequenceoutputSizes; +}; - - A *global* pooling operation such as one for the max pooling operation is a variant of pooling where the window dimensions is the spatial dimensions (last two dimensions) of the input shape, as follow. -+partial interface MLGraphBuilder { + MLOperand averagePool2d(MLOperand input, optional MLPool2dOptions options = {}); + MLOperand l2Pool2d(MLOperand input, optional MLPool2dOptions options = {}); + MLOperand maxPool2d(MLOperand input, optional MLPool2dOptions options = {}); +}; + {{MLPool2dOptions}} has the following members:- // 'global' max pooling - builder.maxPool2d(input); --@@ -4387,11 +4824,34 @@ partial interface MLGraphBuilder { Specifies the sizes of the two spacial dimensions of the output tensor. When the output sizes are explicitly specified, the {{MLPool2dOptions/roundingType}} is ignored. If not specified, the output sizes are automatically computed. -
-++ **Arguments:** + - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape + is interpreted according to the value of *options.layout*. + - *options*: an optional {{MLPool2dOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the + result of the reduction. The logical shape is interpreted according to the + value of *layout*. More specifically, if the *options.roundingType* is *"floor"*, the spatial dimensions of the output tensor can be calculated as follow: + + *output size = floor(1 + (input size - filter size + beginning padding + ending padding) / stride)* + + or if *options.roundingType* is *"ceil"*: + + *output size = ceil(1 + (input size - filter size + beginning padding + ending padding) / stride)* ++ ++ A *global* pooling operation such as one for the max pooling operation is a variant of pooling where the window dimensions is the spatial dimensions (last two dimensions) of the input shape, as follow. +++ // 'global' max pooling + builder.maxPool2d(input); ++-### The prelu() method ### {#api-mlgraphbuilder-prelu} +#### averagePool2d #### {#api-mlgraphbuilder-pool2d-average} +Calculate the average value for patches of a feature map, and use it to create a pooled feature map. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +#### l2Pool2d #### {#api-mlgraphbuilder-pool2d-l2} +Apply the L2 norm function to a region of the input feature map. The L2 norm is the square root of the sum of the squares of its elements. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +#### maxPool2d #### {#api-mlgraphbuilder-pool2d-max} +Calculate the maximum value for patches of a feature map, and use it to create a pooled feature map. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +### prelu ### {#api-mlgraphbuilder-prelu} Calculate the parametric version of rectified linear function (Parametric ReLU) on the input tensor element-wise. Parametric ReLU is a type of leaky ReLU that, instead of having a scalar slope like 0.01, making the slope (coefficient of leakage) into a parameter that is learned during the model training phase of this operation. The calculation follows the expression `max(0, x) + slope ∗ min(0, x)`. +{{MLReduceOptions}} has the following members: +To create pooling operation given |op|, |input| and |options|, run the following steps:
@@ -4454,7 +4914,16 @@ partial interface MLGraphBuilder {+ : axes + :: + A sequence of {{unsigned long}}. The dimensions to reduce. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. If not present, all dimensions are reduced. + + : keepDimensions + :: + A {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. The default value is false. +
+**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - *options*: an optional {{MLReduceOptions}}. The optional parameters of the operation. - - *axes*: a sequence of {{unsigned long}}. The dimensions to reduce. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. - If not present, all dimensions are reduced. - - *keepDimensions*: a {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. - The default value is false. **Returns:** an {{MLOperand}}. The reduced output tensor.@@ -4559,7 +5035,6 @@ partial interface MLGraphBuilder {--### The relu() method ### {#api-mlgraphbuilder-relu-method} +### relu ### {#api-mlgraphbuilder-relu-method} Compute the rectified linear function of the input tensor. + +To create reduce operation given |op|, |input| and |options|, run the following steps:
@@ -4567,8 +5042,12 @@ partial interface MLGraphBuilder { 1. [=Assert=]: |op| is one of "reduceL1", "reduceL2", "reduceLogSum", "reduceLogSumExp", "reduceMax", "reduceMean", "reduceMin", "reduceProduct", "reduceSum", "reduceSumSquare". 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If |options|.{{MLReduceOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |outputShape| be the result of invoking the underlying implementation for calculating reduction output dimensions, given |options|. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Let |output| be the result of creating an MLOperand given [=this=] and |desc|. 1. Make a request to the underlying platform to: 1. Let |opImpl| be an [=implementation-defined=] platform operator for the |op| reduce operation, given |options|. 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. @@ -4655,7 +5134,7 @@ partial interface MLGraphBuilder {++ +#### {{MLGraphBuilder/tanh(input)}} #### {#api-mlgraphbuilder-tanh-input} ++++ The behavior of this operation can be generically emulated from the usage of + other operations as follow. However, user agents typically have a more + efficient implementation for it, therefore its usage is encouraged from the + performance standpoint. +
++ return builder.div( + builder.sub(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1)), + builder.add(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1))); +++ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. ++ ++ ++ +#### {{MLGraphBuilder/tanh()}} #### {#api-mlgraphbuilder-tanh} ++ The tanh(|input|) method steps are: +
++ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the hyperbolic tangent operation. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +++ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the tanh operation. ++ +++ +### transpose ### {#api-mlgraphbuilder-transpose} +Permute the dimensions of the input tensor according to the *permutation* argument. + + +{{MLTransposeOptions}} has the following members: ++ The tanh() method steps are: +
++ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"tanh"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +++ : permutation + :: + A sequence of {{unsigned long}} values. + Specifies the values used to permute the output shape. + The default value is [N-1, ..., 0], where N is the [=rank=] of the input tensor, e.g. [2,1,0] for a 3-D tensor. + These default values cause the output to become a transposed tensor of the input. When specified, the number of values in the sequence must be the same as the [=rank=] of the input tensor, and the values in the sequence must be within the range from 0 to N-1 with no two or more same values found in the sequence. +
+ ++ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor. + - *options*: an optional {{MLTransposeOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The permuted or transposed N-D tensor. ++ +++ +### triangular ### {#api-mlgraphbuilder-triangular} +Given a 2-D tensor (matrix), return a 2-D tensor containing either the upper or lower triangular part of the input tensor. + + + +{{MLTriangularOptions}} has the following members: ++ The transpose(|input|, |options|) method steps are: +
++ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If |options|.{{MLTransposeOptions/permutation}} does not [=map/exist=], let |options|.{{MLTransposeOptions/permutation}} be the reversed sequence of all indices for |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Otherwise if |options|.{{MLTransposeOptions/permutation}} [=map/exists=]: + 1. If the [=rank=] of |options|.{{MLTransposeOptions/permutation}} is not the same as the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a {{TypeError}}. + 1. If the values in |options|.{{MLTransposeOptions/permutation}} are not in [=the range=] 0 and the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} exclusive, then [=exception/throw=] a {{TypeError}}. + 1. If the values in |options|.{{MLTransposeOptions/permutation}} contain duplicate value, then [=exception/throw=] a {{TypeError}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the transpose operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +++ : upper + :: + A {{boolean}} value. Indicate whether the output the upper or the lower part of the input matrix is retained. If not set, it is assumed to be true, indicating that the upper part is retained. + : diagonal + :: + A {{long}} value. Specify how many diagonals above or below the main diagonals of the input matrix are retained or excluded. If not set, this value is assumed to be 0, which means no diagonals other than the main diagonals are affected. +
+ ++ **Arguments:** + - *input*: an {{MLOperand}}. The input 2-D tensor. + - *options*: an optional {{MLTriangularOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output 2-D tensor representing a triangular matrix. ++ +++ ++ The triangular(|input|, |options|) method steps are: +
++ 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the triangular operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +++-### The squeeze() method ### {#api-mlgraphbuilder-squeeze} -Reduce the [=rank=] of a tensor by eliminating dimensions with size 1 of the tensor shape. Squeeze only affects the tensor's logical dimensions. It does not copy or change the content in the tensor. -++ Examples of how triangular works in different diagonal settings.
- // This sample shows the case that the splits parameter is an array. - const outputs = []; - let starts = Array(input_rank).fill(0); - let sizes = input_shape; - let start = 0; - for (const size of splits) { - starts[options.axis] = start; - sizes[options.axis] = size; - outputs.push(builder.slice(input, starts, sizes)); - start += size; - } - return outputs; + // input: + // [[7, 1, 2], + // [9, 4, 8], + // [2, 6, 3]] + const input = builder.constant( + { dimensions: [3,3] }, new Float32Array([7,1,2,9,4,8,2,6,3])); + + // upper triangular matrix: + // [[7, 1, 2], + // [0, 4, 8], + // [0, 0, 3]] + const upper = builder.triangular(input); + + // upper triangular matrix with one additional set of diagonals excluded: + // [[0, 1, 2], + // [0, 0, 8], + // [0, 0, 0]] + const upperPositive = builder.triangular(input, { diagonal: 1 }); + + // upper triangular matrix with one additional set of diagonals retained: + // [[7, 1, 2], + // [9, 4, 8], + // [0, 6, 3]] + const upperNegative = builder.triangular(input, { diagonal: -1 }); + + // lower triangular matrix: + // [[7, 0, 0], + // [9, 4, 0], + // [2, 6, 3]] + const lower = builder.triangular(input, { upper: false }); + + // lower triangular matrix with one additional set of diagonals retained: + // [[7, 1, 0], + // [9, 4, 8], + // [2, 6, 3]] + const lowerPositive = builder.triangular(input, { upper: false, diagonal: 1 }); + + // lower triangular matrix with one additional set of diagonals excluded: + // [[0, 0, 0], + // [9, 0, 0], + // [2, 6, 0]] + const lowerNegative = builder.triangular(input, { upper: false, diagonal: -1 });**Arguments:** - - *input*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLSqueezeOptions}}. The optional parameters of the operation. + - *condition*: an {{MLOperand}}. The condition tensor. + - *input*: an {{MLOperand}}. The input tensor from which the value is selected when the condition of the corresponding element is set to true. + - *other*: an {{MLOperand}}. The other tensor from which the value is selected when the condition of the corresponding element is set to false. - **Returns:** an {{MLOperand}}. The output tensor of the same or reduced rank with the shape dimensions of size 1 eliminated. + **Returns:** an {{MLOperand}}. The output tensor that contains the values selected element-wise from either the input or the other tensor.-{{MLSqueezeOptions}} has the following members: -- : axes - :: - A sequence of {{unsigned long}}. - Specifies the indices to the shape dimensions of size 1 to eliminate. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. - When not specified, every shape dimensions of size 1 in the tensor are eliminated. -
---### The tanh() method ### {#api-mlgraphbuilder-tanh-method} -Compute the hyperbolic tangent function of the input tensor. The calculation follows the expression `(exp(2 * x) - 1) / (exp(2 * x) + 1)`. - -- The squeeze(|input|, |options|) method steps are: + The where(|condition|, |input|, |other|) method steps are:
- 1. [=Assert=]: the type of |input| is {{MLOperand}}. - 1. If |options|.{{MLSqueezeOptions/axes}} [=map/exists=], then: - 1. Let |dimensions| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. - 1. Let |axesLength| be the [=list/size=] of |options|.{{MLSqueezeOptions/axes}}. - 1. If |axesLength| is not smaller than the rank of |dimensions|, - 1. For |index| in [=the range=] 0 to |axesLength|, exclusive: - 1. Let |oneDimIndex| be |options|.{{MLSqueezeOptions/axes}}[|index|]. - 1. If |dimensions|[|oneDimIndex|] is not 1, then [=exception/throw=] a {{TypeError}}. + 1. [=Assert=]: the type of |condition|, |input| and |other| is {{MLOperand}}. + 1. If |condition|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to "uint8", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |other|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. + 1. Let |descriptor|.{{MLOperandDescriptor/dimensions}} be the result of running the [=MLGraphBuilder/broadcast-shapes=] steps given |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |other|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. If |condition| is not unidirectionally broadcastable to |descriptor|.{{MLOperandDescriptor/dimensions}} according to the [[!numpy-broadcasting-rule]], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Let |output| be the result of creating an MLOperand given [=this=] and |descriptor|. 1. Make a request to the underlying platform to: - 1. Let |opImpl| be an [=implementation-defined=] platform operator for the squeeze operation, given |options|. + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the where operation, given |condition|, |input| and |other|. 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |condition|.{{MLOperand/[[operand]]}}, |input| and |other|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. 1. Return |output|.-#### The {{MLGraphBuilder/tanh(input)}} method #### {#api-mlgraphbuilder-tanh-input} -- The behavior of this operation can be generically emulated from the usage of - other operations as follow. However, user agents typically have a more - efficient implementation for it, therefore its usage is encouraged from the - performance standpoint. + The behavior of this operation can be generically emulated from the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint.
- return builder.div( - builder.sub(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1)), - builder.add(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1))); + const c = builder.clamp(condition, {'minValue': 0, 'maxValue': 1}); + builder.add( + builder.mul( + input, + builder.cast(c, input.dataType())), + builder.mul( + other, + builder.cast(builder.not(c), other.dataType())));- **Arguments:** - - *input*: an {{MLOperand}}. The input tensor. +## {{MLOperand}} interface ## {#api-mloperand} - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *input*. +An {{MLOperand}} represents an intermediary graph being constructed as a result of compositing parts of an operation into a fully composed operation. + +For instance, an {{MLOperand}} may represent a constant feeding to an operation or the result from combining multiple constants together into an operation. See also [[#programming-model]]. + + + ++{{MLOperand}} has the following internal slots: +-+ : \[[builder]] of type {{MLGraphBuilder}} + :: + The {{MLOperand}}'s associated builder object. + + : \[[descriptor]] of type {{MLOperandDescriptor}} + :: + The {{MLOperand}}'s descriptor. + + : \[[name]] of type [=string=] + :: + The {{MLOperand}}'s name (only for input operands). + + : \[[operand]] of type [=object=] + :: + Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operand object. + + : \[[operator]] of type [=object=] + :: + Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operator object. +
++To get the rank of an {{MLOperand}} |operand|, run the following steps: ++ +Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. +### Creating {{MLOperand}} ### {#api-mloperand-create} +The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, internally using the following algorithms. + ++ 1. Return the [=list/size=] of |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. ++-#### The {{MLGraphBuilder/tanh()}} method #### {#api-mlgraphbuilder-tanh} -- The tanh(|input|) method steps are: + To create an MLOperand given |builder| and |desc|, run the following steps:
- 1. [=Assert=]: the type of |input| is {{MLOperand}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be an [=implementation-defined=] platform operator for the hyperbolic tangent operation. - 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. - 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. - 1. Return |output|. + 1. [=Assert=]: the type of |builder| is {{MLGraphBuilder}}. + 1. [=Assert=]: the type of |desc| is {{MLOperandDescriptor}}. + 1. Let |operand| be a new [=object=]. + 1. Set |operand|.{{MLOperand/[[builder]]}} to |builder|. + 1. Set |operand|.{{MLOperand/[[descriptor]]}} to |desc|. + 1. Return |operand|.- **Arguments:** - - None. +++- **Returns:** - - an {{MLActivation}}. The activation function representing the tanh operation. -+ To copy an MLOperand given |operand|, run the following steps: +
++ 1. [=Assert=]: the type of |operand| is {{MLOperand}}. + 1. Let |result| be a new [=object=]. + 1. Set |result|.{{MLOperand/[[builder]]}} to |operand|.{{MLOperand/[[builder]]}}. + 1. Set |result|.{{MLOperand/[[descriptor]]}} to |operand|.{{MLOperand/[[descriptor]]}}. + 1. If |operand|.{{MLOperand/[[name]]}} [=map/exists=], then set |result|.{{MLOperand/[[name]]}} to |operand|.{{MLOperand/[[name]]}}. + 1. Return |result|. ++++ To check dimensions given |dimensions| and |type|, run the following steps: +
++ 1. If the [=list/size=] of |dimensions| is 0, return false. + 1. If the [=list/size=] of |dimensions| is too large to be supported by the implementation, return false. + 1. If any element of |dimensions| is not a positive number, or it is too large to be supported by the implementation given |type|, return false. + 1. Return true. ++-### The transpose() method ### {#api-mlgraphbuilder-transpose} -Permute the dimensions of the input tensor according to the *permutation* argument. +### dataType ### {#api-mloperand-datatype} +Return a data type of the {{MLOperand}}. + -partial interface MLGraphBuilder { - MLOperand transpose(MLOperand input, optional MLTransposeOptions options = {}); +- The tanh() method steps are: + To validate MLOperand given |operand| and |builder|, run the following steps:
- 1. Let |op| be the result of creating an MLActivation given [=this=] and `"tanh"`. - 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. - 1. Return |op|. + 1. [=Assert=]: the type of |operand|.{{MLOperand/[[builder]]}} is {{MLGraphBuilder}}. + 1. If |builder| is not equal to |operand|.{{MLOperand/[[builder]]}}, return false. + 1. Let |desc| be |operand|.{{MLOperand/[[descriptor]]}}. + 1. If |desc|.{{MLOperandDescriptor/dimensions}} [=map/exists=] and invoking check dimensions given |desc|.{{MLOperandDescriptor/dimensions}} and |desc|.{{MLOperandDescriptor/dataType}} returns false, then return false. + 1. Return true.+ **Returns:** an {{MLOperandDataType}}. The data type of the operand. ++ +++ +### shape ### {#api-mloperand-shape} +Return a shape of the {{MLOperand}}. + ++ The dataType() method steps are: +
++ 1. Return [=this=].{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. ++- **Arguments:** - - *input*: an {{MLOperand}}. The input N-D tensor. - - *options*: an optional {{MLTransposeOptions}}. The optional parameters of the operation. - - **Returns:** an {{MLOperand}}. The permuted or transposed N-D tensor. + **Returns:** a sequence of {{unsigned long}}. The shape of the operand.-{{MLTransposeOptions}} has the following members: -- : permutation - :: - A sequence of {{unsigned long}} values. - Specifies the values used to permute the output shape. - The default value is [N-1, ..., 0], where N is the [=rank=] of the input tensor, e.g. [2,1,0] for a 3-D tensor. - These default values cause the output to become a transposed tensor of the input. When specified, the number of values in the sequence must be the same as the [=rank=] of the input tensor, and the values in the sequence must be within the range from 0 to N-1 with no two or more same values found in the sequence. -
+++ +## {{MLOperandDescriptor}} dictionary ## {#api-mloperanddescriptor} ++ The shape() method steps are: +
++ 1. Return [=this=].{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. ++@@ -5657,6 +6466,8 @@ Thanks to Kaustubha Govind and Chrome privacy reviewers for feedback and privacy Thanks to Jiewei Qian for Chromium implementation review and feedback. +Thanks to Dwayne Robinson for his work investigating and providing recommendation for transformer support, and for providing reviews of operator conformance and WPT implementation. +- The transpose(|input|, |options|) method steps are: + The byte length of an {{MLOperandDescriptor}} |desc| is the value returned by the following steps:
- 1. [=Assert=]: the type of |input| is {{MLOperand}}. - 1. If |options|.{{MLTransposeOptions/permutation}} does not [=map/exist=], let |options|.{{MLTransposeOptions/permutation}} be the reversed sequence of all indices for |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. - 1. Otherwise if |options|.{{MLTransposeOptions/permutation}} [=map/exists=]: - 1. If the [=rank=] of |options|.{{MLTransposeOptions/permutation}} is not the same as the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a {{TypeError}}. - 1. If the values in |options|.{{MLTransposeOptions/permutation}} are not in [=the range=] 0 and the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} exclusive, then [=exception/throw=] a {{TypeError}}. - 1. If the values in |options|.{{MLTransposeOptions/permutation}} contain duplicate value, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be an [=implementation-defined=] platform operator for the transpose operation, given |options|. - 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. - 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. - 1. Return |output|. + 1. Let |elementLength| be 1. + 1. [=map/For each=] |dimension| of |desc|.{{MLOperandDescriptor/dimensions}}: + 1. Set |elementLength| to |elementLength| × |dimension|. + 1. Let |elementSize| be the [=element size=] of one of the {{ArrayBufferView}} types that matches |desc|.{{MLOperandDescriptor/dataType}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility). + 1. Return |elementLength| × |elementSize|.{ "Models": { @@ -5911,6 +6722,24 @@ Thanks to Jiewei Qian for Chromium implementation review and feedback. ], "date": "July 2016" }, + "Layer-Normalization": { + "href": "https://arxiv.org/abs/1607.06450", + "title": "Layer Normalization", + "authors": [ + "Jimmy Lei Ba", + "Jamie Ryan Kiros", + "Geoffrey E. Hinton" + ], + "date": "July 2016" + }, + "Error-Function": { + "href": "https://books.google.com/books?id=2CAqsF-RebgC&pg=PA110", + "title": "Special functions of mathematics for engineers", + "authors": [ + "Larry C. Andrews" + ], + "date": "1998" + }, "FaceForensics++": { "href": "https://github.com/ondyari/FaceForensics", "title": "FaceForensics++", @@ -5951,4 +6780,4 @@ Thanks to Jiewei Qian for Chromium implementation review and feedback. ] } } -+ \ No newline at end of file