(inputShape: Shape|Shape[])
| 524 | } |
| 525 | |
| 526 | public override build(inputShape: Shape|Shape[]): void { |
| 527 | inputShape = getExactlyOneShape(inputShape); |
| 528 | const nDims = inputShape.length; |
| 529 | |
| 530 | // Convert axis to array and resolve negatives. |
| 531 | if (typeof this.axis === 'number') { |
| 532 | this.axis = [this.axis]; |
| 533 | } |
| 534 | for (let i = 0; i < this.axis.length; ++i) { |
| 535 | if (this.axis[i] < 0) { |
| 536 | this.axis[i] += nDims; |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | // Further validate axes. |
| 541 | for (const axis of this.axis) { |
| 542 | if (axis < 0 || axis >= nDims) { |
| 543 | throw new Error(`Invalid axis: ${axis}`); |
| 544 | } |
| 545 | } |
| 546 | if (this.axis.length !== generic_utils.unique(this.axis).length) { |
| 547 | throw new Error(`Found duplicate axes in: ${this.axis}`); |
| 548 | } |
| 549 | |
| 550 | const paramShape = this.axis.map(axis => inputShape[axis]) as number[]; |
| 551 | |
| 552 | const trainable = true; |
| 553 | if (this.scale) { |
| 554 | this.gamma = this.addWeight( |
| 555 | 'gamma', paramShape, 'float32', this.gammaInitializer, |
| 556 | this.gammaRegularizer, trainable); |
| 557 | } else { |
| 558 | this.gamma = null; |
| 559 | } |
| 560 | if (this.center) { |
| 561 | this.beta = this.addWeight( |
| 562 | 'beta', paramShape, 'float32', this.betaInitializer, |
| 563 | this.betaRegularizer, trainable); |
| 564 | } else { |
| 565 | this.beta = null; |
| 566 | } |
| 567 | |
| 568 | this.built = true; |
| 569 | } |
| 570 | |
| 571 | override call(inputs: Tensor|Tensor[], kwargs: Kwargs): Tensor|Tensor[] { |
| 572 | const input = getExactlyOneTensor(inputs); |
nothing calls this directly
no test coverage detected