From 585c06220956da6ffe9136ec3f2b6d02c2b16cba Mon Sep 17 00:00:00 2001 From: David Don Young Kim Date: Mon, 19 Sep 2022 09:59:09 -0700 Subject: [PATCH 1/2] PR issues resolved --- tfjs-layers/src/exports_layers.ts | 3442 ++++++++--------- .../preprocessing/image_preprocessing.ts | 96 +- .../preprocessing/image_preprocessing_test.ts | 4 +- 3 files changed, 1772 insertions(+), 1770 deletions(-) diff --git a/tfjs-layers/src/exports_layers.ts b/tfjs-layers/src/exports_layers.ts index 77777cf8005..f585eff55a8 100755 --- a/tfjs-layers/src/exports_layers.ts +++ b/tfjs-layers/src/exports_layers.ts @@ -8,1724 +8,1724 @@ * ============================================================================= */ - import {InputLayer, InputLayerArgs} from './engine/input_layer'; - import {Layer, LayerArgs} from './engine/topology'; - import {input} from './exports'; - import {ELU, ELULayerArgs, LeakyReLU, LeakyReLULayerArgs, PReLU, PReLULayerArgs, ReLU, ReLULayerArgs, Softmax, SoftmaxLayerArgs, ThresholdedReLU, ThresholdedReLULayerArgs} from './layers/advanced_activations'; - import {Conv1D, Conv2D, Conv2DTranspose, Conv3D, ConvLayerArgs, Cropping2D, Cropping2DLayerArgs, SeparableConv2D, SeparableConvLayerArgs, UpSampling2D, UpSampling2DLayerArgs, Conv3DTranspose} from './layers/convolutional'; - import {DepthwiseConv2D, DepthwiseConv2DLayerArgs} from './layers/convolutional_depthwise'; - import {ConvLSTM2D, ConvLSTM2DArgs, ConvLSTM2DCell, ConvLSTM2DCellArgs} from './layers/convolutional_recurrent'; - import {Activation, ActivationLayerArgs, Dense, DenseLayerArgs, Dropout, DropoutLayerArgs, Flatten, FlattenLayerArgs, Masking, MaskingArgs, Permute, PermuteLayerArgs, RepeatVector, RepeatVectorLayerArgs, Reshape, ReshapeLayerArgs, SpatialDropout1D, SpatialDropout1DLayerConfig} from './layers/core'; - import {Embedding, EmbeddingLayerArgs} from './layers/embeddings'; - import {Add, Average, Concatenate, ConcatenateLayerArgs, Dot, DotLayerArgs, Maximum, Minimum, Multiply} from './layers/merge'; - import {AlphaDropout, AlphaDropoutArgs, GaussianDropout, GaussianDropoutArgs, GaussianNoise, GaussianNoiseArgs} from './layers/noise'; - import {BatchNormalization, BatchNormalizationLayerArgs, LayerNormalization, LayerNormalizationLayerArgs} from './layers/normalization'; - import {ZeroPadding2D, ZeroPadding2DLayerArgs} from './layers/padding'; - import {AveragePooling1D, AveragePooling2D, AveragePooling3D, GlobalAveragePooling1D, GlobalAveragePooling2D, GlobalMaxPooling1D, GlobalMaxPooling2D, GlobalPooling2DLayerArgs, MaxPooling1D, MaxPooling2D, MaxPooling3D, Pooling1DLayerArgs, Pooling2DLayerArgs, Pooling3DLayerArgs} from './layers/pooling'; - import {GRU, GRUCell, GRUCellLayerArgs, GRULayerArgs, LSTM, LSTMCell, LSTMCellLayerArgs, LSTMLayerArgs, RNN, RNNCell, RNNLayerArgs, SimpleRNN, SimpleRNNCell, SimpleRNNCellLayerArgs, SimpleRNNLayerArgs, StackedRNNCells, StackedRNNCellsArgs} from './layers/recurrent'; - import {Bidirectional, BidirectionalLayerArgs, TimeDistributed, WrapperLayerArgs} from './layers/wrappers'; - import { Rescaling, RescalingArgs } from './layers/preprocessing/image_preprocessing'; - - // TODO(cais): Add doc string to all the public static functions in this - // class; include exectuable JavaScript code snippets where applicable - // (b/74074458). - - // Input Layer. - /** - * An input layer is an entry point into a `tf.LayersModel`. - * - * `InputLayer` is generated automatically for `tf.Sequential` models by - * specifying the `inputshape` or `batchInputShape` for the first layer. It - * should not be specified explicitly. However, it can be useful sometimes, - * e.g., when constructing a sequential model from a subset of another - * sequential model's layers. Like the code snippet below shows. - * - * ```js - * // Define a model which simply adds two inputs. - * const model1 = tf.sequential(); - * model1.add(tf.layers.dense({inputShape: [4], units: 3, activation: 'relu'})); - * model1.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); - * model1.summary(); - * model1.predict(tf.zeros([1, 4])).print(); - * - * // Construct another model, reusing the second layer of `model1` while - * // not using the first layer of `model1`. Note that you cannot add the second - * // layer of `model` directly as the first layer of the new sequential model, - * // because doing so will lead to an error related to the fact that the layer - * // is not an input layer. Instead, you need to create an `inputLayer` and add - * // it to the new sequential model before adding the reused layer. - * const model2 = tf.sequential(); - * // Use an inputShape that matches the input shape of `model1`'s second - * // layer. - * model2.add(tf.layers.inputLayer({inputShape: [3]})); - * model2.add(model1.layers[1]); - * model2.summary(); - * model2.predict(tf.zeros([1, 3])).print(); - * ``` - * - * @doc {heading: 'Layers', subheading: 'Inputs', namespace: 'layers'} - */ - export function inputLayer(args: InputLayerArgs) { - return new InputLayer(args); - } - - // Advanced Activation Layers. - - /** - * Exponential Linear Unit (ELU). - * - * It follows: - * `f(x) = alpha * (exp(x) - 1.) for x < 0`, - * `f(x) = x for x >= 0`. - * - * Input shape: - * Arbitrary. Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * Output shape: - * Same shape as the input. - * - * References: - * - [Fast and Accurate Deep Network Learning by Exponential Linear Units - * (ELUs)](https://arxiv.org/abs/1511.07289v1) - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function elu(args?: ELULayerArgs) { - return new ELU(args); - } - - /** - * Rectified Linear Unit activation function. - * - * Input shape: - * Arbitrary. Use the config field `inputShape` (Array of integers, does - * not include the sample axis) when using this layer as the first layer - * in a model. - * - * Output shape: - * Same shape as the input. - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function reLU(args?: ReLULayerArgs) { - return new ReLU(args); - } - - /** - * Leaky version of a rectified linear unit. - * - * It allows a small gradient when the unit is not active: - * `f(x) = alpha * x for x < 0.` - * `f(x) = x for x >= 0.` - * - * Input shape: - * Arbitrary. Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * Output shape: - * Same shape as the input. - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function leakyReLU(args?: LeakyReLULayerArgs) { - return new LeakyReLU(args); - } - - /** - * Parameterized version of a leaky rectified linear unit. - * - * It follows - * `f(x) = alpha * x for x < 0.` - * `f(x) = x for x >= 0.` - * wherein `alpha` is a trainable weight. - * - * Input shape: - * Arbitrary. Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * Output shape: - * Same shape as the input. - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function prelu(args?: PReLULayerArgs) { - return new PReLU(args); - } - - /** - * Softmax activation layer. - * - * Input shape: - * Arbitrary. Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * Output shape: - * Same shape as the input. - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function softmax(args?: SoftmaxLayerArgs) { - return new Softmax(args); - } - - /** - * Thresholded Rectified Linear Unit. - * - * It follows: - * `f(x) = x for x > theta`, - * `f(x) = 0 otherwise`. - * - * Input shape: - * Arbitrary. Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * Output shape: - * Same shape as the input. - * - * References: - * - [Zero-Bias Autoencoders and the Benefits of Co-Adapting - * Features](http://arxiv.org/abs/1402.3337) - * - * @doc { - * heading: 'Layers', - * subheading: 'Advanced Activation', - * namespace: 'layers' - * } - */ - export function thresholdedReLU(args?: ThresholdedReLULayerArgs) { - return new ThresholdedReLU(args); - } - - // Convolutional Layers. - - /** - * 1D convolution layer (e.g., temporal convolution). - * - * This layer creates a convolution kernel that is convolved - * with the layer input over a single spatial (or temporal) dimension - * to produce a tensor of outputs. - * - * If `use_bias` is True, a bias vector is created and added to the outputs. - * - * If `activation` is not `null`, it is applied to the outputs as well. - * - * When using this layer as the first layer in a model, provide an - * `inputShape` argument `Array` or `null`. - * - * For example, `inputShape` would be: - * - `[10, 128]` for sequences of 10 vectors of 128-dimensional vectors - * - `[null, 128]` for variable-length sequences of 128-dimensional vectors. - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function conv1d(args: ConvLayerArgs) { - return new Conv1D(args); - } - - /** - * 2D convolution layer (e.g. spatial convolution over images). - * - * This layer creates a convolution kernel that is convolved - * with the layer input to produce a tensor of outputs. - * - * If `useBias` is True, a bias vector is created and added to the outputs. - * - * If `activation` is not `null`, it is applied to the outputs as well. - * - * When using this layer as the first layer in a model, - * provide the keyword argument `inputShape` - * (Array of integers, does not include the sample axis), - * e.g. `inputShape=[128, 128, 3]` for 128x128 RGB pictures - * in `dataFormat='channelsLast'`. - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function conv2d(args: ConvLayerArgs) { - return new Conv2D(args); - } - - /** - * Transposed convolutional layer (sometimes called Deconvolution). - * - * The need for transposed convolutions generally arises - * from the desire to use a transformation going in the opposite direction of - * a normal convolution, i.e., from something that has the shape of the output - * of some convolution to something that has the shape of its input while - * maintaining a connectivity pattern that is compatible with said - * convolution. - * - * When using this layer as the first layer in a model, provide the - * configuration `inputShape` (`Array` of integers, does not include the - * sample axis), e.g., `inputShape: [128, 128, 3]` for 128x128 RGB pictures in - * `dataFormat: 'channelsLast'`. - * - * Input shape: - * 4D tensor with shape: - * `[batch, channels, rows, cols]` if `dataFormat` is `'channelsFirst'`. - * or 4D tensor with shape - * `[batch, rows, cols, channels]` if `dataFormat` is `'channelsLast'`. - * - * Output shape: - * 4D tensor with shape: - * `[batch, filters, newRows, newCols]` if `dataFormat` is - * `'channelsFirst'`. or 4D tensor with shape: - * `[batch, newRows, newCols, filters]` if `dataFormat` is `'channelsLast'`. - * - * References: - * - [A guide to convolution arithmetic for deep - * learning](https://arxiv.org/abs/1603.07285v1) - * - [Deconvolutional - * Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf) - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function conv2dTranspose(args: ConvLayerArgs) { - return new Conv2DTranspose(args); - } - - /** - * 3D convolution layer (e.g. spatial convolution over volumes). - * - * This layer creates a convolution kernel that is convolved - * with the layer input to produce a tensor of outputs. - * - * If `useBias` is True, a bias vector is created and added to the outputs. - * - * If `activation` is not `null`, it is applied to the outputs as well. - * - * When using this layer as the first layer in a model, - * provide the keyword argument `inputShape` - * (Array of integers, does not include the sample axis), - * e.g. `inputShape=[128, 128, 128, 1]` for 128x128x128 grayscale volumes - * in `dataFormat='channelsLast'`. - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function conv3d(args: ConvLayerArgs) { - return new Conv3D(args); - } - - export function conv3dTranspose(args: ConvLayerArgs): Layer { - return new Conv3DTranspose(args); - } - - /** - * Depthwise separable 2D convolution. - * - * Separable convolution consists of first performing - * a depthwise spatial convolution - * (which acts on each input channel separately) - * followed by a pointwise convolution which mixes together the resulting - * output channels. The `depthMultiplier` argument controls how many - * output channels are generated per input channel in the depthwise step. - * - * Intuitively, separable convolutions can be understood as - * a way to factorize a convolution kernel into two smaller kernels, - * or as an extreme version of an Inception block. - * - * Input shape: - * 4D tensor with shape: - * `[batch, channels, rows, cols]` if data_format='channelsFirst' - * or 4D tensor with shape: - * `[batch, rows, cols, channels]` if data_format='channelsLast'. - * - * Output shape: - * 4D tensor with shape: - * `[batch, filters, newRows, newCols]` if data_format='channelsFirst' - * or 4D tensor with shape: - * `[batch, newRows, newCols, filters]` if data_format='channelsLast'. - * `rows` and `cols` values might have changed due to padding. - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function separableConv2d(args: SeparableConvLayerArgs) { - return new SeparableConv2D(args); - } - - /** - * Cropping layer for 2D input (e.g., image). - * - * This layer can crop an input - * at the top, bottom, left and right side of an image tensor. - * - * Input shape: - * 4D tensor with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, rows, cols, channels]` - * - If `data_format` is `"channels_first"`: - * `[batch, channels, rows, cols]`. - * - * Output shape: - * 4D with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, croppedRows, croppedCols, channels]` - * - If `dataFormat` is `"channelsFirst"`: - * `[batch, channels, croppedRows, croppedCols]`. - * - * Examples - * ```js - * - * const model = tf.sequential(); - * model.add(tf.layers.cropping2D({cropping:[[2, 2], [2, 2]], - * inputShape: [128, 128, 3]})); - * //now output shape is [batch, 124, 124, 3] - * ``` - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function cropping2D(args: Cropping2DLayerArgs) { - return new Cropping2D(args); - } - - /** - * Upsampling layer for 2D inputs. - * - * Repeats the rows and columns of the data - * by size[0] and size[1] respectively. - * - * - * Input shape: - * 4D tensor with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, rows, cols, channels]` - * - If `dataFormat` is `"channelsFirst"`: - * `[batch, channels, rows, cols]` - * - * Output shape: - * 4D tensor with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, upsampledRows, upsampledCols, channels]` - * - If `dataFormat` is `"channelsFirst"`: - * `[batch, channels, upsampledRows, upsampledCols]` - * - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function upSampling2d(args: UpSampling2DLayerArgs) { - return new UpSampling2D(args); - } - - // Convolutional(depthwise) Layers. - - /** - * Depthwise separable 2D convolution. - * - * Depthwise Separable convolutions consists in performing just the first step - * in a depthwise spatial convolution (which acts on each input channel - * separately). The `depthMultiplier` argument controls how many output channels - * are generated per input channel in the depthwise step. - * - * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} - */ - export function depthwiseConv2d(args: DepthwiseConv2DLayerArgs) { - return new DepthwiseConv2D(args); - } - - // Basic Layers. - - /** - * Applies an activation function to an output. - * - * This layer applies element-wise activation function. Other layers, notably - * `dense` can also apply activation functions. Use this isolated activation - * function to extract the values before and after the - * activation. For instance: - * - * ```js - * const input = tf.input({shape: [5]}); - * const denseLayer = tf.layers.dense({units: 1}); - * const activationLayer = tf.layers.activation({activation: 'relu6'}); - * - * // Obtain the output symbolic tensors by applying the layers in order. - * const denseOutput = denseLayer.apply(input); - * const activationOutput = activationLayer.apply(denseOutput); - * - * // Create the model based on the inputs. - * const model = tf.model({ - * inputs: input, - * outputs: [denseOutput, activationOutput] - * }); - * - * // Collect both outputs and print separately. - * const [denseOut, activationOut] = model.predict(tf.randomNormal([6, 5])); - * denseOut.print(); - * activationOut.print(); - * ``` - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function activation(args: ActivationLayerArgs) { - return new Activation(args); - } - - /** - * Creates a dense (fully connected) layer. - * - * This layer implements the operation: - * `output = activation(dot(input, kernel) + bias)` - * - * `activation` is the element-wise activation function - * passed as the `activation` argument. - * - * `kernel` is a weights matrix created by the layer. - * - * `bias` is a bias vector created by the layer (only applicable if `useBias` - * is `true`). - * - * **Input shape:** - * - * nD `tf.Tensor` with shape: `(batchSize, ..., inputDim)`. - * - * The most common situation would be - * a 2D input with shape `(batchSize, inputDim)`. - * - * **Output shape:** - * - * nD tensor with shape: `(batchSize, ..., units)`. - * - * For instance, for a 2D input with shape `(batchSize, inputDim)`, - * the output would have shape `(batchSize, units)`. - * - * Note: if the input to the layer has a rank greater than 2, then it is - * flattened prior to the initial dot product with the kernel. - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function dense(args: DenseLayerArgs) { - return new Dense(args); - } - - /** - * Applies - * [dropout](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) to - * the input. - * - * Dropout consists in randomly setting a fraction `rate` of input units to 0 at - * each update during training time, which helps prevent overfitting. - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function dropout(args: DropoutLayerArgs) { - return new Dropout(args); - } - - /** - * Spatial 1D version of Dropout. - * - * This Layer type performs the same function as the Dropout layer, but it drops - * entire 1D feature maps instead of individual elements. For example, if an - * input example consists of 3 timesteps and the feature map for each timestep - * has a size of 4, a `spatialDropout1d` layer may zero out the feature maps - * of the 1st timesteps and 2nd timesteps completely while sparing all feature - * elements of the 3rd timestep. - * - * If adjacent frames (timesteps) are strongly correlated (as is normally the - * case in early convolution layers), regular dropout will not regularize the - * activation and will otherwise just result in merely an effective learning - * rate decrease. In this case, `spatialDropout1d` will help promote - * independence among feature maps and should be used instead. - * - * **Arguments:** - * rate: A floating-point number >=0 and <=1. Fraction of the input elements - * to drop. - * - * **Input shape:** - * 3D tensor with shape `(samples, timesteps, channels)`. - * - * **Output shape:** - * Same as the input shape. - * - * References: - * - [Efficient Object Localization Using Convolutional - * Networks](https://arxiv.org/abs/1411.4280) - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function spatialDropout1d(args: SpatialDropout1DLayerConfig) { - return new SpatialDropout1D(args); - } - - /** - * Flattens the input. Does not affect the batch size. - * - * A `Flatten` layer flattens each batch in its inputs to 1D (making the output - * 2D). - * - * For example: - * - * ```js - * const input = tf.input({shape: [4, 3]}); - * const flattenLayer = tf.layers.flatten(); - * // Inspect the inferred output shape of the flatten layer, which - * // equals `[null, 12]`. The 2nd dimension is 4 * 3, i.e., the result of the - * // flattening. (The 1st dimension is the undermined batch size.) - * console.log(JSON.stringify(flattenLayer.apply(input).shape)); - * ``` - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function flatten(args?: FlattenLayerArgs) { - return new Flatten(args); - } - - /** - * Repeats the input n times in a new dimension. - * - * ```js - * const model = tf.sequential(); - * model.add(tf.layers.repeatVector({n: 4, inputShape: [2]})); - * const x = tf.tensor2d([[10, 20]]); - * // Use the model to do inference on a data point the model hasn't see - * model.predict(x).print(); - * // output shape is now [batch, 2, 4] - * ``` - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function repeatVector(args: RepeatVectorLayerArgs) { - return new RepeatVector(args); - } - - /** - * Reshapes an input to a certain shape. - * - * ```js - * const input = tf.input({shape: [4, 3]}); - * const reshapeLayer = tf.layers.reshape({targetShape: [2, 6]}); - * // Inspect the inferred output shape of the Reshape layer, which - * // equals `[null, 2, 6]`. (The 1st dimension is the undermined batch size.) - * console.log(JSON.stringify(reshapeLayer.apply(input).shape)); - * ``` - * - * Input shape: - * Arbitrary, although all dimensions in the input shape must be fixed. - * Use the configuration `inputShape` when using this layer as the - * first layer in a model. - * - * - * Output shape: - * [batchSize, targetShape[0], targetShape[1], ..., - * targetShape[targetShape.length - 1]]. - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function reshape(args: ReshapeLayerArgs) { - return new Reshape(args); - } - - /** - * Permutes the dimensions of the input according to a given pattern. - * - * Useful for, e.g., connecting RNNs and convnets together. - * - * Example: - * - * ```js - * const model = tf.sequential(); - * model.add(tf.layers.permute({ - * dims: [2, 1], - * inputShape: [10, 64] - * })); - * console.log(model.outputShape); - * // Now model's output shape is [null, 64, 10], where null is the - * // unpermuted sample (batch) dimension. - * ``` - * - * Input shape: - * Arbitrary. Use the configuration field `inputShape` when using this - * layer as the first layer in a model. - * - * Output shape: - * Same rank as the input shape, but with the dimensions re-ordered (i.e., - * permuted) according to the `dims` configuration of this layer. - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function permute(args: PermuteLayerArgs) { - return new Permute(args); - } - - /** - * Maps positive integers (indices) into dense vectors of fixed size. - * E.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] - * - * **Input shape:** 2D tensor with shape: `[batchSize, sequenceLength]`. - * - * **Output shape:** 3D tensor with shape: `[batchSize, sequenceLength, - * outputDim]`. - * - * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} - */ - export function embedding(args: EmbeddingLayerArgs) { - return new Embedding(args); - } - - // Merge Layers. - - /** - * Layer that performs element-wise addition on an `Array` of inputs. - * - * It takes as input a list of tensors, all of the same shape, and returns a - * single tensor (also of the same shape). The inputs are specified as an - * `Array` when the `apply` method of the `Add` layer instance is called. For - * example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 2]}); - * const addLayer = tf.layers.add(); - * const sum = addLayer.apply([input1, input2]); - * console.log(JSON.stringify(sum.shape)); - * // You get [null, 2, 2], with the first dimension as the undetermined batch - * // dimension. - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function add(args?: LayerArgs) { - return new Add(args); - } - - /** - * Layer that performs element-wise averaging on an `Array` of inputs. - * - * It takes as input a list of tensors, all of the same shape, and returns a - * single tensor (also of the same shape). For example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 2]}); - * const averageLayer = tf.layers.average(); - * const average = averageLayer.apply([input1, input2]); - * console.log(JSON.stringify(average.shape)); - * // You get [null, 2, 2], with the first dimension as the undetermined batch - * // dimension. - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function average(args?: LayerArgs) { - return new Average(args); - } - - /** - * Layer that concatenates an `Array` of inputs. - * - * It takes a list of tensors, all of the same shape except for the - * concatenation axis, and returns a single tensor, the concatenation - * of all inputs. For example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 3]}); - * const concatLayer = tf.layers.concatenate(); - * const output = concatLayer.apply([input1, input2]); - * console.log(JSON.stringify(output.shape)); - * // You get [null, 2, 5], with the first dimension as the undetermined batch - * // dimension. The last dimension (5) is the result of concatenating the - * // last dimensions of the inputs (2 and 3). - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function concatenate(args?: ConcatenateLayerArgs) { - return new Concatenate(args); - } - - /** - * Layer that computes the element-wise maximum of an `Array` of inputs. - * - * It takes as input a list of tensors, all of the same shape, and returns a - * single tensor (also of the same shape). For example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 2]}); - * const maxLayer = tf.layers.maximum(); - * const max = maxLayer.apply([input1, input2]); - * console.log(JSON.stringify(max.shape)); - * // You get [null, 2, 2], with the first dimension as the undetermined batch - * // dimension. - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function maximum(args?: LayerArgs) { - return new Maximum(args); - } - - /** - * Layer that computes the element-wise minimum of an `Array` of inputs. - * - * It takes as input a list of tensors, all of the same shape, and returns a - * single tensor (also of the same shape). For example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 2]}); - * const minLayer = tf.layers.minimum(); - * const min = minLayer.apply([input1, input2]); - * console.log(JSON.stringify(min.shape)); - * // You get [null, 2, 2], with the first dimension as the undetermined batch - * // dimension. - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function minimum(args?: LayerArgs) { - return new Minimum(args); - } - - /** - * Layer that multiplies (element-wise) an `Array` of inputs. - * - * It takes as input an Array of tensors, all of the same - * shape, and returns a single tensor (also of the same shape). - * For example: - * - * ```js - * const input1 = tf.input({shape: [2, 2]}); - * const input2 = tf.input({shape: [2, 2]}); - * const input3 = tf.input({shape: [2, 2]}); - * const multiplyLayer = tf.layers.multiply(); - * const product = multiplyLayer.apply([input1, input2, input3]); - * console.log(product.shape); - * // You get [null, 2, 2], with the first dimension as the undetermined batch - * // dimension. - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function multiply(args?: LayerArgs) { - return new Multiply(args); - } - - /** - * Layer that computes a dot product between samples in two tensors. - * - * E.g., if applied to a list of two tensors `a` and `b` both of shape - * `[batchSize, n]`, the output will be a tensor of shape `[batchSize, 1]`, - * where each entry at index `[i, 0]` will be the dot product between - * `a[i, :]` and `b[i, :]`. - * - * Example: - * - * ```js - * const dotLayer = tf.layers.dot({axes: -1}); - * const x1 = tf.tensor2d([[10, 20], [30, 40]]); - * const x2 = tf.tensor2d([[-1, -2], [-3, -4]]); - * - * // Invoke the layer's apply() method in eager (imperative) mode. - * const y = dotLayer.apply([x1, x2]); - * y.print(); - * ``` - * - * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} - */ - export function dot(args: DotLayerArgs) { - return new Dot(args); - } - - // Normalization Layers. - - /** - * Batch normalization layer (Ioffe and Szegedy, 2014). - * - * Normalize the activations of the previous layer at each batch, - * i.e. applies a transformation that maintains the mean activation - * close to 0 and the activation standard deviation close to 1. - * - * Input shape: - * Arbitrary. Use the keyword argument `inputShape` (Array of integers, does - * not include the sample axis) when calling the constructor of this class, - * if this layer is used as a first layer in a model. - * - * Output shape: - * Same shape as input. - * - * References: - * - [Batch Normalization: Accelerating Deep Network Training by Reducing - * Internal Covariate Shift](https://arxiv.org/abs/1502.03167) - * - * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} - */ - export function batchNormalization(args?: BatchNormalizationLayerArgs) { - return new BatchNormalization(args); - } - - /** - * Layer-normalization layer (Ba et al., 2016). - * - * Normalizes the activations of the previous layer for each given example in a - * batch independently, instead of across a batch like in `batchNormalization`. - * In other words, this layer applies a transformation that maintains the mean - * activation within each example close to 0 and activation variance close to 1. - * - * Input shape: - * Arbitrary. Use the argument `inputShape` when using this layer as the first - * layer in a model. - * - * Output shape: - * Same as input. - * - * References: - * - [Layer Normalization](https://arxiv.org/abs/1607.06450) - * - * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} - */ - export function layerNormalization(args?: LayerNormalizationLayerArgs) { - return new LayerNormalization(args); - } - - // Padding Layers. - - /** - * Zero-padding layer for 2D input (e.g., image). - * - * This layer can add rows and columns of zeros - * at the top, bottom, left and right side of an image tensor. - * - * Input shape: - * 4D tensor with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, rows, cols, channels]` - * - If `data_format` is `"channels_first"`: - * `[batch, channels, rows, cols]`. - * - * Output shape: - * 4D with shape: - * - If `dataFormat` is `"channelsLast"`: - * `[batch, paddedRows, paddedCols, channels]` - * - If `dataFormat` is `"channelsFirst"`: - * `[batch, channels, paddedRows, paddedCols]`. - * - * @doc {heading: 'Layers', subheading: 'Padding', namespace: 'layers'} - */ - export function zeroPadding2d(args?: ZeroPadding2DLayerArgs) { - return new ZeroPadding2D(args); - } - - // Pooling Layers. - - /** - * Average pooling operation for spatial data. - * - * Input shape: `[batchSize, inLength, channels]` - * - * Output shape: `[batchSize, pooledLength, channels]` - * - * `tf.avgPool1d` is an alias. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function averagePooling1d(args: Pooling1DLayerArgs) { - return new AveragePooling1D(args); - } - export function avgPool1d(args: Pooling1DLayerArgs) { - return averagePooling1d(args); - } - // For backwards compatibility. - // See https://github.com/tensorflow/tfjs/issues/152 - export function avgPooling1d(args: Pooling1DLayerArgs) { - return averagePooling1d(args); - } - - /** - * Average pooling operation for spatial data. - * - * Input shape: - * - If `dataFormat === CHANNEL_LAST`: - * 4D tensor with shape: - * `[batchSize, rows, cols, channels]` - * - If `dataFormat === CHANNEL_FIRST`: - * 4D tensor with shape: - * `[batchSize, channels, rows, cols]` - * - * Output shape - * - If `dataFormat === CHANNEL_LAST`: - * 4D tensor with shape: - * `[batchSize, pooledRows, pooledCols, channels]` - * - If `dataFormat === CHANNEL_FIRST`: - * 4D tensor with shape: - * `[batchSize, channels, pooledRows, pooledCols]` - * - * `tf.avgPool2d` is an alias. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function averagePooling2d(args: Pooling2DLayerArgs) { - return new AveragePooling2D(args); - } - export function avgPool2d(args: Pooling2DLayerArgs) { - return averagePooling2d(args); - } - // For backwards compatibility. - // See https://github.com/tensorflow/tfjs/issues/152 - export function avgPooling2d(args: Pooling2DLayerArgs) { - return averagePooling2d(args); - } - - /** - * Average pooling operation for 3D data. - * - * Input shape - * - If `dataFormat === channelsLast`: - * 5D tensor with shape: - * `[batchSize, depths, rows, cols, channels]` - * - If `dataFormat === channelsFirst`: - * 4D tensor with shape: - * `[batchSize, channels, depths, rows, cols]` - * - * Output shape - * - If `dataFormat=channelsLast`: - * 5D tensor with shape: - * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` - * - If `dataFormat=channelsFirst`: - * 5D tensor with shape: - * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function averagePooling3d(args: Pooling3DLayerArgs) { - return new AveragePooling3D(args); - } - export function avgPool3d(args: Pooling3DLayerArgs) { - return averagePooling3d(args); - } - // For backwards compatibility. - // See https://github.com/tensorflow/tfjs/issues/152 - export function avgPooling3d(args: Pooling3DLayerArgs) { - return averagePooling3d(args); - } - - /** - * Global average pooling operation for temporal data. - * - * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. - * - * Output Shape: 2D tensor with shape: `[batchSize, features]`. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function globalAveragePooling1d(args?: LayerArgs) { - return new GlobalAveragePooling1D(args); - } - - /** - * Global average pooling operation for spatial data. - * - * Input shape: - * - If `dataFormat` is `CHANNEL_LAST`: - * 4D tensor with shape: `[batchSize, rows, cols, channels]`. - * - If `dataFormat` is `CHANNEL_FIRST`: - * 4D tensor with shape: `[batchSize, channels, rows, cols]`. - * - * Output shape: - * 2D tensor with shape: `[batchSize, channels]`. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function globalAveragePooling2d(args: GlobalPooling2DLayerArgs) { - return new GlobalAveragePooling2D(args); - } - - /** - * Global max pooling operation for temporal data. - * - * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. - * - * Output Shape: 2D tensor with shape: `[batchSize, features]`. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function globalMaxPooling1d(args?: LayerArgs) { - return new GlobalMaxPooling1D(args); - } - - /** - * Global max pooling operation for spatial data. - * - * Input shape: - * - If `dataFormat` is `CHANNEL_LAST`: - * 4D tensor with shape: `[batchSize, rows, cols, channels]`. - * - If `dataFormat` is `CHANNEL_FIRST`: - * 4D tensor with shape: `[batchSize, channels, rows, cols]`. - * - * Output shape: - * 2D tensor with shape: `[batchSize, channels]`. - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function globalMaxPooling2d(args: GlobalPooling2DLayerArgs) { - return new GlobalMaxPooling2D(args); - } - - /** - * Max pooling operation for temporal data. - * - * Input shape: `[batchSize, inLength, channels]` - * - * Output shape: `[batchSize, pooledLength, channels]` - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function maxPooling1d(args: Pooling1DLayerArgs) { - return new MaxPooling1D(args); - } - - /** - * Max pooling operation for spatial data. - * - * Input shape - * - If `dataFormat === CHANNEL_LAST`: - * 4D tensor with shape: - * `[batchSize, rows, cols, channels]` - * - If `dataFormat === CHANNEL_FIRST`: - * 4D tensor with shape: - * `[batchSize, channels, rows, cols]` - * - * Output shape - * - If `dataFormat=CHANNEL_LAST`: - * 4D tensor with shape: - * `[batchSize, pooledRows, pooledCols, channels]` - * - If `dataFormat=CHANNEL_FIRST`: - * 4D tensor with shape: - * `[batchSize, channels, pooledRows, pooledCols]` - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function maxPooling2d(args: Pooling2DLayerArgs) { - return new MaxPooling2D(args); - } - - /** - * Max pooling operation for 3D data. - * - * Input shape - * - If `dataFormat === channelsLast`: - * 5D tensor with shape: - * `[batchSize, depths, rows, cols, channels]` - * - If `dataFormat === channelsFirst`: - * 5D tensor with shape: - * `[batchSize, channels, depths, rows, cols]` - * - * Output shape - * - If `dataFormat=channelsLast`: - * 5D tensor with shape: - * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` - * - If `dataFormat=channelsFirst`: - * 5D tensor with shape: - * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` - * - * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} - */ - export function maxPooling3d(args: Pooling3DLayerArgs) { - return new MaxPooling3D(args); - } - - // Recurrent Layers. - - /** - * Gated Recurrent Unit - Cho et al. 2014. - * - * This is an `RNN` layer consisting of one `GRUCell`. However, unlike - * the underlying `GRUCell`, the `apply` method of `SimpleRNN` operates - * on a sequence of inputs. The shape of the input (not including the first, - * batch dimension) needs to be at least 2-D, with the first dimension being - * time steps. For example: - * - * ```js - * const rnn = tf.layers.gru({units: 8, returnSequences: true}); - * - * // Create an input with 10 time steps. - * const input = tf.input({shape: [10, 20]}); - * const output = rnn.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the `GRUCell`'s number of units. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function gru(args: GRULayerArgs) { - return new GRU(args); - } - - /** - * Cell class for `GRU`. - * - * `GRUCell` is distinct from the `RNN` subclass `GRU` in that its - * `apply` method takes the input data of only a single time step and returns - * the cell's output at the time step, while `GRU` takes the input data - * over a number of time steps. For example: - * - * ```js - * const cell = tf.layers.gruCell({units: 2}); - * const input = tf.input({shape: [10]}); - * const output = cell.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10]: This is the cell's output at a single time step. The 1st - * // dimension is the unknown batch size. - * ``` - * - * Instance(s) of `GRUCell` can be used to construct `RNN` layers. The - * most typical use of this workflow is to combine a number of cells into a - * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an - * RNN. For example: - * - * ```js - * const cells = [ - * tf.layers.gruCell({units: 4}), - * tf.layers.gruCell({units: 8}), - * ]; - * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); - * - * // Create an input with 10 time steps and a length-20 vector at each step. - * const input = tf.input({shape: [10, 20]}); - * const output = rnn.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the last `gruCell`'s number of units. - * ``` - * - * To create an `RNN` consisting of only *one* `GRUCell`, use the - * `tf.layers.gru`. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function gruCell(args: GRUCellLayerArgs) { - return new GRUCell(args); - } - - /** - * Long-Short Term Memory layer - Hochreiter 1997. - * - * This is an `RNN` layer consisting of one `LSTMCell`. However, unlike - * the underlying `LSTMCell`, the `apply` method of `LSTM` operates - * on a sequence of inputs. The shape of the input (not including the first, - * batch dimension) needs to be at least 2-D, with the first dimension being - * time steps. For example: - * - * ```js - * const lstm = tf.layers.lstm({units: 8, returnSequences: true}); - * - * // Create an input with 10 time steps. - * const input = tf.input({shape: [10, 20]}); - * const output = lstm.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the `LSTMCell`'s number of units. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function lstm(args: LSTMLayerArgs) { - return new LSTM(args); - } - - /** - * Cell class for `LSTM`. - * - * `LSTMCell` is distinct from the `RNN` subclass `LSTM` in that its - * `apply` method takes the input data of only a single time step and returns - * the cell's output at the time step, while `LSTM` takes the input data - * over a number of time steps. For example: - * - * ```js - * const cell = tf.layers.lstmCell({units: 2}); - * const input = tf.input({shape: [10]}); - * const output = cell.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10]: This is the cell's output at a single time step. The 1st - * // dimension is the unknown batch size. - * ``` - * - * Instance(s) of `LSTMCell` can be used to construct `RNN` layers. The - * most typical use of this workflow is to combine a number of cells into a - * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an - * RNN. For example: - * - * ```js - * const cells = [ - * tf.layers.lstmCell({units: 4}), - * tf.layers.lstmCell({units: 8}), - * ]; - * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); - * - * // Create an input with 10 time steps and a length-20 vector at each step. - * const input = tf.input({shape: [10, 20]}); - * const output = rnn.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the last `lstmCell`'s number of units. - * ``` - * - * To create an `RNN` consisting of only *one* `LSTMCell`, use the - * `tf.layers.lstm`. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function lstmCell(args: LSTMCellLayerArgs) { - return new LSTMCell(args); - } - - /** - * Fully-connected RNN where the output is to be fed back to input. - * - * This is an `RNN` layer consisting of one `SimpleRNNCell`. However, unlike - * the underlying `SimpleRNNCell`, the `apply` method of `SimpleRNN` operates - * on a sequence of inputs. The shape of the input (not including the first, - * batch dimension) needs to be at least 2-D, with the first dimension being - * time steps. For example: - * - * ```js - * const rnn = tf.layers.simpleRNN({units: 8, returnSequences: true}); - * - * // Create an input with 10 time steps. - * const input = tf.input({shape: [10, 20]}); - * const output = rnn.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the `SimpleRNNCell`'s number of units. - * ``` - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function simpleRNN(args: SimpleRNNLayerArgs) { - return new SimpleRNN(args); - } - - /** - * Cell class for `SimpleRNN`. - * - * `SimpleRNNCell` is distinct from the `RNN` subclass `SimpleRNN` in that its - * `apply` method takes the input data of only a single time step and returns - * the cell's output at the time step, while `SimpleRNN` takes the input data - * over a number of time steps. For example: - * - * ```js - * const cell = tf.layers.simpleRNNCell({units: 2}); - * const input = tf.input({shape: [10]}); - * const output = cell.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10]: This is the cell's output at a single time step. The 1st - * // dimension is the unknown batch size. - * ``` - * - * Instance(s) of `SimpleRNNCell` can be used to construct `RNN` layers. The - * most typical use of this workflow is to combine a number of cells into a - * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an - * RNN. For example: - * - * ```js - * const cells = [ - * tf.layers.simpleRNNCell({units: 4}), - * tf.layers.simpleRNNCell({units: 8}), - * ]; - * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); - * - * // Create an input with 10 time steps and a length-20 vector at each step. - * const input = tf.input({shape: [10, 20]}); - * const output = rnn.apply(input); - * - * console.log(JSON.stringify(output.shape)); - * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the - * // same as the sequence length of `input`, due to `returnSequences`: `true`; - * // 3rd dimension is the last `SimpleRNNCell`'s number of units. - * ``` - * - * To create an `RNN` consisting of only *one* `SimpleRNNCell`, use the - * `tf.layers.simpleRNN`. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function simpleRNNCell(args: SimpleRNNCellLayerArgs) { - return new SimpleRNNCell(args); - } - - /** - * Convolutional LSTM layer - Xingjian Shi 2015. - * - * This is a `ConvRNN2D` layer consisting of one `ConvLSTM2DCell`. However, - * unlike the underlying `ConvLSTM2DCell`, the `apply` method of `ConvLSTM2D` - * operates on a sequence of inputs. The shape of the input (not including the - * first, batch dimension) needs to be 4-D, with the first dimension being time - * steps. For example: - * - * ```js - * const filters = 3; - * const kernelSize = 3; - * - * const batchSize = 4; - * const sequenceLength = 2; - * const size = 5; - * const channels = 3; - * - * const inputShape = [batchSize, sequenceLength, size, size, channels]; - * const input = tf.ones(inputShape); - * - * const layer = tf.layers.convLstm2d({filters, kernelSize}); - * - * const output = layer.apply(input); - * ``` - */ - /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ - export function convLstm2d(args: ConvLSTM2DArgs) { - return new ConvLSTM2D(args); - } - - /** - * Cell class for `ConvLSTM2D`. - * - * `ConvLSTM2DCell` is distinct from the `ConvRNN2D` subclass `ConvLSTM2D` in - * that its `call` method takes the input data of only a single time step and - * returns the cell's output at the time step, while `ConvLSTM2D` takes the - * input data over a number of time steps. For example: - * - * ```js - * const filters = 3; - * const kernelSize = 3; - * - * const sequenceLength = 1; - * const size = 5; - * const channels = 3; - * - * const inputShape = [sequenceLength, size, size, channels]; - * const input = tf.ones(inputShape); - * - * const cell = tf.layers.convLstm2dCell({filters, kernelSize}); - * - * cell.build(input.shape); - * - * const outputSize = size - kernelSize + 1; - * const outShape = [sequenceLength, outputSize, outputSize, filters]; - * - * const initialH = tf.zeros(outShape); - * const initialC = tf.zeros(outShape); - * - * const [o, h, c] = cell.call([input, initialH, initialC], {}); - * ``` - */ - /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ - export function convLstm2dCell(args: ConvLSTM2DCellArgs) { - return new ConvLSTM2DCell(args); - } - - /** - * Base class for recurrent layers. - * - * Input shape: - * 3D tensor with shape `[batchSize, timeSteps, inputDim]`. - * - * Output shape: - * - if `returnState`, an Array of tensors (i.e., `tf.Tensor`s). The first - * tensor is the output. The remaining tensors are the states at the - * last time step, each with shape `[batchSize, units]`. - * - if `returnSequences`, the output will have shape - * `[batchSize, timeSteps, units]`. - * - else, the output will have shape `[batchSize, units]`. - * - * Masking: - * This layer supports masking for input data with a variable number - * of timesteps. To introduce masks to your data, - * use an embedding layer with the `mask_zero` parameter - * set to `True`. - * - * Notes on using statefulness in RNNs: - * You can set RNN layers to be 'stateful', which means that the states - * computed for the samples in one batch will be reused as initial states - * for the samples in the next batch. This assumes a one-to-one mapping - * between samples in different successive batches. - * - * To enable statefulness: - * - specify `stateful: true` in the layer constructor. - * - specify a fixed batch size for your model, by passing - * if sequential model: - * `batchInputShape=[...]` to the first layer in your model. - * else for functional model with 1 or more Input layers: - * `batchShape=[...]` to all the first layers in your model. - * This is the expected shape of your inputs *including the batch size*. - * It should be a tuple of integers, e.g. `(32, 10, 100)`. - * - specify `shuffle=False` when calling fit(). - * - * To reset the states of your model, call `.resetStates()` on either - * a specific layer, or on your entire model. - * - * Note on specifying the initial state of RNNs - * You can specify the initial state of RNN layers symbolically by - * calling them with the option `initialState`. The value of - * `initialState` should be a tensor or list of tensors representing - * the initial state of the RNN layer. - * - * You can specify the initial state of RNN layers numerically by - * calling `resetStates` with the keyword argument `states`. The value of - * `states` should be a numpy array or list of numpy arrays representing - * the initial state of the RNN layer. - * - * Note on passing external constants to RNNs - * You can pass "external" constants to the cell using the `constants` - * keyword argument of `RNN.call` method. This requires that the `cell.call` - * method accepts the same keyword argument `constants`. Such constants - * can be used to condition the cell transformation on additional static - * inputs (not changing over time), a.k.a. an attention mechanism. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function rnn(args: RNNLayerArgs) { - return new RNN(args); - } - - /** - * Wrapper allowing a stack of RNN cells to behave as a single cell. - * - * Used to implement efficient stacked RNNs. - * - * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} - */ - export function stackedRNNCells(args: StackedRNNCellsArgs){ - return new StackedRNNCells(args); - } - - // Wrapper Layers. - - /** @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} */ - export function bidirectional(args: BidirectionalLayerArgs) { - return new Bidirectional(args); - } - - /** - * This wrapper applies a layer to every temporal slice of an input. - * - * The input should be at least 3D, and the dimension of the index `1` will be - * considered to be the temporal dimension. - * - * Consider a batch of 32 samples, where each sample is a sequence of 10 vectors - * of 16 dimensions. The batch input shape of the layer is then `[32, 10, - * 16]`, and the `inputShape`, not including the sample dimension, is - * `[10, 16]`. - * - * You can then use `TimeDistributed` to apply a `Dense` layer to each of the 10 - * timesteps, independently: - * - * ```js - * const model = tf.sequential(); - * model.add(tf.layers.timeDistributed({ - * layer: tf.layers.dense({units: 8}), - * inputShape: [10, 16], - * })); - * - * // Now model.outputShape = [null, 10, 8]. - * // The output will then have shape `[32, 10, 8]`. - * - * // In subsequent layers, there is no need for `inputShape`: - * model.add(tf.layers.timeDistributed({layer: tf.layers.dense({units: 32})})); - * console.log(JSON.stringify(model.outputs[0].shape)); - * // Now model.outputShape = [null, 10, 32]. - * ``` - * - * The output will then have shape `[32, 10, 32]`. - * - * `TimeDistributed` can be used with arbitrary layers, not just `Dense`, for - * instance a `Conv2D` layer. - * - * ```js - * const model = tf.sequential(); - * model.add(tf.layers.timeDistributed({ - * layer: tf.layers.conv2d({filters: 64, kernelSize: [3, 3]}), - * inputShape: [10, 299, 299, 3], - * })); - * console.log(JSON.stringify(model.outputs[0].shape)); - * ``` - * - * @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} - */ - export function timeDistributed(args: WrapperLayerArgs) { - return new TimeDistributed(args); - } - - // Aliases for pooling. - export const globalMaxPool1d = globalMaxPooling1d; - export const globalMaxPool2d = globalMaxPooling2d; - export const maxPool1d = maxPooling1d; - export const maxPool2d = maxPooling2d; - - export {Layer, RNN, RNNCell, input /* alias for tf.input */}; - - /** - * Apply additive zero-centered Gaussian noise. - * - * As it is a regularization layer, it is only active at training time. - * - * This is useful to mitigate overfitting - * (you could see it as a form of random data augmentation). - * Gaussian Noise (GS) is a natural choice as corruption process - * for real valued inputs. - * - * # Arguments - * stddev: float, standard deviation of the noise distribution. - * - * # Input shape - * Arbitrary. Use the keyword argument `input_shape` - * (tuple of integers, does not include the samples axis) - * when using this layer as the first layer in a model. - * - * # Output shape - * Same shape as input. - * - * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} - */ - export function gaussianNoise(args: GaussianNoiseArgs) { - return new GaussianNoise(args); - } - - /** - * Apply multiplicative 1-centered Gaussian noise. - * - * As it is a regularization layer, it is only active at training time. - * - * Arguments: - * - `rate`: float, drop probability (as with `Dropout`). - * The multiplicative noise will have - * standard deviation `sqrt(rate / (1 - rate))`. - * - * Input shape: - * Arbitrary. Use the keyword argument `inputShape` - * (tuple of integers, does not include the samples axis) - * when using this layer as the first layer in a model. - * - * Output shape: - * Same shape as input. - * - * References: - * - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting]( - * http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) - * - * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} - */ - export function gaussianDropout(args: GaussianDropoutArgs) { - return new GaussianDropout(args); - } - - /** - * Applies Alpha Dropout to the input. - * - * As it is a regularization layer, it is only active at training time. - * - * Alpha Dropout is a `Dropout` that keeps mean and variance of inputs - * to their original values, in order to ensure the self-normalizing property - * even after this dropout. - * Alpha Dropout fits well to Scaled Exponential Linear Units - * by randomly setting activations to the negative saturation value. - * - * Arguments: - * - `rate`: float, drop probability (as with `Dropout`). - * The multiplicative noise will have - * standard deviation `sqrt(rate / (1 - rate))`. - * - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the - * shape for randomly generated keep/drop flags. - * - * Input shape: - * Arbitrary. Use the keyword argument `inputShape` - * (tuple of integers, does not include the samples axis) - * when using this layer as the first layer in a model. - * - * Output shape: - * Same shape as input. - * - * References: - * - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) - * - * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} - */ - export function alphaDropout(args: AlphaDropoutArgs) { - return new AlphaDropout(args); - } - - /** - * Masks a sequence by using a mask value to skip timesteps. - * - * If all features for a given sample timestep are equal to `mask_value`, - * then the sample timestep will be masked (skipped) in all downstream layers - * (as long as they support masking). - * - * If any downstream layer does not support masking yet receives such - * an input mask, an exception will be raised. - * - * Arguments: - * - `maskValue`: Either None or mask value to skip. - * - * Input shape: - * Arbitrary. Use the keyword argument `inputShape` - * (tuple of integers, does not include the samples axis) - * when using this layer as the first layer in a model. - * - * Output shape: - * Same shape as input. - * - * @doc {heading: 'Layers', subheading: 'Mask', namespace: 'layers'} - */ - export function masking(args?: MaskingArgs) { - return new Masking(args); - } - - /** - * A preprocessing layer which rescales input values to a new range. - * - * This layer rescales every value of an input (often an image) by multiplying - * by `scale` and adding `offset`. - * - * For instance: - * 1. To rescale an input in the ``[0, 255]`` range - * to be in the `[0, 1]` range, you would pass `scale=1/255`. - * 2. To rescale an input in the ``[0, 255]`` range to be in the `[-1, 1]` - * range, you would pass `scale=1./127.5, offset=-1`. - * The rescaling is applied both during training and inference. Inputs can be - * of integer or floating point dtype, and by default the layer will output - * floats. - * - * Arguments: - * - `scale`: Float, the scale to apply to the inputs. - * - `offset`: Float, the offset to apply to the inputs. - * - * Input shape: - * Arbitrary. - * - * Output shape: - * Same as input. - * - * @doc {heading: 'Layers', subheading: 'Rescaling', namespace: 'layers'} - */ - export function rescaling(args?: RescalingArgs) { - return new Rescaling(args); - } +import {InputLayer, InputLayerArgs} from './engine/input_layer'; +import {Layer, LayerArgs} from './engine/topology'; +import {input} from './exports'; +import {ELU, ELULayerArgs, LeakyReLU, LeakyReLULayerArgs, PReLU, PReLULayerArgs, ReLU, ReLULayerArgs, Softmax, SoftmaxLayerArgs, ThresholdedReLU, ThresholdedReLULayerArgs} from './layers/advanced_activations'; +import {Conv1D, Conv2D, Conv2DTranspose, Conv3D, ConvLayerArgs, Cropping2D, Cropping2DLayerArgs, SeparableConv2D, SeparableConvLayerArgs, UpSampling2D, UpSampling2DLayerArgs, Conv3DTranspose} from './layers/convolutional'; +import {DepthwiseConv2D, DepthwiseConv2DLayerArgs} from './layers/convolutional_depthwise'; +import {ConvLSTM2D, ConvLSTM2DArgs, ConvLSTM2DCell, ConvLSTM2DCellArgs} from './layers/convolutional_recurrent'; +import {Activation, ActivationLayerArgs, Dense, DenseLayerArgs, Dropout, DropoutLayerArgs, Flatten, FlattenLayerArgs, Masking, MaskingArgs, Permute, PermuteLayerArgs, RepeatVector, RepeatVectorLayerArgs, Reshape, ReshapeLayerArgs, SpatialDropout1D, SpatialDropout1DLayerConfig} from './layers/core'; +import {Embedding, EmbeddingLayerArgs} from './layers/embeddings'; +import {Add, Average, Concatenate, ConcatenateLayerArgs, Dot, DotLayerArgs, Maximum, Minimum, Multiply} from './layers/merge'; +import {AlphaDropout, AlphaDropoutArgs, GaussianDropout, GaussianDropoutArgs, GaussianNoise, GaussianNoiseArgs} from './layers/noise'; +import {BatchNormalization, BatchNormalizationLayerArgs, LayerNormalization, LayerNormalizationLayerArgs} from './layers/normalization'; +import {ZeroPadding2D, ZeroPadding2DLayerArgs} from './layers/padding'; +import {AveragePooling1D, AveragePooling2D, AveragePooling3D, GlobalAveragePooling1D, GlobalAveragePooling2D, GlobalMaxPooling1D, GlobalMaxPooling2D, GlobalPooling2DLayerArgs, MaxPooling1D, MaxPooling2D, MaxPooling3D, Pooling1DLayerArgs, Pooling2DLayerArgs, Pooling3DLayerArgs} from './layers/pooling'; +import {GRU, GRUCell, GRUCellLayerArgs, GRULayerArgs, LSTM, LSTMCell, LSTMCellLayerArgs, LSTMLayerArgs, RNN, RNNCell, RNNLayerArgs, SimpleRNN, SimpleRNNCell, SimpleRNNCellLayerArgs, SimpleRNNLayerArgs, StackedRNNCells, StackedRNNCellsArgs} from './layers/recurrent'; +import {Bidirectional, BidirectionalLayerArgs, TimeDistributed, WrapperLayerArgs} from './layers/wrappers'; +import { Rescaling, RescalingArgs } from './layers/preprocessing/image_preprocessing'; + +// TODO(cais): Add doc string to all the public static functions in this +// class; include exectuable JavaScript code snippets where applicable +// (b/74074458). + +// Input Layer. +/** +* An input layer is an entry point into a `tf.LayersModel`. +* +* `InputLayer` is generated automatically for `tf.Sequential` models by +* specifying the `inputshape` or `batchInputShape` for the first layer. It +* should not be specified explicitly. However, it can be useful sometimes, +* e.g., when constructing a sequential model from a subset of another +* sequential model's layers. Like the code snippet below shows. +* +* ```js +* // Define a model which simply adds two inputs. +* const model1 = tf.sequential(); +* model1.add(tf.layers.dense({inputShape: [4], units: 3, activation: 'relu'})); +* model1.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); +* model1.summary(); +* model1.predict(tf.zeros([1, 4])).print(); +* +* // Construct another model, reusing the second layer of `model1` while +* // not using the first layer of `model1`. Note that you cannot add the second +* // layer of `model` directly as the first layer of the new sequential model, +* // because doing so will lead to an error related to the fact that the layer +* // is not an input layer. Instead, you need to create an `inputLayer` and add +* // it to the new sequential model before adding the reused layer. +* const model2 = tf.sequential(); +* // Use an inputShape that matches the input shape of `model1`'s second +* // layer. +* model2.add(tf.layers.inputLayer({inputShape: [3]})); +* model2.add(model1.layers[1]); +* model2.summary(); +* model2.predict(tf.zeros([1, 3])).print(); +* ``` +* +* @doc {heading: 'Layers', subheading: 'Inputs', namespace: 'layers'} +*/ +export function inputLayer(args: InputLayerArgs) { + return new InputLayer(args); +} + +// Advanced Activation Layers. + +/** +* Exponential Linear Unit (ELU). +* +* It follows: +* `f(x) = alpha * (exp(x) - 1.) for x < 0`, +* `f(x) = x for x >= 0`. +* +* Input shape: +* Arbitrary. Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* Output shape: +* Same shape as the input. +* +* References: +* - [Fast and Accurate Deep Network Learning by Exponential Linear Units +* (ELUs)](https://arxiv.org/abs/1511.07289v1) +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function elu(args?: ELULayerArgs) { + return new ELU(args); +} + +/** +* Rectified Linear Unit activation function. +* +* Input shape: +* Arbitrary. Use the config field `inputShape` (Array of integers, does +* not include the sample axis) when using this layer as the first layer +* in a model. +* +* Output shape: +* Same shape as the input. +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function reLU(args?: ReLULayerArgs) { + return new ReLU(args); +} + +/** +* Leaky version of a rectified linear unit. +* +* It allows a small gradient when the unit is not active: +* `f(x) = alpha * x for x < 0.` +* `f(x) = x for x >= 0.` +* +* Input shape: +* Arbitrary. Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* Output shape: +* Same shape as the input. +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function leakyReLU(args?: LeakyReLULayerArgs) { + return new LeakyReLU(args); +} + +/** +* Parameterized version of a leaky rectified linear unit. +* +* It follows +* `f(x) = alpha * x for x < 0.` +* `f(x) = x for x >= 0.` +* wherein `alpha` is a trainable weight. +* +* Input shape: +* Arbitrary. Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* Output shape: +* Same shape as the input. +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function prelu(args?: PReLULayerArgs) { + return new PReLU(args); +} + +/** +* Softmax activation layer. +* +* Input shape: +* Arbitrary. Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* Output shape: +* Same shape as the input. +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function softmax(args?: SoftmaxLayerArgs) { + return new Softmax(args); +} + +/** +* Thresholded Rectified Linear Unit. +* +* It follows: +* `f(x) = x for x > theta`, +* `f(x) = 0 otherwise`. +* +* Input shape: +* Arbitrary. Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* Output shape: +* Same shape as the input. +* +* References: +* - [Zero-Bias Autoencoders and the Benefits of Co-Adapting +* Features](http://arxiv.org/abs/1402.3337) +* +* @doc { +* heading: 'Layers', +* subheading: 'Advanced Activation', +* namespace: 'layers' +* } +*/ +export function thresholdedReLU(args?: ThresholdedReLULayerArgs) { + return new ThresholdedReLU(args); +} + +// Convolutional Layers. + +/** +* 1D convolution layer (e.g., temporal convolution). +* +* This layer creates a convolution kernel that is convolved +* with the layer input over a single spatial (or temporal) dimension +* to produce a tensor of outputs. +* +* If `use_bias` is True, a bias vector is created and added to the outputs. +* +* If `activation` is not `null`, it is applied to the outputs as well. +* +* When using this layer as the first layer in a model, provide an +* `inputShape` argument `Array` or `null`. +* +* For example, `inputShape` would be: +* - `[10, 128]` for sequences of 10 vectors of 128-dimensional vectors +* - `[null, 128]` for variable-length sequences of 128-dimensional vectors. +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function conv1d(args: ConvLayerArgs) { + return new Conv1D(args); +} + +/** +* 2D convolution layer (e.g. spatial convolution over images). +* +* This layer creates a convolution kernel that is convolved +* with the layer input to produce a tensor of outputs. +* +* If `useBias` is True, a bias vector is created and added to the outputs. +* +* If `activation` is not `null`, it is applied to the outputs as well. +* +* When using this layer as the first layer in a model, +* provide the keyword argument `inputShape` +* (Array of integers, does not include the sample axis), +* e.g. `inputShape=[128, 128, 3]` for 128x128 RGB pictures +* in `dataFormat='channelsLast'`. +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function conv2d(args: ConvLayerArgs) { + return new Conv2D(args); +} + +/** +* Transposed convolutional layer (sometimes called Deconvolution). +* +* The need for transposed convolutions generally arises +* from the desire to use a transformation going in the opposite direction of +* a normal convolution, i.e., from something that has the shape of the output +* of some convolution to something that has the shape of its input while +* maintaining a connectivity pattern that is compatible with said +* convolution. +* +* When using this layer as the first layer in a model, provide the +* configuration `inputShape` (`Array` of integers, does not include the +* sample axis), e.g., `inputShape: [128, 128, 3]` for 128x128 RGB pictures in +* `dataFormat: 'channelsLast'`. +* +* Input shape: +* 4D tensor with shape: +* `[batch, channels, rows, cols]` if `dataFormat` is `'channelsFirst'`. +* or 4D tensor with shape +* `[batch, rows, cols, channels]` if `dataFormat` is `'channelsLast'`. +* +* Output shape: +* 4D tensor with shape: +* `[batch, filters, newRows, newCols]` if `dataFormat` is +* `'channelsFirst'`. or 4D tensor with shape: +* `[batch, newRows, newCols, filters]` if `dataFormat` is `'channelsLast'`. +* +* References: +* - [A guide to convolution arithmetic for deep +* learning](https://arxiv.org/abs/1603.07285v1) +* - [Deconvolutional +* Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf) +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function conv2dTranspose(args: ConvLayerArgs) { + return new Conv2DTranspose(args); +} + +/** +* 3D convolution layer (e.g. spatial convolution over volumes). +* +* This layer creates a convolution kernel that is convolved +* with the layer input to produce a tensor of outputs. +* +* If `useBias` is True, a bias vector is created and added to the outputs. +* +* If `activation` is not `null`, it is applied to the outputs as well. +* +* When using this layer as the first layer in a model, +* provide the keyword argument `inputShape` +* (Array of integers, does not include the sample axis), +* e.g. `inputShape=[128, 128, 128, 1]` for 128x128x128 grayscale volumes +* in `dataFormat='channelsLast'`. +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function conv3d(args: ConvLayerArgs) { + return new Conv3D(args); +} + +export function conv3dTranspose(args: ConvLayerArgs): Layer { + return new Conv3DTranspose(args); +} + +/** +* Depthwise separable 2D convolution. +* +* Separable convolution consists of first performing +* a depthwise spatial convolution +* (which acts on each input channel separately) +* followed by a pointwise convolution which mixes together the resulting +* output channels. The `depthMultiplier` argument controls how many +* output channels are generated per input channel in the depthwise step. +* +* Intuitively, separable convolutions can be understood as +* a way to factorize a convolution kernel into two smaller kernels, +* or as an extreme version of an Inception block. +* +* Input shape: +* 4D tensor with shape: +* `[batch, channels, rows, cols]` if data_format='channelsFirst' +* or 4D tensor with shape: +* `[batch, rows, cols, channels]` if data_format='channelsLast'. +* +* Output shape: +* 4D tensor with shape: +* `[batch, filters, newRows, newCols]` if data_format='channelsFirst' +* or 4D tensor with shape: +* `[batch, newRows, newCols, filters]` if data_format='channelsLast'. +* `rows` and `cols` values might have changed due to padding. +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function separableConv2d(args: SeparableConvLayerArgs) { + return new SeparableConv2D(args); +} + +/** +* Cropping layer for 2D input (e.g., image). +* +* This layer can crop an input +* at the top, bottom, left and right side of an image tensor. +* +* Input shape: +* 4D tensor with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, rows, cols, channels]` +* - If `data_format` is `"channels_first"`: +* `[batch, channels, rows, cols]`. +* +* Output shape: +* 4D with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, croppedRows, croppedCols, channels]` +* - If `dataFormat` is `"channelsFirst"`: +* `[batch, channels, croppedRows, croppedCols]`. +* +* Examples +* ```js +* +* const model = tf.sequential(); +* model.add(tf.layers.cropping2D({cropping:[[2, 2], [2, 2]], +* inputShape: [128, 128, 3]})); +* //now output shape is [batch, 124, 124, 3] +* ``` +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function cropping2D(args: Cropping2DLayerArgs) { + return new Cropping2D(args); +} + +/** +* Upsampling layer for 2D inputs. +* +* Repeats the rows and columns of the data +* by size[0] and size[1] respectively. +* +* +* Input shape: +* 4D tensor with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, rows, cols, channels]` +* - If `dataFormat` is `"channelsFirst"`: +* `[batch, channels, rows, cols]` +* +* Output shape: +* 4D tensor with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, upsampledRows, upsampledCols, channels]` +* - If `dataFormat` is `"channelsFirst"`: +* `[batch, channels, upsampledRows, upsampledCols]` +* +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function upSampling2d(args: UpSampling2DLayerArgs) { + return new UpSampling2D(args); +} + +// Convolutional(depthwise) Layers. + +/** +* Depthwise separable 2D convolution. +* +* Depthwise Separable convolutions consists in performing just the first step +* in a depthwise spatial convolution (which acts on each input channel +* separately). The `depthMultiplier` argument controls how many output channels +* are generated per input channel in the depthwise step. +* +* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} +*/ +export function depthwiseConv2d(args: DepthwiseConv2DLayerArgs) { + return new DepthwiseConv2D(args); +} + +// Basic Layers. + +/** +* Applies an activation function to an output. +* +* This layer applies element-wise activation function. Other layers, notably +* `dense` can also apply activation functions. Use this isolated activation +* function to extract the values before and after the +* activation. For instance: +* +* ```js +* const input = tf.input({shape: [5]}); +* const denseLayer = tf.layers.dense({units: 1}); +* const activationLayer = tf.layers.activation({activation: 'relu6'}); +* +* // Obtain the output symbolic tensors by applying the layers in order. +* const denseOutput = denseLayer.apply(input); +* const activationOutput = activationLayer.apply(denseOutput); +* +* // Create the model based on the inputs. +* const model = tf.model({ +* inputs: input, +* outputs: [denseOutput, activationOutput] +* }); +* +* // Collect both outputs and print separately. +* const [denseOut, activationOut] = model.predict(tf.randomNormal([6, 5])); +* denseOut.print(); +* activationOut.print(); +* ``` +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function activation(args: ActivationLayerArgs) { + return new Activation(args); +} + +/** +* Creates a dense (fully connected) layer. +* +* This layer implements the operation: +* `output = activation(dot(input, kernel) + bias)` +* +* `activation` is the element-wise activation function +* passed as the `activation` argument. +* +* `kernel` is a weights matrix created by the layer. +* +* `bias` is a bias vector created by the layer (only applicable if `useBias` +* is `true`). +* +* **Input shape:** +* +* nD `tf.Tensor` with shape: `(batchSize, ..., inputDim)`. +* +* The most common situation would be +* a 2D input with shape `(batchSize, inputDim)`. +* +* **Output shape:** +* +* nD tensor with shape: `(batchSize, ..., units)`. +* +* For instance, for a 2D input with shape `(batchSize, inputDim)`, +* the output would have shape `(batchSize, units)`. +* +* Note: if the input to the layer has a rank greater than 2, then it is +* flattened prior to the initial dot product with the kernel. +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function dense(args: DenseLayerArgs) { + return new Dense(args); +} + +/** +* Applies +* [dropout](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) to +* the input. +* +* Dropout consists in randomly setting a fraction `rate` of input units to 0 at +* each update during training time, which helps prevent overfitting. +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function dropout(args: DropoutLayerArgs) { + return new Dropout(args); +} + +/** +* Spatial 1D version of Dropout. +* +* This Layer type performs the same function as the Dropout layer, but it drops +* entire 1D feature maps instead of individual elements. For example, if an +* input example consists of 3 timesteps and the feature map for each timestep +* has a size of 4, a `spatialDropout1d` layer may zero out the feature maps +* of the 1st timesteps and 2nd timesteps completely while sparing all feature +* elements of the 3rd timestep. +* +* If adjacent frames (timesteps) are strongly correlated (as is normally the +* case in early convolution layers), regular dropout will not regularize the +* activation and will otherwise just result in merely an effective learning +* rate decrease. In this case, `spatialDropout1d` will help promote +* independence among feature maps and should be used instead. +* +* **Arguments:** +* rate: A floating-point number >=0 and <=1. Fraction of the input elements +* to drop. +* +* **Input shape:** +* 3D tensor with shape `(samples, timesteps, channels)`. +* +* **Output shape:** +* Same as the input shape. +* +* References: +* - [Efficient Object Localization Using Convolutional +* Networks](https://arxiv.org/abs/1411.4280) +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function spatialDropout1d(args: SpatialDropout1DLayerConfig) { + return new SpatialDropout1D(args); +} + +/** +* Flattens the input. Does not affect the batch size. +* +* A `Flatten` layer flattens each batch in its inputs to 1D (making the output +* 2D). +* +* For example: +* +* ```js +* const input = tf.input({shape: [4, 3]}); +* const flattenLayer = tf.layers.flatten(); +* // Inspect the inferred output shape of the flatten layer, which +* // equals `[null, 12]`. The 2nd dimension is 4 * 3, i.e., the result of the +* // flattening. (The 1st dimension is the undermined batch size.) +* console.log(JSON.stringify(flattenLayer.apply(input).shape)); +* ``` +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function flatten(args?: FlattenLayerArgs) { + return new Flatten(args); +} + +/** +* Repeats the input n times in a new dimension. +* +* ```js +* const model = tf.sequential(); +* model.add(tf.layers.repeatVector({n: 4, inputShape: [2]})); +* const x = tf.tensor2d([[10, 20]]); +* // Use the model to do inference on a data point the model hasn't see +* model.predict(x).print(); +* // output shape is now [batch, 2, 4] +* ``` +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function repeatVector(args: RepeatVectorLayerArgs) { + return new RepeatVector(args); +} + +/** +* Reshapes an input to a certain shape. +* +* ```js +* const input = tf.input({shape: [4, 3]}); +* const reshapeLayer = tf.layers.reshape({targetShape: [2, 6]}); +* // Inspect the inferred output shape of the Reshape layer, which +* // equals `[null, 2, 6]`. (The 1st dimension is the undermined batch size.) +* console.log(JSON.stringify(reshapeLayer.apply(input).shape)); +* ``` +* +* Input shape: +* Arbitrary, although all dimensions in the input shape must be fixed. +* Use the configuration `inputShape` when using this layer as the +* first layer in a model. +* +* +* Output shape: +* [batchSize, targetShape[0], targetShape[1], ..., +* targetShape[targetShape.length - 1]]. +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function reshape(args: ReshapeLayerArgs) { + return new Reshape(args); +} + +/** +* Permutes the dimensions of the input according to a given pattern. +* +* Useful for, e.g., connecting RNNs and convnets together. +* +* Example: +* +* ```js +* const model = tf.sequential(); +* model.add(tf.layers.permute({ +* dims: [2, 1], +* inputShape: [10, 64] +* })); +* console.log(model.outputShape); +* // Now model's output shape is [null, 64, 10], where null is the +* // unpermuted sample (batch) dimension. +* ``` +* +* Input shape: +* Arbitrary. Use the configuration field `inputShape` when using this +* layer as the first layer in a model. +* +* Output shape: +* Same rank as the input shape, but with the dimensions re-ordered (i.e., +* permuted) according to the `dims` configuration of this layer. +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function permute(args: PermuteLayerArgs) { + return new Permute(args); +} + +/** +* Maps positive integers (indices) into dense vectors of fixed size. +* E.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] +* +* **Input shape:** 2D tensor with shape: `[batchSize, sequenceLength]`. +* +* **Output shape:** 3D tensor with shape: `[batchSize, sequenceLength, +* outputDim]`. +* +* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} +*/ +export function embedding(args: EmbeddingLayerArgs) { + return new Embedding(args); +} + +// Merge Layers. + +/** +* Layer that performs element-wise addition on an `Array` of inputs. +* +* It takes as input a list of tensors, all of the same shape, and returns a +* single tensor (also of the same shape). The inputs are specified as an +* `Array` when the `apply` method of the `Add` layer instance is called. For +* example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 2]}); +* const addLayer = tf.layers.add(); +* const sum = addLayer.apply([input1, input2]); +* console.log(JSON.stringify(sum.shape)); +* // You get [null, 2, 2], with the first dimension as the undetermined batch +* // dimension. +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function add(args?: LayerArgs) { + return new Add(args); +} + +/** +* Layer that performs element-wise averaging on an `Array` of inputs. +* +* It takes as input a list of tensors, all of the same shape, and returns a +* single tensor (also of the same shape). For example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 2]}); +* const averageLayer = tf.layers.average(); +* const average = averageLayer.apply([input1, input2]); +* console.log(JSON.stringify(average.shape)); +* // You get [null, 2, 2], with the first dimension as the undetermined batch +* // dimension. +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function average(args?: LayerArgs) { + return new Average(args); +} + +/** +* Layer that concatenates an `Array` of inputs. +* +* It takes a list of tensors, all of the same shape except for the +* concatenation axis, and returns a single tensor, the concatenation +* of all inputs. For example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 3]}); +* const concatLayer = tf.layers.concatenate(); +* const output = concatLayer.apply([input1, input2]); +* console.log(JSON.stringify(output.shape)); +* // You get [null, 2, 5], with the first dimension as the undetermined batch +* // dimension. The last dimension (5) is the result of concatenating the +* // last dimensions of the inputs (2 and 3). +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function concatenate(args?: ConcatenateLayerArgs) { + return new Concatenate(args); +} + +/** +* Layer that computes the element-wise maximum of an `Array` of inputs. +* +* It takes as input a list of tensors, all of the same shape, and returns a +* single tensor (also of the same shape). For example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 2]}); +* const maxLayer = tf.layers.maximum(); +* const max = maxLayer.apply([input1, input2]); +* console.log(JSON.stringify(max.shape)); +* // You get [null, 2, 2], with the first dimension as the undetermined batch +* // dimension. +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function maximum(args?: LayerArgs) { + return new Maximum(args); +} + +/** +* Layer that computes the element-wise minimum of an `Array` of inputs. +* +* It takes as input a list of tensors, all of the same shape, and returns a +* single tensor (also of the same shape). For example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 2]}); +* const minLayer = tf.layers.minimum(); +* const min = minLayer.apply([input1, input2]); +* console.log(JSON.stringify(min.shape)); +* // You get [null, 2, 2], with the first dimension as the undetermined batch +* // dimension. +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function minimum(args?: LayerArgs) { + return new Minimum(args); +} + +/** +* Layer that multiplies (element-wise) an `Array` of inputs. +* +* It takes as input an Array of tensors, all of the same +* shape, and returns a single tensor (also of the same shape). +* For example: +* +* ```js +* const input1 = tf.input({shape: [2, 2]}); +* const input2 = tf.input({shape: [2, 2]}); +* const input3 = tf.input({shape: [2, 2]}); +* const multiplyLayer = tf.layers.multiply(); +* const product = multiplyLayer.apply([input1, input2, input3]); +* console.log(product.shape); +* // You get [null, 2, 2], with the first dimension as the undetermined batch +* // dimension. +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function multiply(args?: LayerArgs) { + return new Multiply(args); +} + +/** +* Layer that computes a dot product between samples in two tensors. +* +* E.g., if applied to a list of two tensors `a` and `b` both of shape +* `[batchSize, n]`, the output will be a tensor of shape `[batchSize, 1]`, +* where each entry at index `[i, 0]` will be the dot product between +* `a[i, :]` and `b[i, :]`. +* +* Example: +* +* ```js +* const dotLayer = tf.layers.dot({axes: -1}); +* const x1 = tf.tensor2d([[10, 20], [30, 40]]); +* const x2 = tf.tensor2d([[-1, -2], [-3, -4]]); +* +* // Invoke the layer's apply() method in eager (imperative) mode. +* const y = dotLayer.apply([x1, x2]); +* y.print(); +* ``` +* +* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} +*/ +export function dot(args: DotLayerArgs) { + return new Dot(args); +} + +// Normalization Layers. + +/** +* Batch normalization layer (Ioffe and Szegedy, 2014). +* +* Normalize the activations of the previous layer at each batch, +* i.e. applies a transformation that maintains the mean activation +* close to 0 and the activation standard deviation close to 1. +* +* Input shape: +* Arbitrary. Use the keyword argument `inputShape` (Array of integers, does +* not include the sample axis) when calling the constructor of this class, +* if this layer is used as a first layer in a model. +* +* Output shape: +* Same shape as input. +* +* References: +* - [Batch Normalization: Accelerating Deep Network Training by Reducing +* Internal Covariate Shift](https://arxiv.org/abs/1502.03167) +* +* @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} +*/ +export function batchNormalization(args?: BatchNormalizationLayerArgs) { + return new BatchNormalization(args); +} + +/** +* Layer-normalization layer (Ba et al., 2016). +* +* Normalizes the activations of the previous layer for each given example in a +* batch independently, instead of across a batch like in `batchNormalization`. +* In other words, this layer applies a transformation that maintains the mean +* activation within each example close to 0 and activation variance close to 1. +* +* Input shape: +* Arbitrary. Use the argument `inputShape` when using this layer as the first +* layer in a model. +* +* Output shape: +* Same as input. +* +* References: +* - [Layer Normalization](https://arxiv.org/abs/1607.06450) +* +* @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} +*/ +export function layerNormalization(args?: LayerNormalizationLayerArgs) { + return new LayerNormalization(args); +} + +// Padding Layers. + +/** +* Zero-padding layer for 2D input (e.g., image). +* +* This layer can add rows and columns of zeros +* at the top, bottom, left and right side of an image tensor. +* +* Input shape: +* 4D tensor with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, rows, cols, channels]` +* - If `data_format` is `"channels_first"`: +* `[batch, channels, rows, cols]`. +* +* Output shape: +* 4D with shape: +* - If `dataFormat` is `"channelsLast"`: +* `[batch, paddedRows, paddedCols, channels]` +* - If `dataFormat` is `"channelsFirst"`: +* `[batch, channels, paddedRows, paddedCols]`. +* +* @doc {heading: 'Layers', subheading: 'Padding', namespace: 'layers'} +*/ +export function zeroPadding2d(args?: ZeroPadding2DLayerArgs) { + return new ZeroPadding2D(args); +} + +// Pooling Layers. + +/** +* Average pooling operation for spatial data. +* +* Input shape: `[batchSize, inLength, channels]` +* +* Output shape: `[batchSize, pooledLength, channels]` +* +* `tf.avgPool1d` is an alias. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function averagePooling1d(args: Pooling1DLayerArgs) { + return new AveragePooling1D(args); +} +export function avgPool1d(args: Pooling1DLayerArgs) { + return averagePooling1d(args); +} +// For backwards compatibility. +// See https://github.com/tensorflow/tfjs/issues/152 +export function avgPooling1d(args: Pooling1DLayerArgs) { + return averagePooling1d(args); +} + +/** +* Average pooling operation for spatial data. +* +* Input shape: +* - If `dataFormat === CHANNEL_LAST`: +* 4D tensor with shape: +* `[batchSize, rows, cols, channels]` +* - If `dataFormat === CHANNEL_FIRST`: +* 4D tensor with shape: +* `[batchSize, channels, rows, cols]` +* +* Output shape +* - If `dataFormat === CHANNEL_LAST`: +* 4D tensor with shape: +* `[batchSize, pooledRows, pooledCols, channels]` +* - If `dataFormat === CHANNEL_FIRST`: +* 4D tensor with shape: +* `[batchSize, channels, pooledRows, pooledCols]` +* +* `tf.avgPool2d` is an alias. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function averagePooling2d(args: Pooling2DLayerArgs) { + return new AveragePooling2D(args); +} +export function avgPool2d(args: Pooling2DLayerArgs) { + return averagePooling2d(args); +} +// For backwards compatibility. +// See https://github.com/tensorflow/tfjs/issues/152 +export function avgPooling2d(args: Pooling2DLayerArgs) { + return averagePooling2d(args); +} + +/** +* Average pooling operation for 3D data. +* +* Input shape +* - If `dataFormat === channelsLast`: +* 5D tensor with shape: +* `[batchSize, depths, rows, cols, channels]` +* - If `dataFormat === channelsFirst`: +* 4D tensor with shape: +* `[batchSize, channels, depths, rows, cols]` +* +* Output shape +* - If `dataFormat=channelsLast`: +* 5D tensor with shape: +* `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` +* - If `dataFormat=channelsFirst`: +* 5D tensor with shape: +* `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function averagePooling3d(args: Pooling3DLayerArgs) { + return new AveragePooling3D(args); +} +export function avgPool3d(args: Pooling3DLayerArgs) { + return averagePooling3d(args); +} +// For backwards compatibility. +// See https://github.com/tensorflow/tfjs/issues/152 +export function avgPooling3d(args: Pooling3DLayerArgs) { + return averagePooling3d(args); +} + +/** +* Global average pooling operation for temporal data. +* +* Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. +* +* Output Shape: 2D tensor with shape: `[batchSize, features]`. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function globalAveragePooling1d(args?: LayerArgs) { + return new GlobalAveragePooling1D(args); +} + +/** +* Global average pooling operation for spatial data. +* +* Input shape: +* - If `dataFormat` is `CHANNEL_LAST`: +* 4D tensor with shape: `[batchSize, rows, cols, channels]`. +* - If `dataFormat` is `CHANNEL_FIRST`: +* 4D tensor with shape: `[batchSize, channels, rows, cols]`. +* +* Output shape: +* 2D tensor with shape: `[batchSize, channels]`. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function globalAveragePooling2d(args: GlobalPooling2DLayerArgs) { + return new GlobalAveragePooling2D(args); +} + +/** +* Global max pooling operation for temporal data. +* +* Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. +* +* Output Shape: 2D tensor with shape: `[batchSize, features]`. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function globalMaxPooling1d(args?: LayerArgs) { + return new GlobalMaxPooling1D(args); +} + +/** +* Global max pooling operation for spatial data. +* +* Input shape: +* - If `dataFormat` is `CHANNEL_LAST`: +* 4D tensor with shape: `[batchSize, rows, cols, channels]`. +* - If `dataFormat` is `CHANNEL_FIRST`: +* 4D tensor with shape: `[batchSize, channels, rows, cols]`. +* +* Output shape: +* 2D tensor with shape: `[batchSize, channels]`. +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function globalMaxPooling2d(args: GlobalPooling2DLayerArgs) { + return new GlobalMaxPooling2D(args); +} + +/** +* Max pooling operation for temporal data. +* +* Input shape: `[batchSize, inLength, channels]` +* +* Output shape: `[batchSize, pooledLength, channels]` +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function maxPooling1d(args: Pooling1DLayerArgs) { + return new MaxPooling1D(args); +} + +/** +* Max pooling operation for spatial data. +* +* Input shape +* - If `dataFormat === CHANNEL_LAST`: +* 4D tensor with shape: +* `[batchSize, rows, cols, channels]` +* - If `dataFormat === CHANNEL_FIRST`: +* 4D tensor with shape: +* `[batchSize, channels, rows, cols]` +* +* Output shape +* - If `dataFormat=CHANNEL_LAST`: +* 4D tensor with shape: +* `[batchSize, pooledRows, pooledCols, channels]` +* - If `dataFormat=CHANNEL_FIRST`: +* 4D tensor with shape: +* `[batchSize, channels, pooledRows, pooledCols]` +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function maxPooling2d(args: Pooling2DLayerArgs) { + return new MaxPooling2D(args); +} + +/** +* Max pooling operation for 3D data. +* +* Input shape +* - If `dataFormat === channelsLast`: +* 5D tensor with shape: +* `[batchSize, depths, rows, cols, channels]` +* - If `dataFormat === channelsFirst`: +* 5D tensor with shape: +* `[batchSize, channels, depths, rows, cols]` +* +* Output shape +* - If `dataFormat=channelsLast`: +* 5D tensor with shape: +* `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` +* - If `dataFormat=channelsFirst`: +* 5D tensor with shape: +* `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` +* +* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} +*/ +export function maxPooling3d(args: Pooling3DLayerArgs) { + return new MaxPooling3D(args); +} + +// Recurrent Layers. + +/** +* Gated Recurrent Unit - Cho et al. 2014. +* +* This is an `RNN` layer consisting of one `GRUCell`. However, unlike +* the underlying `GRUCell`, the `apply` method of `SimpleRNN` operates +* on a sequence of inputs. The shape of the input (not including the first, +* batch dimension) needs to be at least 2-D, with the first dimension being +* time steps. For example: +* +* ```js +* const rnn = tf.layers.gru({units: 8, returnSequences: true}); +* +* // Create an input with 10 time steps. +* const input = tf.input({shape: [10, 20]}); +* const output = rnn.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the `GRUCell`'s number of units. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function gru(args: GRULayerArgs) { + return new GRU(args); +} + +/** +* Cell class for `GRU`. +* +* `GRUCell` is distinct from the `RNN` subclass `GRU` in that its +* `apply` method takes the input data of only a single time step and returns +* the cell's output at the time step, while `GRU` takes the input data +* over a number of time steps. For example: +* +* ```js +* const cell = tf.layers.gruCell({units: 2}); +* const input = tf.input({shape: [10]}); +* const output = cell.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10]: This is the cell's output at a single time step. The 1st +* // dimension is the unknown batch size. +* ``` +* +* Instance(s) of `GRUCell` can be used to construct `RNN` layers. The +* most typical use of this workflow is to combine a number of cells into a +* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an +* RNN. For example: +* +* ```js +* const cells = [ +* tf.layers.gruCell({units: 4}), +* tf.layers.gruCell({units: 8}), +* ]; +* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); +* +* // Create an input with 10 time steps and a length-20 vector at each step. +* const input = tf.input({shape: [10, 20]}); +* const output = rnn.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the last `gruCell`'s number of units. +* ``` +* +* To create an `RNN` consisting of only *one* `GRUCell`, use the +* `tf.layers.gru`. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function gruCell(args: GRUCellLayerArgs) { + return new GRUCell(args); +} + +/** +* Long-Short Term Memory layer - Hochreiter 1997. +* +* This is an `RNN` layer consisting of one `LSTMCell`. However, unlike +* the underlying `LSTMCell`, the `apply` method of `LSTM` operates +* on a sequence of inputs. The shape of the input (not including the first, +* batch dimension) needs to be at least 2-D, with the first dimension being +* time steps. For example: +* +* ```js +* const lstm = tf.layers.lstm({units: 8, returnSequences: true}); +* +* // Create an input with 10 time steps. +* const input = tf.input({shape: [10, 20]}); +* const output = lstm.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the `LSTMCell`'s number of units. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function lstm(args: LSTMLayerArgs) { + return new LSTM(args); +} + +/** +* Cell class for `LSTM`. +* +* `LSTMCell` is distinct from the `RNN` subclass `LSTM` in that its +* `apply` method takes the input data of only a single time step and returns +* the cell's output at the time step, while `LSTM` takes the input data +* over a number of time steps. For example: +* +* ```js +* const cell = tf.layers.lstmCell({units: 2}); +* const input = tf.input({shape: [10]}); +* const output = cell.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10]: This is the cell's output at a single time step. The 1st +* // dimension is the unknown batch size. +* ``` +* +* Instance(s) of `LSTMCell` can be used to construct `RNN` layers. The +* most typical use of this workflow is to combine a number of cells into a +* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an +* RNN. For example: +* +* ```js +* const cells = [ +* tf.layers.lstmCell({units: 4}), +* tf.layers.lstmCell({units: 8}), +* ]; +* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); +* +* // Create an input with 10 time steps and a length-20 vector at each step. +* const input = tf.input({shape: [10, 20]}); +* const output = rnn.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the last `lstmCell`'s number of units. +* ``` +* +* To create an `RNN` consisting of only *one* `LSTMCell`, use the +* `tf.layers.lstm`. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function lstmCell(args: LSTMCellLayerArgs) { + return new LSTMCell(args); +} + +/** +* Fully-connected RNN where the output is to be fed back to input. +* +* This is an `RNN` layer consisting of one `SimpleRNNCell`. However, unlike +* the underlying `SimpleRNNCell`, the `apply` method of `SimpleRNN` operates +* on a sequence of inputs. The shape of the input (not including the first, +* batch dimension) needs to be at least 2-D, with the first dimension being +* time steps. For example: +* +* ```js +* const rnn = tf.layers.simpleRNN({units: 8, returnSequences: true}); +* +* // Create an input with 10 time steps. +* const input = tf.input({shape: [10, 20]}); +* const output = rnn.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the `SimpleRNNCell`'s number of units. +* ``` +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function simpleRNN(args: SimpleRNNLayerArgs) { + return new SimpleRNN(args); +} + +/** +* Cell class for `SimpleRNN`. +* +* `SimpleRNNCell` is distinct from the `RNN` subclass `SimpleRNN` in that its +* `apply` method takes the input data of only a single time step and returns +* the cell's output at the time step, while `SimpleRNN` takes the input data +* over a number of time steps. For example: +* +* ```js +* const cell = tf.layers.simpleRNNCell({units: 2}); +* const input = tf.input({shape: [10]}); +* const output = cell.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10]: This is the cell's output at a single time step. The 1st +* // dimension is the unknown batch size. +* ``` +* +* Instance(s) of `SimpleRNNCell` can be used to construct `RNN` layers. The +* most typical use of this workflow is to combine a number of cells into a +* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an +* RNN. For example: +* +* ```js +* const cells = [ +* tf.layers.simpleRNNCell({units: 4}), +* tf.layers.simpleRNNCell({units: 8}), +* ]; +* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); +* +* // Create an input with 10 time steps and a length-20 vector at each step. +* const input = tf.input({shape: [10, 20]}); +* const output = rnn.apply(input); +* +* console.log(JSON.stringify(output.shape)); +* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the +* // same as the sequence length of `input`, due to `returnSequences`: `true`; +* // 3rd dimension is the last `SimpleRNNCell`'s number of units. +* ``` +* +* To create an `RNN` consisting of only *one* `SimpleRNNCell`, use the +* `tf.layers.simpleRNN`. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function simpleRNNCell(args: SimpleRNNCellLayerArgs) { + return new SimpleRNNCell(args); +} + +/** +* Convolutional LSTM layer - Xingjian Shi 2015. +* +* This is a `ConvRNN2D` layer consisting of one `ConvLSTM2DCell`. However, +* unlike the underlying `ConvLSTM2DCell`, the `apply` method of `ConvLSTM2D` +* operates on a sequence of inputs. The shape of the input (not including the +* first, batch dimension) needs to be 4-D, with the first dimension being time +* steps. For example: +* +* ```js +* const filters = 3; +* const kernelSize = 3; +* +* const batchSize = 4; +* const sequenceLength = 2; +* const size = 5; +* const channels = 3; +* +* const inputShape = [batchSize, sequenceLength, size, size, channels]; +* const input = tf.ones(inputShape); +* +* const layer = tf.layers.convLstm2d({filters, kernelSize}); +* +* const output = layer.apply(input); +* ``` +*/ +/** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ +export function convLstm2d(args: ConvLSTM2DArgs) { + return new ConvLSTM2D(args); +} + +/** +* Cell class for `ConvLSTM2D`. +* +* `ConvLSTM2DCell` is distinct from the `ConvRNN2D` subclass `ConvLSTM2D` in +* that its `call` method takes the input data of only a single time step and +* returns the cell's output at the time step, while `ConvLSTM2D` takes the +* input data over a number of time steps. For example: +* +* ```js +* const filters = 3; +* const kernelSize = 3; +* +* const sequenceLength = 1; +* const size = 5; +* const channels = 3; +* +* const inputShape = [sequenceLength, size, size, channels]; +* const input = tf.ones(inputShape); +* +* const cell = tf.layers.convLstm2dCell({filters, kernelSize}); +* +* cell.build(input.shape); +* +* const outputSize = size - kernelSize + 1; +* const outShape = [sequenceLength, outputSize, outputSize, filters]; +* +* const initialH = tf.zeros(outShape); +* const initialC = tf.zeros(outShape); +* +* const [o, h, c] = cell.call([input, initialH, initialC], {}); +* ``` +*/ +/** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ +export function convLstm2dCell(args: ConvLSTM2DCellArgs) { + return new ConvLSTM2DCell(args); +} + +/** +* Base class for recurrent layers. +* +* Input shape: +* 3D tensor with shape `[batchSize, timeSteps, inputDim]`. +* +* Output shape: +* - if `returnState`, an Array of tensors (i.e., `tf.Tensor`s). The first +* tensor is the output. The remaining tensors are the states at the +* last time step, each with shape `[batchSize, units]`. +* - if `returnSequences`, the output will have shape +* `[batchSize, timeSteps, units]`. +* - else, the output will have shape `[batchSize, units]`. +* +* Masking: +* This layer supports masking for input data with a variable number +* of timesteps. To introduce masks to your data, +* use an embedding layer with the `mask_zero` parameter +* set to `True`. +* +* Notes on using statefulness in RNNs: +* You can set RNN layers to be 'stateful', which means that the states +* computed for the samples in one batch will be reused as initial states +* for the samples in the next batch. This assumes a one-to-one mapping +* between samples in different successive batches. +* +* To enable statefulness: +* - specify `stateful: true` in the layer constructor. +* - specify a fixed batch size for your model, by passing +* if sequential model: +* `batchInputShape=[...]` to the first layer in your model. +* else for functional model with 1 or more Input layers: +* `batchShape=[...]` to all the first layers in your model. +* This is the expected shape of your inputs *including the batch size*. +* It should be a tuple of integers, e.g. `(32, 10, 100)`. +* - specify `shuffle=False` when calling fit(). +* +* To reset the states of your model, call `.resetStates()` on either +* a specific layer, or on your entire model. +* +* Note on specifying the initial state of RNNs +* You can specify the initial state of RNN layers symbolically by +* calling them with the option `initialState`. The value of +* `initialState` should be a tensor or list of tensors representing +* the initial state of the RNN layer. +* +* You can specify the initial state of RNN layers numerically by +* calling `resetStates` with the keyword argument `states`. The value of +* `states` should be a numpy array or list of numpy arrays representing +* the initial state of the RNN layer. +* +* Note on passing external constants to RNNs +* You can pass "external" constants to the cell using the `constants` +* keyword argument of `RNN.call` method. This requires that the `cell.call` +* method accepts the same keyword argument `constants`. Such constants +* can be used to condition the cell transformation on additional static +* inputs (not changing over time), a.k.a. an attention mechanism. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function rnn(args: RNNLayerArgs) { + return new RNN(args); +} + +/** +* Wrapper allowing a stack of RNN cells to behave as a single cell. +* +* Used to implement efficient stacked RNNs. +* +* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} +*/ +export function stackedRNNCells(args: StackedRNNCellsArgs){ + return new StackedRNNCells(args); +} + +// Wrapper Layers. + +/** @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} */ +export function bidirectional(args: BidirectionalLayerArgs) { + return new Bidirectional(args); +} + +/** +* This wrapper applies a layer to every temporal slice of an input. +* +* The input should be at least 3D, and the dimension of the index `1` will be +* considered to be the temporal dimension. +* +* Consider a batch of 32 samples, where each sample is a sequence of 10 vectors +* of 16 dimensions. The batch input shape of the layer is then `[32, 10, +* 16]`, and the `inputShape`, not including the sample dimension, is +* `[10, 16]`. +* +* You can then use `TimeDistributed` to apply a `Dense` layer to each of the 10 +* timesteps, independently: +* +* ```js +* const model = tf.sequential(); +* model.add(tf.layers.timeDistributed({ +* layer: tf.layers.dense({units: 8}), +* inputShape: [10, 16], +* })); +* +* // Now model.outputShape = [null, 10, 8]. +* // The output will then have shape `[32, 10, 8]`. +* +* // In subsequent layers, there is no need for `inputShape`: +* model.add(tf.layers.timeDistributed({layer: tf.layers.dense({units: 32})})); +* console.log(JSON.stringify(model.outputs[0].shape)); +* // Now model.outputShape = [null, 10, 32]. +* ``` +* +* The output will then have shape `[32, 10, 32]`. +* +* `TimeDistributed` can be used with arbitrary layers, not just `Dense`, for +* instance a `Conv2D` layer. +* +* ```js +* const model = tf.sequential(); +* model.add(tf.layers.timeDistributed({ +* layer: tf.layers.conv2d({filters: 64, kernelSize: [3, 3]}), +* inputShape: [10, 299, 299, 3], +* })); +* console.log(JSON.stringify(model.outputs[0].shape)); +* ``` +* +* @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} +*/ +export function timeDistributed(args: WrapperLayerArgs) { + return new TimeDistributed(args); +} + +// Aliases for pooling. +export const globalMaxPool1d = globalMaxPooling1d; +export const globalMaxPool2d = globalMaxPooling2d; +export const maxPool1d = maxPooling1d; +export const maxPool2d = maxPooling2d; + +export {Layer, RNN, RNNCell, input /* alias for tf.input */}; + +/** +* Apply additive zero-centered Gaussian noise. +* +* As it is a regularization layer, it is only active at training time. +* +* This is useful to mitigate overfitting +* (you could see it as a form of random data augmentation). +* Gaussian Noise (GS) is a natural choice as corruption process +* for real valued inputs. +* +* # Arguments +* stddev: float, standard deviation of the noise distribution. +* +* # Input shape +* Arbitrary. Use the keyword argument `input_shape` +* (tuple of integers, does not include the samples axis) +* when using this layer as the first layer in a model. +* +* # Output shape +* Same shape as input. +* +* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} +*/ +export function gaussianNoise(args: GaussianNoiseArgs) { + return new GaussianNoise(args); +} + +/** +* Apply multiplicative 1-centered Gaussian noise. +* +* As it is a regularization layer, it is only active at training time. +* +* Arguments: +* - `rate`: float, drop probability (as with `Dropout`). +* The multiplicative noise will have +* standard deviation `sqrt(rate / (1 - rate))`. +* +* Input shape: +* Arbitrary. Use the keyword argument `inputShape` +* (tuple of integers, does not include the samples axis) +* when using this layer as the first layer in a model. +* +* Output shape: +* Same shape as input. +* +* References: +* - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting]( +* http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) +* +* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} +*/ +export function gaussianDropout(args: GaussianDropoutArgs) { + return new GaussianDropout(args); +} + +/** +* Applies Alpha Dropout to the input. +* +* As it is a regularization layer, it is only active at training time. +* +* Alpha Dropout is a `Dropout` that keeps mean and variance of inputs +* to their original values, in order to ensure the self-normalizing property +* even after this dropout. +* Alpha Dropout fits well to Scaled Exponential Linear Units +* by randomly setting activations to the negative saturation value. +* +* Arguments: +* - `rate`: float, drop probability (as with `Dropout`). +* The multiplicative noise will have +* standard deviation `sqrt(rate / (1 - rate))`. +* - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the +* shape for randomly generated keep/drop flags. +* +* Input shape: +* Arbitrary. Use the keyword argument `inputShape` +* (tuple of integers, does not include the samples axis) +* when using this layer as the first layer in a model. +* +* Output shape: +* Same shape as input. +* +* References: +* - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) +* +* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} +*/ +export function alphaDropout(args: AlphaDropoutArgs) { + return new AlphaDropout(args); +} + +/** +* Masks a sequence by using a mask value to skip timesteps. +* +* If all features for a given sample timestep are equal to `mask_value`, +* then the sample timestep will be masked (skipped) in all downstream layers +* (as long as they support masking). +* +* If any downstream layer does not support masking yet receives such +* an input mask, an exception will be raised. +* +* Arguments: +* - `maskValue`: Either None or mask value to skip. +* +* Input shape: +* Arbitrary. Use the keyword argument `inputShape` +* (tuple of integers, does not include the samples axis) +* when using this layer as the first layer in a model. +* +* Output shape: +* Same shape as input. +* +* @doc {heading: 'Layers', subheading: 'Mask', namespace: 'layers'} +*/ +export function masking(args?: MaskingArgs) { + return new Masking(args); +} + +/** +* A preprocessing layer which rescales input values to a new range. +* +* This layer rescales every value of an input (often an image) by multiplying +* by `scale` and adding `offset`. +* +* For instance: +* 1. To rescale an input in the ``[0, 255]`` range +* to be in the `[0, 1]` range, you would pass `scale=1/255`. +* 2. To rescale an input in the ``[0, 255]`` range to be in the `[-1, 1]` +* range, you would pass `scale=1./127.5, offset=-1`. +* The rescaling is applied both during training and inference. Inputs can be +* of integer or floating point dtype, and by default the layer will output +* floats. +* +* Arguments: +* - `scale`: Float, the scale to apply to the inputs. +* - `offset`: Float, the offset to apply to the inputs. +* +* Input shape: +* Arbitrary. +* +* Output shape: +* Same as input. +* +* @doc {heading: 'Layers', subheading: 'Rescaling', namespace: 'layers'} +*/ +export function rescaling(args?: RescalingArgs) { + return new Rescaling(args); +} diff --git a/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts b/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts index 1b9ec0bd955..2bfe0ebce4e 100644 --- a/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts +++ b/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts @@ -8,58 +8,60 @@ * ============================================================================= */ - import {LayerArgs, Layer} from '../../engine/topology' - import { serialization, Tensor} from '@tensorflow/tfjs-core'; - import { getExactlyOneTensor } from '../../utils/types_utils'; - import * as K from '../../backend/tfjs_backend'; - import { mul, add } from "@tensorflow/tfjs-core"; - import { Kwargs } from "../../types"; +import {LayerArgs, Layer} from '../../engine/topology' +import { serialization, Tensor} from '@tensorflow/tfjs-core'; +import { getExactlyOneTensor } from '../../utils/types_utils'; +import * as K from '../../backend/tfjs_backend'; +import { mul, add, tidy } from "@tensorflow/tfjs-core"; +import { Kwargs } from "../../types"; - export declare interface RescalingArgs extends LayerArgs { - scale: number; - offset?: number - } +export declare interface RescalingArgs extends LayerArgs { + scale: number; + offset?: number +} - /** - * Preprocessing Rescaling Layer - * - * This rescales images by a scaling and offset factor - */ - export class Rescaling extends Layer { - /** @nocollapse */ - static className = "Rescaling"; - private readonly scale: number; - private readonly offset: number; - constructor(args: RescalingArgs) { - super(args); +/** +* Preprocessing Rescaling Layer +* +* This rescales images by a scaling and offset factor +*/ +export class Rescaling extends Layer { + /** @nocollapse */ + static className = "Rescaling"; + private readonly scale: number; + private readonly offset: number; + constructor(args: RescalingArgs) { + super(args); - this.scale = args.scale; + this.scale = args.scale; - if(args.offset) { - this.offset = args.offset; - } else { - this.offset = 0; - } - } + if(args.offset) { + this.offset = args.offset; + } else { + this.offset = 0; + } + } - getConfig(): serialization.ConfigDict { - const config: serialization.ConfigDict = { - "scale": this.scale, - "offset": this.offset - }; + getConfig(): serialization.ConfigDict { + const config: serialization.ConfigDict = { + "scale": this.scale, + "offset": this.offset + }; - const baseConfig = super.getConfig(); - Object.assign(config, baseConfig); - return config; - } + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } - call(inputs: Tensor|Tensor[], kwargs: Kwargs): Tensor[]|Tensor { - inputs = getExactlyOneTensor(inputs); - if(inputs.dtype != 'float32') { - inputs = K.cast(inputs, "float32"); - } - return add(mul(inputs, this.scale), this.offset) - } - } + call(inputs: Tensor|Tensor[], kwargs: Kwargs): Tensor[]|Tensor { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + if(inputs.dtype != 'float32') { + inputs = K.cast(inputs, "float32"); + } + return add(mul(inputs, this.scale), this.offset); + }); + } +} - serialization.registerClass(Rescaling); +serialization.registerClass(Rescaling); diff --git a/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts b/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts index 924a3dccd7b..8f1e5e3cf20 100644 --- a/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts +++ b/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts @@ -1,8 +1,8 @@ import { Tensor, randomNormal, mul, add} from '@tensorflow/tfjs-core'; import { Rescaling } from './image_preprocessing' -import { expectTensorsClose } from '../../utils/test_utils'; +import { describeMathCPUAndGPU, expectTensorsClose } from '../../utils/test_utils'; -describe("Rescaling Layer", () => { +describeMathCPUAndGPU("Rescaling Layer", () => { it("Check if input shape matches output shape", () => { const scale = 1.0 / 127.5; From 3f6cff6473545ab1f673a6741659fbdf1bb29877 Mon Sep 17 00:00:00 2001 From: David Don Young Kim Date: Mon, 19 Sep 2022 10:40:37 -0700 Subject: [PATCH 2/2] linting and PR issues resolved Co-authored-by: Adam Lang (@AdamLang96) Co-authored-by: (@Brianzheng123) --- tfjs-layers/src/exports_layers.ts | 2672 ++++++++--------- .../preprocessing/image_preprocessing.ts | 27 +- .../preprocessing/image_preprocessing_test.ts | 31 +- 3 files changed, 1364 insertions(+), 1366 deletions(-) diff --git a/tfjs-layers/src/exports_layers.ts b/tfjs-layers/src/exports_layers.ts index f585eff55a8..0e7b9da6ca4 100755 --- a/tfjs-layers/src/exports_layers.ts +++ b/tfjs-layers/src/exports_layers.ts @@ -32,39 +32,39 @@ import { Rescaling, RescalingArgs } from './layers/preprocessing/image_preproces // Input Layer. /** -* An input layer is an entry point into a `tf.LayersModel`. -* -* `InputLayer` is generated automatically for `tf.Sequential` models by -* specifying the `inputshape` or `batchInputShape` for the first layer. It -* should not be specified explicitly. However, it can be useful sometimes, -* e.g., when constructing a sequential model from a subset of another -* sequential model's layers. Like the code snippet below shows. -* -* ```js -* // Define a model which simply adds two inputs. -* const model1 = tf.sequential(); -* model1.add(tf.layers.dense({inputShape: [4], units: 3, activation: 'relu'})); -* model1.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); -* model1.summary(); -* model1.predict(tf.zeros([1, 4])).print(); -* -* // Construct another model, reusing the second layer of `model1` while -* // not using the first layer of `model1`. Note that you cannot add the second -* // layer of `model` directly as the first layer of the new sequential model, -* // because doing so will lead to an error related to the fact that the layer -* // is not an input layer. Instead, you need to create an `inputLayer` and add -* // it to the new sequential model before adding the reused layer. -* const model2 = tf.sequential(); -* // Use an inputShape that matches the input shape of `model1`'s second -* // layer. -* model2.add(tf.layers.inputLayer({inputShape: [3]})); -* model2.add(model1.layers[1]); -* model2.summary(); -* model2.predict(tf.zeros([1, 3])).print(); -* ``` -* -* @doc {heading: 'Layers', subheading: 'Inputs', namespace: 'layers'} -*/ + * An input layer is an entry point into a `tf.LayersModel`. + * + * `InputLayer` is generated automatically for `tf.Sequential` models by + * specifying the `inputshape` or `batchInputShape` for the first layer. It + * should not be specified explicitly. However, it can be useful sometimes, + * e.g., when constructing a sequential model from a subset of another + * sequential model's layers. Like the code snippet below shows. + * + * ```js + * // Define a model which simply adds two inputs. + * const model1 = tf.sequential(); + * model1.add(tf.layers.dense({inputShape: [4], units: 3, activation: 'relu'})); + * model1.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); + * model1.summary(); + * model1.predict(tf.zeros([1, 4])).print(); + * + * // Construct another model, reusing the second layer of `model1` while + * // not using the first layer of `model1`. Note that you cannot add the second + * // layer of `model` directly as the first layer of the new sequential model, + * // because doing so will lead to an error related to the fact that the layer + * // is not an input layer. Instead, you need to create an `inputLayer` and add + * // it to the new sequential model before adding the reused layer. + * const model2 = tf.sequential(); + * // Use an inputShape that matches the input shape of `model1`'s second + * // layer. + * model2.add(tf.layers.inputLayer({inputShape: [3]})); + * model2.add(model1.layers[1]); + * model2.summary(); + * model2.predict(tf.zeros([1, 3])).print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Inputs', namespace: 'layers'} + */ export function inputLayer(args: InputLayerArgs) { return new InputLayer(args); } @@ -72,147 +72,147 @@ export function inputLayer(args: InputLayerArgs) { // Advanced Activation Layers. /** -* Exponential Linear Unit (ELU). -* -* It follows: -* `f(x) = alpha * (exp(x) - 1.) for x < 0`, -* `f(x) = x for x >= 0`. -* -* Input shape: -* Arbitrary. Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* Output shape: -* Same shape as the input. -* -* References: -* - [Fast and Accurate Deep Network Learning by Exponential Linear Units -* (ELUs)](https://arxiv.org/abs/1511.07289v1) -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Exponential Linear Unit (ELU). + * + * It follows: + * `f(x) = alpha * (exp(x) - 1.) for x < 0`, + * `f(x) = x for x >= 0`. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * References: + * - [Fast and Accurate Deep Network Learning by Exponential Linear Units + * (ELUs)](https://arxiv.org/abs/1511.07289v1) + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function elu(args?: ELULayerArgs) { return new ELU(args); } /** -* Rectified Linear Unit activation function. -* -* Input shape: -* Arbitrary. Use the config field `inputShape` (Array of integers, does -* not include the sample axis) when using this layer as the first layer -* in a model. -* -* Output shape: -* Same shape as the input. -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Rectified Linear Unit activation function. + * + * Input shape: + * Arbitrary. Use the config field `inputShape` (Array of integers, does + * not include the sample axis) when using this layer as the first layer + * in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function reLU(args?: ReLULayerArgs) { return new ReLU(args); } /** -* Leaky version of a rectified linear unit. -* -* It allows a small gradient when the unit is not active: -* `f(x) = alpha * x for x < 0.` -* `f(x) = x for x >= 0.` -* -* Input shape: -* Arbitrary. Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* Output shape: -* Same shape as the input. -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Leaky version of a rectified linear unit. + * + * It allows a small gradient when the unit is not active: + * `f(x) = alpha * x for x < 0.` + * `f(x) = x for x >= 0.` + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function leakyReLU(args?: LeakyReLULayerArgs) { return new LeakyReLU(args); } /** -* Parameterized version of a leaky rectified linear unit. -* -* It follows -* `f(x) = alpha * x for x < 0.` -* `f(x) = x for x >= 0.` -* wherein `alpha` is a trainable weight. -* -* Input shape: -* Arbitrary. Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* Output shape: -* Same shape as the input. -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Parameterized version of a leaky rectified linear unit. + * + * It follows + * `f(x) = alpha * x for x < 0.` + * `f(x) = x for x >= 0.` + * wherein `alpha` is a trainable weight. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function prelu(args?: PReLULayerArgs) { return new PReLU(args); } /** -* Softmax activation layer. -* -* Input shape: -* Arbitrary. Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* Output shape: -* Same shape as the input. -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Softmax activation layer. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function softmax(args?: SoftmaxLayerArgs) { return new Softmax(args); } /** -* Thresholded Rectified Linear Unit. -* -* It follows: -* `f(x) = x for x > theta`, -* `f(x) = 0 otherwise`. -* -* Input shape: -* Arbitrary. Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* Output shape: -* Same shape as the input. -* -* References: -* - [Zero-Bias Autoencoders and the Benefits of Co-Adapting -* Features](http://arxiv.org/abs/1402.3337) -* -* @doc { -* heading: 'Layers', -* subheading: 'Advanced Activation', -* namespace: 'layers' -* } -*/ + * Thresholded Rectified Linear Unit. + * + * It follows: + * `f(x) = x for x > theta`, + * `f(x) = 0 otherwise`. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * References: + * - [Zero-Bias Autoencoders and the Benefits of Co-Adapting + * Features](http://arxiv.org/abs/1402.3337) + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ export function thresholdedReLU(args?: ThresholdedReLULayerArgs) { return new ThresholdedReLU(args); } @@ -220,108 +220,108 @@ export function thresholdedReLU(args?: ThresholdedReLULayerArgs) { // Convolutional Layers. /** -* 1D convolution layer (e.g., temporal convolution). -* -* This layer creates a convolution kernel that is convolved -* with the layer input over a single spatial (or temporal) dimension -* to produce a tensor of outputs. -* -* If `use_bias` is True, a bias vector is created and added to the outputs. -* -* If `activation` is not `null`, it is applied to the outputs as well. -* -* When using this layer as the first layer in a model, provide an -* `inputShape` argument `Array` or `null`. -* -* For example, `inputShape` would be: -* - `[10, 128]` for sequences of 10 vectors of 128-dimensional vectors -* - `[null, 128]` for variable-length sequences of 128-dimensional vectors. -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * 1D convolution layer (e.g., temporal convolution). + * + * This layer creates a convolution kernel that is convolved + * with the layer input over a single spatial (or temporal) dimension + * to produce a tensor of outputs. + * + * If `use_bias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, provide an + * `inputShape` argument `Array` or `null`. + * + * For example, `inputShape` would be: + * - `[10, 128]` for sequences of 10 vectors of 128-dimensional vectors + * - `[null, 128]` for variable-length sequences of 128-dimensional vectors. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function conv1d(args: ConvLayerArgs) { return new Conv1D(args); } /** -* 2D convolution layer (e.g. spatial convolution over images). -* -* This layer creates a convolution kernel that is convolved -* with the layer input to produce a tensor of outputs. -* -* If `useBias` is True, a bias vector is created and added to the outputs. -* -* If `activation` is not `null`, it is applied to the outputs as well. -* -* When using this layer as the first layer in a model, -* provide the keyword argument `inputShape` -* (Array of integers, does not include the sample axis), -* e.g. `inputShape=[128, 128, 3]` for 128x128 RGB pictures -* in `dataFormat='channelsLast'`. -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * 2D convolution layer (e.g. spatial convolution over images). + * + * This layer creates a convolution kernel that is convolved + * with the layer input to produce a tensor of outputs. + * + * If `useBias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, + * provide the keyword argument `inputShape` + * (Array of integers, does not include the sample axis), + * e.g. `inputShape=[128, 128, 3]` for 128x128 RGB pictures + * in `dataFormat='channelsLast'`. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function conv2d(args: ConvLayerArgs) { return new Conv2D(args); } /** -* Transposed convolutional layer (sometimes called Deconvolution). -* -* The need for transposed convolutions generally arises -* from the desire to use a transformation going in the opposite direction of -* a normal convolution, i.e., from something that has the shape of the output -* of some convolution to something that has the shape of its input while -* maintaining a connectivity pattern that is compatible with said -* convolution. -* -* When using this layer as the first layer in a model, provide the -* configuration `inputShape` (`Array` of integers, does not include the -* sample axis), e.g., `inputShape: [128, 128, 3]` for 128x128 RGB pictures in -* `dataFormat: 'channelsLast'`. -* -* Input shape: -* 4D tensor with shape: -* `[batch, channels, rows, cols]` if `dataFormat` is `'channelsFirst'`. -* or 4D tensor with shape -* `[batch, rows, cols, channels]` if `dataFormat` is `'channelsLast'`. -* -* Output shape: -* 4D tensor with shape: -* `[batch, filters, newRows, newCols]` if `dataFormat` is -* `'channelsFirst'`. or 4D tensor with shape: -* `[batch, newRows, newCols, filters]` if `dataFormat` is `'channelsLast'`. -* -* References: -* - [A guide to convolution arithmetic for deep -* learning](https://arxiv.org/abs/1603.07285v1) -* - [Deconvolutional -* Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf) -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * Transposed convolutional layer (sometimes called Deconvolution). + * + * The need for transposed convolutions generally arises + * from the desire to use a transformation going in the opposite direction of + * a normal convolution, i.e., from something that has the shape of the output + * of some convolution to something that has the shape of its input while + * maintaining a connectivity pattern that is compatible with said + * convolution. + * + * When using this layer as the first layer in a model, provide the + * configuration `inputShape` (`Array` of integers, does not include the + * sample axis), e.g., `inputShape: [128, 128, 3]` for 128x128 RGB pictures in + * `dataFormat: 'channelsLast'`. + * + * Input shape: + * 4D tensor with shape: + * `[batch, channels, rows, cols]` if `dataFormat` is `'channelsFirst'`. + * or 4D tensor with shape + * `[batch, rows, cols, channels]` if `dataFormat` is `'channelsLast'`. + * + * Output shape: + * 4D tensor with shape: + * `[batch, filters, newRows, newCols]` if `dataFormat` is + * `'channelsFirst'`. or 4D tensor with shape: + * `[batch, newRows, newCols, filters]` if `dataFormat` is `'channelsLast'`. + * + * References: + * - [A guide to convolution arithmetic for deep + * learning](https://arxiv.org/abs/1603.07285v1) + * - [Deconvolutional + * Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf) + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function conv2dTranspose(args: ConvLayerArgs) { return new Conv2DTranspose(args); } /** -* 3D convolution layer (e.g. spatial convolution over volumes). -* -* This layer creates a convolution kernel that is convolved -* with the layer input to produce a tensor of outputs. -* -* If `useBias` is True, a bias vector is created and added to the outputs. -* -* If `activation` is not `null`, it is applied to the outputs as well. -* -* When using this layer as the first layer in a model, -* provide the keyword argument `inputShape` -* (Array of integers, does not include the sample axis), -* e.g. `inputShape=[128, 128, 128, 1]` for 128x128x128 grayscale volumes -* in `dataFormat='channelsLast'`. -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * 3D convolution layer (e.g. spatial convolution over volumes). + * + * This layer creates a convolution kernel that is convolved + * with the layer input to produce a tensor of outputs. + * + * If `useBias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, + * provide the keyword argument `inputShape` + * (Array of integers, does not include the sample axis), + * e.g. `inputShape=[128, 128, 128, 1]` for 128x128x128 grayscale volumes + * in `dataFormat='channelsLast'`. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function conv3d(args: ConvLayerArgs) { return new Conv3D(args); } @@ -331,97 +331,97 @@ export function conv3dTranspose(args: ConvLayerArgs): Layer { } /** -* Depthwise separable 2D convolution. -* -* Separable convolution consists of first performing -* a depthwise spatial convolution -* (which acts on each input channel separately) -* followed by a pointwise convolution which mixes together the resulting -* output channels. The `depthMultiplier` argument controls how many -* output channels are generated per input channel in the depthwise step. -* -* Intuitively, separable convolutions can be understood as -* a way to factorize a convolution kernel into two smaller kernels, -* or as an extreme version of an Inception block. -* -* Input shape: -* 4D tensor with shape: -* `[batch, channels, rows, cols]` if data_format='channelsFirst' -* or 4D tensor with shape: -* `[batch, rows, cols, channels]` if data_format='channelsLast'. -* -* Output shape: -* 4D tensor with shape: -* `[batch, filters, newRows, newCols]` if data_format='channelsFirst' -* or 4D tensor with shape: -* `[batch, newRows, newCols, filters]` if data_format='channelsLast'. -* `rows` and `cols` values might have changed due to padding. -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * Depthwise separable 2D convolution. + * + * Separable convolution consists of first performing + * a depthwise spatial convolution + * (which acts on each input channel separately) + * followed by a pointwise convolution which mixes together the resulting + * output channels. The `depthMultiplier` argument controls how many + * output channels are generated per input channel in the depthwise step. + * + * Intuitively, separable convolutions can be understood as + * a way to factorize a convolution kernel into two smaller kernels, + * or as an extreme version of an Inception block. + * + * Input shape: + * 4D tensor with shape: + * `[batch, channels, rows, cols]` if data_format='channelsFirst' + * or 4D tensor with shape: + * `[batch, rows, cols, channels]` if data_format='channelsLast'. + * + * Output shape: + * 4D tensor with shape: + * `[batch, filters, newRows, newCols]` if data_format='channelsFirst' + * or 4D tensor with shape: + * `[batch, newRows, newCols, filters]` if data_format='channelsLast'. + * `rows` and `cols` values might have changed due to padding. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function separableConv2d(args: SeparableConvLayerArgs) { return new SeparableConv2D(args); } /** -* Cropping layer for 2D input (e.g., image). -* -* This layer can crop an input -* at the top, bottom, left and right side of an image tensor. -* -* Input shape: -* 4D tensor with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, rows, cols, channels]` -* - If `data_format` is `"channels_first"`: -* `[batch, channels, rows, cols]`. -* -* Output shape: -* 4D with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, croppedRows, croppedCols, channels]` -* - If `dataFormat` is `"channelsFirst"`: -* `[batch, channels, croppedRows, croppedCols]`. -* -* Examples -* ```js -* -* const model = tf.sequential(); -* model.add(tf.layers.cropping2D({cropping:[[2, 2], [2, 2]], -* inputShape: [128, 128, 3]})); -* //now output shape is [batch, 124, 124, 3] -* ``` -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * Cropping layer for 2D input (e.g., image). + * + * This layer can crop an input + * at the top, bottom, left and right side of an image tensor. + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `data_format` is `"channels_first"`: + * `[batch, channels, rows, cols]`. + * + * Output shape: + * 4D with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, croppedRows, croppedCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, croppedRows, croppedCols]`. + * + * Examples + * ```js + * + * const model = tf.sequential(); + * model.add(tf.layers.cropping2D({cropping:[[2, 2], [2, 2]], + * inputShape: [128, 128, 3]})); + * //now output shape is [batch, 124, 124, 3] + * ``` + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function cropping2D(args: Cropping2DLayerArgs) { return new Cropping2D(args); } /** -* Upsampling layer for 2D inputs. -* -* Repeats the rows and columns of the data -* by size[0] and size[1] respectively. -* -* -* Input shape: -* 4D tensor with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, rows, cols, channels]` -* - If `dataFormat` is `"channelsFirst"`: -* `[batch, channels, rows, cols]` -* -* Output shape: -* 4D tensor with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, upsampledRows, upsampledCols, channels]` -* - If `dataFormat` is `"channelsFirst"`: -* `[batch, channels, upsampledRows, upsampledCols]` -* -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * Upsampling layer for 2D inputs. + * + * Repeats the rows and columns of the data + * by size[0] and size[1] respectively. + * + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, rows, cols]` + * + * Output shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, upsampledRows, upsampledCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, upsampledRows, upsampledCols]` + * + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function upSampling2d(args: UpSampling2DLayerArgs) { return new UpSampling2D(args); } @@ -429,15 +429,15 @@ export function upSampling2d(args: UpSampling2DLayerArgs) { // Convolutional(depthwise) Layers. /** -* Depthwise separable 2D convolution. -* -* Depthwise Separable convolutions consists in performing just the first step -* in a depthwise spatial convolution (which acts on each input channel -* separately). The `depthMultiplier` argument controls how many output channels -* are generated per input channel in the depthwise step. -* -* @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} -*/ + * Depthwise separable 2D convolution. + * + * Depthwise Separable convolutions consists in performing just the first step + * in a depthwise spatial convolution (which acts on each input channel + * separately). The `depthMultiplier` argument controls how many output channels + * are generated per input channel in the depthwise step. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ export function depthwiseConv2d(args: DepthwiseConv2DLayerArgs) { return new DepthwiseConv2D(args); } @@ -445,238 +445,238 @@ export function depthwiseConv2d(args: DepthwiseConv2DLayerArgs) { // Basic Layers. /** -* Applies an activation function to an output. -* -* This layer applies element-wise activation function. Other layers, notably -* `dense` can also apply activation functions. Use this isolated activation -* function to extract the values before and after the -* activation. For instance: -* -* ```js -* const input = tf.input({shape: [5]}); -* const denseLayer = tf.layers.dense({units: 1}); -* const activationLayer = tf.layers.activation({activation: 'relu6'}); -* -* // Obtain the output symbolic tensors by applying the layers in order. -* const denseOutput = denseLayer.apply(input); -* const activationOutput = activationLayer.apply(denseOutput); -* -* // Create the model based on the inputs. -* const model = tf.model({ -* inputs: input, -* outputs: [denseOutput, activationOutput] -* }); -* -* // Collect both outputs and print separately. -* const [denseOut, activationOut] = model.predict(tf.randomNormal([6, 5])); -* denseOut.print(); -* activationOut.print(); -* ``` -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Applies an activation function to an output. + * + * This layer applies element-wise activation function. Other layers, notably + * `dense` can also apply activation functions. Use this isolated activation + * function to extract the values before and after the + * activation. For instance: + * + * ```js + * const input = tf.input({shape: [5]}); + * const denseLayer = tf.layers.dense({units: 1}); + * const activationLayer = tf.layers.activation({activation: 'relu6'}); + * + * // Obtain the output symbolic tensors by applying the layers in order. + * const denseOutput = denseLayer.apply(input); + * const activationOutput = activationLayer.apply(denseOutput); + * + * // Create the model based on the inputs. + * const model = tf.model({ + * inputs: input, + * outputs: [denseOutput, activationOutput] + * }); + * + * // Collect both outputs and print separately. + * const [denseOut, activationOut] = model.predict(tf.randomNormal([6, 5])); + * denseOut.print(); + * activationOut.print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function activation(args: ActivationLayerArgs) { return new Activation(args); } /** -* Creates a dense (fully connected) layer. -* -* This layer implements the operation: -* `output = activation(dot(input, kernel) + bias)` -* -* `activation` is the element-wise activation function -* passed as the `activation` argument. -* -* `kernel` is a weights matrix created by the layer. -* -* `bias` is a bias vector created by the layer (only applicable if `useBias` -* is `true`). -* -* **Input shape:** -* -* nD `tf.Tensor` with shape: `(batchSize, ..., inputDim)`. -* -* The most common situation would be -* a 2D input with shape `(batchSize, inputDim)`. -* -* **Output shape:** -* -* nD tensor with shape: `(batchSize, ..., units)`. -* -* For instance, for a 2D input with shape `(batchSize, inputDim)`, -* the output would have shape `(batchSize, units)`. -* -* Note: if the input to the layer has a rank greater than 2, then it is -* flattened prior to the initial dot product with the kernel. -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Creates a dense (fully connected) layer. + * + * This layer implements the operation: + * `output = activation(dot(input, kernel) + bias)` + * + * `activation` is the element-wise activation function + * passed as the `activation` argument. + * + * `kernel` is a weights matrix created by the layer. + * + * `bias` is a bias vector created by the layer (only applicable if `useBias` + * is `true`). + * + * **Input shape:** + * + * nD `tf.Tensor` with shape: `(batchSize, ..., inputDim)`. + * + * The most common situation would be + * a 2D input with shape `(batchSize, inputDim)`. + * + * **Output shape:** + * + * nD tensor with shape: `(batchSize, ..., units)`. + * + * For instance, for a 2D input with shape `(batchSize, inputDim)`, + * the output would have shape `(batchSize, units)`. + * + * Note: if the input to the layer has a rank greater than 2, then it is + * flattened prior to the initial dot product with the kernel. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function dense(args: DenseLayerArgs) { return new Dense(args); } /** -* Applies -* [dropout](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) to -* the input. -* -* Dropout consists in randomly setting a fraction `rate` of input units to 0 at -* each update during training time, which helps prevent overfitting. -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Applies + * [dropout](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) to + * the input. + * + * Dropout consists in randomly setting a fraction `rate` of input units to 0 at + * each update during training time, which helps prevent overfitting. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function dropout(args: DropoutLayerArgs) { return new Dropout(args); } /** -* Spatial 1D version of Dropout. -* -* This Layer type performs the same function as the Dropout layer, but it drops -* entire 1D feature maps instead of individual elements. For example, if an -* input example consists of 3 timesteps and the feature map for each timestep -* has a size of 4, a `spatialDropout1d` layer may zero out the feature maps -* of the 1st timesteps and 2nd timesteps completely while sparing all feature -* elements of the 3rd timestep. -* -* If adjacent frames (timesteps) are strongly correlated (as is normally the -* case in early convolution layers), regular dropout will not regularize the -* activation and will otherwise just result in merely an effective learning -* rate decrease. In this case, `spatialDropout1d` will help promote -* independence among feature maps and should be used instead. -* -* **Arguments:** -* rate: A floating-point number >=0 and <=1. Fraction of the input elements -* to drop. -* -* **Input shape:** -* 3D tensor with shape `(samples, timesteps, channels)`. -* -* **Output shape:** -* Same as the input shape. -* -* References: -* - [Efficient Object Localization Using Convolutional -* Networks](https://arxiv.org/abs/1411.4280) -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Spatial 1D version of Dropout. + * + * This Layer type performs the same function as the Dropout layer, but it drops + * entire 1D feature maps instead of individual elements. For example, if an + * input example consists of 3 timesteps and the feature map for each timestep + * has a size of 4, a `spatialDropout1d` layer may zero out the feature maps + * of the 1st timesteps and 2nd timesteps completely while sparing all feature + * elements of the 3rd timestep. + * + * If adjacent frames (timesteps) are strongly correlated (as is normally the + * case in early convolution layers), regular dropout will not regularize the + * activation and will otherwise just result in merely an effective learning + * rate decrease. In this case, `spatialDropout1d` will help promote + * independence among feature maps and should be used instead. + * + * **Arguments:** + * rate: A floating-point number >=0 and <=1. Fraction of the input elements + * to drop. + * + * **Input shape:** + * 3D tensor with shape `(samples, timesteps, channels)`. + * + * **Output shape:** + * Same as the input shape. + * + * References: + * - [Efficient Object Localization Using Convolutional + * Networks](https://arxiv.org/abs/1411.4280) + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function spatialDropout1d(args: SpatialDropout1DLayerConfig) { return new SpatialDropout1D(args); } /** -* Flattens the input. Does not affect the batch size. -* -* A `Flatten` layer flattens each batch in its inputs to 1D (making the output -* 2D). -* -* For example: -* -* ```js -* const input = tf.input({shape: [4, 3]}); -* const flattenLayer = tf.layers.flatten(); -* // Inspect the inferred output shape of the flatten layer, which -* // equals `[null, 12]`. The 2nd dimension is 4 * 3, i.e., the result of the -* // flattening. (The 1st dimension is the undermined batch size.) -* console.log(JSON.stringify(flattenLayer.apply(input).shape)); -* ``` -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Flattens the input. Does not affect the batch size. + * + * A `Flatten` layer flattens each batch in its inputs to 1D (making the output + * 2D). + * + * For example: + * + * ```js + * const input = tf.input({shape: [4, 3]}); + * const flattenLayer = tf.layers.flatten(); + * // Inspect the inferred output shape of the flatten layer, which + * // equals `[null, 12]`. The 2nd dimension is 4 * 3, i.e., the result of the + * // flattening. (The 1st dimension is the undermined batch size.) + * console.log(JSON.stringify(flattenLayer.apply(input).shape)); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function flatten(args?: FlattenLayerArgs) { return new Flatten(args); } /** -* Repeats the input n times in a new dimension. -* -* ```js -* const model = tf.sequential(); -* model.add(tf.layers.repeatVector({n: 4, inputShape: [2]})); -* const x = tf.tensor2d([[10, 20]]); -* // Use the model to do inference on a data point the model hasn't see -* model.predict(x).print(); -* // output shape is now [batch, 2, 4] -* ``` -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Repeats the input n times in a new dimension. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.repeatVector({n: 4, inputShape: [2]})); + * const x = tf.tensor2d([[10, 20]]); + * // Use the model to do inference on a data point the model hasn't see + * model.predict(x).print(); + * // output shape is now [batch, 2, 4] + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function repeatVector(args: RepeatVectorLayerArgs) { return new RepeatVector(args); } /** -* Reshapes an input to a certain shape. -* -* ```js -* const input = tf.input({shape: [4, 3]}); -* const reshapeLayer = tf.layers.reshape({targetShape: [2, 6]}); -* // Inspect the inferred output shape of the Reshape layer, which -* // equals `[null, 2, 6]`. (The 1st dimension is the undermined batch size.) -* console.log(JSON.stringify(reshapeLayer.apply(input).shape)); -* ``` -* -* Input shape: -* Arbitrary, although all dimensions in the input shape must be fixed. -* Use the configuration `inputShape` when using this layer as the -* first layer in a model. -* -* -* Output shape: -* [batchSize, targetShape[0], targetShape[1], ..., -* targetShape[targetShape.length - 1]]. -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Reshapes an input to a certain shape. + * + * ```js + * const input = tf.input({shape: [4, 3]}); + * const reshapeLayer = tf.layers.reshape({targetShape: [2, 6]}); + * // Inspect the inferred output shape of the Reshape layer, which + * // equals `[null, 2, 6]`. (The 1st dimension is the undermined batch size.) + * console.log(JSON.stringify(reshapeLayer.apply(input).shape)); + * ``` + * + * Input shape: + * Arbitrary, although all dimensions in the input shape must be fixed. + * Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * + * Output shape: + * [batchSize, targetShape[0], targetShape[1], ..., + * targetShape[targetShape.length - 1]]. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function reshape(args: ReshapeLayerArgs) { return new Reshape(args); } /** -* Permutes the dimensions of the input according to a given pattern. -* -* Useful for, e.g., connecting RNNs and convnets together. -* -* Example: -* -* ```js -* const model = tf.sequential(); -* model.add(tf.layers.permute({ -* dims: [2, 1], -* inputShape: [10, 64] -* })); -* console.log(model.outputShape); -* // Now model's output shape is [null, 64, 10], where null is the -* // unpermuted sample (batch) dimension. -* ``` -* -* Input shape: -* Arbitrary. Use the configuration field `inputShape` when using this -* layer as the first layer in a model. -* -* Output shape: -* Same rank as the input shape, but with the dimensions re-ordered (i.e., -* permuted) according to the `dims` configuration of this layer. -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Permutes the dimensions of the input according to a given pattern. + * + * Useful for, e.g., connecting RNNs and convnets together. + * + * Example: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.permute({ + * dims: [2, 1], + * inputShape: [10, 64] + * })); + * console.log(model.outputShape); + * // Now model's output shape is [null, 64, 10], where null is the + * // unpermuted sample (batch) dimension. + * ``` + * + * Input shape: + * Arbitrary. Use the configuration field `inputShape` when using this + * layer as the first layer in a model. + * + * Output shape: + * Same rank as the input shape, but with the dimensions re-ordered (i.e., + * permuted) according to the `dims` configuration of this layer. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function permute(args: PermuteLayerArgs) { return new Permute(args); } /** -* Maps positive integers (indices) into dense vectors of fixed size. -* E.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] -* -* **Input shape:** 2D tensor with shape: `[batchSize, sequenceLength]`. -* -* **Output shape:** 3D tensor with shape: `[batchSize, sequenceLength, -* outputDim]`. -* -* @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} -*/ + * Maps positive integers (indices) into dense vectors of fixed size. + * E.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] + * + * **Input shape:** 2D tensor with shape: `[batchSize, sequenceLength]`. + * + * **Output shape:** 3D tensor with shape: `[batchSize, sequenceLength, + * outputDim]`. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ export function embedding(args: EmbeddingLayerArgs) { return new Embedding(args); } @@ -684,164 +684,164 @@ export function embedding(args: EmbeddingLayerArgs) { // Merge Layers. /** -* Layer that performs element-wise addition on an `Array` of inputs. -* -* It takes as input a list of tensors, all of the same shape, and returns a -* single tensor (also of the same shape). The inputs are specified as an -* `Array` when the `apply` method of the `Add` layer instance is called. For -* example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 2]}); -* const addLayer = tf.layers.add(); -* const sum = addLayer.apply([input1, input2]); -* console.log(JSON.stringify(sum.shape)); -* // You get [null, 2, 2], with the first dimension as the undetermined batch -* // dimension. -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that performs element-wise addition on an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). The inputs are specified as an + * `Array` when the `apply` method of the `Add` layer instance is called. For + * example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const addLayer = tf.layers.add(); + * const sum = addLayer.apply([input1, input2]); + * console.log(JSON.stringify(sum.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function add(args?: LayerArgs) { return new Add(args); } /** -* Layer that performs element-wise averaging on an `Array` of inputs. -* -* It takes as input a list of tensors, all of the same shape, and returns a -* single tensor (also of the same shape). For example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 2]}); -* const averageLayer = tf.layers.average(); -* const average = averageLayer.apply([input1, input2]); -* console.log(JSON.stringify(average.shape)); -* // You get [null, 2, 2], with the first dimension as the undetermined batch -* // dimension. -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that performs element-wise averaging on an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const averageLayer = tf.layers.average(); + * const average = averageLayer.apply([input1, input2]); + * console.log(JSON.stringify(average.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function average(args?: LayerArgs) { return new Average(args); } /** -* Layer that concatenates an `Array` of inputs. -* -* It takes a list of tensors, all of the same shape except for the -* concatenation axis, and returns a single tensor, the concatenation -* of all inputs. For example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 3]}); -* const concatLayer = tf.layers.concatenate(); -* const output = concatLayer.apply([input1, input2]); -* console.log(JSON.stringify(output.shape)); -* // You get [null, 2, 5], with the first dimension as the undetermined batch -* // dimension. The last dimension (5) is the result of concatenating the -* // last dimensions of the inputs (2 and 3). -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that concatenates an `Array` of inputs. + * + * It takes a list of tensors, all of the same shape except for the + * concatenation axis, and returns a single tensor, the concatenation + * of all inputs. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 3]}); + * const concatLayer = tf.layers.concatenate(); + * const output = concatLayer.apply([input1, input2]); + * console.log(JSON.stringify(output.shape)); + * // You get [null, 2, 5], with the first dimension as the undetermined batch + * // dimension. The last dimension (5) is the result of concatenating the + * // last dimensions of the inputs (2 and 3). + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function concatenate(args?: ConcatenateLayerArgs) { return new Concatenate(args); } /** -* Layer that computes the element-wise maximum of an `Array` of inputs. -* -* It takes as input a list of tensors, all of the same shape, and returns a -* single tensor (also of the same shape). For example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 2]}); -* const maxLayer = tf.layers.maximum(); -* const max = maxLayer.apply([input1, input2]); -* console.log(JSON.stringify(max.shape)); -* // You get [null, 2, 2], with the first dimension as the undetermined batch -* // dimension. -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that computes the element-wise maximum of an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const maxLayer = tf.layers.maximum(); + * const max = maxLayer.apply([input1, input2]); + * console.log(JSON.stringify(max.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function maximum(args?: LayerArgs) { return new Maximum(args); } /** -* Layer that computes the element-wise minimum of an `Array` of inputs. -* -* It takes as input a list of tensors, all of the same shape, and returns a -* single tensor (also of the same shape). For example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 2]}); -* const minLayer = tf.layers.minimum(); -* const min = minLayer.apply([input1, input2]); -* console.log(JSON.stringify(min.shape)); -* // You get [null, 2, 2], with the first dimension as the undetermined batch -* // dimension. -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that computes the element-wise minimum of an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const minLayer = tf.layers.minimum(); + * const min = minLayer.apply([input1, input2]); + * console.log(JSON.stringify(min.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function minimum(args?: LayerArgs) { return new Minimum(args); } /** -* Layer that multiplies (element-wise) an `Array` of inputs. -* -* It takes as input an Array of tensors, all of the same -* shape, and returns a single tensor (also of the same shape). -* For example: -* -* ```js -* const input1 = tf.input({shape: [2, 2]}); -* const input2 = tf.input({shape: [2, 2]}); -* const input3 = tf.input({shape: [2, 2]}); -* const multiplyLayer = tf.layers.multiply(); -* const product = multiplyLayer.apply([input1, input2, input3]); -* console.log(product.shape); -* // You get [null, 2, 2], with the first dimension as the undetermined batch -* // dimension. -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that multiplies (element-wise) an `Array` of inputs. + * + * It takes as input an Array of tensors, all of the same + * shape, and returns a single tensor (also of the same shape). + * For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const input3 = tf.input({shape: [2, 2]}); + * const multiplyLayer = tf.layers.multiply(); + * const product = multiplyLayer.apply([input1, input2, input3]); + * console.log(product.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function multiply(args?: LayerArgs) { return new Multiply(args); } /** -* Layer that computes a dot product between samples in two tensors. -* -* E.g., if applied to a list of two tensors `a` and `b` both of shape -* `[batchSize, n]`, the output will be a tensor of shape `[batchSize, 1]`, -* where each entry at index `[i, 0]` will be the dot product between -* `a[i, :]` and `b[i, :]`. -* -* Example: -* -* ```js -* const dotLayer = tf.layers.dot({axes: -1}); -* const x1 = tf.tensor2d([[10, 20], [30, 40]]); -* const x2 = tf.tensor2d([[-1, -2], [-3, -4]]); -* -* // Invoke the layer's apply() method in eager (imperative) mode. -* const y = dotLayer.apply([x1, x2]); -* y.print(); -* ``` -* -* @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} -*/ + * Layer that computes a dot product between samples in two tensors. + * + * E.g., if applied to a list of two tensors `a` and `b` both of shape + * `[batchSize, n]`, the output will be a tensor of shape `[batchSize, 1]`, + * where each entry at index `[i, 0]` will be the dot product between + * `a[i, :]` and `b[i, :]`. + * + * Example: + * + * ```js + * const dotLayer = tf.layers.dot({axes: -1}); + * const x1 = tf.tensor2d([[10, 20], [30, 40]]); + * const x2 = tf.tensor2d([[-1, -2], [-3, -4]]); + * + * // Invoke the layer's apply() method in eager (imperative) mode. + * const y = dotLayer.apply([x1, x2]); + * y.print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ export function dot(args: DotLayerArgs) { return new Dot(args); } @@ -849,50 +849,50 @@ export function dot(args: DotLayerArgs) { // Normalization Layers. /** -* Batch normalization layer (Ioffe and Szegedy, 2014). -* -* Normalize the activations of the previous layer at each batch, -* i.e. applies a transformation that maintains the mean activation -* close to 0 and the activation standard deviation close to 1. -* -* Input shape: -* Arbitrary. Use the keyword argument `inputShape` (Array of integers, does -* not include the sample axis) when calling the constructor of this class, -* if this layer is used as a first layer in a model. -* -* Output shape: -* Same shape as input. -* -* References: -* - [Batch Normalization: Accelerating Deep Network Training by Reducing -* Internal Covariate Shift](https://arxiv.org/abs/1502.03167) -* -* @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} -*/ + * Batch normalization layer (Ioffe and Szegedy, 2014). + * + * Normalize the activations of the previous layer at each batch, + * i.e. applies a transformation that maintains the mean activation + * close to 0 and the activation standard deviation close to 1. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` (Array of integers, does + * not include the sample axis) when calling the constructor of this class, + * if this layer is used as a first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Batch Normalization: Accelerating Deep Network Training by Reducing + * Internal Covariate Shift](https://arxiv.org/abs/1502.03167) + * + * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} + */ export function batchNormalization(args?: BatchNormalizationLayerArgs) { return new BatchNormalization(args); } /** -* Layer-normalization layer (Ba et al., 2016). -* -* Normalizes the activations of the previous layer for each given example in a -* batch independently, instead of across a batch like in `batchNormalization`. -* In other words, this layer applies a transformation that maintains the mean -* activation within each example close to 0 and activation variance close to 1. -* -* Input shape: -* Arbitrary. Use the argument `inputShape` when using this layer as the first -* layer in a model. -* -* Output shape: -* Same as input. -* -* References: -* - [Layer Normalization](https://arxiv.org/abs/1607.06450) -* -* @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} -*/ + * Layer-normalization layer (Ba et al., 2016). + * + * Normalizes the activations of the previous layer for each given example in a + * batch independently, instead of across a batch like in `batchNormalization`. + * In other words, this layer applies a transformation that maintains the mean + * activation within each example close to 0 and activation variance close to 1. + * + * Input shape: + * Arbitrary. Use the argument `inputShape` when using this layer as the first + * layer in a model. + * + * Output shape: + * Same as input. + * + * References: + * - [Layer Normalization](https://arxiv.org/abs/1607.06450) + * + * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} + */ export function layerNormalization(args?: LayerNormalizationLayerArgs) { return new LayerNormalization(args); } @@ -900,27 +900,27 @@ export function layerNormalization(args?: LayerNormalizationLayerArgs) { // Padding Layers. /** -* Zero-padding layer for 2D input (e.g., image). -* -* This layer can add rows and columns of zeros -* at the top, bottom, left and right side of an image tensor. -* -* Input shape: -* 4D tensor with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, rows, cols, channels]` -* - If `data_format` is `"channels_first"`: -* `[batch, channels, rows, cols]`. -* -* Output shape: -* 4D with shape: -* - If `dataFormat` is `"channelsLast"`: -* `[batch, paddedRows, paddedCols, channels]` -* - If `dataFormat` is `"channelsFirst"`: -* `[batch, channels, paddedRows, paddedCols]`. -* -* @doc {heading: 'Layers', subheading: 'Padding', namespace: 'layers'} -*/ + * Zero-padding layer for 2D input (e.g., image). + * + * This layer can add rows and columns of zeros + * at the top, bottom, left and right side of an image tensor. + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `data_format` is `"channels_first"`: + * `[batch, channels, rows, cols]`. + * + * Output shape: + * 4D with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, paddedRows, paddedCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, paddedRows, paddedCols]`. + * + * @doc {heading: 'Layers', subheading: 'Padding', namespace: 'layers'} + */ export function zeroPadding2d(args?: ZeroPadding2DLayerArgs) { return new ZeroPadding2D(args); } @@ -928,16 +928,16 @@ export function zeroPadding2d(args?: ZeroPadding2DLayerArgs) { // Pooling Layers. /** -* Average pooling operation for spatial data. -* -* Input shape: `[batchSize, inLength, channels]` -* -* Output shape: `[batchSize, pooledLength, channels]` -* -* `tf.avgPool1d` is an alias. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Average pooling operation for spatial data. + * + * Input shape: `[batchSize, inLength, channels]` + * + * Output shape: `[batchSize, pooledLength, channels]` + * + * `tf.avgPool1d` is an alias. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function averagePooling1d(args: Pooling1DLayerArgs) { return new AveragePooling1D(args); } @@ -951,28 +951,28 @@ export function avgPooling1d(args: Pooling1DLayerArgs) { } /** -* Average pooling operation for spatial data. -* -* Input shape: -* - If `dataFormat === CHANNEL_LAST`: -* 4D tensor with shape: -* `[batchSize, rows, cols, channels]` -* - If `dataFormat === CHANNEL_FIRST`: -* 4D tensor with shape: -* `[batchSize, channels, rows, cols]` -* -* Output shape -* - If `dataFormat === CHANNEL_LAST`: -* 4D tensor with shape: -* `[batchSize, pooledRows, pooledCols, channels]` -* - If `dataFormat === CHANNEL_FIRST`: -* 4D tensor with shape: -* `[batchSize, channels, pooledRows, pooledCols]` -* -* `tf.avgPool2d` is an alias. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Average pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, rows, cols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, rows, cols]` + * + * Output shape + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, pooledRows, pooledCols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, pooledRows, pooledCols]` + * + * `tf.avgPool2d` is an alias. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function averagePooling2d(args: Pooling2DLayerArgs) { return new AveragePooling2D(args); } @@ -986,26 +986,26 @@ export function avgPooling2d(args: Pooling2DLayerArgs) { } /** -* Average pooling operation for 3D data. -* -* Input shape -* - If `dataFormat === channelsLast`: -* 5D tensor with shape: -* `[batchSize, depths, rows, cols, channels]` -* - If `dataFormat === channelsFirst`: -* 4D tensor with shape: -* `[batchSize, channels, depths, rows, cols]` -* -* Output shape -* - If `dataFormat=channelsLast`: -* 5D tensor with shape: -* `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` -* - If `dataFormat=channelsFirst`: -* 5D tensor with shape: -* `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Average pooling operation for 3D data. + * + * Input shape + * - If `dataFormat === channelsLast`: + * 5D tensor with shape: + * `[batchSize, depths, rows, cols, channels]` + * - If `dataFormat === channelsFirst`: + * 4D tensor with shape: + * `[batchSize, channels, depths, rows, cols]` + * + * Output shape + * - If `dataFormat=channelsLast`: + * 5D tensor with shape: + * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` + * - If `dataFormat=channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function averagePooling3d(args: Pooling3DLayerArgs) { return new AveragePooling3D(args); } @@ -1019,126 +1019,126 @@ export function avgPooling3d(args: Pooling3DLayerArgs) { } /** -* Global average pooling operation for temporal data. -* -* Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. -* -* Output Shape: 2D tensor with shape: `[batchSize, features]`. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Global average pooling operation for temporal data. + * + * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. + * + * Output Shape: 2D tensor with shape: `[batchSize, features]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function globalAveragePooling1d(args?: LayerArgs) { return new GlobalAveragePooling1D(args); } /** -* Global average pooling operation for spatial data. -* -* Input shape: -* - If `dataFormat` is `CHANNEL_LAST`: -* 4D tensor with shape: `[batchSize, rows, cols, channels]`. -* - If `dataFormat` is `CHANNEL_FIRST`: -* 4D tensor with shape: `[batchSize, channels, rows, cols]`. -* -* Output shape: -* 2D tensor with shape: `[batchSize, channels]`. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Global average pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat` is `CHANNEL_LAST`: + * 4D tensor with shape: `[batchSize, rows, cols, channels]`. + * - If `dataFormat` is `CHANNEL_FIRST`: + * 4D tensor with shape: `[batchSize, channels, rows, cols]`. + * + * Output shape: + * 2D tensor with shape: `[batchSize, channels]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function globalAveragePooling2d(args: GlobalPooling2DLayerArgs) { return new GlobalAveragePooling2D(args); } /** -* Global max pooling operation for temporal data. -* -* Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. -* -* Output Shape: 2D tensor with shape: `[batchSize, features]`. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Global max pooling operation for temporal data. + * + * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. + * + * Output Shape: 2D tensor with shape: `[batchSize, features]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function globalMaxPooling1d(args?: LayerArgs) { return new GlobalMaxPooling1D(args); } /** -* Global max pooling operation for spatial data. -* -* Input shape: -* - If `dataFormat` is `CHANNEL_LAST`: -* 4D tensor with shape: `[batchSize, rows, cols, channels]`. -* - If `dataFormat` is `CHANNEL_FIRST`: -* 4D tensor with shape: `[batchSize, channels, rows, cols]`. -* -* Output shape: -* 2D tensor with shape: `[batchSize, channels]`. -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Global max pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat` is `CHANNEL_LAST`: + * 4D tensor with shape: `[batchSize, rows, cols, channels]`. + * - If `dataFormat` is `CHANNEL_FIRST`: + * 4D tensor with shape: `[batchSize, channels, rows, cols]`. + * + * Output shape: + * 2D tensor with shape: `[batchSize, channels]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function globalMaxPooling2d(args: GlobalPooling2DLayerArgs) { return new GlobalMaxPooling2D(args); } /** -* Max pooling operation for temporal data. -* -* Input shape: `[batchSize, inLength, channels]` -* -* Output shape: `[batchSize, pooledLength, channels]` -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Max pooling operation for temporal data. + * + * Input shape: `[batchSize, inLength, channels]` + * + * Output shape: `[batchSize, pooledLength, channels]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function maxPooling1d(args: Pooling1DLayerArgs) { return new MaxPooling1D(args); } /** -* Max pooling operation for spatial data. -* -* Input shape -* - If `dataFormat === CHANNEL_LAST`: -* 4D tensor with shape: -* `[batchSize, rows, cols, channels]` -* - If `dataFormat === CHANNEL_FIRST`: -* 4D tensor with shape: -* `[batchSize, channels, rows, cols]` -* -* Output shape -* - If `dataFormat=CHANNEL_LAST`: -* 4D tensor with shape: -* `[batchSize, pooledRows, pooledCols, channels]` -* - If `dataFormat=CHANNEL_FIRST`: -* 4D tensor with shape: -* `[batchSize, channels, pooledRows, pooledCols]` -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Max pooling operation for spatial data. + * + * Input shape + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, rows, cols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, rows, cols]` + * + * Output shape + * - If `dataFormat=CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, pooledRows, pooledCols, channels]` + * - If `dataFormat=CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function maxPooling2d(args: Pooling2DLayerArgs) { return new MaxPooling2D(args); } /** -* Max pooling operation for 3D data. -* -* Input shape -* - If `dataFormat === channelsLast`: -* 5D tensor with shape: -* `[batchSize, depths, rows, cols, channels]` -* - If `dataFormat === channelsFirst`: -* 5D tensor with shape: -* `[batchSize, channels, depths, rows, cols]` -* -* Output shape -* - If `dataFormat=channelsLast`: -* 5D tensor with shape: -* `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` -* - If `dataFormat=channelsFirst`: -* 5D tensor with shape: -* `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` -* -* @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} -*/ + * Max pooling operation for 3D data. + * + * Input shape + * - If `dataFormat === channelsLast`: + * 5D tensor with shape: + * `[batchSize, depths, rows, cols, channels]` + * - If `dataFormat === channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, depths, rows, cols]` + * + * Output shape + * - If `dataFormat=channelsLast`: + * 5D tensor with shape: + * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` + * - If `dataFormat=channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ export function maxPooling3d(args: Pooling3DLayerArgs) { return new MaxPooling3D(args); } @@ -1146,373 +1146,373 @@ export function maxPooling3d(args: Pooling3DLayerArgs) { // Recurrent Layers. /** -* Gated Recurrent Unit - Cho et al. 2014. -* -* This is an `RNN` layer consisting of one `GRUCell`. However, unlike -* the underlying `GRUCell`, the `apply` method of `SimpleRNN` operates -* on a sequence of inputs. The shape of the input (not including the first, -* batch dimension) needs to be at least 2-D, with the first dimension being -* time steps. For example: -* -* ```js -* const rnn = tf.layers.gru({units: 8, returnSequences: true}); -* -* // Create an input with 10 time steps. -* const input = tf.input({shape: [10, 20]}); -* const output = rnn.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the `GRUCell`'s number of units. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Gated Recurrent Unit - Cho et al. 2014. + * + * This is an `RNN` layer consisting of one `GRUCell`. However, unlike + * the underlying `GRUCell`, the `apply` method of `SimpleRNN` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const rnn = tf.layers.gru({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `GRUCell`'s number of units. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function gru(args: GRULayerArgs) { return new GRU(args); } /** -* Cell class for `GRU`. -* -* `GRUCell` is distinct from the `RNN` subclass `GRU` in that its -* `apply` method takes the input data of only a single time step and returns -* the cell's output at the time step, while `GRU` takes the input data -* over a number of time steps. For example: -* -* ```js -* const cell = tf.layers.gruCell({units: 2}); -* const input = tf.input({shape: [10]}); -* const output = cell.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10]: This is the cell's output at a single time step. The 1st -* // dimension is the unknown batch size. -* ``` -* -* Instance(s) of `GRUCell` can be used to construct `RNN` layers. The -* most typical use of this workflow is to combine a number of cells into a -* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an -* RNN. For example: -* -* ```js -* const cells = [ -* tf.layers.gruCell({units: 4}), -* tf.layers.gruCell({units: 8}), -* ]; -* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); -* -* // Create an input with 10 time steps and a length-20 vector at each step. -* const input = tf.input({shape: [10, 20]}); -* const output = rnn.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the last `gruCell`'s number of units. -* ``` -* -* To create an `RNN` consisting of only *one* `GRUCell`, use the -* `tf.layers.gru`. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Cell class for `GRU`. + * + * `GRUCell` is distinct from the `RNN` subclass `GRU` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `GRU` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.gruCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `GRUCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.gruCell({units: 4}), + * tf.layers.gruCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `gruCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `GRUCell`, use the + * `tf.layers.gru`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function gruCell(args: GRUCellLayerArgs) { return new GRUCell(args); } /** -* Long-Short Term Memory layer - Hochreiter 1997. -* -* This is an `RNN` layer consisting of one `LSTMCell`. However, unlike -* the underlying `LSTMCell`, the `apply` method of `LSTM` operates -* on a sequence of inputs. The shape of the input (not including the first, -* batch dimension) needs to be at least 2-D, with the first dimension being -* time steps. For example: -* -* ```js -* const lstm = tf.layers.lstm({units: 8, returnSequences: true}); -* -* // Create an input with 10 time steps. -* const input = tf.input({shape: [10, 20]}); -* const output = lstm.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the `LSTMCell`'s number of units. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Long-Short Term Memory layer - Hochreiter 1997. + * + * This is an `RNN` layer consisting of one `LSTMCell`. However, unlike + * the underlying `LSTMCell`, the `apply` method of `LSTM` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const lstm = tf.layers.lstm({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = lstm.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `LSTMCell`'s number of units. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function lstm(args: LSTMLayerArgs) { return new LSTM(args); } /** -* Cell class for `LSTM`. -* -* `LSTMCell` is distinct from the `RNN` subclass `LSTM` in that its -* `apply` method takes the input data of only a single time step and returns -* the cell's output at the time step, while `LSTM` takes the input data -* over a number of time steps. For example: -* -* ```js -* const cell = tf.layers.lstmCell({units: 2}); -* const input = tf.input({shape: [10]}); -* const output = cell.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10]: This is the cell's output at a single time step. The 1st -* // dimension is the unknown batch size. -* ``` -* -* Instance(s) of `LSTMCell` can be used to construct `RNN` layers. The -* most typical use of this workflow is to combine a number of cells into a -* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an -* RNN. For example: -* -* ```js -* const cells = [ -* tf.layers.lstmCell({units: 4}), -* tf.layers.lstmCell({units: 8}), -* ]; -* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); -* -* // Create an input with 10 time steps and a length-20 vector at each step. -* const input = tf.input({shape: [10, 20]}); -* const output = rnn.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the last `lstmCell`'s number of units. -* ``` -* -* To create an `RNN` consisting of only *one* `LSTMCell`, use the -* `tf.layers.lstm`. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Cell class for `LSTM`. + * + * `LSTMCell` is distinct from the `RNN` subclass `LSTM` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `LSTM` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.lstmCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `LSTMCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.lstmCell({units: 4}), + * tf.layers.lstmCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `lstmCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `LSTMCell`, use the + * `tf.layers.lstm`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function lstmCell(args: LSTMCellLayerArgs) { return new LSTMCell(args); } /** -* Fully-connected RNN where the output is to be fed back to input. -* -* This is an `RNN` layer consisting of one `SimpleRNNCell`. However, unlike -* the underlying `SimpleRNNCell`, the `apply` method of `SimpleRNN` operates -* on a sequence of inputs. The shape of the input (not including the first, -* batch dimension) needs to be at least 2-D, with the first dimension being -* time steps. For example: -* -* ```js -* const rnn = tf.layers.simpleRNN({units: 8, returnSequences: true}); -* -* // Create an input with 10 time steps. -* const input = tf.input({shape: [10, 20]}); -* const output = rnn.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the `SimpleRNNCell`'s number of units. -* ``` -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Fully-connected RNN where the output is to be fed back to input. + * + * This is an `RNN` layer consisting of one `SimpleRNNCell`. However, unlike + * the underlying `SimpleRNNCell`, the `apply` method of `SimpleRNN` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const rnn = tf.layers.simpleRNN({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `SimpleRNNCell`'s number of units. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function simpleRNN(args: SimpleRNNLayerArgs) { return new SimpleRNN(args); } /** -* Cell class for `SimpleRNN`. -* -* `SimpleRNNCell` is distinct from the `RNN` subclass `SimpleRNN` in that its -* `apply` method takes the input data of only a single time step and returns -* the cell's output at the time step, while `SimpleRNN` takes the input data -* over a number of time steps. For example: -* -* ```js -* const cell = tf.layers.simpleRNNCell({units: 2}); -* const input = tf.input({shape: [10]}); -* const output = cell.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10]: This is the cell's output at a single time step. The 1st -* // dimension is the unknown batch size. -* ``` -* -* Instance(s) of `SimpleRNNCell` can be used to construct `RNN` layers. The -* most typical use of this workflow is to combine a number of cells into a -* stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an -* RNN. For example: -* -* ```js -* const cells = [ -* tf.layers.simpleRNNCell({units: 4}), -* tf.layers.simpleRNNCell({units: 8}), -* ]; -* const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); -* -* // Create an input with 10 time steps and a length-20 vector at each step. -* const input = tf.input({shape: [10, 20]}); -* const output = rnn.apply(input); -* -* console.log(JSON.stringify(output.shape)); -* // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the -* // same as the sequence length of `input`, due to `returnSequences`: `true`; -* // 3rd dimension is the last `SimpleRNNCell`'s number of units. -* ``` -* -* To create an `RNN` consisting of only *one* `SimpleRNNCell`, use the -* `tf.layers.simpleRNN`. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Cell class for `SimpleRNN`. + * + * `SimpleRNNCell` is distinct from the `RNN` subclass `SimpleRNN` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `SimpleRNN` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.simpleRNNCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `SimpleRNNCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.simpleRNNCell({units: 4}), + * tf.layers.simpleRNNCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `SimpleRNNCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `SimpleRNNCell`, use the + * `tf.layers.simpleRNN`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function simpleRNNCell(args: SimpleRNNCellLayerArgs) { return new SimpleRNNCell(args); } /** -* Convolutional LSTM layer - Xingjian Shi 2015. -* -* This is a `ConvRNN2D` layer consisting of one `ConvLSTM2DCell`. However, -* unlike the underlying `ConvLSTM2DCell`, the `apply` method of `ConvLSTM2D` -* operates on a sequence of inputs. The shape of the input (not including the -* first, batch dimension) needs to be 4-D, with the first dimension being time -* steps. For example: -* -* ```js -* const filters = 3; -* const kernelSize = 3; -* -* const batchSize = 4; -* const sequenceLength = 2; -* const size = 5; -* const channels = 3; -* -* const inputShape = [batchSize, sequenceLength, size, size, channels]; -* const input = tf.ones(inputShape); -* -* const layer = tf.layers.convLstm2d({filters, kernelSize}); -* -* const output = layer.apply(input); -* ``` -*/ + * Convolutional LSTM layer - Xingjian Shi 2015. + * + * This is a `ConvRNN2D` layer consisting of one `ConvLSTM2DCell`. However, + * unlike the underlying `ConvLSTM2DCell`, the `apply` method of `ConvLSTM2D` + * operates on a sequence of inputs. The shape of the input (not including the + * first, batch dimension) needs to be 4-D, with the first dimension being time + * steps. For example: + * + * ```js + * const filters = 3; + * const kernelSize = 3; + * + * const batchSize = 4; + * const sequenceLength = 2; + * const size = 5; + * const channels = 3; + * + * const inputShape = [batchSize, sequenceLength, size, size, channels]; + * const input = tf.ones(inputShape); + * + * const layer = tf.layers.convLstm2d({filters, kernelSize}); + * + * const output = layer.apply(input); + * ``` + */ /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ export function convLstm2d(args: ConvLSTM2DArgs) { return new ConvLSTM2D(args); } /** -* Cell class for `ConvLSTM2D`. -* -* `ConvLSTM2DCell` is distinct from the `ConvRNN2D` subclass `ConvLSTM2D` in -* that its `call` method takes the input data of only a single time step and -* returns the cell's output at the time step, while `ConvLSTM2D` takes the -* input data over a number of time steps. For example: -* -* ```js -* const filters = 3; -* const kernelSize = 3; -* -* const sequenceLength = 1; -* const size = 5; -* const channels = 3; -* -* const inputShape = [sequenceLength, size, size, channels]; -* const input = tf.ones(inputShape); -* -* const cell = tf.layers.convLstm2dCell({filters, kernelSize}); -* -* cell.build(input.shape); -* -* const outputSize = size - kernelSize + 1; -* const outShape = [sequenceLength, outputSize, outputSize, filters]; -* -* const initialH = tf.zeros(outShape); -* const initialC = tf.zeros(outShape); -* -* const [o, h, c] = cell.call([input, initialH, initialC], {}); -* ``` -*/ + * Cell class for `ConvLSTM2D`. + * + * `ConvLSTM2DCell` is distinct from the `ConvRNN2D` subclass `ConvLSTM2D` in + * that its `call` method takes the input data of only a single time step and + * returns the cell's output at the time step, while `ConvLSTM2D` takes the + * input data over a number of time steps. For example: + * + * ```js + * const filters = 3; + * const kernelSize = 3; + * + * const sequenceLength = 1; + * const size = 5; + * const channels = 3; + * + * const inputShape = [sequenceLength, size, size, channels]; + * const input = tf.ones(inputShape); + * + * const cell = tf.layers.convLstm2dCell({filters, kernelSize}); + * + * cell.build(input.shape); + * + * const outputSize = size - kernelSize + 1; + * const outShape = [sequenceLength, outputSize, outputSize, filters]; + * + * const initialH = tf.zeros(outShape); + * const initialC = tf.zeros(outShape); + * + * const [o, h, c] = cell.call([input, initialH, initialC], {}); + * ``` + */ /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ export function convLstm2dCell(args: ConvLSTM2DCellArgs) { return new ConvLSTM2DCell(args); } /** -* Base class for recurrent layers. -* -* Input shape: -* 3D tensor with shape `[batchSize, timeSteps, inputDim]`. -* -* Output shape: -* - if `returnState`, an Array of tensors (i.e., `tf.Tensor`s). The first -* tensor is the output. The remaining tensors are the states at the -* last time step, each with shape `[batchSize, units]`. -* - if `returnSequences`, the output will have shape -* `[batchSize, timeSteps, units]`. -* - else, the output will have shape `[batchSize, units]`. -* -* Masking: -* This layer supports masking for input data with a variable number -* of timesteps. To introduce masks to your data, -* use an embedding layer with the `mask_zero` parameter -* set to `True`. -* -* Notes on using statefulness in RNNs: -* You can set RNN layers to be 'stateful', which means that the states -* computed for the samples in one batch will be reused as initial states -* for the samples in the next batch. This assumes a one-to-one mapping -* between samples in different successive batches. -* -* To enable statefulness: -* - specify `stateful: true` in the layer constructor. -* - specify a fixed batch size for your model, by passing -* if sequential model: -* `batchInputShape=[...]` to the first layer in your model. -* else for functional model with 1 or more Input layers: -* `batchShape=[...]` to all the first layers in your model. -* This is the expected shape of your inputs *including the batch size*. -* It should be a tuple of integers, e.g. `(32, 10, 100)`. -* - specify `shuffle=False` when calling fit(). -* -* To reset the states of your model, call `.resetStates()` on either -* a specific layer, or on your entire model. -* -* Note on specifying the initial state of RNNs -* You can specify the initial state of RNN layers symbolically by -* calling them with the option `initialState`. The value of -* `initialState` should be a tensor or list of tensors representing -* the initial state of the RNN layer. -* -* You can specify the initial state of RNN layers numerically by -* calling `resetStates` with the keyword argument `states`. The value of -* `states` should be a numpy array or list of numpy arrays representing -* the initial state of the RNN layer. -* -* Note on passing external constants to RNNs -* You can pass "external" constants to the cell using the `constants` -* keyword argument of `RNN.call` method. This requires that the `cell.call` -* method accepts the same keyword argument `constants`. Such constants -* can be used to condition the cell transformation on additional static -* inputs (not changing over time), a.k.a. an attention mechanism. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Base class for recurrent layers. + * + * Input shape: + * 3D tensor with shape `[batchSize, timeSteps, inputDim]`. + * + * Output shape: + * - if `returnState`, an Array of tensors (i.e., `tf.Tensor`s). The first + * tensor is the output. The remaining tensors are the states at the + * last time step, each with shape `[batchSize, units]`. + * - if `returnSequences`, the output will have shape + * `[batchSize, timeSteps, units]`. + * - else, the output will have shape `[batchSize, units]`. + * + * Masking: + * This layer supports masking for input data with a variable number + * of timesteps. To introduce masks to your data, + * use an embedding layer with the `mask_zero` parameter + * set to `True`. + * + * Notes on using statefulness in RNNs: + * You can set RNN layers to be 'stateful', which means that the states + * computed for the samples in one batch will be reused as initial states + * for the samples in the next batch. This assumes a one-to-one mapping + * between samples in different successive batches. + * + * To enable statefulness: + * - specify `stateful: true` in the layer constructor. + * - specify a fixed batch size for your model, by passing + * if sequential model: + * `batchInputShape=[...]` to the first layer in your model. + * else for functional model with 1 or more Input layers: + * `batchShape=[...]` to all the first layers in your model. + * This is the expected shape of your inputs *including the batch size*. + * It should be a tuple of integers, e.g. `(32, 10, 100)`. + * - specify `shuffle=False` when calling fit(). + * + * To reset the states of your model, call `.resetStates()` on either + * a specific layer, or on your entire model. + * + * Note on specifying the initial state of RNNs + * You can specify the initial state of RNN layers symbolically by + * calling them with the option `initialState`. The value of + * `initialState` should be a tensor or list of tensors representing + * the initial state of the RNN layer. + * + * You can specify the initial state of RNN layers numerically by + * calling `resetStates` with the keyword argument `states`. The value of + * `states` should be a numpy array or list of numpy arrays representing + * the initial state of the RNN layer. + * + * Note on passing external constants to RNNs + * You can pass "external" constants to the cell using the `constants` + * keyword argument of `RNN.call` method. This requires that the `cell.call` + * method accepts the same keyword argument `constants`. Such constants + * can be used to condition the cell transformation on additional static + * inputs (not changing over time), a.k.a. an attention mechanism. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function rnn(args: RNNLayerArgs) { return new RNN(args); } /** -* Wrapper allowing a stack of RNN cells to behave as a single cell. -* -* Used to implement efficient stacked RNNs. -* -* @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} -*/ + * Wrapper allowing a stack of RNN cells to behave as a single cell. + * + * Used to implement efficient stacked RNNs. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ export function stackedRNNCells(args: StackedRNNCellsArgs){ return new StackedRNNCells(args); } @@ -1525,51 +1525,51 @@ export function bidirectional(args: BidirectionalLayerArgs) { } /** -* This wrapper applies a layer to every temporal slice of an input. -* -* The input should be at least 3D, and the dimension of the index `1` will be -* considered to be the temporal dimension. -* -* Consider a batch of 32 samples, where each sample is a sequence of 10 vectors -* of 16 dimensions. The batch input shape of the layer is then `[32, 10, -* 16]`, and the `inputShape`, not including the sample dimension, is -* `[10, 16]`. -* -* You can then use `TimeDistributed` to apply a `Dense` layer to each of the 10 -* timesteps, independently: -* -* ```js -* const model = tf.sequential(); -* model.add(tf.layers.timeDistributed({ -* layer: tf.layers.dense({units: 8}), -* inputShape: [10, 16], -* })); -* -* // Now model.outputShape = [null, 10, 8]. -* // The output will then have shape `[32, 10, 8]`. -* -* // In subsequent layers, there is no need for `inputShape`: -* model.add(tf.layers.timeDistributed({layer: tf.layers.dense({units: 32})})); -* console.log(JSON.stringify(model.outputs[0].shape)); -* // Now model.outputShape = [null, 10, 32]. -* ``` -* -* The output will then have shape `[32, 10, 32]`. -* -* `TimeDistributed` can be used with arbitrary layers, not just `Dense`, for -* instance a `Conv2D` layer. -* -* ```js -* const model = tf.sequential(); -* model.add(tf.layers.timeDistributed({ -* layer: tf.layers.conv2d({filters: 64, kernelSize: [3, 3]}), -* inputShape: [10, 299, 299, 3], -* })); -* console.log(JSON.stringify(model.outputs[0].shape)); -* ``` -* -* @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} -*/ + * This wrapper applies a layer to every temporal slice of an input. + * + * The input should be at least 3D, and the dimension of the index `1` will be + * considered to be the temporal dimension. + * + * Consider a batch of 32 samples, where each sample is a sequence of 10 vectors + * of 16 dimensions. The batch input shape of the layer is then `[32, 10, + * 16]`, and the `inputShape`, not including the sample dimension, is + * `[10, 16]`. + * + * You can then use `TimeDistributed` to apply a `Dense` layer to each of the 10 + * timesteps, independently: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.timeDistributed({ + * layer: tf.layers.dense({units: 8}), + * inputShape: [10, 16], + * })); + * + * // Now model.outputShape = [null, 10, 8]. + * // The output will then have shape `[32, 10, 8]`. + * + * // In subsequent layers, there is no need for `inputShape`: + * model.add(tf.layers.timeDistributed({layer: tf.layers.dense({units: 32})})); + * console.log(JSON.stringify(model.outputs[0].shape)); + * // Now model.outputShape = [null, 10, 32]. + * ``` + * + * The output will then have shape `[32, 10, 32]`. + * + * `TimeDistributed` can be used with arbitrary layers, not just `Dense`, for + * instance a `Conv2D` layer. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.timeDistributed({ + * layer: tf.layers.conv2d({filters: 64, kernelSize: [3, 3]}), + * inputShape: [10, 299, 299, 3], + * })); + * console.log(JSON.stringify(model.outputs[0].shape)); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} + */ export function timeDistributed(args: WrapperLayerArgs) { return new TimeDistributed(args); } @@ -1583,149 +1583,149 @@ export const maxPool2d = maxPooling2d; export {Layer, RNN, RNNCell, input /* alias for tf.input */}; /** -* Apply additive zero-centered Gaussian noise. -* -* As it is a regularization layer, it is only active at training time. -* -* This is useful to mitigate overfitting -* (you could see it as a form of random data augmentation). -* Gaussian Noise (GS) is a natural choice as corruption process -* for real valued inputs. -* -* # Arguments -* stddev: float, standard deviation of the noise distribution. -* -* # Input shape -* Arbitrary. Use the keyword argument `input_shape` -* (tuple of integers, does not include the samples axis) -* when using this layer as the first layer in a model. -* -* # Output shape -* Same shape as input. -* -* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} -*/ + * Apply additive zero-centered Gaussian noise. + * + * As it is a regularization layer, it is only active at training time. + * + * This is useful to mitigate overfitting + * (you could see it as a form of random data augmentation). + * Gaussian Noise (GS) is a natural choice as corruption process + * for real valued inputs. + * + * # Arguments + * stddev: float, standard deviation of the noise distribution. + * + * # Input shape + * Arbitrary. Use the keyword argument `input_shape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * # Output shape + * Same shape as input. + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ export function gaussianNoise(args: GaussianNoiseArgs) { return new GaussianNoise(args); } /** -* Apply multiplicative 1-centered Gaussian noise. -* -* As it is a regularization layer, it is only active at training time. -* -* Arguments: -* - `rate`: float, drop probability (as with `Dropout`). -* The multiplicative noise will have -* standard deviation `sqrt(rate / (1 - rate))`. -* -* Input shape: -* Arbitrary. Use the keyword argument `inputShape` -* (tuple of integers, does not include the samples axis) -* when using this layer as the first layer in a model. -* -* Output shape: -* Same shape as input. -* -* References: -* - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting]( -* http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) -* -* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} -*/ + * Apply multiplicative 1-centered Gaussian noise. + * + * As it is a regularization layer, it is only active at training time. + * + * Arguments: + * - `rate`: float, drop probability (as with `Dropout`). + * The multiplicative noise will have + * standard deviation `sqrt(rate / (1 - rate))`. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting]( + * http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ export function gaussianDropout(args: GaussianDropoutArgs) { return new GaussianDropout(args); } /** -* Applies Alpha Dropout to the input. -* -* As it is a regularization layer, it is only active at training time. -* -* Alpha Dropout is a `Dropout` that keeps mean and variance of inputs -* to their original values, in order to ensure the self-normalizing property -* even after this dropout. -* Alpha Dropout fits well to Scaled Exponential Linear Units -* by randomly setting activations to the negative saturation value. -* -* Arguments: -* - `rate`: float, drop probability (as with `Dropout`). -* The multiplicative noise will have -* standard deviation `sqrt(rate / (1 - rate))`. -* - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the -* shape for randomly generated keep/drop flags. -* -* Input shape: -* Arbitrary. Use the keyword argument `inputShape` -* (tuple of integers, does not include the samples axis) -* when using this layer as the first layer in a model. -* -* Output shape: -* Same shape as input. -* -* References: -* - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) -* -* @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} -*/ + * Applies Alpha Dropout to the input. + * + * As it is a regularization layer, it is only active at training time. + * + * Alpha Dropout is a `Dropout` that keeps mean and variance of inputs + * to their original values, in order to ensure the self-normalizing property + * even after this dropout. + * Alpha Dropout fits well to Scaled Exponential Linear Units + * by randomly setting activations to the negative saturation value. + * + * Arguments: + * - `rate`: float, drop probability (as with `Dropout`). + * The multiplicative noise will have + * standard deviation `sqrt(rate / (1 - rate))`. + * - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the + * shape for randomly generated keep/drop flags. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ export function alphaDropout(args: AlphaDropoutArgs) { return new AlphaDropout(args); } /** -* Masks a sequence by using a mask value to skip timesteps. -* -* If all features for a given sample timestep are equal to `mask_value`, -* then the sample timestep will be masked (skipped) in all downstream layers -* (as long as they support masking). -* -* If any downstream layer does not support masking yet receives such -* an input mask, an exception will be raised. -* -* Arguments: -* - `maskValue`: Either None or mask value to skip. -* -* Input shape: -* Arbitrary. Use the keyword argument `inputShape` -* (tuple of integers, does not include the samples axis) -* when using this layer as the first layer in a model. -* -* Output shape: -* Same shape as input. -* -* @doc {heading: 'Layers', subheading: 'Mask', namespace: 'layers'} -*/ + * Masks a sequence by using a mask value to skip timesteps. + * + * If all features for a given sample timestep are equal to `mask_value`, + * then the sample timestep will be masked (skipped) in all downstream layers + * (as long as they support masking). + * + * If any downstream layer does not support masking yet receives such + * an input mask, an exception will be raised. + * + * Arguments: + * - `maskValue`: Either None or mask value to skip. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * @doc {heading: 'Layers', subheading: 'Mask', namespace: 'layers'} + */ export function masking(args?: MaskingArgs) { return new Masking(args); } /** -* A preprocessing layer which rescales input values to a new range. -* -* This layer rescales every value of an input (often an image) by multiplying -* by `scale` and adding `offset`. -* -* For instance: -* 1. To rescale an input in the ``[0, 255]`` range -* to be in the `[0, 1]` range, you would pass `scale=1/255`. -* 2. To rescale an input in the ``[0, 255]`` range to be in the `[-1, 1]` -* range, you would pass `scale=1./127.5, offset=-1`. -* The rescaling is applied both during training and inference. Inputs can be -* of integer or floating point dtype, and by default the layer will output -* floats. -* -* Arguments: -* - `scale`: Float, the scale to apply to the inputs. -* - `offset`: Float, the offset to apply to the inputs. -* -* Input shape: -* Arbitrary. -* -* Output shape: -* Same as input. -* -* @doc {heading: 'Layers', subheading: 'Rescaling', namespace: 'layers'} -*/ + * A preprocessing layer which rescales input values to a new range. + * + * This layer rescales every value of an input (often an image) by multiplying + * by `scale` and adding `offset`. + * + * For instance: + * 1. To rescale an input in the ``[0, 255]`` range + * to be in the `[0, 1]` range, you would pass `scale=1/255`. + * 2. To rescale an input in the ``[0, 255]`` range to be in the `[-1, 1]` + * range, you would pass `scale=1./127.5, offset=-1`. + * The rescaling is applied both during training and inference. Inputs can be + * of integer or floating point dtype, and by default the layer will output + * floats. + * + * Arguments: + * - `scale`: Float, the scale to apply to the inputs. + * - `offset`: Float, the offset to apply to the inputs. + * + * Input shape: + * Arbitrary. + * + * Output shape: + * Same as input. + * + * @doc {heading: 'Layers', subheading: 'Rescaling', namespace: 'layers'} + */ export function rescaling(args?: RescalingArgs) { return new Rescaling(args); } diff --git a/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts b/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts index 2bfe0ebce4e..184c244c540 100644 --- a/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts +++ b/tfjs-layers/src/layers/preprocessing/image_preprocessing.ts @@ -8,26 +8,25 @@ * ============================================================================= */ -import {LayerArgs, Layer} from '../../engine/topology' -import { serialization, Tensor} from '@tensorflow/tfjs-core'; +import {LayerArgs, Layer} from '../../engine/topology'; +import { serialization, Tensor, mul, add, tidy } from '@tensorflow/tfjs-core'; import { getExactlyOneTensor } from '../../utils/types_utils'; import * as K from '../../backend/tfjs_backend'; -import { mul, add, tidy } from "@tensorflow/tfjs-core"; -import { Kwargs } from "../../types"; +import { Kwargs } from '../../types'; export declare interface RescalingArgs extends LayerArgs { scale: number; - offset?: number + offset?: number; } /** -* Preprocessing Rescaling Layer -* -* This rescales images by a scaling and offset factor -*/ + * Preprocessing Rescaling Layer + * + * This rescales images by a scaling and offset factor + */ export class Rescaling extends Layer { /** @nocollapse */ - static className = "Rescaling"; + static className = 'Rescaling'; private readonly scale: number; private readonly offset: number; constructor(args: RescalingArgs) { @@ -44,8 +43,8 @@ export class Rescaling extends Layer { getConfig(): serialization.ConfigDict { const config: serialization.ConfigDict = { - "scale": this.scale, - "offset": this.offset + 'scale': this.scale, + 'offset': this.offset }; const baseConfig = super.getConfig(); @@ -56,8 +55,8 @@ export class Rescaling extends Layer { call(inputs: Tensor|Tensor[], kwargs: Kwargs): Tensor[]|Tensor { return tidy(() => { inputs = getExactlyOneTensor(inputs); - if(inputs.dtype != 'float32') { - inputs = K.cast(inputs, "float32"); + if(inputs.dtype !== 'float32') { + inputs = K.cast(inputs, 'float32'); } return add(mul(inputs, this.scale), this.offset); }); diff --git a/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts b/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts index 8f1e5e3cf20..d40e2fec879 100644 --- a/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts +++ b/tfjs-layers/src/layers/preprocessing/image_preprocessing_test.ts @@ -1,47 +1,46 @@ import { Tensor, randomNormal, mul, add} from '@tensorflow/tfjs-core'; -import { Rescaling } from './image_preprocessing' +import { Rescaling } from './image_preprocessing'; import { describeMathCPUAndGPU, expectTensorsClose } from '../../utils/test_utils'; -describeMathCPUAndGPU("Rescaling Layer", () => { +describeMathCPUAndGPU('Rescaling Layer', () => { - it("Check if input shape matches output shape", () => { + it('Check if input shape matches output shape', () => { const scale = 1.0 / 127.5; const offset = 0; const input = randomNormal([2, 4, 5, 3]); const expectedOutputTensor = add(mul(input, scale), offset); - const scalingLayer = new Rescaling({scale: scale, offset: offset}); + const scalingLayer = new Rescaling({scale, offset}); const layerOutputTensor = scalingLayer.apply(input) as Tensor; expect(expectedOutputTensor.shape).toEqual(layerOutputTensor.shape); }); - it("Rescales input layer based on specified scaling factor and offset", () => { + it('Rescales input layer based on scaling factor and offset', () => { const scale = 1.0 / 127.5; const offset = -1.0; const input = randomNormal([2, 4, 5, 3]); const expectedOutputTensor = add(mul(input, scale), offset); - const scalingLayer = new Rescaling({scale: scale, offset: offset}); + const scalingLayer = new Rescaling({scale, offset}); const layerOutputTensor = scalingLayer.apply(input) as Tensor; expectTensorsClose(layerOutputTensor, expectedOutputTensor); }); - it("Recasts dtype to float32", () => { + it('Recasts dtype to float32', () => { const scale = 1.0 / 127.5; const offset = -1.0; - const intTensor = randomNormal([2, 4, 5, 3], 7, 2, "int32"); + const intTensor = randomNormal([2, 4, 5, 3], 7, 2, 'int32'); const expectedOutputTensor = add(mul(intTensor, scale), offset); - const scalingLayer = new Rescaling({scale: scale , offset: offset}); + const scalingLayer = new Rescaling({scale, offset}); const outputTensor = scalingLayer.apply(intTensor) as Tensor; - expect(outputTensor.dtype).toBe("float32"); // check dtype here - expectTensorsClose(outputTensor, expectedOutputTensor); // check actual values here + expect(outputTensor.dtype).toBe('float32'); + expectTensorsClose(outputTensor, expectedOutputTensor); }); - it("Config holds correct name", () => { + it('Config holds correct name', () => { const scale = 1.0 / 127.5; const offset = -1.0; - const scalingLayer = new Rescaling({scale: scale , offset: offset, name: "Rescaling"}); - const config = scalingLayer.getConfig() - expect(config.name).toEqual("Rescaling"); // check dtype here + const scalingLayer = new Rescaling({scale, offset, name: 'Rescaling'}); + const config = scalingLayer.getConfig(); + expect(config.name).toEqual('Rescaling'); }); }); -