Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic cleanup rest of framework, activations and initializers #231

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c57a2e7
Merge pull request #3 from tensorflow/master
JimClarke5 Oct 8, 2020
09fc07e
Merge pull request #4 from tensorflow/master
JimClarke5 Oct 27, 2020
a99dcb4
Merge pull request #5 from tensorflow/master
JimClarke5 Nov 17, 2020
ba294ea
Merge pull request #6 from tensorflow/master
JimClarke5 Nov 19, 2020
04f419a
Merge pull request #7 from tensorflow/master
JimClarke5 Dec 30, 2020
02e7ebf
Merge pull request #8 from tensorflow/master
JimClarke5 Jan 29, 2021
e0c9ed8
Merge pull request #9 from tensorflow/master
JimClarke5 Feb 1, 2021
5b0374b
Merge pull request #10 from tensorflow/master
JimClarke5 Feb 11, 2021
e038bbd
Merge pull request #11 from tensorflow/master
JimClarke5 Feb 23, 2021
28a34dd
Clean up generics, remove generics from class and fix call method to …
JimClarke5 Mar 3, 2021
309b834
resynch with master, for some reason when I build on mac, the order f…
JimClarke5 Mar 3, 2021
def3051
Merge pull request #13 from tensorflow/master
JimClarke5 Mar 3, 2021
3a9ae37
Merge branch 'master' of https://github.com/JimClarke5/java into Gene…
JimClarke5 Mar 3, 2021
c5d37bf
Add GeLU activation present in TF 2.4
JimClarke5 Mar 4, 2021
11f8ac9
Fix @param<T> and reformat
JimClarke5 Mar 4, 2021
40a95af
Fix JavaDoc to add @param <T>
JimClarke5 Mar 6, 2021
d0e8de9
Refactor to add generic to base class and change signature of call me…
JimClarke5 Mar 6, 2021
478b78a
Add check for scalar.
JimClarke5 Mar 6, 2021
f53fa08
Change to accept TString value.
JimClarke5 Mar 7, 2021
79594da
Fix GeLU equations with separate Operands
JimClarke5 Mar 9, 2021
112c740
Fix Constant to handle TString properly
JimClarke5 Mar 9, 2021
61e6206
Added Stddev check for not less than 0.
JimClarke5 Mar 9, 2021
3b4b607
Fix fix fill to cast the 1 to the approriate type before the fill
JimClarke5 Mar 9, 2021
98df654
Code reformat
JimClarke5 Mar 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -354,20 +354,20 @@ public final class Ops {

public final SparseOps sparse;

public final TpuOps tpu;

public final BitwiseOps bitwise;

public final TpuOps tpu;

public final MathOps math;

public final AudioOps audio;

public final SignalOps signal;

public final TrainOps train;

public final QuantizationOps quantization;

public final TrainOps train;

private final Scope scope;

private Ops(Scope scope) {
Expand All @@ -385,13 +385,13 @@ private Ops(Scope scope) {
random = new RandomOps(this);
strings = new StringsOps(this);
sparse = new SparseOps(this);
tpu = new TpuOps(this);
bitwise = new BitwiseOps(this);
tpu = new TpuOps(this);
math = new MathOps(this);
audio = new AudioOps(this);
signal = new SignalOps(this);
train = new TrainOps(this);
quantization = new QuantizationOps(this);
train = new TrainOps(this);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,7 @@
import org.tensorflow.op.Ops;
import org.tensorflow.types.family.TNumber;

/**
* Abstract base class for Activations
*
* <p><b>Note:</b> The {@link #tf} attribute must be set prior to invoking the call method. See
* {@link #setTF(Ops)} and the constructor {@link #Activation(Ops)}.
*
* @param <T> the data type of the activation
*/
/** Abstract base class for Activations */
public abstract class Activation<T extends TNumber> {

/** The TensorFlow Ops */
Expand All @@ -41,28 +34,29 @@ protected Activation(Ops tf) {
}

/**
* Sets the TensorFlow Ops
* Gets the TensorFlow Ops
*
* @param tf the TensorFlow Ops
* @return the TensorFlow Ops
*/
protected void setTF(Ops tf) {
this.tf = tf;
protected Ops getTF() {
return this.tf;
}

/**
* Gets the TensorFlow Ops
* Sets the TensorFlow Ops
*
* @return the TensorFlow Ops
* @param tf the TensorFlow Ops
*/
protected Ops getTF() {
return this.tf;
protected void setTF(Ops tf) {
this.tf = tf;
}

/**
* Gets the calculation operation for the activation.
*
* @param input the input tensor
* @param <U> the data type of the input and result
* @return The operand for the activation
*/
public abstract Operand<T> call(Operand<T> input);
public abstract <U extends T> Operand<U> call(Operand<U> input);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@
* Operand&lt;TFloat32&gt; result = elu.call(input);
* </pre>
*
* @param <T> the data type of the activation
* @see <a href="https://arxiv.org/abs/1511.07289">Clevert et al, 2016, Fast and Accurate Deep
* Network Learning by Exponential Linear Units (ELUs)</a>
*/
public class ELU<T extends TFloating> extends Activation<T> {
public class ELU extends Activation<TFloating> {

private static final double ALPHA_DEFAULT = 1.0;

Expand Down Expand Up @@ -76,20 +75,16 @@ public ELU(Ops tf, double alpha) {
this.alpha = alpha;
}

/**
* Gets the calculation operation for the activation.
*
* @param input the input tensor
* @return The operand for the activation
*/
/** {@inheritDoc} */
@Override
public Operand<T> call(Operand<T> input) {
public <U extends TFloating> Operand<U> call(Operand<U> input) {

Operand<T> result = tf.nn.elu(input);
if (alpha == 1.0) return result;
else {
Class<T> inputType = input.type();
Operand<T> y = tf.math.mul(result, tf.dtypes.cast(tf.constant(alpha), inputType));
Operand<U> result = tf.nn.elu(input);
if (alpha == 1.0) {
return result;
} else {
Class<U> inputType = input.type();
Operand<U> y = tf.math.mul(result, tf.dtypes.cast(tf.constant(alpha), inputType));
Operand<TBool> cond = tf.math.greater(result, tf.dtypes.cast(tf.constant(0), inputType));
return tf.select(cond, result, y);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
* Operand&lt;TFloat32&gt; result = exp.call(input);
* // result is [0.04978707f, 0.36787945f, 1.f, 2.7182817f, 20.085537f]
* </pre>
*
* @param <T> the data type of the activation
*/
public class Exponential<T extends TFloating> extends Activation<T> {
public class Exponential extends Activation<TFloating> {

/**
* Creates an Exponential activation.
Expand All @@ -48,10 +46,13 @@ public Exponential(Ops tf) {
* Calculates the Exponential activation.
*
* @param input the input tensor
* @param <U> the data type of the input and result
* @return an Operand for the exponential activation: <code>exp(x)</code>.
*/
@Override
public Operand<T> call(Operand<T> input) {
public <U extends TFloating> Operand<U> call(Operand<U> input) {


return tf.math.exp(input);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=======================================================================*/
package org.tensorflow.framework.activations;

import org.tensorflow.Operand;
import org.tensorflow.op.Ops;
import org.tensorflow.types.family.TFloating;

import static org.tensorflow.framework.utils.CastHelper.cast;

/**
* Applies the Gaussian error linear unit (GELU) activation function.
*
* <p>Gaussian error linear unit (GELU) computes {@code x * P(X <= x)}, where {@code P(X) ~ N(0,
* 1)}. The (GELU) nonlinearity weights inputs by their value, rather than gates inputs by their
* sign as in ReLU. if <code>approximate</code> is <code>true</code> :
*
* <pre>
* 0.5 * x * (1 + tanh(sqrt(2 / pi) * (x + 0.044715 * x^3)))
* </pre>
*
* <p>or, if <code>approximate</code> is <code>false</code>.
*
* <pre>
* x * P(X &lt;= x) = 0.5 * x * (1 + erf(x / sqrt(2))),
* </pre>
*
* where <code>P(X) ~ N(0, 1)</code>.
*
* @see <a href="https://arxiv.org/abs/1606.08415">Hendrycks, Dan and Gimpel, Kevin, 2016-2020,
* Gaussian Error Linear Units (GELUs)</a>
*/
public class GeLU extends Activation<TFloating> {

private final boolean approximate;

/**
* Creates a e Gaussian error linear unit (GELU) activation, with approximate set to false
*
* @param tf The TensorFlow ops
*/
public GeLU(Ops tf) {
this(tf, false);
}

/**
* Creates a e Gaussian error linear unit (GELU) activation
*
* @param tf The TensorFlow ops
* @param approximate indicator whether to enable approximation.
*/
public GeLU(Ops tf, boolean approximate) {
super(tf);
this.approximate = approximate;
}

/** {@inheritDoc} */
@Override
public <U extends TFloating> Operand<U> call(Operand<U> input) {

if (approximate) {
/*
coeff = math_ops.cast(0.044715, features.dtype)
return 0.5 * features * (
1.0 + math_ops.tanh(0.7978845608028654 *
(features + coeff * math_ops.pow(features, 3))))
*/
Operand<U> coeff = cast(tf, tf.constant(0.044715), input.type());
Operand<U> point5 = cast(tf, tf.constant(0.5), input.type());
Operand<U> one = cast(tf, tf.constant(1.0), input.type());

return tf.math.mul(
point5,
tf.math.mul(
input,
tf.math.add(
one,
tf.math.tanh(
tf.math.mul(
// sqrt(2.0 / PI)
cast(tf, tf.constant(0.7978845608028654), input.type()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this one pulled out like the others?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was mainly for debugging and keeping the parts of the equation manageable. I will change this one and add one for the constant "three".

BTW: It would be nice if we could pass a type to tf.constant, something liketf.constant(3, input.dtype())to return the correct type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good extension to have. That should be fairly straightforward.

tf.math.add(
input,
tf.math.mul(
coeff,
tf.math.pow(input, cast(tf, tf.constant(3), input.type()))) // mul
) // add
) // mul
) // tanh
) // add
) // mul
); // mul

} else {
/*
return 0.5 * features * (1.0 + math_ops.erf(
features / math_ops.cast(1.4142135623730951, features.dtype)))
*/
return tf.math.mul(
cast(tf, tf.constant(0.5), input.type()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe hoist this and the one below out of the if statement and use local variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

tf.math.mul(
input,
tf.math.add(
cast(tf, tf.constant(1), input.type()),
tf.math.erf(
tf.math.div(
input, cast(tf, tf.constant(1.4142135623730951), input.type()))))));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import org.tensorflow.Operand;
import org.tensorflow.op.Ops;
import org.tensorflow.types.family.TFloating;
import org.tensorflow.types.family.TNumber;

/**
* Hard sigmoid activation.
Expand All @@ -40,10 +40,8 @@
* Operand&lt;TFloat32&gt; result = hardSigmoid.call(input);
* // result is [0.f , 0.3f, 0.5f, 0.7f, 1.f]
* </pre>
*
* @param <T> the data type of the result
*/
public class HardSigmoid<T extends TFloating> extends Activation<T> {
public class HardSigmoid extends Activation<TNumber> {

/**
* Creates Hard sigmoid activation.
Expand All @@ -54,19 +52,14 @@ public HardSigmoid(Ops tf) {
super(tf);
}

/**
* Gets the calculation operation for the activation.
*
* @param input the input tensor
* @return The operand for the activation
*/
/** {@inheritDoc} */
@Override
public Operand<T> call(Operand<T> input) {
Class<T> inputType = input.type();
Operand<T> point2 = tf.dtypes.cast(tf.constant(0.2), inputType);
Operand<T> point5 = tf.dtypes.cast(tf.constant(0.5), inputType);
public <U extends TNumber> Operand<U> call(Operand<U> input) {
Class<U> inputType = input.type();
Operand<U> point2 = tf.dtypes.cast(tf.constant(0.2), inputType);
Operand<U> point5 = tf.dtypes.cast(tf.constant(0.5), inputType);

Operand<T> x = tf.math.add(tf.math.mul(input, point2), point5);
Operand<U> x = tf.math.add(tf.math.mul(input, point2), point5);
return tf.clipByValue(
x, tf.dtypes.cast(tf.constant(0), inputType), tf.dtypes.cast(tf.constant(1), inputType));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import org.tensorflow.types.family.TNumber;

/**
* Linear activation function (pass-through).
* Linear activation function (pass-through).
*
* <p>The linear activation returns its input. It is also known as the Identity activation function.</p>
* <p>The linear activation returns its input. It is also known as the Identity activation function.
*
* <p>For example:
*
Expand All @@ -33,7 +33,7 @@
* // result is [-3.0f,-1.0f, 0.0f,1.0f,3.0f]
* </pre>
*/
public class Linear<U extends TNumber> extends Activation<U> {
public class Linear extends Activation<TNumber> {

/**
* Creates a linear activation.
Expand All @@ -46,7 +46,7 @@ public Linear(Ops tf) {

/** {@inheritDoc} */
@Override
public Operand<U> call(Operand<U> input) {
public <U extends TNumber> Operand<U> call(Operand<U> input) {
return input;
}
}
Loading