import java.util.ArrayList;
import java.util.List;
import edu.neuralnet.core.activation.ActivationFunction;
import edu.neuralnet.core.input.InputSummingFunction;
/**
* Represents a neuron model comprised of(以下内容组成的神经元模型): </br>
* <ul>
* <li>Summing part(求和部分) - input summing function(输入求和函数 )</li>
* <li>Activation function(激活函数)</li>
* <li>Input connections(输入连接)</li>
* <li>Output connections(输出连接)</li>
* </ul>
*/
public class Neuron {
/**
* Neuron's identifier
* 神经元标识符
*/
private String id;
/**
* Collection of neuron's input connections (connections to this neuron)
* 神经元输入连接的集合(与此神经元的连接)
*/
protected List < Connection > inputConnections;
/**
* Collection of neuron's output connections (connections from this to other
* neurons)
* 神经元输出连接的集合(从这个到其他神经元的连接)
*/
protected List < Connection > outputConnections;
/**
* Input summing function for this neuron
* 该神经元的输入和函数
*/
protected InputSummingFunction inputSummingFunction;
/**
* Activation function for this neuron
* 这个神经元的激活函数
*/
protected ActivationFunction activationFunction;
/**
* Default constructor
* 默认构造方法
*/
public Neuron() {
this.inputConnections = new ArrayList < > ();
this.outputConnections = new ArrayList < > ();
}
/**
* Calculates the neuron's output
* 计算神经元输出
*/
public double calculateOutput() {
double totalInput = inputSummingFunction.getOutput(inputConnections);
return activationFunction.getOutput(totalInput);
}
...
}
神经元有输入和输出连接、输入求和值和激活函数,那输入权重在哪里呢?它们包含在连接本身中,如下所示:
/**
* Represents a connection between two neurons an the associated weight.
* 表示两个神经元之间的连接以及相关的权重
*/
public class NeuronsConnection {
/**
* From neuron for this connection (source neuron). This connection is
* output connection for from neuron.
* 从神经元中获取这个连接(源神经元)。此连接是来自神经元的输出连接
*/
protected Neuron fromNeuron;
/**
* To neuron for this connection (target, destination neuron) This
* connection is input connection for to neuron.
* 对于用于此连接的神经元(目标,目标神经元),此连接是神经元的输入连接
*/
protected Neuron toNeuron;
/**
* Connection weight
* 连接权重
*/
protected double weight;
/**
* Creates a new connection between specified neurons with random weight.
* 在具有随机权重的指定神经元之间创建一个新的连接
* @param fromNeuron
* neuron to connect from
* @param toNeuron
* neuron to connect to
*/
public NeuronsConnection(Neuron fromNeuron, Neuron toNeuron) {
this.fromNeuron = fromNeuron;
this.toNeuron = toNeuron;
this.weight = Math.random();
}
/**
* Creates a new connection to specified neuron with specified weight object
* 创建与指定权重对象的指定神经元的新连接
*
* @param fromNeuron
* neuron to connect from
* @param toNeuron
* neuron to connect to
* @param weight
* weight for this connection
*/
public NeuronsConnection(Neuron fromNeuron, Neuron toNeuron, double weight) {
this(fromNeuron, toNeuron);
this.weight = weight;
}
/**
* Returns weight for this connection
* 返回此连接的权重
* @return weight for this connection
*/
public double getWeight() {
return weight;
}
/**
* Set the weight of the connection.
* 设置连接的权值
* @param weight
* The new weight of the connection to be set
*/
public void setWeight(double weight) {
this.weight = weight;
}
/**
* Returns input of this connection - the activation function result
* calculated in the input neuron of this connection.
* 返回此连接的输入 - 在此连接输入神经元中激活函数计算的结果
* @return input received through this connection
*/
public double getInput() {
return fromNeuron.calculateOutput();
}
/**
* Returns the weighted input of this connection
* 返回此连接的权值输入
* @return weighted input of the connection
*/
public double getWeightedInput() {
return fromNeuron.calculateOutput() * weight;
}
/**
* Gets from neuron for this connection
* 从神经元获取此连接
* @return from neuron for this connection
*/
public Neuron getFromNeuron() {
return fromNeuron;
}
/**
* Gets to neuron for this connection
* 获取用于此连接的神经元
* @return neuron to set as to neuron
*/
public Neuron getToNeuron() {
return toNeuron;
}
...
}
连接对象提供权重并负责计算输入的权值。
求和函数被定义为接口,以便能够替换神经元的计算策略:
import java.util.List;
import edu.neuralnet.core.Connection;
/**
* Represents the inputs summing part of a neuron also called signal collector.
* 神经元的求和部分,也可以称为信号收集器
*/
public interface InputSummingFunction {
/**
* Performs calculations based on the output values of the input neurons.
* 根据输入神经元的输出值执行计算
* @param inputConnections
* neuron's input connections
* @return total input for the neuron having the input connections
* 总输入,具有输入连接的神经元
*/
double collectOutput(List<Connection> inputConnections);
}
分别实现为:
import java.util.List;
import edu.neuralnet.core.Connection;
/**
* Calculates the weighted sums of the input neurons' outputs.
* 计算输入神经元输出的加权和
*/
public final class WeightedSumFunction implements InputSummingFunction {
/**
* {@inheritDoc}
*/
@Override
public double collectOutput(List<Connection> inputConnections) {
double weightedSum = 0d;
for (Connection connection : inputConnections) {
weightedSum += connection.getWeightedInput();
}
return weightedSum;
}
}
激活函数的接口可以定义如下::
/**
* Neural networks activation function interface.
* 神经网络激活函数的接口
*/
public interface ActivationFunction {
/**
* Performs calculation based on the sum of input neurons output.
* 基于输入神经元输出的和来进行计算
* @param summedInput
* neuron's sum of outputs respectively inputs for the connected
* neuron
*
* @return Output's calculation based on the sum of inputs
* 基于输入和来计算输出
*/
double calculateOutput(double summedInput);
}
import java.util.ArrayList;
import java.util.List;
/**
* Neural networks can be composed of several linked layers, forming the
* so-called multilayer networks. A layer can be defined as a set of neurons
* comprising a single neural net's layer.
* 神经网络可以由多个连接层组成,形成所谓的多层网络,
* 一层可以定义为一组包含神经网络层的神经元
*/
public class NeuralNetLayer {
/**
* Layer's identifier
* 层次标识符
*/
private String id;
/**
* Collection of neurons in this layer
* 该层神经元的集合
*/
protected List<Neuron> neurons;
/**
* Creates an empty layer with an id.
* 用ID创建一个空层
* @param id
* layer's identifier
*/
public NeuralNetLayer(String id) {
this.id = id;
neurons = new ArrayList<>();
}
/**
* Creates a layer with a list of neurons and an id.
* 创建一个包含神经元列表和id的层
* @param id
* layer's identifier 层次标识符
* @param neurons
* list of neurons to be added to the layer 添加到该层的神经元列表
*/
public NeuralNetLayer(String id, List<Neuron> neurons) {
this.id = id;
this.neurons = neurons;
}
...
}
最后,用Java创建一个简单的神经网络:
/**
* Represents an artificial neural network with layers containing neurons.
* 含有神经元层的人工神经网络
*/
public class NeuralNet {
/**
* Neural network id
* 神经网络ID
*/
private String id;
/**
* Neural network input layer
* 神经网络的输入层
*/
private NeuralNetLayer inputLayer;
/**
* Neural network hidden layers
* 神经网络隐藏的层
*/
private List<NeuralNetLayer> hiddenLayers;
/**
* Neural network output layer
* 神经网络的输出层
*/
private NeuralNetLayer outputLayer;
/**
* Constructs a neural net with all layers present.
* 构造一个具有所有层的神经网络
* @param id
* Neural network id to be set 设置神经网络标识
* @param inputLayer
* Neural network input layer to be set 设置神经网络的输入层
* @param hiddenLayers
* Neural network hidden layers to be set 设置神经网络隐藏的层
* @param outputLayer
* Neural network output layer to be set 设置神经网络的输出层
*/
public NeuralNet(String id, NeuralNetLayer inputLayer, List<NeuralNetLayer> hiddenLayers,
NeuralNetLayer outputLayer) {
this.id = id;
this.inputLayer = inputLayer;
this.hiddenLayers = hiddenLayers;
this.outputLayer = outputLayer;
}
/**
* Constructs a neural net without hidden layers.
* 构造一个没有隐藏层的神经网络
* @param id
* Neural network id to be set 设置神经网络标识
* @param inputLayer
* Neural network input layer to be set 设置神经网络的输入层
* @param outputLayer
* Neural network output layer to be set 设置神经网络隐藏的层
*/
public NeuralNet(String id, NeuralNetLayer inputLayer, NeuralNetLayer outputLayer) {
this.id = id;
this.inputLayer = inputLayer;
this.outputLayer = outputLayer;
}
...
}