UNPKG

@tensorflow/tfjs-layers

Version:

TensorFlow layers API in JavaScript

1 lines 2.56 MB
{"version":3,"file":"tf-layers.es2017.js","sources":["../../../../tfjs-layers/src/errors.ts","../../../../tfjs-layers/src/utils/executor_utils.ts","../../../../tfjs-layers/src/utils/generic_utils.ts","../../../../tfjs-layers/src/backend/state.ts","../../../../tfjs-layers/src/keras_format/common.ts","../../../../tfjs-layers/src/common.ts","../../../../tfjs-layers/src/utils/math_utils.ts","../../../../tfjs-layers/src/backend/common.ts","../../../../tfjs-layers/src/backend/tfjs_backend.ts","../../../../tfjs-layers/src/keras_format/initializer_config.ts","../../../../tfjs-layers/src/initializers.ts","../../../../tfjs-layers/src/utils/types_utils.ts","../../../../tfjs-layers/src/utils/variable_utils.ts","../../../../tfjs-layers/src/variables.ts","../../../../tfjs-layers/src/engine/topology.ts","../../../../tfjs-layers/src/engine/input_layer.ts","../../../../tfjs-layers/src/engine/executor.ts","../../../../tfjs-layers/src/flags_layers.ts","../../../../../tfjs-core/src/kernel_names.ts","../../../../../tfjs-core/src/backends/backend.ts","../../../../../tfjs-core/src/util_base.ts","../../../../../tfjs-core/src/environment.ts","../../../../../tfjs-core/src/global_util.ts","../../../../../tfjs-core/src/log.ts","../../../../../tfjs-core/src/kernel_registry.ts","../../../../../tfjs-core/src/platforms/is_typed_array_browser.ts","../../../../node_modules/long/src/long.js","../../../../../tfjs-core/src/hash_util.ts","../../../../../tfjs-core/src/util.ts","../../../../../tfjs-core/src/profiler.ts","../../../../../tfjs-core/src/tape.ts","../../../../../tfjs-core/src/tensor_format.ts","../../../../../tfjs-core/src/tensor.ts","../../../../../tfjs-core/src/types.ts","../../../../../tfjs-core/src/tensor_util.ts","../../../../../tfjs-core/src/engine.ts","../../../../../tfjs-core/src/tensor_util_env.ts","../../../../../tfjs-core/src/ops/operation.ts","../../../../../tfjs-core/src/ops/cast.ts","../../../../../tfjs-core/src/ops/mul.ts","../../../../../tfjs-core/src/ops/step.ts","../../../../../tfjs-core/src/gradients/Abs_grad.ts","../../../../../tfjs-core/src/ops/floorDiv.ts","../../../../../tfjs-core/src/ops/div.ts","../../../../../tfjs-core/src/ops/neg.ts","../../../../../tfjs-core/src/ops/tensor_ops_util.ts","../../../../../tfjs-core/src/ops/scalar.ts","../../../../../tfjs-core/src/ops/sqrt.ts","../../../../../tfjs-core/src/ops/square.ts","../../../../../tfjs-core/src/ops/sub.ts","../../../../../tfjs-core/src/gradients/Acos_grad.ts","../../../../../tfjs-core/src/gradients/Acosh_grad.ts","../../../../../tfjs-core/src/ops/broadcast_util.ts","../../../../../tfjs-core/src/ops/reshape.ts","../../../../../tfjs-core/src/ops/sum.ts","../../../../../tfjs-core/src/gradients/Add_grad.ts","../../../../../tfjs-core/src/gradients/AddN_grad.ts","../../../../../tfjs-core/src/ops/zeros_like.ts","../../../../../tfjs-core/src/gradients/ArgMax_grad.ts","../../../../../tfjs-core/src/gradients/ArgMin_grad.ts","../../../../../tfjs-core/src/gradients/Asin_grad.ts","../../../../../tfjs-core/src/ops/add.ts","../../../../../tfjs-core/src/gradients/Asinh_grad.ts","../../../../../tfjs-core/src/gradients/Atan2_grad.ts","../../../../../tfjs-core/src/gradients/Atan_grad.ts","../../../../../tfjs-core/src/gradients/Atanh_grad.ts","../../../../../tfjs-core/src/ops/conv_util.ts","../../../../../tfjs-core/src/ops/avg_pool_3d_grad.ts","../../../../../tfjs-core/src/gradients/AvgPool3D_grad.ts","../../../../../tfjs-core/src/ops/avg_pool_grad.ts","../../../../../tfjs-core/src/gradients/AvgPool_grad.ts","../../../../../tfjs-core/src/ops/mat_mul.ts","../../../../../tfjs-core/src/gradients/BatchMatMul_grad.ts","../../../../../tfjs-core/src/ops/space_to_batch_nd.ts","../../../../../tfjs-core/src/gradients/BatchToSpaceND_grad.ts","../../../../../tfjs-core/src/gradients/BroadcastTo_grad.ts","../../../../../tfjs-core/src/gradients/Cast_grad.ts","../../../../../tfjs-core/src/gradients/Ceil_grad.ts","../../../../../tfjs-core/src/ops/greater_equal.ts","../../../../../tfjs-core/src/ops/less_equal.ts","../../../../../tfjs-core/src/ops/logical_and.ts","../../../../../tfjs-core/src/ops/clone.ts","../../../../../tfjs-core/src/ops/broadcast_to.ts","../../../../../tfjs-core/src/ops/where.ts","../../../../../tfjs-core/src/gradients/ClipByValue_grad.ts","../../../../../tfjs-core/src/gradients/ComplexAbs_grad.ts","../../../../../tfjs-core/src/ops/split.ts","../../../../../tfjs-core/src/gradients/Concat_grad.ts","../../../../../tfjs-core/src/ops/conv2d_backprop_filter.ts","../../../../../tfjs-core/src/ops/conv2d_backprop_input.ts","../../../../../tfjs-core/src/gradients/Conv2D_grad.ts","../../../../../tfjs-core/src/ops/conv2d.ts","../../../../../tfjs-core/src/gradients/Conv2DBackpropInput_grad.ts","../../../../../tfjs-core/src/ops/conv3d_backprop_filter.ts","../../../../../tfjs-core/src/ops/conv3d_backprop_input.ts","../../../../../tfjs-core/src/gradients/Conv3D_grad.ts","../../../../../tfjs-core/src/ops/sin.ts","../../../../../tfjs-core/src/gradients/Cos_grad.ts","../../../../../tfjs-core/src/ops/sinh.ts","../../../../../tfjs-core/src/gradients/Cosh_grad.ts","../../../../../tfjs-core/src/ops/axis_util.ts","../../../../../tfjs-core/src/ops/cumsum.ts","../../../../../tfjs-core/src/globals.ts","../../../../../tfjs-core/src/ops/complex.ts","../../../../../tfjs-core/src/ops/imag.ts","../../../../../tfjs-core/src/ops/real.ts","../../../../../tfjs-core/src/ops/transpose.ts","../../../../../tfjs-core/src/gradients/Cumsum_grad.ts","../../../../../tfjs-core/src/ops/depthwise_conv2d_native_backprop_filter.ts","../../../../../tfjs-core/src/ops/depthwise_conv2d_native_backprop_input.ts","../../../../../tfjs-core/src/gradients/DepthwiseConv2dNative_grad.ts","../../../../../tfjs-core/src/gradients/Dilation2D_grad.ts","../../../../../tfjs-core/src/gradients/Elu_grad.ts","../../../../../tfjs-core/src/ops/exp.ts","../../../../../tfjs-core/src/gradients/Erf_grad.ts","../../../../../tfjs-core/src/gradients/Exp_grad.ts","../../../../../tfjs-core/src/gradients/ExpandDims_grad.ts","../../../../../tfjs-core/src/gradients/Expm1_grad.ts","../../../../../tfjs-core/src/gradients/Floor_grad.ts","../../../../../tfjs-core/src/gradients/FloorDiv_grad.ts","../../../../../tfjs-core/src/ops/rsqrt.ts","../../../../../tfjs-core/src/ops/tile.ts","../../../../../tfjs-core/src/gradients/FusedBatchNorm_grad.ts","../../../../../tfjs-core/src/ops/stack.ts","../../../../../tfjs-core/src/ops/unsorted_segment_sum.ts","../../../../../tfjs-core/src/gradients/GatherV2_grad.ts","../../../../../tfjs-core/src/gradients/GreaterEqual_grad.ts","../../../../../tfjs-core/src/gradients/Identity_grad.ts","../../../../../tfjs-core/src/gradients/IsFinite_grad.ts","../../../../../tfjs-core/src/gradients/IsInf_grad.ts","../../../../../tfjs-core/src/gradients/IsNan_grad.ts","../../../../../tfjs-core/src/ops/greater.ts","../../../../../tfjs-core/src/gradients/LeakyRelu_grad.ts","../../../../../tfjs-core/src/gradients/Log1p_grad.ts","../../../../../tfjs-core/src/gradients/Log_grad.ts","../../../../../tfjs-core/src/gradients/LogSoftmax_grad.ts","../../../../../tfjs-core/src/ops/local_response_normalization_backprop.ts","../../../../../tfjs-core/src/gradients/LRN_grad.ts","../../../../../tfjs-core/src/ops/equal.ts","../../../../../tfjs-core/src/gradients/min_max_grad_util.ts","../../../../../tfjs-core/src/gradients/Max_grad.ts","../../../../../tfjs-core/src/ops/less.ts","../../../../../tfjs-core/src/gradients/Maximum_grad.ts","../../../../../tfjs-core/src/ops/max_pool_3d_grad.ts","../../../../../tfjs-core/src/gradients/MaxPool3D_grad.ts","../../../../../tfjs-core/src/ops/max_pool_grad.ts","../../../../../tfjs-core/src/gradients/MaxPool_grad.ts","../../../../../tfjs-core/src/ops/zeros.ts","../../../../../tfjs-core/src/ops/ones.ts","../../../../../tfjs-core/src/gradients/Mean_grad.ts","../../../../../tfjs-core/src/gradients/Min_grad.ts","../../../../../tfjs-core/src/gradients/Minimum_grad.ts","../../../../../tfjs-core/src/ops/slice.ts","../../../../../tfjs-core/src/gradients/MirrorPad_grad.ts","../../../../../tfjs-core/src/ops/floor.ts","../../../../../tfjs-core/src/gradients/Mod_grad.ts","../../../../../tfjs-core/src/gradients/Multiply_grad.ts","../../../../../tfjs-core/src/gradients/Neg_grad.ts","../../../../../tfjs-core/src/gradients/OneHot_grad.ts","../../../../../tfjs-core/src/gradients/OnesLike_grad.ts","../../../../../tfjs-core/src/ops/unstack.ts","../../../../../tfjs-core/src/gradients/Pack_grad.ts","../../../../../tfjs-core/src/gradients/PadV2_grad.ts","../../../../../tfjs-core/src/ops/log.ts","../../../../../tfjs-core/src/ops/pow.ts","../../../../../tfjs-core/src/gradients/Pow_grad.ts","../../../../../tfjs-core/src/gradients/Prelu_grad.ts","../../../../../tfjs-core/src/device_util.ts","../../../../../tfjs-core/src/flags.ts","../../../../../tfjs-core/src/io/composite_array_buffer.ts","../../../../../tfjs-core/src/io/io_utils.ts","../../../../../tfjs-core/src/io/router_registry.ts","../../../../../tfjs-core/src/io/indexed_db.ts","../../../../../tfjs-core/src/io/local_storage.ts","../../../../../tfjs-core/src/io/browser_files.ts","../../../../../tfjs-core/src/io/progress.ts","../../../../../tfjs-core/src/io/weights_loader.ts","../../../../../tfjs-core/src/io/http.ts","../../../../../tfjs-core/src/ops/scatter_nd_util.ts","../../../../../tfjs-core/src/ops/slice_util.ts","../../../../../tfjs-core/src/ops/concat.ts","../../../../../tfjs-core/src/ops/sigmoid.ts","../../../../../tfjs-core/src/ops/batch_to_space_nd.ts","../../../../../tfjs-core/src/ops/cos.ts","../../../../../tfjs-core/src/ops/cosh.ts","../../../../../tfjs-core/src/ops/cumprod.ts","../../../../../tfjs-core/src/ops/expand_dims.ts","../../../../../tfjs-core/src/ops/gather.ts","../../../../../tfjs-core/src/ops/logical_not.ts","../../../../../tfjs-core/src/ops/maximum.ts","../../../../../tfjs-core/src/ops/pad.ts","../../../../node_modules/seedrandom/lib/alea.js","../../../../node_modules/seedrandom/lib/xor128.js","../../../../node_modules/seedrandom/lib/xorwow.js","../../../../node_modules/seedrandom/lib/xorshift7.js","../../../../node_modules/seedrandom/lib/xor4096.js","../../../../node_modules/seedrandom/lib/tychei.js","../../../../node_modules/seedrandom/seedrandom.js","../../../../node_modules/seedrandom/index.js","../../../../../tfjs-core/src/ops/reverse.ts","../../../../../tfjs-core/src/ops/tensor_scatter_update.ts","../../../../../tfjs-core/src/ops/loss_ops_utils.ts","../../../../../tfjs-core/src/browser_util.ts","../../../../../tfjs-core/src/ops/ragged_to_dense_util.ts","../../../../../tfjs-core/src/ops/selu_util.ts","../../../../../tfjs-core/src/gradients/Prod_grad.ts","../../../../../tfjs-core/src/gradients/RealDiv_grad.ts","../../../../../tfjs-core/src/gradients/Reciprocal_grad.ts","../../../../../tfjs-core/src/gradients/Relu6_grad.ts","../../../../../tfjs-core/src/gradients/Relu_grad.ts","../../../../../tfjs-core/src/gradients/Reshape_grad.ts","../../../../../tfjs-core/src/gradients/ResizeBilinear_grad.ts","../../../../../tfjs-core/src/gradients/ResizeNearestNeighbor_grad.ts","../../../../../tfjs-core/src/gradients/Reverse_grad.ts","../../../../../tfjs-core/src/gradients/Round_grad.ts","../../../../../tfjs-core/src/gradients/Rsqrt_grad.ts","../../../../../tfjs-core/src/gradients/Select_grad.ts","../../../../../tfjs-core/src/gradients/Selu_grad.ts","../../../../../tfjs-core/src/gradients/Sigmoid_grad.ts","../../../../../tfjs-core/src/gradients/Sign_grad.ts","../../../../../tfjs-core/src/gradients/Sin_grad.ts","../../../../../tfjs-core/src/gradients/Sinh_grad.ts","../../../../../tfjs-core/src/gradients/Slice_grad.ts","../../../../../tfjs-core/src/gradients/Softmax_grad.ts","../../../../../tfjs-core/src/gradients/Softplus_grad.ts","../../../../../tfjs-core/src/gradients/SpaceToBatchND_grad.ts","../../../../../tfjs-core/src/gradients/SplitV_grad.ts","../../../../../tfjs-core/src/gradients/Sqrt_grad.ts","../../../../../tfjs-core/src/gradients/Square_grad.ts","../../../../../tfjs-core/src/gradients/SquaredDifference_grad.ts","../../../../../tfjs-core/src/gradients/Step_grad.ts","../../../../../tfjs-core/src/gradients/Sub_grad.ts","../../../../../tfjs-core/src/gradients/Sum_grad.ts","../../../../../tfjs-core/src/gradients/Tan_grad.ts","../../../../../tfjs-core/src/gradients/Tanh_grad.ts","../../../../../tfjs-core/src/gradients/Tile_grad.ts","../../../../../tfjs-core/src/gradients/Transpose_grad.ts","../../../../../tfjs-core/src/gradients/Unpack_grad.ts","../../../../../tfjs-core/src/gradients/UnsortedSegmentSum_grad.ts","../../../../../tfjs-core/src/gradients/ZerosLike_grad.ts","../../../../../tfjs-core/src/register_all_gradients.ts","../../../../tfjs-layers/src/constraints.ts","../../../../tfjs-layers/src/exports_constraints.ts","../../../../tfjs-layers/src/exports_initializers.ts","../../../../tfjs-layers/src/logs.ts","../../../../tfjs-layers/src/base_callbacks.ts","../../../../tfjs-layers/src/layers/serialization.ts","../../../../tfjs-layers/src/losses.ts","../../../../tfjs-layers/src/metrics.ts","../../../../tfjs-layers/src/optimizers.ts","../../../../tfjs-layers/src/user_defined_metadata.ts","../../../../tfjs-layers/src/utils/layer_utils.ts","../../../../tfjs-layers/src/utils/serialization_utils.ts","../../../../tfjs-layers/src/version.ts","../../../../tfjs-layers/src/engine/container.ts","../../../../tfjs-layers/src/engine/training_utils.ts","../../../../tfjs-layers/src/engine/training_dataset.ts","../../../../tfjs-layers/src/engine/training_tensors.ts","../../../../tfjs-layers/src/engine/training.ts","../../../../tfjs-layers/src/models.ts","../../../../tfjs-layers/src/exports.ts","../../../../tfjs-layers/src/activations.ts","../../../../tfjs-layers/src/regularizers.ts","../../../../tfjs-layers/src/layers/advanced_activations.ts","../../../../tfjs-layers/src/utils/conv_utils.ts","../../../../tfjs-layers/src/layers/convolutional.ts","../../../../tfjs-layers/src/layers/convolutional_depthwise.ts","../../../../tfjs-layers/src/layers/recurrent.ts","../../../../tfjs-layers/src/layers/convolutional_recurrent.ts","../../../../tfjs-layers/src/layers/core.ts","../../../../tfjs-layers/src/layers/embeddings.ts","../../../../tfjs-layers/src/layers/merge.ts","../../../../tfjs-layers/src/layers/noise.ts","../../../../tfjs-layers/src/layers/normalization.ts","../../../../tfjs-layers/src/layers/padding.ts","../../../../tfjs-layers/src/layers/pooling.ts","../../../../tfjs-layers/src/layers/wrappers.ts","../../../../tfjs-layers/src/layers/preprocessing/image_preprocessing.ts","../../../../tfjs-layers/src/layers/preprocessing/center_crop.ts","../../../../tfjs-layers/src/layers/preprocessing/preprocessing_utils.ts","../../../../tfjs-layers/src/layers/preprocessing/category_encoding.ts","../../../../tfjs-layers/src/layers/preprocessing/image_resizing.ts","../../../../tfjs-layers/src/backend/random_seed.ts","../../../../tfjs-layers/src/engine/base_random_layer.ts","../../../../tfjs-layers/src/layers/preprocessing/random_width.ts","../../../../tfjs-layers/src/exports_layers.ts","../../../../tfjs-layers/src/exports_metrics.ts","../../../../tfjs-layers/src/exports_models.ts","../../../../tfjs-layers/src/exports_regularizers.ts","../../../../tfjs-layers/src/callbacks.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/**\n * Explicit error types.\n *\n * See the following link for more information about why the code includes\n * calls to setPrototypeOf:\n *\n * https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n */\n// tslint:enable\n\n/**\n * Equivalent of Python's AttributeError.\n */\nexport class AttributeError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, AttributeError.prototype);\n }\n}\n\n/**\n * Equivalent of Python's RuntimeError.\n */\nexport class RuntimeError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, RuntimeError.prototype);\n }\n}\n\n/**\n * Equivalent of Python's ValueError.\n */\nexport class ValueError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, ValueError.prototype);\n }\n}\n\n/**\n * Equivalent of Python's NotImplementedError.\n */\nexport class NotImplementedError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, NotImplementedError.prototype);\n }\n}\n\n/**\n * Equivalent of Python's AssertionError.\n */\nexport class AssertionError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, AssertionError.prototype);\n }\n}\n\n/**\n * Equivalent of Python's IndexError.\n */\nexport class IndexError extends Error {\n constructor(message?: string) {\n super(message);\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, IndexError.prototype);\n }\n}\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n/**\n * LruCache: A mapping from the String to T. If the number of the entries is\n * exceeding the `maxEntries`, the LruCache will delete the least recently\n * used entry.\n */\n\nexport class LruCache<T> {\n private cache: Map<string, T>;\n private maxEntries: number;\n\n constructor(maxEntries?: number) {\n this.maxEntries = maxEntries || 100;\n this.cache = new Map<string, T>();\n }\n\n /**\n * Get the entry for the key and mark it as used recently.\n */\n public get(key: string): T {\n let entry: T;\n if (this.cache.has(key)) {\n entry = this.cache.get(key);\n this.cache.delete(key);\n this.cache.set(key, entry);\n }\n return entry;\n }\n\n /**\n * Put the entry into the cache. If the key already existed, mark the key as\n * used recently.\n */\n public put(key: string, value: T): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxEntries) {\n const keyToDelete = this.cache.keys().next().value;\n this.cache.delete(keyToDelete);\n }\n this.cache.set(key, value);\n }\n\n /**\n * Get the MaxEntries of the cache.\n */\n public getMaxEntries(): number {\n return this.maxEntries;\n }\n\n /**\n * Set the MaxEntries of the cache. If the maxEntries is decreased, reduce\n * entries in the cache.\n */\n public setMaxEntries(maxEntries: number): void {\n if (maxEntries < 0) {\n throw new Error(\n `The maxEntries of LRU caches must be at least 0, but got ${\n maxEntries}.`);\n }\n\n if (this.maxEntries > maxEntries) {\n for (let i = 0; i < this.maxEntries - maxEntries; i++) {\n const keyToDelete = this.cache.keys().next().value;\n this.cache.delete(keyToDelete);\n }\n }\n\n this.maxEntries = maxEntries;\n }\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/* Original source: utils/generic_utils.py */\n\nimport {DataType, fused, serialization, util} from '@tensorflow/tfjs-core';\n\nimport {AssertionError, ValueError} from '../errors';\n\n// tslint:enable\n\n/**\n * If `value` is an Array, equivalent to Python's `value * numValues`.\n * If `value` is not an Array, equivalent to Python's `[value] * numValues`\n */\n// tslint:disable-next-line:no-any\nexport function pyListRepeat(value: any, numValues: number): any[] {\n if (Array.isArray(value)) {\n // tslint:disable-next-line:no-any\n let newArray: any[] = [];\n for (let i = 0; i < numValues; i++) {\n newArray = newArray.concat(value);\n }\n return newArray;\n } else {\n const newArray = new Array(numValues);\n newArray.fill(value);\n return newArray;\n }\n}\n\nexport function assert(val: boolean, message?: string): void {\n if (!val) {\n throw new AssertionError(message);\n }\n}\n\n/**\n * Count the number of elements of the `array` that are equal to `reference`.\n */\nexport function count<T>(array: T[], refernce: T) {\n let counter = 0;\n for (const item of array) {\n if (item === refernce) {\n counter++;\n }\n }\n return counter;\n}\n\n/**\n * If an array is of length 1, just return the first element. Otherwise, return\n * the full array.\n * @param tensors\n */\nexport function singletonOrArray<T>(xs: T[]): T|T[] {\n if (xs.length === 1) {\n return xs[0];\n }\n return xs;\n}\n\n/**\n * Normalizes a list/tensor into a list.\n *\n * If a tensor is passed, we return\n * a list of size 1 containing the tensor.\n *\n * @param x target object to be normalized.\n */\n// tslint:disable-next-line:no-any\nexport function toList<T>(x: T|T[]): T[] {\n if (Array.isArray(x)) {\n return x;\n }\n return [x];\n}\n\n/**\n * Generate a UID for a list\n */\n// tslint:disable-next-line:no-any\nexport function objectListUid(objs: any|any[]): string {\n const objectList = toList(objs);\n let retVal = '';\n for (const obj of objectList) {\n if (obj.id == null) {\n throw new ValueError(\n `Object ${obj} passed to objectListUid without an id`);\n }\n if (retVal !== '') {\n retVal = retVal + ', ';\n }\n retVal = `${retVal}${Math.abs(obj.id)}`;\n }\n return retVal;\n}\n/**\n * Converts string to snake-case.\n * @param name\n */\nexport function toSnakeCase(name: string): string {\n const intermediate = name.replace(/(.)([A-Z][a-z0-9]+)/g, '$1_$2');\n const insecure =\n intermediate.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();\n /*\n If the class is private the name starts with \"_\" which is not secure\n for creating scopes. We prefix the name with \"private\" in this case.\n */\n if (insecure[0] !== '_') {\n return insecure;\n }\n return 'private' + insecure;\n}\n\nexport function toCamelCase(identifier: string): string {\n // quick return for empty string or single character strings\n if (identifier.length <= 1) {\n return identifier;\n }\n // Check for the underscore indicating snake_case\n if (identifier.indexOf('_') === -1) {\n return identifier;\n }\n return identifier.replace(/[_]+(\\w|$)/g, (m, p1) => p1.toUpperCase());\n}\n\n// tslint:disable-next-line:no-any\nlet _GLOBAL_CUSTOM_OBJECTS = {} as {[objName: string]: any};\n\nexport function serializeKerasObject(instance: serialization.Serializable):\n serialization.ConfigDictValue {\n if (instance === null || instance === undefined) {\n return null;\n }\n const dict: serialization.ConfigDictValue = {};\n dict['className'] = instance.getClassName();\n dict['config'] = instance.getConfig();\n return dict;\n}\n\n/**\n * Replace ndarray-style scalar objects in serialization objects with numbers.\n *\n * Background: In some versions of tf.keras, certain scalar values in the HDF5\n * model save file can be serialized as: `{'type': 'ndarray', 'value': num}`,\n * where in `num` is a plain number. This method converts such serialization\n * to a `number`.\n *\n * @param config The keras-format serialization object to be processed\n * (in place).\n */\nfunction convertNDArrayScalarsInConfig(config: serialization.ConfigDictValue):\n void {\n if (config == null || typeof config !== 'object') {\n return;\n } else if (Array.isArray(config)) {\n config.forEach(configItem => convertNDArrayScalarsInConfig(configItem));\n } else {\n const fields = Object.keys(config);\n for (const field of fields) {\n const value = config[field];\n if (value != null && typeof value === 'object') {\n if (!Array.isArray(value) && value['type'] === 'ndarray' &&\n typeof value['value'] === 'number') {\n config[field] = value['value'];\n } else {\n convertNDArrayScalarsInConfig(value as serialization.ConfigDict);\n }\n }\n }\n }\n}\n\n/**\n * Deserialize a saved Keras Object\n * @param identifier either a string ID or a saved Keras dictionary\n * @param moduleObjects a list of Python class names to object constructors\n * @param customObjects a list of Python class names to object constructors\n * @param printableModuleName debug text for the object being reconstituted\n * @param fastWeightInit Optional flag to use fast weight initialization\n * during deserialization. This is applicable to cases in which\n * the initialization will be immediately overwritten by loaded weight\n * values. Default: `false`.\n * @returns a TensorFlow.js Layers object\n */\n// tslint:disable:no-any\nexport function deserializeKerasObject(\n identifier: string|serialization.ConfigDict,\n moduleObjects = {} as {[objName: string]: any},\n customObjects = {} as {[objName: string]: any},\n printableModuleName = 'object', fastWeightInit = false): any {\n // tslint:enable\n if (typeof identifier === 'string') {\n const functionName = identifier;\n let fn;\n if (functionName in customObjects) {\n fn = customObjects[functionName];\n } else if (functionName in _GLOBAL_CUSTOM_OBJECTS) {\n fn = _GLOBAL_CUSTOM_OBJECTS[functionName];\n } else {\n fn = moduleObjects[functionName];\n if (fn == null) {\n throw new ValueError(\n `Unknown ${printableModuleName}: ${identifier}. ` +\n `This may be due to one of the following reasons:\\n` +\n `1. The ${printableModuleName} is defined in Python, in which ` +\n `case it needs to be ported to TensorFlow.js or your JavaScript ` +\n `code.\\n` +\n `2. The custom ${printableModuleName} is defined in JavaScript, ` +\n `but is not registered properly with ` +\n `tf.serialization.registerClass().`);\n // TODO(cais): Add link to tutorial page on custom layers.\n }\n }\n return fn;\n } else {\n // In this case we are dealing with a Keras config dictionary.\n const config = identifier;\n if (config['className'] == null || config['config'] == null) {\n throw new ValueError(\n `${printableModuleName}: Improper config format: ` +\n `${JSON.stringify(config)}.\\n` +\n `'className' and 'config' must set.`);\n }\n const className = config['className'] as string;\n let cls, fromConfig;\n if (className in customObjects) {\n [cls, fromConfig] = customObjects[className];\n } else if (className in _GLOBAL_CUSTOM_OBJECTS) {\n [cls, fromConfig] = _GLOBAL_CUSTOM_OBJECTS['className'];\n } else if (className in moduleObjects) {\n [cls, fromConfig] = moduleObjects[className];\n }\n if (cls == null) {\n throw new ValueError(\n `Unknown ${printableModuleName}: ${className}. ` +\n `This may be due to one of the following reasons:\\n` +\n `1. The ${printableModuleName} is defined in Python, in which ` +\n `case it needs to be ported to TensorFlow.js or your JavaScript ` +\n `code.\\n` +\n `2. The custom ${printableModuleName} is defined in JavaScript, ` +\n `but is not registered properly with ` +\n `tf.serialization.registerClass().`);\n // TODO(cais): Add link to tutorial page on custom layers.\n }\n if (fromConfig != null) {\n // Porting notes: Instead of checking to see whether fromConfig accepts\n // customObjects, we create a customObjects dictionary and tack it on to\n // config['config'] as config['config'].customObjects. Objects can use it,\n // if they want.\n\n // tslint:disable-next-line:no-any\n const customObjectsCombined = {} as {[objName: string]: any};\n for (const key of Object.keys(_GLOBAL_CUSTOM_OBJECTS)) {\n customObjectsCombined[key] = _GLOBAL_CUSTOM_OBJECTS[key];\n }\n for (const key of Object.keys(customObjects)) {\n customObjectsCombined[key] = customObjects[key];\n }\n // Add the customObjects to config\n const nestedConfig = config['config'] as serialization.ConfigDict;\n nestedConfig['customObjects'] = customObjectsCombined;\n\n const backupCustomObjects = {..._GLOBAL_CUSTOM_OBJECTS};\n for (const key of Object.keys(customObjects)) {\n _GLOBAL_CUSTOM_OBJECTS[key] = customObjects[key];\n }\n convertNDArrayScalarsInConfig(config['config']);\n const returnObj =\n fromConfig(cls, config['config'], customObjects, fastWeightInit);\n _GLOBAL_CUSTOM_OBJECTS = {...backupCustomObjects};\n\n return returnObj;\n } else {\n // Then `cls` may be a function returning a class.\n // In this case by convention `config` holds\n // the kwargs of the function.\n const backupCustomObjects = {..._GLOBAL_CUSTOM_OBJECTS};\n for (const key of Object.keys(customObjects)) {\n _GLOBAL_CUSTOM_OBJECTS[key] = customObjects[key];\n }\n // In python this is **config['config'], for tfjs-layers we require\n // classes that use this fall-through construction method to take\n // a config interface that mimics the expansion of named parameters.\n const returnObj = new cls(config['config']);\n _GLOBAL_CUSTOM_OBJECTS = {...backupCustomObjects};\n return returnObj;\n }\n }\n}\n\n/**\n * Compares two numbers for sorting.\n * @param a\n * @param b\n */\nexport function numberCompare(a: number, b: number) {\n return (a < b) ? -1 : ((a > b) ? 1 : 0);\n}\n\n/**\n * Comparison of two numbers for reverse sorting.\n * @param a\n * @param b\n */\nexport function reverseNumberCompare(a: number, b: number) {\n return -1 * numberCompare(a, b);\n}\n\n/**\n * Convert a string into the corresponding DType.\n * @param dtype\n * @returns An instance of DType.\n */\nexport function stringToDType(dtype: string): DataType {\n switch (dtype) {\n case 'float32':\n return 'float32';\n default:\n throw new ValueError(`Invalid dtype: ${dtype}`);\n }\n}\n\n/**\n * Test the element-by-element equality of two Arrays of strings.\n * @param xs First array of strings.\n * @param ys Second array of strings.\n * @returns Wether the two arrays are all equal, element by element.\n */\nexport function stringsEqual(xs: string[], ys: string[]): boolean {\n if (xs == null || ys == null) {\n return xs === ys;\n }\n if (xs.length !== ys.length) {\n return false;\n }\n for (let i = 0; i < xs.length; ++i) {\n if (xs[i] !== ys[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Get the unique elements of an array.\n * @param xs Array.\n * @returns An Array consisting of the unique elements in `xs`.\n */\nexport function unique<T>(xs: T[]): T[] {\n if (xs == null) {\n return xs;\n }\n const out: T[] = [];\n // TODO(cais): Maybe improve performance by sorting.\n for (const x of xs) {\n if (out.indexOf(x) === -1) {\n out.push(x);\n }\n }\n return out;\n}\n\n/**\n * Determine if an Object is empty (i.e., does not have own properties).\n * @param obj Object\n * @returns Whether the Object is empty.\n * @throws ValueError: If object is `null` or `undefined`.\n */\nexport function isObjectEmpty(obj: {}): boolean {\n if (obj == null) {\n throw new ValueError(`Invalid value in obj: ${JSON.stringify(obj)}`);\n }\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Helper function used to build type union/enum run-time checkers.\n * @param values The list of allowed values.\n * @param label A string name for the type\n * @param value The value to test.\n * @throws ValueError: If the value is not in values nor `undefined`/`null`.\n */\nexport function checkStringTypeUnionValue(\n values: string[], label: string, value: string): void {\n if (value == null) {\n return;\n }\n if (values.indexOf(value) < 0) {\n throw new ValueError(`${value} is not a valid ${label}. Valid values are ${\n values} or null/undefined.`);\n }\n}\n\n/**\n * Helper function for verifying the types of inputs.\n *\n * Ensures that the elements of `x` are all of type `expectedType`.\n * Also verifies that the length of `x` is within bounds.\n *\n * @param x Object to test.\n * @param expectedType The string expected type of all of the elements in the\n * Array.\n * @param minLength Return false if x.length is less than this.\n * @param maxLength Return false if x.length is greater than this.\n * @returns true if and only if `x` is an `Array<expectedType>` with\n * length >= `minLength` and <= `maxLength`.\n */\n// tslint:disable:no-any\nexport function checkArrayTypeAndLength(\n x: any, expectedType: string, minLength = 0,\n maxLength = Infinity): boolean {\n assert(minLength >= 0);\n assert(maxLength >= minLength);\n return (\n Array.isArray(x) && x.length >= minLength && x.length <= maxLength &&\n x.every(e => typeof e === expectedType));\n}\n// tslint:enable:no-any\n\n/**\n * Assert that a value or an array of value are positive integer.\n *\n * @param value The value being asserted on. May be a single number or an array\n * of numbers.\n * @param name Name of the value, used to make the error message.\n */\nexport function assertPositiveInteger(value: number|number[], name: string) {\n if (Array.isArray(value)) {\n util.assert(\n value.length > 0, () => `${name} is unexpectedly an empty array.`);\n value.forEach(\n (v, i) => assertPositiveInteger(v, `element ${i + 1} of ${name}`));\n } else {\n util.assert(\n Number.isInteger(value) && value > 0,\n () => `Expected ${name} to be a positive integer, but got ` +\n `${formatAsFriendlyString(value)}.`);\n }\n}\n\n/**\n * Format a value into a display-friendly, human-readable fashion.\n *\n * - `null` is formatted as `'null'`\n * - Strings are formated with flanking pair of quotes.\n * - Arrays are formatted with flanking pair of square brackets.\n *\n * @param value The value to display.\n * @return Formatted string.\n */\n// tslint:disable-next-line:no-any\nexport function formatAsFriendlyString(value: any): string {\n if (value === null) {\n return 'null';\n } else if (Array.isArray(value)) {\n return '[' + value.map(v => formatAsFriendlyString(v)).join(',') + ']';\n } else if (typeof value === 'string') {\n return `\"${value}\"`;\n } else {\n return `${value}`;\n }\n}\n\n/**\n * Returns a function `f2` (decorator) which wraps the original function\n * `f`. `f2` guarantees that `f` can be called at most once\n * every `waitMs` ms. If `f2` is called more often, it will return\n * the last returned result of `f`.\n *\n * @param f The original function `f` to wrap.\n * @param waitMs The time between two consecutive calls to `f` in ms.\n */\nexport function debounce<T>(\n f: (...args: Array<{}>) => T, waitMs: number,\n nowFunc?: Function): (...args: Array<{}>) => T {\n let lastTime = nowFunc != null ? nowFunc() : util.now();\n let lastResult: T;\n const f2 = (...args: Array<{}>) => {\n const now = nowFunc != null ? nowFunc() : util.now();\n if (now - lastTime < waitMs) {\n return lastResult;\n }\n lastTime = now;\n lastResult = f(...args);\n return lastResult;\n };\n return f2;\n}\n\n/**\n * Returns the fusable activation given a layers identifier.\n *\n * @param activationName The layers identifier string.\n * @return The name of the fusable activation.\n */\nexport function mapActivationToFusedKernel(activationName: string):\n fused.Activation {\n if (activationName === 'relu') {\n return 'relu';\n }\n if (activationName === 'linear') {\n return 'linear';\n }\n if (activationName === 'elu') {\n return 'elu';\n }\n return null;\n}\n\ntype PossibleValues = Array<Array<boolean|string|number>>;\n\n/**\n * Returns the cartesian product of sets of values.\n * This works the same as itertools.product in Python.\n *\n * Example:\n *\n * filters = [128, 256, 512]\n * paddings = ['same', 'valid']\n *\n * product = [ [128, 'same'], [128, 'valid'], [256, 'same'], [256, 'valid'],\n * [512, 'same'], [512, 'valid']]\n *\n * @param arrayOfValues List/array of values.\n * @return The cartesian product.\n */\nexport function getCartesianProductOfValues(...arrayOfValues: PossibleValues):\n PossibleValues {\n assert(arrayOfValues.length > 0, 'arrayOfValues is empty');\n\n for (const values of arrayOfValues) {\n assert(Array.isArray(values), 'one of the values is not an array');\n assert(values.length > 0, 'one of the values is empty');\n }\n\n return arrayOfValues.reduce((products, values) => {\n if (products.length === 0) {\n return values.map(value => [value]);\n }\n\n return values\n .map(value => {\n return products.map((prevValue) => [...prevValue, value]);\n })\n .reduce((flattenedProduct, unflattenedProduct) => {\n return flattenedProduct.concat(unflattenedProduct);\n }, []);\n }, [] as PossibleValues);\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/**\n * Utilities related to persistent state in the backend.\n */\n\n/**\n * An ID to track `tf.SymbolicTensor`s and derived classes.\n * Required in different places in engine/topology.ts to identify unique\n * tensors.\n */\nlet _nextUniqueTensorId = 0;\n\nexport function getNextUniqueTensorId(): number {\n return _nextUniqueTensorId++;\n}\n\nconst _uidPrefixes: {[prefix: string]: number} = {};\n\n/**\n * Provides a unique UID given a string prefix.\n *\n * @param prefix\n */\nexport function getUid(prefix = ''): string {\n if (!(prefix in _uidPrefixes)) {\n _uidPrefixes[prefix] = 0;\n }\n _uidPrefixes[prefix] += 1;\n return prefix + _uidPrefixes[prefix].toString();\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n// TODO(huan): add layer-specific input shape types (see: https://github.com/tensorflow/tfjs-layers/pull/492)\n/** @docalias (null | number)[] */\nexport type Shape = Array<null | number>;\n\n// The tfjs-core version of DataType must stay synced with this.\nexport type DataType = 'float32'|'int32'|'bool'|'complex64'|'string';\n\n// TODO(soergel): Move the CamelCase versions back out of keras_format\n// e.g. to src/common.ts. Maybe even duplicate *all* of these to be pedantic?\n/** @docinline */\nexport type DataFormat = 'channelsFirst'|'channelsLast';\nexport const VALID_DATA_FORMAT_VALUES = ['channelsFirst', 'channelsLast'];\n\nexport type InterpolationFormat = 'nearest'|'bilinear';\nexport const VALID_INTERPOLATION_FORMAT_VALUES = ['nearest', 'bilinear'];\n// These constants have a snake vs. camel distinction.\nexport type DataFormatSerialization = 'channels_first'|'channels_last';\n\n/** @docinline */\nexport type PaddingMode = 'valid'|'same'|'causal';\nexport const VALID_PADDING_MODE_VALUES = ['valid', 'same', 'causal'];\n\n/** @docinline */\nexport type PoolMode = 'max'|'avg';\nexport const VALID_POOL_MODE_VALUES = ['max', 'avg'];\n\n/** @docinline */\nexport type BidirectionalMergeMode = 'sum'|'mul'|'concat'|'ave';\nexport const VALID_BIDIRECTIONAL_MERGE_MODES = ['sum', 'mul', 'concat', 'ave'];\n\n/** @docinline */\nexport type SampleWeightMode = 'temporal';\nexport const VALID_SAMPLE_WEIGHT_MODES = ['temporal'];\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/**\n * Common functions for TensorFlow.js Layers.\n */\nimport {VALID_DATA_FORMAT_VALUES, VALID_INTERPOLATION_FORMAT_VALUES, VALID_PADDING_MODE_VALUES, VALID_POOL_MODE_VALUES} from './keras_format/common';\nimport {checkStringTypeUnionValue} from './utils/generic_utils';\n\n// A map from the requested scoped name of a Tensor to the number of Tensors\n// wanting that name so far. This allows enforcing name uniqueness by appending\n// an incrementing index, e.g. scope/name, scope/name_1, scope/name_2, etc.\nconst nameMap: Map<string, number> = new Map<string, number>();\n\nexport function checkDataFormat(value?: string): void {\n checkStringTypeUnionValue(VALID_DATA_FORMAT_VALUES, 'DataFormat', value);\n}\n\nexport function checkInterpolationFormat(value?: string): void {\n checkStringTypeUnionValue(\n VALID_INTERPOLATION_FORMAT_VALUES, 'InterpolationFormat', value);\n}\n\nexport function checkPaddingMode(value?: string): void {\n checkStringTypeUnionValue(VALID_PADDING_MODE_VALUES, 'PaddingMode', value);\n}\n\nexport function checkPoolMode(value?: string): void {\n checkStringTypeUnionValue(VALID_POOL_MODE_VALUES, 'PoolMode', value);\n}\n\nconst _nameScopeStack: string[] = [];\nconst _nameScopeDivider = '/';\n\n/**\n * Enter namescope, which can be nested.\n */\nexport function nameScope<T>(name: string, fn: () => T): T {\n _nameScopeStack.push(name);\n try {\n const val: T = fn();\n _nameScopeStack.pop();\n return val;\n } catch (e) {\n _nameScopeStack.pop();\n throw e;\n }\n}\n\n/**\n * Get the current namescope as a flat, concatenated string.\n */\nfunction currentNameScopePrefix(): string {\n if (_nameScopeStack.length === 0) {\n return '';\n } else {\n return _nameScopeStack.join(_nameScopeDivider) + _nameScopeDivider;\n }\n}\n\n/**\n * Get the name a Tensor (or Variable) would have if not uniqueified.\n * @param tensorName\n * @return Scoped name string.\n */\nexport function getScopedTensorName(tensorName: string): string {\n if (!isValidTensorName(tensorName)) {\n throw new Error('Not a valid tensor name: \\'' + tensorName + '\\'');\n }\n return currentNameScopePrefix() + tensorName;\n}\n\n/**\n * Get unique names for Tensors and Variables.\n * @param scopedName The fully-qualified name of the Tensor, i.e. as produced by\n * `getScopedTensorName()`.\n * @return A unique version of the given fully scoped name.\n * If this is the first time that the scoped name is seen in this session,\n * then the given `scopedName` is returned unaltered. If the same name is\n * seen again (producing a collision), an incrementing suffix is added to the\n * end of the name, so it takes the form 'scope/name_1', 'scope/name_2', etc.\n */\nexport function getUniqueTensorName(scopedName: string): string {\n if (!isValidTensorName(scopedName)) {\n throw new Error('Not a valid tensor name: \\'' + scopedName + '\\'');\n }\n if (!nameMap.has(scopedName)) {\n nameMap.set(scopedName, 0);\n }\n const index = nameMap.get(scopedName);\n nameMap.set(scopedName, nameMap.get(scopedName) + 1);\n\n if (index > 0) {\n const result = `${scopedName}_${index}`;\n // Mark the composed name as used in case someone wants\n // to call getUniqueTensorName(\"name_1\").\n nameMap.set(result, 1);\n return result;\n } else {\n return scopedName;\n }\n}\n\nconst tensorNameRegex = new RegExp(/^[A-Za-z0-9][-A-Za-z0-9\\._\\/]*$/);\n\n/**\n * Determine whether a string is a valid tensor name.\n * @param name\n * @returns A Boolean indicating whether `name` is a valid tensor name.\n */\nexport function isValidTensorName(name: string): boolean {\n return !!name.match(tensorNameRegex);\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/**\n * Math utility functions.\n *\n * This file contains some frequently used math function that operates on\n * number[] or Float32Array and return a number. Many of these functions are\n * not-so-thick wrappers around TF.js Core functions. But they offer the\n * convenience of\n * 1) not having to convert the inputs into Tensors,\n * 2) not having to convert the returned Tensors to numbers.\n */\n\nimport {ValueError} from '../errors';\n\nexport type ArrayTypes = Uint8Array|Int32Array|Float32Array;\n\n/**\n * Determine if a number is an integer.\n */\nexport function isInteger(x: number): boolean {\n return x === parseInt(x.toString(), 10);\n}\n\n/**\n * Calculate the product of an array of numbers.\n * @param array The array to calculate the product over.\n * @param begin Beginning index, inclusive.\n * @param end Ending index, exclusive.\n * @return The product.\n */\nexport function arrayProd(\n array: number[]|ArrayTypes, begin?: number, end?: number): number {\n if (begin == null) {\n begin = 0;\n }\n if (end == null) {\n end = array.length;\n }\n\n let prod = 1;\n for (let i = begin; i < end; ++i) {\n prod *= array[i];\n }\n return prod;\n}\n\n/**\n * Compute minimum value.\n * @param array\n * @return minimum value.\n */\nexport function min(array: number[]|Float32Array): number {\n // same behavior as tf.min()\n if (array.length === 0) {\n return Number.NaN;\n }\n let min = Number.POSITIVE_INFINITY;\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n if (value < min) {\n min = value;\n }\n }\n return min;\n}\n\n/**\n * Compute maximum value.\n * @param array\n * @return maximum value\n */\nexport function max(array: number[]|Float32Array): number {\n // same behavior as tf.max()\n if (array.length === 0) {\n return Number.NaN;\n }\n let max = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n if (value > max) {\n max = value;\n }\n }\n return max;\n}\n\n/**\n * Compute sum of array.\n * @param array\n * @return The sum.\n */\nexport function sum(array: number[]|Float32Array): number {\n let sum = 0;\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n sum += value;\n }\n return sum;\n}\n\n/**\n * Compute mean of array.\n * @param array\n * @return The mean.\n */\nexport function mean(array: number[]|Float32Array): number {\n return sum(array) / array.length;\n}\n\n/**\n * Compute variance of array.\n * @param array\n * @return The variance.\n */\nexport function variance(array: number[]|Float32Array): number {\n const meanValue = mean(array);\n const demeaned = array.map((value: number) => value - meanValue);\n let sumSquare = 0;\n for (let i = 0; i < demeaned.length; i++) {\n const value = demeaned[i];\n sumSquare += value * value;\n }\n return sumSquare / array.length;\n}\n\n/**\n * Compute median of array.\n * @param array\n * @return The median value.\n */\nexport function median(array: number[]|Float32Array): number {\n const arraySorted = array.slice().sort((a, b) => a - b);\n const lowIdx = Math.floor((arraySorted.length - 1) / 2);\n const highIdx = Math.ceil((arraySorted.length - 1) / 2);\n if (lowIdx === highIdx) {\n return arraySorted[lowIdx];\n }\n return (arraySorted[lowIdx] + arraySorted[highIdx]) / 2;\n}\n\n/**\n * Generate an array of integers in [begin, end).\n * @param begin Beginning integer, inclusive.\n * @param end Ending integer, exclusive.\n * @returns Range array.\n * @throws ValueError, iff `end` < `begin`.\n */\nexport function range(begin: number, end: number): number[] {\n if (end < begin) {\n throw new ValueError(`end (${end}) < begin (${begin}) is forbidden.`);\n }\n const out: number[] = [];\n for (let i = begin; i < end; ++i) {\n out.push(i);\n }\n return out;\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\nimport {backend} from '@tensorflow/tfjs-core';\nimport {DataFormat} from '../keras_format/common';\n\nlet _epsilon: number;\n\n/**\n * Returns the value of the fuzz factor used in numeric expressions.\n */\nexport function epsilon() {\n if (_epsilon == null) {\n _epsilon = backend().epsilon();\n }\n return _epsilon;\n}\n\n/**\n * Sets the value of the fuzz factor used in numeric expressions.\n * @param e New value of epsilon.\n */\nexport function setEpsilon(e: number) {\n _epsilon = e;\n}\n\n/**\n * Returns the default image data format convention.\n */\nexport function imageDataFormat(): DataFormat {\n return 'channelsLast';\n}\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Use of this source code is governed by an MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n * =============================================================================\n */\n\n/**\n * deeplearn.js backend.\n */\n\nimport * as tfc from '@tensorflow/tfjs-core';\nimport {onesLike as coreOnesLike, scalar, Tensor, Tensor1D, tensor1d, Tensor2D, Tensor3D, Ten