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 | */
|
17 | import { 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 | */
|
24 | export 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 | */
|
60 | export 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 | */
|
105 | export 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 |