diff --git a/ApiDocument.txt b/ApiDocument.txt new file mode 100644 index 0000000..109a0c1 --- /dev/null +++ b/ApiDocument.txt @@ -0,0 +1,38 @@ +//MyBrain-JAVA 神经网络api说明文档 +//构建一个神经网络管理器,参数:(感知神经元个数,隐层神经元个数,输出神经元个数,隐层神经元深度) +//一个神经网络管理管理一个神经网络学习内容,所以当初始化一个神经网络管理器,请将它置于静态对象 +NerveManager nerveManager = +new NerveManager(int sensoryNerveNub,int hiddenNerverNub,int outNerveNub,int hiddenDepth); +//开始构建神经网络,参数(各神经元是否进行权重及阈值的初始化),若不进行初始化,则用户需将之前保存的训练数据加载进神经元 +nerveManager.init(boolean initPower); +//设置学习率(取值范围是0-1开区间),若不设置默认为0.1 +nerveManager.setStudyPoint(0.2); +//添加判断回调输出类,参数:创建一个类 这将这类实现OutBack接口和其类方法,检测状态下的输出神经元,会将输出结果回调到这个类 +//若神经网络是学习状态,可不设置。检测状态若不设置会报错 +nerveManager.setOutBack(new Test()); +//获取感知神经元集合 +List sensoryNerves = nerveManager.getSensoryNerves(); +//从集合里拿出一个感知神经元进行输入,参数:事件ID,输入参数,是否是学习状态,期望结果 +sensoryNerves.get(i).postMessage(long eventId, double parameter, boolean isStudy, double E); +//实现OutBack 接口的类 回调 getBack() 参数:该输出神经元输出值,该神经元ID,该事件ID +public void getBack(double out, int id, long eventId) { + System.out.println("out==" + out + ",id==" + id + ",eventId==" + eventId); + } +神经管理器说明 +private List sensoryNerves = new ArrayList<>();//感知神经元 +private List> depthNerves = new ArrayList<>();//隐层神经元 +private List outNevers = new ArrayList<>();//输出神经元 +学习结束通过GET方法 获取三类神经元 集合并通过Nerve类 的 +public Map getDendrites() {//各参数权重 + return dendrites; + } + public double getThreshold() {//该神经元阈值 + return threshold; + } +获取这两个参数 并保存数据库,等下次服务启动 将对应数据在通过其SET方法 加载进对应神经元,此为上次学习结果 +参数说明: +eventId:事件ID,进行一次神经网络判断,为一次事件ID,ID唯一,可通过IdCreator.get().nextId 生成 +其目的就是 回调的时候 通过这个ID 判断 输出的结果是对应哪一个检测及输入事件 +parameter:就是输入参数 +isStudy:是否是学习状态,判断状态传FALSE,模板学习传TRUE,注意:学习状态输出神经元不输出结果 +E:期望结果,检测状态随便写值没有影响,学习状态是,该模板期望的结果,通常为0或者1,即分类值 \ No newline at end of file diff --git a/src/main/java/org/wlld/App.java b/src/main/java/org/wlld/App.java index 085c2dc..b47e89c 100644 --- a/src/main/java/org/wlld/App.java +++ b/src/main/java/org/wlld/App.java @@ -14,12 +14,20 @@ public class App { } public static void createNerveTest() throws Exception { + //构建一个神经网络管理器,参数:(感知神经元个数,隐层神经元个数,输出神经元个数,输出神经元深度) + //一个神经网络管理管理一个神经网络学习内容, NerveManager nerveManager = new NerveManager(2, 3, 1, 2); + //开始构建神经网络,参数为是否初始化权重及阈值,若 nerveManager.init(true); + nerveManager.setStudyPoint(0.2);//设置学习率(取值范围是0-1开区间),若不设置默认为0.1 + nerveManager.setOutBack(new Test());//添加判断回调输出类 List sensoryNerves = nerveManager.getSensoryNerves(); for (int i = 0; i < sensoryNerves.size(); i++) { sensoryNerves.get(i).postMessage(1, 2 + i, true, 1); } + for (int i = 0; i < sensoryNerves.size(); i++) { + sensoryNerves.get(i).postMessage(1, 2 + i, false, 1); + } } } diff --git a/src/main/java/org/wlld/Test.java b/src/main/java/org/wlld/Test.java new file mode 100644 index 0000000..7548395 --- /dev/null +++ b/src/main/java/org/wlld/Test.java @@ -0,0 +1,15 @@ +package org.wlld; + +import org.wlld.i.OutBack; + +/** + * @author lidapeng + * @description + * @date 1:19 下午 2019/12/24 + */ +public class Test implements OutBack { + @Override + public void getBack(double out, int id, long eventId) { + System.out.println("out==" + out + ",id==" + id + ",eventId==" + eventId); + } +} diff --git a/src/main/java/org/wlld/i/OutBack.java b/src/main/java/org/wlld/i/OutBack.java new file mode 100644 index 0000000..bc773de --- /dev/null +++ b/src/main/java/org/wlld/i/OutBack.java @@ -0,0 +1,11 @@ +package org.wlld.i; + +/** + * @author lidapeng + * @将神经元的输出回调 + * @date 1:07 下午 2019/12/24 + */ +public interface OutBack { + //输出回调 + void getBack(double out, int id, long eventId); +} diff --git a/src/main/java/org/wlld/nerveCenter/NerveManager.java b/src/main/java/org/wlld/nerveCenter/NerveManager.java index 6a1e101..27ab811 100644 --- a/src/main/java/org/wlld/nerveCenter/NerveManager.java +++ b/src/main/java/org/wlld/nerveCenter/NerveManager.java @@ -1,5 +1,6 @@ package org.wlld.nerveCenter; +import org.wlld.i.OutBack; import org.wlld.nerveEntity.HiddenNerve; import org.wlld.nerveEntity.Nerve; import org.wlld.nerveEntity.OutNerve; @@ -23,6 +24,20 @@ public class NerveManager { private List> depthNerves = new ArrayList<>();//隐层神经元 private List outNevers = new ArrayList<>();//输出神经元 private boolean initPower; + private OutBack outBack; + private double studyPoint = 0.1;//学习率 + + public double getStudyPoint() { + return studyPoint; + } + + public void setStudyPoint(double studyPoint) throws Exception { + if (studyPoint < 1 && studyPoint > 0) { + this.studyPoint = studyPoint; + } else { + throw new Exception("studyPoint Values range from 0 to 1"); + } + } public NerveManager(int sensoryNerveNub, int hiddenNerverNub, int outNerveNub , int hiddenDepth) { @@ -32,6 +47,18 @@ public class NerveManager { this.hiddenDepth = hiddenDepth; } + public void setOutBack(OutBack outBack) {//设置回调类 + this.outBack = outBack; + for (Nerve nerve : outNevers) { + OutNerve outNerve = (OutNerve) nerve; + outNerve.setOutBack(outBack); + } + } + + public OutBack getOutBack() {//获取回调类的引用 + return outBack; + } + public int getHiddenNerverNub() { return hiddenNerverNub; } @@ -68,7 +95,7 @@ public class NerveManager { List lastNeveList = depthNerves.get(depthNerves.size() - 1); //初始化输出神经元 for (int i = 1; i < outNerveNub + 1; i++) { - OutNerve outNerve = new OutNerve(i, hiddenNerverNub, 0, initPower); + OutNerve outNerve = new OutNerve(i, hiddenNerverNub, 0, studyPoint, initPower); //输出层神经元连接最后一层隐层神经元 outNerve.connectFathor(lastNeveList); outNevers.add(outNerve); @@ -104,7 +131,7 @@ public class NerveManager { } else { downNub = hiddenNerverNub; } - HiddenNerve hiddenNerve = new HiddenNerve(j, i + 1, upNub, downNub, initPower); + HiddenNerve hiddenNerve = new HiddenNerve(j, i + 1, upNub, downNub, studyPoint, initPower); hiddenNerveList.add(hiddenNerve); } depthNerves.add(hiddenNerveList); diff --git a/src/main/java/org/wlld/nerveEntity/HiddenNerve.java b/src/main/java/org/wlld/nerveEntity/HiddenNerve.java index 1465d9b..48f47ce 100644 --- a/src/main/java/org/wlld/nerveEntity/HiddenNerve.java +++ b/src/main/java/org/wlld/nerveEntity/HiddenNerve.java @@ -3,8 +3,6 @@ package org.wlld.nerveEntity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.Map; - /** * @author lidapeng * 隐层神经元 @@ -14,8 +12,8 @@ public class HiddenNerve extends Nerve { private int depth;//所处深度 static final Logger logger = LogManager.getLogger(HiddenNerve.class); - public HiddenNerve(int id, int depth, int upNub, int downNub, boolean init) {//隐层神经元 - super(id, upNub, "HiddenNerve", downNub, init); + public HiddenNerve(int id, int depth, int upNub, int downNub, double studyPoint, boolean init) {//隐层神经元 + super(id, upNub, "HiddenNerve", downNub, studyPoint, init); this.depth = depth; } diff --git a/src/main/java/org/wlld/nerveEntity/Nerve.java b/src/main/java/org/wlld/nerveEntity/Nerve.java index 51a7a86..8ccd7d8 100644 --- a/src/main/java/org/wlld/nerveEntity/Nerve.java +++ b/src/main/java/org/wlld/nerveEntity/Nerve.java @@ -28,7 +28,7 @@ public abstract class Nerve { protected double outNub;//输出数值(ps:只有训练模式的时候才可保存输出过的数值) protected double E;//模板期望值 protected double gradient;//当前梯度 - protected final double studyPoint = 0.1; + protected double studyPoint; protected double sigmaW;//对上一层权重与上一层梯度的积进行求和 private int backNub = 0;//当前节点被反向传播的次数 @@ -48,11 +48,13 @@ public abstract class Nerve { this.threshold = threshold; } - protected Nerve(int id, int upNub, String name, int downNub, boolean init) {//该神经元在同层神经元中的编号 + protected Nerve(int id, int upNub, String name, int downNub, + double studyPoint, boolean init) {//该神经元在同层神经元中的编号 this.id = id; this.upNub = upNub; this.name = name; this.downNub = downNub; + this.studyPoint = studyPoint; if (init) { initPower();//生成随机权重 } diff --git a/src/main/java/org/wlld/nerveEntity/OutNerve.java b/src/main/java/org/wlld/nerveEntity/OutNerve.java index a0415ff..6780478 100644 --- a/src/main/java/org/wlld/nerveEntity/OutNerve.java +++ b/src/main/java/org/wlld/nerveEntity/OutNerve.java @@ -2,11 +2,9 @@ package org.wlld.nerveEntity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.wlld.i.OutBack; import org.wlld.tools.ArithUtil; -import java.util.List; -import java.util.Map; - /** * @author lidapeng * 输出神经元 @@ -14,9 +12,14 @@ import java.util.Map; */ public class OutNerve extends Nerve { static final Logger logger = LogManager.getLogger(OutNerve.class); + private OutBack outBack; + + public OutNerve(int id, int upNub, int downNub, double studyPoint, boolean init) { + super(id, upNub, "OutNerve", downNub, studyPoint, init); + } - public OutNerve(int id, int upNub, int downNub, boolean init) { - super(id, upNub, "OutNerve", downNub, init); + public void setOutBack(OutBack outBack) { + this.outBack = outBack; } @Override @@ -33,8 +36,13 @@ public class OutNerve extends Nerve { gradient = outGradient();//当前梯度变化 //调整权重 修改阈值 并进行反向传播 updatePower(eventId); - } else { + } else {//获取最后输出 destoryParameter(eventId); + if (outBack != null) { + outBack.getBack(out, getId(), eventId); + } else { + throw new Exception("not find outBack"); + } } } } diff --git a/src/main/java/org/wlld/nerveEntity/SensoryNerve.java b/src/main/java/org/wlld/nerveEntity/SensoryNerve.java index 5fca5bc..74cdc4a 100644 --- a/src/main/java/org/wlld/nerveEntity/SensoryNerve.java +++ b/src/main/java/org/wlld/nerveEntity/SensoryNerve.java @@ -10,7 +10,7 @@ import java.util.List; public class SensoryNerve extends Nerve { public SensoryNerve(int id, int upNub) { - super(id, upNub, "SensoryNerve", 0, false); + super(id, upNub, "SensoryNerve", 0, 0.1, false); } public void postMessage(long eventId, double parameter, boolean isStudy, double E) throws Exception {//感知神经元输出