📄 oann.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Collections;
using System.IO;
namespace com.oatil {
public static class OaUtil {
private static Random random = new Random();
public static double getRandom(double min, double max) {
if (min > max) {
return getRandom(max, min);
}
return (min + (max - min) * random.NextDouble());
}
//验证某字符串是否是数字,支持负数。
public static bool isNumeric(string s) {
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"^[-]?\d+[.]?\d*$");
return reg.IsMatch(s);
}
public static bool isNull(string s) {
if (s == "" || s == null) {
return true;
} else {
return false;
}
}
}
public class Synapse {
public Neuron inputNeuron;
public Neuron outputNeuron;
public double weight = 0;
public Synapse(Neuron inputNeuron, Neuron outputNeuron) {
this.inputNeuron = inputNeuron;
this.outputNeuron = outputNeuron;
}
//learningRate 0.0 to 1.0
public void optimizeWeight(double learningRate) {
weight += learningRate * inputNeuron.value * outputNeuron.error;
}
public void addJitter(double maxJitter) {
weight += maxJitter * OaUtil.getRandom(-1, 1);
if (weight > 1)
weight = 1;
if (weight < -1)
weight = -1;
}
}
public class Neuron {
public Layer layer;
public double biasValue; //阈值
public double value; //
public double error; //误差
public ArrayList inputSynapses = new ArrayList();
public ArrayList outputSynapses = new ArrayList();
public Neuron(Layer layer) {
this.layer = layer;
}
public void connect(Layer layer) {
foreach (Neuron neuron in layer.neurons) {
Synapse synapse = new Synapse(this, neuron);
this.outputSynapses.Add(synapse);
neuron.inputSynapses.Add(synapse);
}
}
public void init() {
Synapse synapse;
double rmsInvertedWeight = 0;
double sumWeights = 0;
biasValue = OaUtil.getRandom(-1, 1);
for (int i = 0; i < inputSynapses.Count; i++) {
synapse = (Synapse)inputSynapses[i];
synapse.weight = OaUtil.getRandom(-1, 1);
rmsInvertedWeight += synapse.weight * synapse.weight;
}
rmsInvertedWeight = Math.Sqrt(1 / rmsInvertedWeight);
for (int i = 0; i < inputSynapses.Count; i++) {
synapse = (Synapse)inputSynapses[i];
synapse.weight *= 2 * rmsInvertedWeight;
sumWeights += synapse.weight;
}
biasValue -= sumWeights / 2;
}
public void propagate() {
Synapse synapse;
value = 0;
for (int i = 0; i < inputSynapses.Count; i++) {
synapse = (Synapse)inputSynapses[i];
value += synapse.inputNeuron.value * synapse.weight;
}
value = activate(value + biasValue);
}
public void backPropagate() {
error = 0;
Synapse synapse;
for (int i = 0; i < outputSynapses.Count; i++) {
synapse = (Synapse)outputSynapses[i];
error += synapse.weight * synapse.outputNeuron.error;
}
error *= derivative(value);
}
public void train(double learningRate) {
biasValue += learningRate * error;
foreach (Synapse synapse in outputSynapses)
synapse.optimizeWeight(learningRate);
}
public void addJitter(double maxJitter) {
foreach (Synapse synapse in outputSynapses)
synapse.addJitter(maxJitter);
}
public double activate(double x) {
const int linear = 1;
const int logarithm = 2;
const int sigmoid = 3;
const int sine = 4;
const int tanh = 5;
int function = sigmoid;
switch (function) {
case sigmoid:
x = Math.Exp(-x);
return 1.0 / (1 + x);
case linear:
return x;
case logarithm:
return Math.Log(1 + Math.Abs(x));
case sine:
return Math.Sin(x);
case tanh:
return Math.Tanh(x);
default:
x = Math.Exp(-x);
return 1.0 / (1 + x);
}
}
public double derivative(double x) {
const int linear = 1;
const int logarithm = 2;
const int sigmoid = 3;
const int sine = 4;
const int tanh = 5;
int function = sigmoid;
switch (function) {
case linear:
return 1;
case logarithm:
return (1d / Math.Exp(x));
case sine:
return Math.Sqrt(1 - x * x);
case tanh:
return (1 - x * x);
default:
return (x * (1 - x));
}
}
}
public class Layer {
public ArrayList neurons = new ArrayList();
public Layer sourceLayer = null;
public Layer targetLayer = null;
public Layer(int sumNeurons, Layer sourceLayer) {
for (int i = 0; i < sumNeurons; i++) {
neurons.Add(new Neuron(this));
}
if (sourceLayer != null)
sourceLayer.targetLayer = this;
this.sourceLayer = sourceLayer;
}
public void autoConnect() {
if (targetLayer != null) {
for (int i = 0; i < neurons.Count; i++) {
((Neuron)neurons[i]).connect(targetLayer);
}
targetLayer.sourceLayer = this;
targetLayer.autoConnect();
}
}
public void propagate() {
if (sourceLayer != null) {
for (int i = 0; i < neurons.Count; i++) {
((Neuron)neurons[i]).propagate();
}
}
if (targetLayer != null)
targetLayer.propagate();
}
public void backPropagate() {
if (targetLayer != null) {
for (int i = 0; i < neurons.Count; i++) {
((Neuron)neurons[i]).backPropagate();
}
}
if (sourceLayer != null)
sourceLayer.backPropagate();
}
//0.0 to 1.0
public void train(double learningRate) {
if (targetLayer != null) {
for (int i = 0; i < neurons.Count; i++)
((Neuron)neurons[i]).train(learningRate);
}
if (sourceLayer != null)
sourceLayer.train(learningRate);
}
public void addJitter(double maxJitter) {
if (targetLayer != null) {//如果不是输出层
for (int i = 0; i < neurons.Count; i++) {
((Neuron)neurons[i]).addJitter(maxJitter);
}
targetLayer.addJitter(maxJitter);
}
}
}
public class Network {
public Layer inputLayer = null;
public Layer outputLayer = null;
public string title = "";
public double learningRate = 0.4;
public double sumSquaredError = 0d;
public int sumLayers = 0;
public Network() {
}
public Network(int sumInputNeurons) {
inputLayer = new Layer(sumInputNeurons, null);
outputLayer = inputLayer;
sumLayers++;
}
public void addLayer(int sumNeurons) {
if (outputLayer == null && inputLayer == null) {
inputLayer = new Layer(sumNeurons, null);
outputLayer = inputLayer;
} else {
outputLayer.targetLayer = new Layer(sumNeurons, outputLayer);
outputLayer = outputLayer.targetLayer;
}
sumLayers++;
}
public void autoConnect() {
inputLayer.autoConnect();
}
public void init() {
for (Layer layer = inputLayer.targetLayer; layer != null; layer = layer.targetLayer) {
foreach (Neuron neuron in layer.neurons) {
neuron.init();
}
}
}
public double[] run(double[] input) {
double[] output = new double[outputLayer.neurons.Count];
for (int i = 0; i < input.Length; i++) {
((Neuron)inputLayer.neurons[i]).value = input[i];
}
inputLayer.propagate();
for (int i = 0; i < output.Length; i++) {
output[i] = ((Neuron)outputLayer.neurons[i]).value;
}
return output;
}
public void train(double[] input, double[] output) {
Neuron neuron;
for (int i = 0; i < input.Length; i++) {
((Neuron)inputLayer.neurons[i]).value = input[i];
}
inputLayer.propagate();
sumSquaredError = 0;
for (int i = 0; i < outputLayer.neurons.Count; i++) {
neuron = (Neuron)outputLayer.neurons[i];
neuron.error = output[i] - neuron.value;
sumSquaredError += neuron.error * neuron.error;
neuron.error *= neuron.derivative(neuron.value);
}
outputLayer.backPropagate();
outputLayer.train(learningRate);
}
public void addJitter(double maxJitter) {
inputLayer.addJitter(maxJitter);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -