UNPKG

3.95 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2018 Google LLC. All Rights Reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * =============================================================================
16 */
17import { assert } from './util';
18/**
19 * Serializable defines the serialization contract.
20 *
21 * TFJS requires serializable classes to return their className when asked
22 * to avoid issues with minification.
23 */
24export class Serializable {
25 /**
26 * Return the class name for this class to use in serialization contexts.
27 *
28 * Generally speaking this will be the same thing that constructor.name
29 * would have returned. However, the class name needs to be robust
30 * against minification for serialization/deserialization to work properly.
31 *
32 * There's also places such as initializers.VarianceScaling, where
33 * implementation details between different languages led to different
34 * class hierarchies and a non-leaf node is used for serialization purposes.
35 */
36 getClassName() {
37 return this.constructor
38 .className;
39 }
40 /**
41 * Creates an instance of T from a ConfigDict.
42 *
43 * This works for most descendants of serializable. A few need to
44 * provide special handling.
45 * @param cls A Constructor for the class to instantiate.
46 * @param config The Configuration for the object.
47 */
48 /** @nocollapse */
49 static fromConfig(cls, config) {
50 return new cls(config);
51 }
52}
53/**
54 * Maps string keys to class constructors.
55 *
56 * Used during (de)serialization from the cross-language JSON format, which
57 * requires the class name in the serialization format matches the class
58 * names as used in Python, should it exist.
59 */
60export class SerializationMap {
61 constructor() {
62 this.classNameMap = {};
63 }
64 /**
65 * Returns the singleton instance of the map.
66 */
67 static getMap() {
68 if (SerializationMap.instance == null) {
69 SerializationMap.instance = new SerializationMap();
70 }
71 return SerializationMap.instance;
72 }
73 /**
74 * Registers the class as serializable.
75 */
76 static register(cls) {
77 SerializationMap.getMap().classNameMap[cls.className] =
78 [cls, cls.fromConfig];
79 }
80}
81/**
82 * Register a class with the serialization map of TensorFlow.js.
83 *
84 * This is often used for registering custom Layers, so they can be
85 * serialized and deserialized.
86 *
87 * Example:
88 *
89 * ```js
90 * class MyCustomLayer extends tf.layers.Layer {
91 * static className = 'MyCustomLayer';
92 *
93 * constructor(config) {
94 * super(config);
95 * }
96 * }
97 * tf.serialization.registerClass(MyCustomLayer);
98 * ```
99 *
100 * @param cls The class to be registered. It must have a public static member
101 * called `className` defined and the value must be a non-empty string.
102 *
103 * @doc {heading: 'Models', subheading: 'Serialization', ignoreCI: true}
104 */
105export function registerClass(cls) {
106 assert(cls.className != null, () => `Class being registered does not have the static className ` +
107 `property defined.`);
108 assert(typeof cls.className === 'string', () => `className is required to be a string, but got type ` +
109 typeof cls.className);
110 assert(cls.className.length > 0, () => `Class being registered has an empty-string as its className, ` +
111 `which is disallowed.`);
112 SerializationMap.register(cls);
113}
114//# sourceMappingURL=serialization.js.map
\No newline at end of file