有监督学习逻辑运算需要先创建一个训练集合,也可以称之为训练规则,需要用到的方法类为Dataset,这个类可以创建一个规则,实例化一个输入2个结果输出一个结果的变量(当然是看自己的需求)。对于线性可分的规则我们可以只需要简单的训练就行,但是对于一些线性不可分的规则来讲,简单的感知机就不行了,这个时候就需要创建多层感知。

AND

首先这里创建一个逻辑与的逻辑运算

0 AND 0 0

0 AND 1 0

1 AND 0 0

1 AND 1 1

1
2
3
4
5
DataSet trainSetAnd = new DataSet(2, 1);  
trainSetAnd.addRow(new DataSetRow(new double[]{0, 0}, new double[]{0}));
trainSetAnd.addRow(new DataSetRow(new double[]{0, 1}, new double[]{0}));
trainSetAnd.addRow(new DataSetRow(new double[]{1, 0}, new double[]{0}));
trainSetAnd.addRow(new DataSetRow(new double[]{1, 1}, new double[]{1}));

创建完了训练集合后,我们需要创建一个神经网络感知机

1
NeuralNetwork perceptron = new Perceptron(2, 1);

接下来训练AND集

1
2
3
perceptron.learn(trainSetAnd);  //训练AND运算
System.out.println("AND训练结果:");
andNeuralNetwork(perceptron, trainSetAnd);

在主函数中输出训练结果

1
2
3
4
5
6
7
8
9
public static void andNeuralNetwork(NeuralNetwork perceptron, DataSet and) {  
for (DataSetRow dataRow : and.getRows()) { //获取列
perceptron.setInput(dataRow.getInput());
perceptron.calculate();
double[ ] networkOutput = perceptron.getOutput();
System.out.print("Input: " + Arrays.toString(dataRow.getInput()) );
System.out.println(" Output: " + Arrays.toString(networkOutput) );
}
}

AND训练结果:

Input: [0.0, 0.0] Output: [0.0]

Input: [0.0, 1.0] Output: [0.0]

Input: [1.0, 0.0] Output: [0.0]

Input: [1.0, 1.0] Output: [1.0]

OR

当然,OR(或)的训练也是一样的

0 AND 0 0

0 AND 1 1

1 AND 0 1

1 AND 1 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DataSet trainSetOr = new DataSet(2, 1);  
trainSetOr.addRow(new DataSetRow(new double[]{0, 0}, new double[]{0}));
trainSetOr.addRow(new DataSetRow(new double[]{0, 1}, new double[]{1}));
trainSetOr.addRow(new DataSetRow(new double[]{1, 0}, new double[]{1}));
trainSetOr.addRow(new DataSetRow(new double[]{1, 1}, new double[]{1}));

//创建感知机
NeuralNetwork perceptron = new Perceptron(2, 1);

//训练OR运算
perceptron.learn(trainSetOr);
System.out.println("OR训练结果:");
orNeuralNetwork(perceptron, trainSetOr);

//在主函数中输出训练结果
public static void orNeuralNetwork(NeuralNetwork perceptron, DataSet or) {
for (DataSetRow dataRow : or.getRows()) { //获取列
perceptron.setInput(dataRow.getInput());
perceptron.calculate();
double[ ] networkOutput = perceptron.getOutput();
System.out.print("Input: " + Arrays.toString(dataRow.getInput()) );
System.out.println(" Output: " + Arrays.toString(networkOutput) );
}
}

OR集训练结果:

Input: [0.0, 0.0] Output: [0.0]

Input: [0.0, 1.0] Output: [1.0]

Input: [1.0, 0.0] Output: [1.0]

Input: [1.0, 1.0] Output: [1.0]

XOR

在这个地方就不能用一个感知机来学习XOR了,因为之前的逻辑运算只有输入输出两层的感知机,可以通过对几条逻辑运算的输入输出情况进行训练,就能完成AND和OR的学习,但是无法对XOR运算在有限次迭代内完成训练。因为XOR是线性不可分的,这样会造成一个死循环,一直无休止的执行训练都不会有结果,所以我们需要采用多层的网络结构,在原来的基础上,增加一个隐层,用多层的结构来让XOR线性可分。

0 AND 0 1

0 AND 1 0

1 AND 0 0

1 AND 1 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//建立一个训练集,两个输入一个输出
DataSet trainingsetXOR = new DataSet(2,1);
trainingsetXOR.addRow(new double[]{0,0}, new double[]{0});
trainingsetXOR.addRow(new double[]{0,1}, new double[]{1});
trainingsetXOR.addRow(new double[]{1,0}, new double[]{1});
trainingsetXOR.addRow(new double[]{1,1}, new double[]{0});

// 三个层,输入两个单元,隐层5个单元,输出层1个单元
MultiLayerPerceptron myMlPerceptron = new MultiLayerPerceptron(TransferFunctionType.TANH,2,5,1);

//创建学习规则
myMlPerceptron.setLearningRule(new BackPropagation());
LearningRule learningRule = myMlPerceptron.getLearningRule();
learningRule.addListener((LearningEventListener) this);

// 训练XOR集
myMlPerceptron.learn(trainingsetXOR);

// 训练结果
System.out.println("XOR训练结果:");
xorNeuralNetwork(myMlPerceptron, trainingsetXOR);

//在主函数中输出训练结果
public static void xorNeuralNetwork(NeuralNetwork myMlPerceptron, DataSet or) {
for (DataSetRow dataRow : or.getRows()) { //获取列
myMlPerceptron.setInput(dataRow.getInput());
myMlPerceptron.calculate();
double[ ] networkOutput = myMlPerceptron.getOutput();
System.out.print("Input: " + Arrays.toString(dataRow.getInput()) );
System.out.println(" Output: " + Arrays.toString(networkOutput) );
}
}

XOR训练结果

Input: [0.0, 0.0] Output: [0.15276357667524357]

Input: [0.0, 1.0] Output: [0.8452278957561844]

Input: [1.0, 0.0] Output: [0.8688182893567877]

Input: [1.0, 1.0] Output: [0.12258603385216649]

总结

现在,AND、OR、XOR的逻辑学习就算完成了,对于需要多层学习或者是线性不可分的,我们可以多加几个隐层神经单元,不仅可以学习线性不可分和线性可分,还可以提高识别的准确率。