pull/1/head
lidapeng 5 years ago
parent 625ecc2c01
commit eff7fc0257

@ -19,7 +19,7 @@ public class App {
nerveManager.init(); nerveManager.init();
List<SensoryNerve> sensoryNerves = nerveManager.getSensoryNerves(); List<SensoryNerve> sensoryNerves = nerveManager.getSensoryNerves();
for (int i = 0; i < sensoryNerves.size(); i++) { for (int i = 0; i < sensoryNerves.size(); i++) {
sensoryNerves.get(i).postMessage(1, 2 + i, true); sensoryNerves.get(i).postMessage(1, 2 + i, true, 1);
} }
} }
} }

@ -11,4 +11,8 @@ public class ActiveFunction {
public double sigmoid(double x) {//sigmoid public double sigmoid(double x) {//sigmoid
return ArithUtil.div(1, ArithUtil.add(1, Math.exp(-x))); return ArithUtil.div(1, ArithUtil.add(1, Math.exp(-x)));
} }
public double sigmoidG(double out) {
return ArithUtil.mul(out, ArithUtil.sub(1, out));
}
} }

@ -42,7 +42,7 @@ public class NerveManager {
//初始化输出神经元 //初始化输出神经元
List<Nerve> outNevers = new ArrayList<>(); List<Nerve> outNevers = new ArrayList<>();
for (int i = 1; i < outNerveNub + 1; i++) { for (int i = 1; i < outNerveNub + 1; i++) {
OutNerve outNerve = new OutNerve(i, hiddenNerverNub); OutNerve outNerve = new OutNerve(i, hiddenNerverNub, 0);
//输出层神经元连接最后一层隐层神经元 //输出层神经元连接最后一层隐层神经元
outNerve.connectFathor(lastNeveList); outNerve.connectFathor(lastNeveList);
outNevers.add(outNerve); outNevers.add(outNerve);
@ -67,12 +67,18 @@ public class NerveManager {
List<Nerve> hiddenNerveList = new ArrayList<>(); List<Nerve> hiddenNerveList = new ArrayList<>();
for (int j = 1; j < hiddenNerverNub + 1; j++) {//遍历同级 for (int j = 1; j < hiddenNerverNub + 1; j++) {//遍历同级
int upNub = 0; int upNub = 0;
int downNub = 0;
if (i == 0) { if (i == 0) {
upNub = sensoryNerveNub; upNub = sensoryNerveNub;
} else { } else {
upNub = hiddenNerverNub; upNub = hiddenNerverNub;
} }
HiddenNerve hiddenNerve = new HiddenNerve(j, i + 1, upNub); if (i == hiddenDepth - 1) {//最后一层隐层神经元z
downNub = outNerveNub;
} else {
downNub = hiddenNerverNub;
}
HiddenNerve hiddenNerve = new HiddenNerve(j, i + 1, upNub, downNub);
hiddenNerveList.add(hiddenNerve); hiddenNerveList.add(hiddenNerve);
} }
depthNerves.add(hiddenNerveList); depthNerves.add(hiddenNerveList);

@ -2,7 +2,6 @@ package org.wlld.nerveEntity;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.wlld.function.ActiveFunction;
/** /**
* @author lidapeng * @author lidapeng
@ -13,13 +12,13 @@ public class HiddenNerve extends Nerve {
private int depth;//所处深度 private int depth;//所处深度
static final Logger logger = LogManager.getLogger(HiddenNerve.class); static final Logger logger = LogManager.getLogger(HiddenNerve.class);
public HiddenNerve(int id, int depth, int upNub) {//隐层神经元 public HiddenNerve(int id, int depth, int upNub, int downNub) {//隐层神经元
super(id, upNub, "HiddenNerve"); super(id, upNub, "HiddenNerve", downNub);
this.depth = depth; this.depth = depth;
} }
@Override @Override
public void input(long eventId, double parameter, boolean isStudy) throws Exception {//接收上一层的输入 public void input(long eventId, double parameter, boolean isStudy, double E) throws Exception {//接收上一层的输入
logger.debug("name:{},myId:{},depth:{},eventId:{},parameter:{}--getInput", name, getId(), depth, eventId, parameter); logger.debug("name:{},myId:{},depth:{},eventId:{},parameter:{}--getInput", name, getId(), depth, eventId, parameter);
boolean allReady = insertParameter(eventId, parameter); boolean allReady = insertParameter(eventId, parameter);
if (allReady) {//参数齐了,开始计算 sigma - threshold if (allReady) {//参数齐了,开始计算 sigma - threshold
@ -28,9 +27,10 @@ public class HiddenNerve extends Nerve {
double out = activeFunction.sigmoid(sigma);//激活函数输出数值 double out = activeFunction.sigmoid(sigma);//激活函数输出数值
if (isStudy) { if (isStudy) {
outNub = out; outNub = out;
this.E = E;
} }
logger.debug("depth:{},myID:{},outPut:{}", depth, getId(), out); logger.debug("depth:{},myID:{},outPut:{}", depth, getId(), out);
sendMessage(eventId, out, isStudy); sendMessage(eventId, out, isStudy, E);
} }
// sendMessage(); // sendMessage();
} }

@ -15,49 +15,84 @@ import java.util.*;
public abstract class Nerve { public abstract class Nerve {
private List<Nerve> son = new ArrayList<>();//轴突下一层的连接神经元 private List<Nerve> son = new ArrayList<>();//轴突下一层的连接神经元
private List<Nerve> fathor = new ArrayList<>();//树突上一层的连接神经元 private List<Nerve> fathor = new ArrayList<>();//树突上一层的连接神经元
private Map<Integer, Double> dendrites = new HashMap<>();//上一层权重 protected Map<Integer, Double> dendrites = new HashMap<>();//上一层权重
protected Map<Integer, Double> wg = new HashMap<>();//上一层权重与梯度的积
private int id;//同级神经元编号,注意在同层编号中ID应有唯一性 private int id;//同级神经元编号,注意在同层编号中ID应有唯一性
protected int upNub;//上一层神经元数量 protected int upNub;//上一层神经元数量
protected int downNub;//下一层神经元的数量
protected Map<Long, List<Double>> features = new HashMap<>(); protected Map<Long, List<Double>> features = new HashMap<>();
static final Logger logger = LogManager.getLogger(Nerve.class); static final Logger logger = LogManager.getLogger(Nerve.class);
private double threshold;//此神经元的阈值 protected double threshold;//此神经元的阈值
protected ActiveFunction activeFunction = new ActiveFunction(); protected ActiveFunction activeFunction = new ActiveFunction();
protected String name;//该神经元所属类型 protected String name;//该神经元所属类型
protected double outNub;//输出数值ps:只有训练模式的时候才可保存输出过的数值) protected double outNub;//输出数值ps:只有训练模式的时候才可保存输出过的数值)
protected double E;//模板期望值
protected double gradient;//当前梯度
protected final double studyPoint = 0.1;
protected double sigmaW;//对上一层权重与上一层梯度的积进行求和
private int backNub = 0;//当前节点被反向传播的次数
protected Nerve(int id, int upNub, String name) {//该神经元在同层神经元中的编号 protected Nerve(int id, int upNub, String name, int downNub) {//该神经元在同层神经元中的编号
this.id = id; this.id = id;
this.upNub = upNub; this.upNub = upNub;
this.name = name; this.name = name;
this.downNub = downNub;
initPower();//生成随机权重 initPower();//生成随机权重
} }
public void sendMessage(long enevtId, double parameter, boolean isStudy) throws Exception { public void sendMessage(long enevtId, double parameter, boolean isStudy, double E) throws Exception {
if (son.size() > 0) { if (son.size() > 0) {
for (Nerve nerve : son) { for (Nerve nerve : son) {
nerve.input(enevtId, parameter, isStudy); nerve.input(enevtId, parameter, isStudy, E);
} }
} else { } else {
throw new Exception("this layer is lastIndex"); throw new Exception("this layer is lastIndex");
} }
} }
public void backSendMessage(double parameter) throws Exception {//反向传播 private void backSendMessage(long eventId) throws Exception {//反向传播
if (fathor.size() > 0) { if (fathor.size() > 0) {
for (Nerve nerve : fathor) { for (int i = 0; i < fathor.size(); i++) {
nerve.backGetMessage(parameter); fathor.get(i).backGetMessage(wg.get(i + 1), eventId);
} }
} else {
throw new Exception("this layer is firstIndex");
} }
} }
protected void input(long eventId, double parameter, boolean isStudy) throws Exception {//输入 protected void input(long eventId, double parameter, boolean isStudy, double E) throws Exception {//输入
}
private void backGetMessage(double parameter, long eventId) throws Exception {//反向传播
backNub++;
sigmaW = ArithUtil.add(sigmaW, parameter);
if (backNub == downNub) {//进行新的梯度计算
backNub = 0;
gradient = ArithUtil.mul(activeFunction.sigmoidG(outNub), sigmaW);
updatePower(eventId);//修改阈值
}
} }
private void backGetMessage(double parameter) {//反向传播 protected void updatePower(long eventId) throws Exception {//修改阈值
double h = ArithUtil.mul(gradient, studyPoint);//梯度下降
threshold = ArithUtil.sub(threshold, h);//更新阈值
updateW(h, eventId);
sigmaW = 0;//求和结果归零
backSendMessage(eventId);
}
private void updateW(double h, long eventId) {//h是学习率 * 当前g梯度
List<Double> list = features.get(eventId);
for (Map.Entry<Integer, Double> entry : dendrites.entrySet()) {
int key = entry.getKey();//上层隐层神经元的编号
double w = entry.getValue();//接收到编号为KEY的上层隐层神经元的权重
double bn = list.get(key - 1);//接收到编号为KEY的上层隐层神经元的输入
double wp = ArithUtil.mul(bn, h);//编号为KEY的上层隐层神经元权重的变化值
w = ArithUtil.add(w, wp);//修正后的编号为KEY的上层隐层神经元权重
double dm = ArithUtil.mul(w, gradient);//返回给相对应的神经元
wg.put(key, dm);//保存上一层权重与梯度的积
dendrites.put(key, w);//保存修正结果
}
features.remove(eventId); //清空当前上层输入参数参数
} }
protected boolean insertParameter(long eventId, double parameter) {//添加参数 protected boolean insertParameter(long eventId, double parameter) {//添加参数
@ -100,7 +135,7 @@ public abstract class Nerve {
dendrites.put(i, random.nextDouble()); dendrites.put(i, random.nextDouble());
} }
//生成随机阈值 //生成随机阈值
threshold = ArithUtil.mul(random.nextDouble(), 10); threshold = random.nextDouble();
} }
} }

@ -2,6 +2,10 @@ package org.wlld.nerveEntity;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.wlld.tools.ArithUtil;
import java.util.List;
import java.util.Map;
/** /**
* @author lidapeng * @author lidapeng
@ -11,21 +15,31 @@ import org.apache.logging.log4j.Logger;
public class OutNerve extends Nerve { public class OutNerve extends Nerve {
static final Logger logger = LogManager.getLogger(OutNerve.class); static final Logger logger = LogManager.getLogger(OutNerve.class);
public OutNerve(int id, int upNub) { public OutNerve(int id, int upNub, int downNub) {
super(id, upNub, "OutNerve"); super(id, upNub, "OutNerve", downNub);
} }
@Override @Override
public void input(long eventId, double parameter, boolean isStudy) { public void input(long eventId, double parameter, boolean isStudy, double E) throws Exception {
logger.debug("Nerve:{},eventId:{},parameter:{}--getInput", name, eventId, parameter); logger.debug("Nerve:{},eventId:{},parameter:{}--getInput", name, eventId, parameter);
boolean allReady = insertParameter(eventId, parameter); boolean allReady = insertParameter(eventId, parameter);
if (allReady) {//参数齐了,开始计算 sigma - threshold if (allReady) {//参数齐了,开始计算 sigma - threshold
double sigma = calculation(eventId); double sigma = calculation(eventId);
double out = activeFunction.sigmoid(sigma); double out = activeFunction.sigmoid(sigma);
if (isStudy) { logger.debug("myId:{},outPut:{}------END", getId(), out);
if (isStudy) {//输出结果并进行BP调整权重及阈值
outNub = out; outNub = out;
this.E = E;
gradient = outGradient();//当前梯度变化
//调整权重 修改阈值 并进行反向传播
updatePower(eventId);
} }
logger.debug("myId:{},outPut:{}------END", getId(), out);
} }
} }
private double outGradient() {//生成输出层神经元梯度变化
//上层神经元输入值 * 当前神经元梯度*学习率 =该上层输入的神经元权重变化
//当前梯度神经元梯度变化 *学习旅 * -1 = 当前神经元阈值变化
return ArithUtil.mul(activeFunction.sigmoidG(outNub), ArithUtil.sub(E, outNub));
}
} }

@ -10,11 +10,11 @@ import java.util.List;
public class SensoryNerve extends Nerve { public class SensoryNerve extends Nerve {
public SensoryNerve(int id, int upNub) { public SensoryNerve(int id, int upNub) {
super(id, upNub, "SensoryNerve"); super(id, upNub, "SensoryNerve", 0);
} }
public void postMessage(long eventId, double parameter, boolean isStudy) throws Exception {//感知神经元输出 public void postMessage(long eventId, double parameter, boolean isStudy, double E) throws Exception {//感知神经元输出
sendMessage(eventId, parameter, isStudy); sendMessage(eventId, parameter, isStudy, E);
} }
@Override @Override

Loading…
Cancel
Save