这篇文章是系列文章的第二部分,讨论使用Java以简单易懂的方式编程神经网络的方法。
在之前的文章,我们定义了神经网络的主要组件,并使用Java作为编程语言来设计它们。在这篇文章中,我们将深入探讨激活功能(也称为传递功能),这也是神经网络的一部分。
为了回顾本系列的第一部分,人造神经元是输入端的信号收集器,输出端的激活单元触发信号,将信号转发到其他神经元,如下图所示:
人造神经元接收一个或多个输入并将它们相加以产生输出或激活。通常,每个节点的总和被加权,总和通过一个激活函数。在大多数情况下,非线性 激活函数允许这种网络仅使用少量节点来计算非平凡问题。
在由生物启发神经网络中,激活函数通常是代表细胞中动作电位发放速率的抽象。使用Java作为编程语言,可以使用激活函数接口来设计此抽象:
/**
* 神经网络的激活功能界面
*/
public interface ActivationFunction {
/**
* 根据输入神经元输出的总和进行计算。
*
* @param summedInput
* 神经元的输出总和分别为连接输入神经元
*
*
* @return 基于输入和的输出计算
*/
double calculateOutput(double summedInput);
}
这个接口的实现将提供一种轻松实验和替换各种类型的激活函数的方法。开始实施吧!
激活函数的最简单的形式是二进制 - 神经元或者正在发射或者不发射。该激活函数的输出 y是二进制的,取决于输入是否满足指定的值 θ是发送“信号”,即如果激活达到阈值,则输出设置为1。
这个功能用于感知器。它通过超平面执行输入空间的划分。这在网络的最后一层用来执行输入的二进制分类是特别有用的。
/**
* 阶跃神经元激活函数,这个激活函数的输出y是二进制, 这取决于输入是否符合指定的阈值:0,如果激活达到
阈值,则发送“信号”,即输出设置为1。
*
*/
public class StepActivationFunction implements ActivationFunction {
/**
* 如果输入高于或等于阈值,则输出值1d.
*/
private double yAbove = 1d;
/**
* 如果输入是低于阈值,则输出值0d。
*/
private double yBellow = 0d;
/**
* 这个激活函数的输出是二进制的,这取决于是否输入符合指定的阈值.
*/
private double threshold = 0d;
/**
* {@inheritDoc}
*/
@Override
public double calculateOutput(double summedInput) {
if (summedInput >= threshold) {
return yAbove;
}
else {
return yBellow;
}
}
}
线性组合是将神经元的加权求和输入与线性相关的偏差相加以构建神经元的输出。许多这样的线性神经元执行输入向量的线性变换。这通常在网络的第一层更有用。
/**
* 线性组合激活函数实现,输出单元为:它的输入与一个偏置项的加权和。
*/
public class LinearCombinationFunction implements ActivationFunction {
/**
* 偏差值
*/
private double bias;
/**
* {@inheritDoc}
*/
@Override
public double calculateOutput(double summedInput) {
return summedInput + bias;
}
}
Sigmoid函数(也是对数函数)使用以下公式计算:
在这个公式中,加权输入乘以斜率参数。
/**
* Sigmoid激活功能。计算基于:
* y = 1/(1+ e^(-slope*x))
*/
public class SigmoidActivationFunction implements ActivationFunction {
/**
* 斜率参数
*/
private double slope = 1d;
/**
*用斜率参数创建S形函数。
*
* @param slope
* slope parameter to be set
*/
public SigmoidActivationFunction(double slope) {
this.slope = slope;
}
/**
* {@inheritDoc}
*/
@Override
public double calculateOutput(double summedInput) {
double denominator = 1 + Math.exp(-slope * summedInput);
return (1d / denominator);
}
}
正弦激活函数基于计算加权输入的正弦。
/**
* 正弦函数。计算基于:
*
* y = sin(x)
*
*/
public class SinusoidActivationFunction implements ActivationFunction {
/**
* {@inheritDoc}
*/
@Override
public double calculateOutput(double summedInput) {
return Math.sin(summedInput);
}
}
该功能也被称为斜坡功能。根据维基百科:
与广泛使用的logistic sigmoid及其更为实用的双曲正切(本文未涉及)相比,它在卷积网络中的使用更为有效。整流器是2015年以来最受欢迎的深度神经网络激活功能。
/**
* 整流线性激活函数
*/
public class RectifiedLinearActivationFunction implements ActivationFunction {
/**
* {@inheritDoc}
*/
@Override
public double calculateOutput(double summedInput) {
return Math.max(0, summedInput);
}
}
维基百科还指出,在神经网络中可能会应用各种激活函数,本文介绍了一些用Java实现的激活函数。他们的数量将在下一篇文章中进一步扩展,介绍各种类型的应用以及神经网络中的学习过程。