/**
* Copyright 2010 Neuroph Project http://neuroph.sourceforge.net
*
* 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.neuroph.core.transfer;
import java.io.Serializable;
import org.neuroph.util.Properties;
/**
*
* Tanh neuron transfer function.
*
* output = amplitude * tanh(slope * input) = amplitude * ( e^(2*slope*input)-1) / ( e^(2*slope*input)+1 )
*
*
* @author Zoran Sevarac , Nyefan
*/
public class Tanh extends TransferFunction implements Serializable {
/**
* The class fingerprint that is set to indicate serialization
* compatibility with a previous version of the class.
*/
private static final long serialVersionUID = 2L;
/**
* The slope parameter of the Tanh function
*/
private double slope = 1d;
/**
* The amplitude parameter
*/
private double amplitude = 1d;
/**
* The output of the getDerivative() function;
*/
private double derivativeOutput;
/**
* Creates an instance of Tanh neuron transfer function with default
* slope=amplitude=1
*/
public Tanh() {
}
/**
* Creates an instance of Tanh neuron transfer function with specified
* value for slope parameter.
*
* @param slope the slope parameter for the Tanh function
*/
public Tanh(double slope) {
this.slope = slope;
}
/**
* Creates an instance of Tanh neuron transfer function with the
* specified properties.
*
* @param properties properties of the Tanh function
*/
public Tanh(Properties properties) {
try {
this.slope = (Double) properties.getProperty("transferFunction.slope");
//this.amplitude = (Double) properties.getProperty("transferFunction.amplitude");
} catch (NullPointerException e) {
// if properties are not set just leave default values
} catch (NumberFormatException e) {
System.err.println("Invalid transfer function properties! Using default values.");
}
}
/**
* Returns the value of this function at x=input
*
* @param input location to evaluate this function
* @return value of this function at x=input
*/
@Override
final public double getOutput(double input) {
// conditional logic helps to avoid NaN
if (Math.abs(input) * slope > 100) { return Math.signum(input) * 1.0d; }
//a*tanh(s*x) = a*[(e^(2*s*x) - 1) / (e^(2*s*x) - 1)]
double E_x = Math.exp(2.0d * slope * input);
output = amplitude * ((E_x - 1.0d) / (E_x + 1.0d));
return output;
}
// The derivative of a*tanh(s*x) is a*s*sech^2(s*x), or a*s*(1-tanh^2(s*x))
/**
* Returns the derivative of this function evaluated at x=input
*
* @param input location to evaluate the derivative
* @return derivative of this function evaluated at x=input
*/
@Override
final public double getDerivative(double input) {
// conditional logic helps to avoid NaN
if (Math.abs(input) * slope > 100) { return 0.0d; }
//output here is a*tanh^2(s*x)
double E_x = Math.exp(2 * slope * input); // we coul duse buffered output here, but in that case we ignor input parameter and it shoul dbe removed to avoid confusion
double tanhsx = (E_x - 1d) / (E_x + 1d);
derivativeOutput = amplitude * slope * (1.0d - tanhsx * tanhsx);
return derivativeOutput;
}
/**
* Returns the slope parameter of this function
*
* @return slope parameter of this function
*/
public double getSlope() {
return slope;
}
/**
* Sets the slope parameter for this function
*
* @param slope value for the slope parameter
*/
public void setSlope(double slope) {
this.slope = slope;
}
/**
* Returns the amplitude parameter of this function
*
* @return amplitude parameter of this function
*/
public double getAmplitude() {
return amplitude;
}
/**
* Sets the slope parameter for this function
*
* @param amplitude value for the amplitude parameter
*/
public void setAmplitude(double amplitude) {
this.amplitude = amplitude;
}
}
Ads help maintain this website.