MCPcopy Create free account
hub / github.com/tensorflow/tfjs-examples / Antirectifier

Class Antirectifier

custom-layer/custom_layer.js:34–88  ·  view source on GitHub ↗

* This custom layer is similar to the 'relu' non-linear Activation `Layer`, but * it keeps both the negative and positive signal. The input is centered at the * mean value, and then the negative activations and positive activations are * separated into different channels, meaning that there are

Source from the content-addressed store, hash-verified

32 * https://github.com/tensorflow/tfjs/issues/254
33 */
34class Antirectifier extends tf.layers.Layer {
35 constructor() {
36 super({});
37 // TODO(bileschi): Can we point to documentation on masking here?
38 this.supportsMasking = true;
39 }
40
41 /**
42 * This layer only works on 4D Tensors [batch, height, width, channels],
43 * and produces output with twice as many channels.
44 *
45 * layer.computeOutputShapes must be overridden in the case that the output
46 * shape is not the same as the input shape.
47 * @param {*} inputShapes
48 */
49 computeOutputShape(inputShape) {
50 return [inputShape[0], inputShape[1], inputShape[2], 2 * inputShape[3]]
51 }
52
53 /**
54 * Centers the input and applies the following function to every element of
55 * the input.
56 *
57 * x => [max(x, 0), max(-x, 0)]
58 *
59 * The theory being that there may be signal in the both negative and positive
60 * portions of the input. Note that this will double the number of channels.
61 * @param inputs Tensor to be treated.
62 * @param kwargs Only used as a pass through to call hooks. Unused in this
63 * example code.
64 */
65 call(inputs, kwargs) {
66 let input = inputs;
67 if (Array.isArray(input)) {
68 input = input[0];
69 }
70 this.invokeCallHook(inputs, kwargs);
71 const origShape = input.shape;
72 const flatShape =
73 [origShape[0], origShape[1] * origShape[2] * origShape[3]];
74 const flattened = input.reshape(flatShape);
75 const centered = tf.sub(flattened, flattened.mean(1).expandDims(1));
76 const pos = centered.relu().reshape(origShape);
77 const neg = centered.neg().relu().reshape(origShape);
78 return tf.concat([pos, neg], 3);
79 }
80
81 /**
82 * If a custom layer class is to support serialization, it must implement
83 * the `className` static getter.
84 */
85 static get className() {
86 return 'Antirectifier';
87 }
88}
89tf.serialization.registerClass(Antirectifier); // Needed for serialization.
90
91export function antirectifier() {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected