对中文语义分类性能进行优化

This commit is contained in:
李大鹏 2023-11-30 13:07:37 +08:00
parent 46b9a14b52
commit cb7dbffdf0
30 changed files with 2075 additions and 413 deletions

View File

@ -6,7 +6,7 @@
<groupId>com.wlld</groupId>
<artifactId>easyAi</artifactId>
<version>1.1.2</version>
<version>1.1.3</version>
<name>easyAi</name>
<!-- FIXME change it to the project's website -->

View File

@ -4,23 +4,19 @@ package org.wlld.config;
import org.wlld.entity.SentenceModel;
/**
* @param
* @DATA
* @Author LiDaPeng
* @Description 参数配置
*/
public class SentenceConfig {
private SentenceModel sentenceModel;
private int typeNub = 11;//分类数量
private int wordVectorDimension = 21;//词向量嵌入维度
private int maxWordLength = 15;//最长字数
private int maxWordLength = 20;//最长字数
private double weStudyPoint = 0.01;//词向量学习学习率
private double weLParam = 0.001;//词向量正则系数
private int randomNumber = 11;//随机网络数量
private int nerveDeep = 6;//随机网络一组深度
private int keyWordNerveDeep = 3;//关键词判断网络深度
private boolean showLog = true;
private int dateAug = 6000;
private int TopNumber = 1;//取最高的几个类别
private int dateAug = 5;
private int minLength = 4;
private double trustPowerTh = 0.5;//权重可信任阈值
private int keyWordNerveDeep = 3;
public int getKeyWordNerveDeep() {
return keyWordNerveDeep;
@ -30,52 +26,12 @@ public class SentenceConfig {
this.keyWordNerveDeep = keyWordNerveDeep;
}
public int getTopNumber() {
return TopNumber;
public SentenceModel getSentenceModel() {
return sentenceModel;
}
public void setTopNumber(int topNumber) {
TopNumber = topNumber;
}
public int getDateAug() {
return dateAug;
}
public void setDateAug(int dateAug) {
this.dateAug = dateAug;
}
public int getNerveDeep() {
return nerveDeep;
}
public void setNerveDeep(int nerveDeep) {
this.nerveDeep = nerveDeep;
}
public int getRandomNumber() {
return randomNumber;
}
public void setRandomNumber(int randomNumber) {
this.randomNumber = randomNumber;
}
public int getMaxWordLength() {
return maxWordLength;
}
public void setMaxWordLength(int maxWordLength) {
this.maxWordLength = maxWordLength;
}
public boolean isShowLog() {
return showLog;
}
public void setShowLog(boolean showLog) {
this.showLog = showLog;
public void setSentenceModel(SentenceModel sentenceModel) {
this.sentenceModel = sentenceModel;
}
public int getTypeNub() {
@ -94,6 +50,14 @@ public class SentenceConfig {
this.wordVectorDimension = wordVectorDimension;
}
public int getMaxWordLength() {
return maxWordLength;
}
public void setMaxWordLength(int maxWordLength) {
this.maxWordLength = maxWordLength;
}
public double getWeStudyPoint() {
return weStudyPoint;
}
@ -109,4 +73,36 @@ public class SentenceConfig {
public void setWeLParam(double weLParam) {
this.weLParam = weLParam;
}
public boolean isShowLog() {
return showLog;
}
public void setShowLog(boolean showLog) {
this.showLog = showLog;
}
public int getDateAug() {
return dateAug;
}
public void setDateAug(int dateAug) {
this.dateAug = dateAug;
}
public int getMinLength() {
return minLength;
}
public void setMinLength(int minLength) {
this.minLength = minLength;
}
public double getTrustPowerTh() {
return trustPowerTh;
}
public void setTrustPowerTh(double trustPowerTh) {
this.trustPowerTh = trustPowerTh;
}
}

View File

@ -4,6 +4,8 @@ package org.wlld.entity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
/**
* @param
* @DATA
@ -21,6 +23,11 @@ public class ConvBack implements OutBack {
public void getBack(double out, int id, long eventId) {
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {
this.matrix = matrix;

View File

@ -4,6 +4,8 @@ package org.wlld.entity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
/**
* @param
* @DATA
@ -39,6 +41,11 @@ public class RegionBack implements OutBack {
}
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {

View File

@ -4,6 +4,8 @@ package org.wlld.entity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
/**
* @param
* @DATA
@ -35,6 +37,11 @@ public class WordBack implements OutBack {
}
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {
}

View File

@ -3,6 +3,9 @@ package org.wlld.entity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.ArrayList;
import java.util.List;
/**
* @param
* @DATA
@ -24,11 +27,24 @@ public class WordMatrix implements OutBack {
return matrix;
}
public List<Double> getList() {
List<Double> list = new ArrayList<>();
for (int i = 0; i < vector.length; i++) {
list.add(vector[i]);
}
return list;
}
@Override
public void getBack(double out, int id, long eventId) {
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {

View File

@ -2,6 +2,8 @@ package org.wlld.i;
import org.wlld.MatrixTools.Matrix;
import java.util.List;
/**
* 将神经元的输出回调
* @author lidapeng
@ -16,6 +18,13 @@ public interface OutBack {
* @param eventId 事件ID
*/
void getBack(double out, int id, long eventId);
/**
* 回调
*
* @param powerList 输出权重路径
* @param eventId 事件ID
*/
void backPower(List<Integer> powerList, long eventId);
/**
* 回调
@ -30,5 +39,6 @@ public interface OutBack {
*
* @param id 当前词向量id
*/
void getWordVector(int id,double w);
void getWordVector(int id, double w);
}

View File

@ -9,10 +9,10 @@ import org.wlld.gameRobot.DynamicState;
import java.util.*;
public class CatchKeyWord {//抓取关键词
private DynamicProgramming dynamicProgramming = new DynamicProgramming();//保存它的状态集合
private List<String> keyWords = new ArrayList<>();//保存词列表
private List<String> finishWords = new ArrayList<>();//终结态词集合
private Set<String> noList = new HashSet<>();//禁止词集合
private final DynamicProgramming dynamicProgramming = new DynamicProgramming();//保存它的状态集合
private final List<String> keyWords = new ArrayList<>();//保存词列表
private final List<String> finishWords = new ArrayList<>();//终结态词集合
private final Set<String> noList = new HashSet<>();//禁止词集合
private double proTh = 0.1;//收益阈值
public void setProTh(double proTh) {
@ -62,16 +62,8 @@ public class CatchKeyWord {//抓取关键词
if (isContinuity) {
wordsValue = new WordsValue();
wordsValue.isMerge = false;
if (start1 > start2) {
wordsValue.startIndex = start2;
} else {
wordsValue.startIndex = start1;
}
if (end1 > end2) {
wordsValue.endIndex = end1;
} else {
wordsValue.endIndex = end2;
}
wordsValue.startIndex = Math.min(start1, start2);
wordsValue.endIndex = Math.max(end1, end2);
}
return wordsValue;
}
@ -92,19 +84,11 @@ public class CatchKeyWord {//抓取关键词
WordsValue wordsValue = isContinuity(startIndex, endIndex, myStart, myEnd);
if (wordsValue != null) {//可进行合并
dynamic.isMerge = true;
if (isFinish || dynamic.isFinish) {
wordsValue.isFinish = true;
} else {
wordsValue.isFinish = false;
}
wordsValue.isFinish = isFinish || dynamic.isFinish;
if (wordsValue.isFinish) {
wordsValue.value = 10;
} else {
if (dynamic.value > value) {
wordsValue.value = dynamic.value;
} else {
wordsValue.value = value;
}
wordsValue.value = Math.max(dynamic.value, value);
}
dynamicState = wordsValue;
}
@ -125,9 +109,7 @@ public class CatchKeyWord {//抓取关键词
KeyWordModel keyWordModel = new KeyWordModel();
List<DyStateModel> dyStateModels = new ArrayList<>();
List<DynamicState> dynamicStateList = dynamicProgramming.getDynamicStateList();
int size = dynamicStateList.size();
for (int i = 0; i < size; i++) {
DynamicState dynamicState = dynamicStateList.get(i);
for (DynamicState dynamicState : dynamicStateList) {
DyStateModel dyStateModel = new DyStateModel();
dyStateModel.setId(dynamicState.getStateId()[0]);
dyStateModel.setFinish(dynamicState.isFinish());
@ -143,13 +125,8 @@ public class CatchKeyWord {//抓取关键词
List<String> myKeyWords = keyWordModel.getKeyWords();
List<DyStateModel> dynamicStates = keyWordModel.getDynamicStateList();
List<DynamicState> dynamicStateList = dynamicProgramming.getDynamicStateList();
int size = myKeyWords.size();
for (int i = 0; i < size; i++) {
keyWords.add(myKeyWords.get(i));
}
int s = dynamicStates.size();
for (int i = 0; i < s; i++) {
DyStateModel modelDy = dynamicStates.get(i);
keyWords.addAll(myKeyWords);
for (DyStateModel modelDy : dynamicStates) {
DynamicState dynamicState = new DynamicState(new int[]{modelDy.getId()});
dynamicState.setValue(modelDy.getValue());
dynamicState.setFinish(modelDy.isFinish());
@ -218,7 +195,7 @@ public class CatchKeyWord {//抓取关键词
int upIndex = sentence.indexOf(maxWord);//最大字符所在的位置
DynamicState upState = null;
double upValue = -1000000;
String myUpWord = null;
String myUpWord;
if (upIndex < sentence.length() - 2) {
myUpWord = sentence.substring(upIndex + 1, upIndex + 3);
upState = getDynamicState(myUpWord, dynamicStateList);
@ -285,7 +262,7 @@ public class CatchKeyWord {//抓取关键词
int index = sentence.indexOf(word);
double myValue = maxDy.value;
DynamicState state = null;
String upWord = null;
String upWord;
if (index > 0) {
int t = index - 1;
upWord = sentence.substring(t, t + word.length());
@ -313,7 +290,7 @@ public class CatchKeyWord {//抓取关键词
int upIndex = sentence.indexOf(maxWord);//最大字符所在的位置
DynamicState upState = null;
double upValue = -1000000;
String myUpWord = null;
String myUpWord;
if (upIndex > 1) {
myUpWord = sentence.substring(upIndex - 2, upIndex);
upState = getDynamicState(myUpWord, dynamicStateList);
@ -361,6 +338,18 @@ public class CatchKeyWord {//抓取关键词
public Set<String> getKeyWord(String sentence) {
List<String> first = getMyKeyWord(sentence, true);
List<String> second = getMyKeyWord(sentence, false);
for (int i = 0; i < first.size(); i++) {
if (first.get(i).length() == 1) {
first.remove(i);
i--;
}
}
for (int i = 0; i < second.size(); i++) {
if (second.get(i).length() == 1) {
second.remove(i);
i--;
}
}
Set<String> set = new HashSet<>();
set.addAll(first);
set.addAll(second);
@ -379,8 +368,7 @@ public class CatchKeyWord {//抓取关键词
//合并完成连接空档
int[] sen = new int[sentence.length()];
Arrays.fill(sen, 1);
for (int i = 0; i < wordsValues.size(); i++) {
WordsValue wordsValue = wordsValues.get(i);
for (WordsValue wordsValue : wordsValues) {
int startIndex = wordsValue.startIndex;
int endIndex = wordsValue.endIndex;
for (int j = startIndex; j <= endIndex; j++) {
@ -407,8 +395,7 @@ public class CatchKeyWord {//抓取关键词
}
}
List<String> keyWords = new ArrayList<>();
for (int i = 0; i < wordsValueList.size(); i++) {
WordsValue wordsValue1 = wordsValueList.get(i);
for (WordsValue wordsValue1 : wordsValueList) {
String keyWord = sentence.substring(wordsValue1.startIndex, wordsValue1.endIndex + 1);
keyWords.add(keyWord);
}
@ -499,10 +486,8 @@ public class CatchKeyWord {//抓取关键词
private int getID(String word) {
int id = 0;
int size = keyWords.size();
boolean isHere = false;
for (int i = 0; i < size; i++) {
String myWord = keyWords.get(i);
for (String myWord : keyWords) {
if (myWord.hashCode() == word.hashCode() && myWord.equals(word)) {
isHere = true;
break;
@ -515,7 +500,7 @@ public class CatchKeyWord {//抓取关键词
return id;
}
class WordsValue {
static class WordsValue {
int id;//词id
int startIndex;//起始下标
int endIndex;//末尾下标

View File

@ -3,6 +3,8 @@ package org.wlld.naturalLanguage.languageCreator;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
public class CreatorWord implements OutBack {
private int id;
private double maxOut = -2;
@ -27,6 +29,11 @@ public class CreatorWord implements OutBack {
}
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {

View File

@ -10,7 +10,6 @@ import org.wlld.function.Tanh;
import org.wlld.i.OutBack;
import org.wlld.rnnNerveCenter.ModelParameter;
import org.wlld.rnnNerveCenter.NerveManager;
import org.wlld.rnnNerveCenter.RandomNerveManager;
import org.wlld.rnnNerveEntity.SensoryNerve;
import java.util.HashMap;
@ -77,7 +76,7 @@ public class MyKeyWord {
if (nerveLength < word.length()) {
times = word.length() - nerveLength + 1;
}
Matrix allFeature = wordEmbedding.getEmbedding(word, eventId);
Matrix allFeature = wordEmbedding.getEmbedding(word, eventId).getFeatureMatrix();
for (int i = 0; i < times; i++) {
if (isStudy) {
E.clear();
@ -109,6 +108,13 @@ public class MyKeyWord {
}
private void studyNerve(long eventId, List<SensoryNerve> sensoryNerves, List<Double> featureList, Matrix rnnMatrix, Map<Integer, Double> E, boolean isStudy, OutBack convBack) throws Exception {
RandomNerveManager.studyMyNerve(eventId, sensoryNerves, featureList, rnnMatrix, E, isStudy, convBack);
if (sensoryNerves.size() == featureList.size()) {
for (int i = 0; i < sensoryNerves.size(); i++) {
sensoryNerves.get(i).postMessage(eventId, featureList.get(i), isStudy, E, convBack, false, rnnMatrix);
}
} else {
throw new Exception("size not equals,feature size:" + featureList.size() + "," +
"sensorySize:" + sensoryNerves.size());
}
}
}

View File

@ -10,6 +10,7 @@ import org.wlld.entity.WordMatrix;
import org.wlld.entity.WordTwoVectorModel;
import org.wlld.function.Tanh;
import org.wlld.i.OutBack;
import org.wlld.rnnJumpNerveEntity.MyWordFeature;
import org.wlld.rnnNerveCenter.NerveManager;
import org.wlld.rnnNerveEntity.SensoryNerve;
@ -55,10 +56,11 @@ public class WordEmbedding {
nerveManager.insertModelParameter(wordTwoVectorModel.getModelParameter());
}
public Matrix getEmbedding(String word, long eventId) throws Exception {//做截断
public MyWordFeature getEmbedding(String word, long eventId) throws Exception {//做截断
if (word.length() > config.getMaxWordLength()) {
word = word.substring(0, config.getMaxWordLength());
}
MyWordFeature myWordFeature = new MyWordFeature();
int wordDim = config.getWordVectorDimension();
Matrix matrix = null;
for (int i = 0; i < word.length(); i++) {
@ -67,12 +69,14 @@ public class WordEmbedding {
int index = getID(myWord);
studyDNN(eventId, index, 0, wordMatrix, true, false);
if (matrix == null) {
myWordFeature.setFirstFeatureList(wordMatrix.getList());
matrix = wordMatrix.getVector();
} else {
matrix = MatrixOperation.pushVector(matrix, wordMatrix.getVector(), true);
}
}
return matrix;
myWordFeature.setFeatureMatrix(matrix);
return myWordFeature;
}
private void studyDNN(long eventId, int featureIndex, int resIndex, OutBack outBack, boolean isEmbedding, boolean isStudy) throws Exception {

View File

@ -3,6 +3,8 @@ package org.wlld.recommend;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
public class CodeBack implements OutBack {
private double[] myFeature;
@ -19,6 +21,11 @@ public class CodeBack implements OutBack {
myFeature[id - 1] = out;
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {

View File

@ -0,0 +1,73 @@
package org.wlld.rnnJumpNerveCenter;
import org.wlld.rnnJumpNerveEntity.DymNerveStudy;
import org.wlld.rnnJumpNerveEntity.NerveStudy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author lidapeng
* &#064;description 学习结果
* &#064;date 3:33 下午 2020/1/8
*/
public class ModelParameter {
//神经远模型参数
private List<List<NerveStudy>> depthNerves = new ArrayList<>();//隐层神经元
private List<NerveStudy> outNerves = new ArrayList<>();//输出神经元
private List<RnnOutNerveStudy> rnnOutNerveStudies = new ArrayList<>();//rnn多级输出神经元
private List<DymNerveStudy> dymNerveStudies = new ArrayList<>();//动态神经元隐层
private DymNerveStudy dymOutNerveStudy = new DymNerveStudy();//动态神经元输出层
private Map<Integer, Double> foodS;//干食品类别对应的积分 需激活注入
public List<RnnOutNerveStudy> getRnnOutNerveStudies() {
return rnnOutNerveStudies;
}
public void setRnnOutNerveStudies(List<RnnOutNerveStudy> rnnOutNerveStudies) {
this.rnnOutNerveStudies = rnnOutNerveStudies;
}
public List<List<NerveStudy>> getDepthNerves() {
return depthNerves;
}
public void setDepthNerves(List<List<NerveStudy>> depthNerves) {
this.depthNerves = depthNerves;
}
public List<NerveStudy> getOutNerves() {
return outNerves;
}
public void setOutNerves(List<NerveStudy> outNerves) {
this.outNerves = outNerves;
}
public List<DymNerveStudy> getDymNerveStudies() {
return dymNerveStudies;
}
public void setDymNerveStudies(List<DymNerveStudy> dymNerveStudies) {
this.dymNerveStudies = dymNerveStudies;
}
public DymNerveStudy getDymOutNerveStudy() {
return dymOutNerveStudy;
}
public void setDymOutNerveStudy(DymNerveStudy dymOutNerveStudy) {
this.dymOutNerveStudy = dymOutNerveStudy;
}
public Map<Integer, Double> getFoodS() {
return foodS;
}
public void setFoodS(Map<Integer, Double> foodS) {
this.foodS = foodS;
}
}

View File

@ -0,0 +1,468 @@
package org.wlld.rnnJumpNerveCenter;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.ActiveFunction;
import org.wlld.rnnJumpNerveEntity.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 神经网络管理工具
* 创建神经网络
*
* @author lidapeng
* &#064;date 11:05 上午 2019/12/21
*/
public class NerveJumpManager {
private final int hiddenNerveNub;//隐层神经元个数
private final int sensoryNerveNub;//输入神经元个数
private final int outNerveNub;//输出神经元个数
private final int hiddenDepth;//隐层深度
private final List<SensoryNerve> sensoryNerves = new ArrayList<>();//感知神经元
private final List<List<Nerve>> depthNerves = new ArrayList<>();//隐层神经元
private final List<Nerve> outNerves = new ArrayList<>();//输出神经元
private final List<Nerve> softMaxList = new ArrayList<>();//softMax层
private final List<RnnOutNerveBody> rnnOutNerveBodies = new ArrayList<>();//rnn输出层神经元
private boolean initPower;
private double studyPoint = 0.1;//学习率
private final ActiveFunction activeFunction;
private Map<Integer, Matrix> matrixMap = new HashMap<>();//主键与期望矩阵的映射
private final boolean isDynamic;//是否是动态神经网络
private boolean isRnn = false;//是否为rnn网络
private final int rzType;//正则化类型默认不进行正则化
private final double lParam;//正则参数
private final List<NerveCenter> nerveCenterList = new ArrayList<>();
private double powerTh = 0.2;//权重阈值
public void setPowerTh(double powerTh) {
this.powerTh = powerTh;
}
public void setMatrixMap(Map<Integer, Matrix> matrixMap) {
this.matrixMap = matrixMap;
}
private Map<String, Double> conversion(Map<Integer, Double> map) {
Map<String, Double> cMap = new HashMap<>();
for (Map.Entry<Integer, Double> entry : map.entrySet()) {
cMap.put(String.valueOf(entry.getKey()), entry.getValue());
}
return cMap;
}
private Map<Integer, Double> unConversion(Map<String, Double> map) {
Map<Integer, Double> cMap = new HashMap<>();
for (Map.Entry<String, Double> entry : map.entrySet()) {
cMap.put(Integer.parseInt(entry.getKey()), entry.getValue());
}
return cMap;
}
private ModelParameter getDymModelParameter() throws Exception {//获取动态神经元参数
ModelParameter modelParameter = new ModelParameter();
List<DymNerveStudy> dymNerveStudies = new ArrayList<>();//动态神经元隐层
DymNerveStudy dymOutNerveStudy = new DymNerveStudy();//动态神经元输出层
modelParameter.setDymNerveStudies(dymNerveStudies);
modelParameter.setDymOutNerveStudy(dymOutNerveStudy);
for (List<Nerve> nerve : depthNerves) {
Nerve depthNerve = nerve.get(0);//隐层神经元
DymNerveStudy deepNerveStudy = new DymNerveStudy();//动态神经元输出层
List<Double> list = deepNerveStudy.getList();
Matrix matrix = depthNerve.getNerveMatrix();
insertWList(matrix, list);
dymNerveStudies.add(deepNerveStudy);
}
Nerve outNerve = outNerves.get(0);
Matrix matrix = outNerve.getNerveMatrix();
List<Double> list = dymOutNerveStudy.getList();
insertWList(matrix, list);
return modelParameter;
}
private void insertWList(Matrix matrix, List<Double> list) throws Exception {//
for (int i = 0; i < matrix.getX(); i++) {
for (int j = 0; j < matrix.getY(); j++) {
list.add(matrix.getNumber(i, j));
}
}
}
public ModelParameter getModelParameter() throws Exception {
if (isRnn) {
return getRnnModelParameter();
} else if (isDynamic) {
return getDymModelParameter();
} else {
return getStaticModelParameter();
}
}
private ModelParameter getRnnModelParameter() {//获取rnn当前模型参数
ModelParameter modelParameter = new ModelParameter();
List<List<NerveStudy>> studyDepthNerves = new ArrayList<>();//隐层神经元模型
List<RnnOutNerveStudy> rnnOutNerveStudies = new ArrayList<>();
modelParameter.setDepthNerves(studyDepthNerves);
modelParameter.setRnnOutNerveStudies(rnnOutNerveStudies);
//隐层神经元
for (List<Nerve> depthNerve : depthNerves) {
//创建一层深度的隐层神经元模型
List<NerveStudy> deepNerve = new ArrayList<>();
for (Nerve nerve : depthNerve) {
//遍历某一层深度的所有隐层神经元
NerveStudy nerveStudy = new NerveStudy();
nerveStudy.setThreshold(nerve.getThreshold());
nerveStudy.setDendrites(conversion(nerve.getDendrites()));
deepNerve.add(nerveStudy);
}
studyDepthNerves.add(deepNerve);
}
for (RnnOutNerveBody rnnOutNerveBody : rnnOutNerveBodies) {
List<NerveStudy> nerveStudies = new ArrayList<>();
RnnOutNerveStudy rnnOutNerveStudy = new RnnOutNerveStudy();
rnnOutNerveStudies.add(rnnOutNerveStudy);
rnnOutNerveStudy.setDepth(rnnOutNerveBody.getDepth());
rnnOutNerveStudy.setNerveStudies(nerveStudies);
List<Nerve> outNerveList = rnnOutNerveBody.getOutNerves();
getOutNerveModel(nerveStudies, outNerveList);
}
return modelParameter;
}
private void getOutNerveModel(List<NerveStudy> nerveStudies, List<Nerve> outNerveList) {
for (Nerve nerve : outNerveList) {
NerveStudy nerveStudy = new NerveStudy();
nerveStudy.setThreshold(nerve.getThreshold());
nerveStudy.setDendrites(conversion(nerve.getDendrites()));
nerveStudies.add(nerveStudy);
}
}
private ModelParameter getStaticModelParameter() {//获取当前模型参数
ModelParameter modelParameter = new ModelParameter();
List<List<NerveStudy>> studyDepthNerves = new ArrayList<>();//隐层神经元模型
List<NerveStudy> outStudyNerves = new ArrayList<>();//输出神经元
//隐层神经元
for (List<Nerve> depthNerve : depthNerves) {
//创建一层深度的隐层神经元模型
List<NerveStudy> deepNerve = new ArrayList<>();
getOutNerveModel(deepNerve, depthNerve);
studyDepthNerves.add(deepNerve);
}
for (Nerve nerve : outNerves) {
NerveStudy nerveStudy = new NerveStudy();
nerveStudy.setThreshold(nerve.getThreshold());
nerveStudy.setDendrites(conversion(nerve.getDendrites()));
outStudyNerves.add(nerveStudy);
}
modelParameter.setDepthNerves(studyDepthNerves);
modelParameter.setOutNerves(outStudyNerves);
return modelParameter;
}
public void insertModelParameter(ModelParameter modelParameter) throws Exception {
if (isRnn) {
insertRnnModelParameter(modelParameter);
} else if (isDynamic) {
insertConvolutionModelParameter(modelParameter);//动态神经元注入
} else {
insertBpModelParameter(modelParameter);//全连接层注入参数
}
}
//注入卷积层模型参数
private void insertConvolutionModelParameter(ModelParameter modelParameter) throws Exception {
List<DymNerveStudy> dymNerveStudyList = modelParameter.getDymNerveStudies();
DymNerveStudy dymOutNerveStudy = modelParameter.getDymOutNerveStudy();
for (int i = 0; i < depthNerves.size(); i++) {
Nerve depthNerve = depthNerves.get(i).get(0);
DymNerveStudy dymNerveStudy = dymNerveStudyList.get(i);
List<Double> list = dymNerveStudy.getList();
Matrix nerveMatrix = depthNerve.getNerveMatrix();
insertMatrix(nerveMatrix, list);
}
Nerve outNerve = outNerves.get(0);
Matrix outNerveMatrix = outNerve.getNerveMatrix();
List<Double> list = dymOutNerveStudy.getList();
insertMatrix(outNerveMatrix, list);
}
private void insertMatrix(Matrix matrix, List<Double> list) throws Exception {
for (int i = 0; i < list.size(); i++) {
matrix.setNub(i, 0, list.get(i));
}
}
private void insertRnnModelParameter(ModelParameter modelParameter) {
List<List<NerveStudy>> depthStudyNerves = modelParameter.getDepthNerves();//隐层神经元
List<RnnOutNerveStudy> rnnOutNerveStudies = modelParameter.getRnnOutNerveStudies();
//隐层神经元参数注入
depthNervesModel(depthStudyNerves);
for (RnnOutNerveStudy rnnOutNerveStudy : rnnOutNerveStudies) {
RnnOutNerveBody rnnOutNerveBody = getRnnOutNerveBody(rnnOutNerveStudy.getDepth());
List<NerveStudy> outStudyNerves = rnnOutNerveStudy.getNerveStudies();
List<Nerve> outNerveBody = rnnOutNerveBody.getOutNerves();
//输出神经元参数注入
outNerveModel(outStudyNerves, outNerveBody);
}
}
private void outNerveModel(List<NerveStudy> outStudyNerves, List<Nerve> outNerveBody) {
for (int i = 0; i < outNerveBody.size(); i++) {
Nerve outNerve = outNerveBody.get(i);
NerveStudy nerveStudy = outStudyNerves.get(i);
outNerve.setThreshold(nerveStudy.getThreshold());
Map<Integer, Double> dendrites = outNerve.getDendrites();
Map<Integer, Double> studyDendrites = unConversion(nerveStudy.getDendrites());
for (Map.Entry<Integer, Double> outEntry : dendrites.entrySet()) {
int key = outEntry.getKey();
dendrites.put(key, studyDendrites.get(key));
}
}
}
private void depthNervesModel(List<List<NerveStudy>> depthStudyNerves) {
for (int i = 0; i < depthNerves.size(); i++) {
List<NerveStudy> depth = depthStudyNerves.get(i);//对应的学习结果
List<Nerve> depthNerve = depthNerves.get(i);//深度隐层神经元
for (int j = 0; j < depthNerve.size(); j++) {//遍历当前深度神经元
Nerve nerve = depthNerve.get(j);
NerveStudy nerveStudy = depth.get(j);
//学习结果
Map<Integer, Double> studyDendrites = unConversion(nerveStudy.getDendrites());
//神经元参数注入
Map<Integer, Double> dendrites = nerve.getDendrites();
nerve.setThreshold(nerveStudy.getThreshold());//注入隐层阈值
for (Map.Entry<Integer, Double> entry : dendrites.entrySet()) {
int key = entry.getKey();
dendrites.put(key, studyDendrites.get(key));//注入隐层权重
}
}
}
}
private RnnOutNerveBody getRnnOutNerveBody(int depth) {
RnnOutNerveBody myRnnOutNerveBody = null;
for (RnnOutNerveBody rnnOutNerveBody : rnnOutNerveBodies) {
if (rnnOutNerveBody.getDepth() == depth) {
myRnnOutNerveBody = rnnOutNerveBody;
break;
}
}
return myRnnOutNerveBody;
}
//注入全连接模型参数
private void insertBpModelParameter(ModelParameter modelParameter) {
List<List<NerveStudy>> depthStudyNerves = modelParameter.getDepthNerves();//隐层神经元
List<NerveStudy> outStudyNerves = modelParameter.getOutNerves();//输出神经元
//隐层神经元参数注入
depthNervesModel(depthStudyNerves);
//输出神经元参数注入
outNerveModel(outStudyNerves, outNerves);
}
/**
* 初始化神经元参数
*
* @param sensoryNerveNub 输入神经元个数
* @param hiddenNerveNub 隐层神经元个数
* @param outNerveNub 输出神经元个数
* @param hiddenDepth 隐层深度
* @param activeFunction 激活函数
* @param isDynamic 是否是动态神经元
* @param rzType 正则函数
* @param lParam 正则系数
* @throws Exception 如果参数错误则抛异常
*/
public NerveJumpManager(int sensoryNerveNub, int hiddenNerveNub, int outNerveNub
, int hiddenDepth, ActiveFunction activeFunction, boolean isDynamic,
double studyPoint, int rzType, double lParam) throws Exception {
if (sensoryNerveNub > 0 && hiddenNerveNub > 0 && outNerveNub > 0 && hiddenDepth > 0 && activeFunction != null) {
this.hiddenNerveNub = hiddenNerveNub;
this.sensoryNerveNub = sensoryNerveNub;
this.outNerveNub = outNerveNub;
this.hiddenDepth = hiddenDepth;
this.activeFunction = activeFunction;
this.isDynamic = isDynamic;
this.rzType = rzType;
this.lParam = lParam;
if (studyPoint > 0 && studyPoint < 1) {
this.studyPoint = studyPoint;
}
} else {
throw new Exception("param is null");
}
}
public List<SensoryNerve> getSensoryNerves() {//获取感知神经元集合
return sensoryNerves;
}
/**
* 初始化
*
* @param initPower 是否是第一次注入
* @param isMatrix 参数是否是一个矩阵
* @param isShowLog 是否打印学习参数
* @param isSoftMax 最后一层是否用softMax激活
* @param step 卷积步长
* @param kernLen 卷积核长
*/
public void init(boolean initPower, boolean isMatrix, boolean isShowLog, boolean isSoftMax
, int step, int kernLen) throws Exception {//进行神经网络的初始化构建
this.initPower = initPower;
initDepthNerve(isMatrix, step, kernLen);//初始化深度隐层神经元
List<Nerve> nerveList = depthNerves.get(0);//第一层隐层神经元
//最后一层隐层神经元啊
List<Nerve> lastNerveList = depthNerves.get(depthNerves.size() - 1);
//初始化输出神经元
for (int i = 1; i < outNerveNub + 1; i++) {
OutNerve outNerve = new OutNerve(i, studyPoint, initPower,
activeFunction, isMatrix, isShowLog, rzType, lParam, isSoftMax, step, kernLen, sensoryNerveNub, hiddenNerveNub, outNerveNub, hiddenDepth);
if (isMatrix) {//是卷积层神经网络
outNerve.setMatrixMap(matrixMap);
}
if (isSoftMax) {
SoftMax softMax = new SoftMax(i, false, outNerve, isShowLog, sensoryNerveNub, hiddenNerveNub, outNerveNub, hiddenDepth);
softMaxList.add(softMax);
}
//输出层神经元连接最后一层隐层神经元
outNerve.connectFather(0, lastNerveList);
outNerves.add(outNerve);
}
//生成softMax层
if (isSoftMax) {//增加softMax层
for (Nerve nerve : outNerves) {
nerve.connect(0, softMaxList);
}
}
//最后一层隐层神经元 与输出神经元进行连接
for (Nerve nerve : lastNerveList) {
nerve.connect(0, outNerves);
}
//初始化感知神经元
for (int i = 1; i < sensoryNerveNub + 1; i++) {
SensoryNerve sensoryNerve = new SensoryNerve(i, hiddenDepth);
//感知神经元与第一层隐层神经元进行连接
sensoryNerve.connect(0, nerveList);
sensoryNerves.add(sensoryNerve);
}
}
private void createRnnOutNerve(boolean initPower, boolean isShowLog, List<Nerve> nerveList, int depth
, boolean toSoftMax) throws Exception {
RnnOutNerveBody rnnOutNerveBody = new RnnOutNerveBody();
List<Nerve> mySoftMaxList = new ArrayList<>();
List<Nerve> rnnOutNerves = new ArrayList<>();
rnnOutNerveBody.setDepth(depth);
rnnOutNerveBody.setOutNerves(rnnOutNerves);
NerveCenter nerveCenter = nerveCenterList.get(depth);
for (int i = 1; i < outNerveNub + 1; i++) {
OutNerve outNerve = new OutNerve(i, studyPoint, initPower,
activeFunction, false, isShowLog, rzType, lParam, toSoftMax, 0, 0, sensoryNerveNub, hiddenNerveNub, outNerveNub, hiddenDepth);
if (toSoftMax) {
SoftMax softMax = new SoftMax(i, false, outNerve, isShowLog, sensoryNerveNub, hiddenNerveNub, outNerveNub, hiddenDepth);
mySoftMaxList.add(softMax);
}
outNerve.setNerveCenter(nerveCenter);
outNerve.connectFather(depth, nerveList);//每一层的输出神经元 链接每一层的隐层神经元
rnnOutNerves.add(outNerve);
}
if (toSoftMax) {
for (Nerve nerve : rnnOutNerves) {
nerve.connect(0, mySoftMaxList);
}
}
for (Nerve nerve : nerveList) {
nerve.connectOut(rnnOutNerves);
}
rnnOutNerveBodies.add(rnnOutNerveBody);
}
public void initRnn(boolean initPower, boolean isShowLog, boolean toSoftMax) throws Exception {
isRnn = true;
initDepthNerve(false, 0, 0);//初始化深度隐层神经元
for (int i = 0; i < depthNerves.size(); i++) {
createRnnOutNerve(initPower, isShowLog, depthNerves.get(i), i + 1, toSoftMax);
}
//初始化感知神经元
for (int i = 1; i < sensoryNerveNub + 1; i++) {
SensoryNerve sensoryNerve = new SensoryNerve(i, hiddenDepth);
for (int j = 0; j < hiddenDepth; j++) {
List<Nerve> hiddenNerveList = depthNerves.get(j);//当前遍历隐层神经元
sensoryNerve.connect(j + 1, hiddenNerveList);
}
sensoryNerves.add(sensoryNerve);
}
}
private void initDepthNerve(boolean isMatrix, int step, int kernLen) throws Exception {//初始化隐层神经元1
if (isRnn) {
NerveCenter nerveCenter = new NerveCenter(0, null, nerveCenterList, powerTh);
nerveCenterList.add(nerveCenter);
}
for (int i = 0; i < hiddenDepth; i++) {//遍历深度
List<Nerve> hiddenNerveList = new ArrayList<>();
double studyPoint = this.studyPoint;
if (studyPoint <= 0 || studyPoint > 1) {
throw new Exception("studyPoint Values range from 0 to 1");
}
if (isRnn) {
NerveCenter nerveCenter = new NerveCenter(i + 1, hiddenNerveList, nerveCenterList, powerTh);
nerveCenterList.add(nerveCenter);
}
for (int j = 1; j < hiddenNerveNub + 1; j++) {//遍历同级
HiddenNerve hiddenNerve = new HiddenNerve(j, i + 1, studyPoint, initPower, activeFunction, isMatrix
, rzType, lParam, step, kernLen, sensoryNerveNub, hiddenNerveNub, outNerveNub, hiddenDepth);
hiddenNerveList.add(hiddenNerve);
}
depthNerves.add(hiddenNerveList);
}
if (isRnn) {
initRnnHiddenNerve();
} else {
initHiddenNerve();
}
}
private void initHiddenNerve() {
for (int i = 0; i < hiddenDepth - 1; i++) {
List<Nerve> hiddenNerveList = depthNerves.get(i);//当前遍历隐层神经元
List<Nerve> nextHiddenNerveList = depthNerves.get(i + 1);
for (Nerve nerve : hiddenNerveList) {
nerve.connect(0, nextHiddenNerveList);
}
for (Nerve nerve : nextHiddenNerveList) {
nerve.connectFather(0, hiddenNerveList);
}
}
}
private void initRnnHiddenNerve() {//初始化隐层神经元2
for (int i = 0; i < hiddenDepth; i++) {//遍历深度
List<Nerve> hiddenNerveList = depthNerves.get(i);//当前遍历隐层神经元
if (i < hiddenDepth - 1) {//向前链接
for (int j = i + 1; j < hiddenDepth; j++) {
List<Nerve> nextHiddenNerveList = depthNerves.get(j);
for (Nerve hiddenNerve : hiddenNerveList) {
hiddenNerve.connect(j + 1, nextHiddenNerveList);
}
}
}
if (i > 0) {//向后链接
for (int t = i - 1; t >= 0; t--) {
List<Nerve> nextHiddenNerveList = depthNerves.get(t);
for (Nerve hiddenNerve : hiddenNerveList) {
hiddenNerve.connectFather(t + 1, nextHiddenNerveList);
}
}
}
}
}
}

View File

@ -0,0 +1,198 @@
package org.wlld.rnnJumpNerveCenter;
import org.wlld.MatrixTools.Matrix;
import org.wlld.config.RZ;
import org.wlld.config.SentenceConfig;
import org.wlld.entity.TypeMapping;
import org.wlld.entity.WordBack;
import org.wlld.function.Tanh;
import org.wlld.i.OutBack;
import org.wlld.naturalLanguage.word.WordEmbedding;
import org.wlld.rnnJumpNerveEntity.MyWordFeature;
import org.wlld.rnnJumpNerveEntity.SensoryNerve;
import java.util.*;
public class RRNerveManager {
private final WordEmbedding wordEmbedding;
private final Map<Integer, Integer> mapping = new HashMap<>();//主键是真实id,值是映射识别用id
private NerveJumpManager typeNerveManager;//类别网络
private final int typeNub;//分类数量
private final int vectorDimension;//特征纵向维度
private final int maxFeatureLength;//特征最长长度
private final double studyPoint;//词向量学习学习率
private final boolean showLog;//是否输出学习数据
private final int minLength;//最小长度
private final int dateAug;//数据增广
public RRNerveManager(SentenceConfig config, WordEmbedding wordEmbedding, boolean initPower) throws Exception {
if (config.getTypeNub() > 0) {
this.minLength = config.getMinLength();
this.wordEmbedding = wordEmbedding;
this.dateAug = config.getDateAug();
this.typeNub = config.getTypeNub();
this.vectorDimension = config.getWordVectorDimension();
this.maxFeatureLength = config.getMaxWordLength();
this.studyPoint = config.getWeStudyPoint();
this.showLog = config.isShowLog();
initNerveManager(initPower, config.getTrustPowerTh());
} else {
throw new Exception("分类种类数量必须大于0");
}
}
private void initNerveManager(boolean initPower, double powerTh) throws Exception {
typeNerveManager = new NerveJumpManager(vectorDimension, vectorDimension, typeNub, maxFeatureLength - 1, new Tanh(), false,
studyPoint, RZ.L1, studyPoint * 0.2);
typeNerveManager.initRnn(initPower, showLog, true);
}
private int getMappingType(int key) {//通过自增主键查找原映射
int id = 0;
for (Map.Entry<Integer, Integer> entry : mapping.entrySet()) {
if (entry.getValue() == key) {
id = entry.getKey();
break;
}
}
return id;
}
private int balance(Map<Integer, List<String>> model) {//强行均衡
int maxNumber = 0;
int index = 1;
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {//查找最大数量
mapping.put(entry.getKey(), index);
if (entry.getValue().size() > maxNumber) {
maxNumber = entry.getValue().size();
}
index++;
}
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {
int size = entry.getValue().size();
if (maxNumber > size) {
int times = maxNumber / size - 1;//循环几次
int sub = maxNumber % size;//余数
List<String> list = entry.getValue();
List<String> otherList = new ArrayList<>(list);
for (int i = 0; i < times; i++) {
list.addAll(otherList);
}
list.addAll(otherList.subList(0, sub));
}
}
return maxNumber;
}
private void studyNerve(long eventId, List<SensoryNerve> sensoryNerves, List<Double> featureList, Matrix rnnMatrix, Map<Integer, Double> E, boolean isStudy, OutBack convBack, int[] storeys) throws Exception {
if (sensoryNerves.size() == featureList.size()) {
for (int i = 0; i < sensoryNerves.size(); i++) {
sensoryNerves.get(i).postMessage(eventId, featureList.get(i), isStudy, E, convBack, false, rnnMatrix, storeys);
}
} else {
throw new Exception("1size not equals,feature size:" + featureList.size() + "," +
"sensorySize:" + sensoryNerves.size());
}
}
public int getType(String sentence, long eventID) throws Exception {//进行理解
if (sentence.length() > maxFeatureLength) {
sentence = sentence.substring(0, maxFeatureLength);
}
MyWordFeature myWordFeature = wordEmbedding.getEmbedding(sentence, eventID);
List<Double> featureList = myWordFeature.getFirstFeatureList();
Matrix featureMatrix = myWordFeature.getFeatureMatrix();
int[] storeys = new int[featureMatrix.getX()];
for (int i = 0; i < storeys.length; i++) {
storeys[i] = i;
}
WordBack wordBack = new WordBack();
studyNerve(eventID, typeNerveManager.getSensoryNerves(), featureList, featureMatrix, null, false, wordBack, storeys);
return getMappingType(wordBack.getId());
}
public void insertModel(RandomModel randomModel) throws Exception {
typeNerveManager.insertModelParameter(randomModel.getTypeModelParameter());
List<TypeMapping> typeMappings = randomModel.getTypeMappings();
mapping.clear();
for (TypeMapping typeMapping : typeMappings) {
mapping.put(typeMapping.getType(), typeMapping.getMapping());
}
}
public RandomModel getModel() throws Exception {
RandomModel randomModel = new RandomModel();
randomModel.setTypeModelParameter(typeNerveManager.getModelParameter());
List<TypeMapping> typeMappings = new ArrayList<>();
randomModel.setTypeMappings(typeMappings);
for (Map.Entry<Integer, Integer> entry : mapping.entrySet()) {
TypeMapping typeMapping = new TypeMapping();
typeMapping.setType(entry.getKey());
typeMapping.setMapping(entry.getValue());
typeMappings.add(typeMapping);
}
return randomModel;
}
public RandomModel studyType(Map<Integer, List<String>> model) throws Exception {
int maxNumber = balance(model);//平衡样本
for (int i = 0; i < dateAug; i++) {//第一阶段学习
System.out.println("1第" + (i + 1) + "次。共:" + dateAug + "");
myStudy(maxNumber, model, i + 1);
}
return getModel();
}
private void myStudy(int maxNumber, Map<Integer, List<String>> model, int time) throws Exception {
int index = 0;
Map<Integer, Double> E = new HashMap<>();
do {
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {
System.out.println("index======" + index + "," + time + "");
E.clear();
List<String> sentence = entry.getValue();
int key = mapping.get(entry.getKey());
E.put(key, 1D);
String word = sentence.get(index);
if (word.length() > maxFeatureLength) {
word = word.substring(0, maxFeatureLength);
}
randomTypeStudy(wordEmbedding.getEmbedding(word, 1), E);
}
index++;
} while (index < maxNumber);
}
private void randomTypeStudy(MyWordFeature myWordFeature, Map<Integer, Double> E) throws Exception {
Matrix featureMatrix = myWordFeature.getFeatureMatrix();
List<Double> firstFeatureList = myWordFeature.getFirstFeatureList();
int len = featureMatrix.getX();//文字长度
Random random = new Random();
if (len > 1) {//长度大于1才可以进行训练
int[] storeys;
if (len < minLength) {
storeys = new int[len];
for (int i = 0; i < len; i++) {
storeys[i] = i;
}
} else {
List<Integer> list = new ArrayList<>();
for (int i = 1; i < len; i++) {
list.add(i);
}
int myLen = (int) (minLength + Math.random() * (len - minLength + 1));
storeys = new int[myLen];
for (int i = 1; i < myLen; i++) {
int index = random.nextInt(list.size());
storeys[i] = list.get(index);
list.remove(index);
}
Arrays.sort(storeys);
}
studyNerve(1, typeNerveManager.getSensoryNerves(), firstFeatureList, featureMatrix
, E, true, null, storeys);
}
}
}

View File

@ -0,0 +1,27 @@
package org.wlld.rnnJumpNerveCenter;
import org.wlld.entity.TypeMapping;
import java.util.List;
public class RandomModel {
private ModelParameter typeModelParameter;
private List<TypeMapping> typeMappings;//映射
public ModelParameter getTypeModelParameter() {
return typeModelParameter;
}
public void setTypeModelParameter(ModelParameter typeModelParameter) {
this.typeModelParameter = typeModelParameter;
}
public List<TypeMapping> getTypeMappings() {
return typeMappings;
}
public void setTypeMappings(List<TypeMapping> typeMappings) {
this.typeMappings = typeMappings;
}
}

View File

@ -0,0 +1,28 @@
package org.wlld.rnnJumpNerveCenter;
import org.wlld.rnnJumpNerveEntity.NerveStudy;
import java.util.List;
public class RnnOutNerveStudy {
private int depth;//深度
private List<NerveStudy> nerveStudies;
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public List<NerveStudy> getNerveStudies() {
return nerveStudies;
}
public void setNerveStudies(List<NerveStudy> nerveStudies) {
this.nerveStudies = nerveStudies;
}
}

View File

@ -0,0 +1,21 @@
package org.wlld.rnnJumpNerveEntity;
import java.util.ArrayList;
import java.util.List;
/**
* @author lidapeng
* @description 动态神经元模型参数
* @date 8:14 上午 2020/1/18
*/
public class DymNerveStudy {
private List<Double> list = new ArrayList<>();
public List<Double> getList() {
return list;
}
public void setList(List<Double> list) {
this.list = list;
}
}

View File

@ -0,0 +1,83 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.ActiveFunction;
import org.wlld.i.OutBack;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author lidapeng
* 隐层神经元
* &#064;date 9:30 上午 2019/12/21
*/
public class HiddenNerve extends Nerve {
private Map<Long, Double> outMap = new HashMap<>();
public HiddenNerve(int id, int depth, double studyPoint,
boolean init, ActiveFunction activeFunction, boolean isDynamic, int rzType, double lParam
, int step, int kernLen, int sensoryNerveNub, int hiddenNerveNub, int outNerveNub, int allDepth) throws Exception {//隐层神经元
super(id, "HiddenNerve", studyPoint,
init, activeFunction, isDynamic, rzType, lParam, step, kernLen, sensoryNerveNub, hiddenNerveNub, outNerveNub, allDepth);
this.depth = depth;
}
@Override
public void input(long eventId, double parameter, boolean isKernelStudy, Map<Integer, Double> E
, OutBack outBack, boolean isEmbedding, Matrix rnnMatrix, int[] storeys, int index) throws Exception {//接收上一层的输入
boolean allReady = insertParameter(eventId, parameter);
if (allReady) {//参数齐了开始计算 sigma - threshold
if (isEmbedding) {
outBack.getWordVector(getId(), getWOne(eventId));
destroyParameter(eventId);
} else {
double sigma = calculation(eventId);
double out = activeFunction.function(sigma);//激活函数输出数值
if (rnnMatrix != null) {//rnn 1改输出值2查看是否需要转向
out = out + rnnMatrix.getNumber(depth, getId() - 1);
}
if (isKernelStudy) {
outNub = out;
} else {
destroyParameter(eventId);
}
sendMessage(eventId, out, isKernelStudy, E, outBack, false, rnnMatrix, storeys, index);
}
}
}
@Override
protected void sendAppointTestMessage(long eventId, double parameter, int fromDepth, Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
boolean allReady = insertParameter(eventId, parameter);//接收测试参数
if (allReady) {//凑齐参数 发送给输出层
double sigma = calculation(eventId);
double out = activeFunction.function(sigma);//激活函数输出数值
out = out + featureMatrix.getNumber(depth, getId() - 1);
destroyParameter(eventId);
outMap.put(eventId, out);
sendRnnTestMessage(eventId, out, fromDepth, featureMatrix, storeys, outBack);
}
}
@Override
protected void sendMyTestMessage(long eventId, int fromDepth, Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
//继续发送
double out = outMap.get(eventId);
sendTestMessage(eventId, out, depth, featureMatrix, storeys, outBack);
}
@Override
protected void clearData(long eventId) {
outMap.remove(eventId);
}
@Override
protected void inputMatrix(long eventId, Matrix matrix, boolean isStudy
, int E, OutBack outBack) throws Exception {
Matrix myMatrix = conv(matrix);//处理过的矩阵
sendMatrix(eventId, myMatrix, isStudy, E, outBack);
}
}

View File

@ -0,0 +1,27 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import java.util.List;
public class MyWordFeature {
private Matrix featureMatrix;
private List<Double> firstFeatureList;
public Matrix getFeatureMatrix() {
return featureMatrix;
}
public void setFeatureMatrix(Matrix featureMatrix) {
this.featureMatrix = featureMatrix;
}
public List<Double> getFirstFeatureList() {
return firstFeatureList;
}
public void setFirstFeatureList(List<Double> firstFeatureList) {
this.firstFeatureList = firstFeatureList;
}
}

View File

@ -0,0 +1,476 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.MatrixTools.MatrixOperation;
import org.wlld.config.RZ;
import org.wlld.i.ActiveFunction;
import org.wlld.i.OutBack;
import java.util.*;
/**
* @author lidapeng
* 神经元所有类别神经元都要继承的类具有公用属性
* &#064;date 9:36 上午 2019/12/21
*/
public abstract class Nerve {
private final Map<Integer, List<Nerve>> son = new HashMap<>();//轴突下一层的连接神经元
private final Map<Integer, List<Nerve>> father = new HashMap<>();//树突上一层的连接神经元
private final List<Nerve> rnnOut = new ArrayList<>();//rnn隐层输出神经元集合
protected Map<Integer, Double> dendrites = new HashMap<>();//上一层权重(需要取出)
protected Map<Integer, Double> wg = new HashMap<>();//上一层权重与梯度的积
private final int id;//同级神经元编号,注意在同层编号中ID应有唯一性
boolean fromOutNerve = false;//是否是输出神经元
private final int hiddenNerveNub;//隐层神经元个数
private final int sensoryNerveNub;//输入神经元个数
private final int outNerveNub;//输出神经元个数
protected Map<Long, List<Double>> features = new HashMap<>();//上一层神经元输入的数值
protected Matrix nerveMatrix;//权重矩阵可获取及注入
protected double threshold;//此神经元的阈值需要取出
protected String name;//该神经元所属类型
protected double outNub;//输出数值ps:只有训练模式的时候才可保存输出过的数值
protected double E;//模板期望值
protected double gradient;//当前梯度
protected double studyPoint;
protected double sigmaW;//对上一层权重与上一层梯度的积进行求和
private int backNub = 0;//当前节点被反向传播的次数
protected ActiveFunction activeFunction;
private final int rzType;//正则化类型默认不进行正则化
private final double lParam;//正则参数
private final int step;//步长
private final int kernLen;//核长
private Matrix im2col;//输入矩阵
private int xInput;//输入矩阵的x
private int yInput;//输入矩阵的y
private Matrix outMatrix;//输出矩阵
private int myUpNumber;//统计参数数量
protected int depth;//所处深度
protected int allDepth;//总深度
public int getDepth() {
return depth;
}
public Map<Integer, Double> getDendrites() {
return dendrites;
}
public Matrix getNerveMatrix() {
return nerveMatrix;
}
public void setNerveMatrix(Matrix nerveMatrix) {
this.nerveMatrix = nerveMatrix;
}
public void setDendrites(Map<Integer, Double> dendrites) {
this.dendrites = dendrites;
}
public double getThreshold() {
return threshold;
}
public void setThreshold(double threshold) {
this.threshold = threshold;
}
protected Nerve(int id, String name,
double studyPoint, boolean init, ActiveFunction activeFunction
, boolean isDynamic, int rzType, double lParam, int step, int kernLen, int sensoryNerveNub
, int hiddenNerveNub, int outNerveNub, int allDepth) throws Exception {//该神经元在同层神经元中的编号
this.id = id;
this.allDepth = allDepth;
this.hiddenNerveNub = hiddenNerveNub;//隐层神经元个数
this.sensoryNerveNub = sensoryNerveNub;//输入神经元个数
this.outNerveNub = outNerveNub;//输出神经元个数
this.name = name;
this.studyPoint = studyPoint;
this.activeFunction = activeFunction;
this.rzType = rzType;
this.lParam = lParam;
this.step = step;
this.kernLen = kernLen;
if (name.equals("OutNerve")) {
fromOutNerve = true;
}
initPower(init, isDynamic);//生成随机权重
}
protected void setStudyPoint(double studyPoint) {
this.studyPoint = studyPoint;
}
private int getNextStorey(int[] storeys, int index) {
int nextStorey = -1;
int nextIndex = index + 1;
if (storeys.length > nextIndex) {//可以继续前进
nextStorey = storeys[nextIndex];
}
return nextStorey;
}
protected void sendSoftMax(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E
, OutBack outBack, Matrix rnnMatrix, int[] storeys, int index) throws Exception {
if (!son.isEmpty()) {
List<Nerve> nerverList = son.get(0);
for (Nerve nerve : nerverList) {
nerve.input(eventId, parameter, isStudy, E, outBack, false, rnnMatrix, storeys, index);
}
} else {
throw new Exception("this storey is lastIndex");
}
}
protected void clearData(long eventId) {
}
protected void sendMyTestMessage(long eventId, int fromDepth, Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
}
protected void sendAppointTestMessage(long eventId, double parameter, int fromDepth,
Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
}
protected void sendTestMessage(long eventId, double parameter, int fromDepth,
Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
if (!son.isEmpty()) {
for (int i = depth + 1; i < featureMatrix.getX(); i++) {
List<Nerve> nerveList = son.get(i);
if (nerveList != null) {
for (Nerve nerve : nerveList) {
nerve.sendAppointTestMessage(eventId, parameter, fromDepth, featureMatrix, storeys, outBack);
}
} else {
throw new Exception("Insufficient layer:" + i);
}
}
} else {
throw new Exception("this layer is lastIndex");
}
}
protected void sendRnnTestMessage(long eventId, double parameter, int fromDepth,
Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
if (!rnnOut.isEmpty()) {
for (Nerve nerve : rnnOut) {
nerve.sendAppointTestMessage(eventId, parameter, fromDepth, featureMatrix, storeys, outBack);
}
} else {
throw new Exception("this layer is lastIndex");
}
}
protected void sendMessage(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E
, OutBack outBack, boolean isEmbedding, Matrix rnnMatrix, int[] storeys, int index) throws Exception {
if (!son.isEmpty()) {
List<Nerve> nerveList = null;
if (storeys == null) {
nerveList = son.get(0);
} else {
int nextStorey = getNextStorey(storeys, index);
if (nextStorey > -1) {//可以继续向前
nerveList = son.get(nextStorey);
index++;
if (nerveList == null) {
throw new Exception("向前->要查找的层数不存在链接,序列:" + index + "层数:" + nextStorey +
",当前所在层数:" + depth + ",我的身份:" + name);
}
}
}
if (nerveList != null) {
for (Nerve nerve : nerveList) {
nerve.input(eventId, parameter, isStudy, E, outBack, isEmbedding, rnnMatrix, storeys, index);
}
} else {//发送到输出神经元
sendRnnMessage(eventId, parameter, isStudy, E, outBack, isEmbedding, rnnMatrix, storeys, index);
}
} else {
throw new Exception("this layer is lastIndex");
}
}
private void sendRnnMessage(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E
, OutBack outBack, boolean isEmbedding, Matrix rnnMatrix, int[] storeys, int index) throws Exception {
if (!rnnOut.isEmpty()) {
for (Nerve nerve : rnnOut) {
nerve.input(eventId, parameter, isStudy, E, outBack, isEmbedding, rnnMatrix, storeys, index);
}
} else {
throw new Exception("this layer is lastIndex");
}
}
protected Matrix conv(Matrix matrix) throws Exception {//正向卷积下取样
xInput = matrix.getX();
yInput = matrix.getY();
int sub = kernLen - step;
int x = (xInput - sub) / step;//线性变换后矩阵的行数 图片长度-核长-步长/步长
int y = (yInput - sub) / step;//线性变换后矩阵的列数
Matrix myMatrix = new Matrix(x, y);//线性变化后的矩阵
im2col = MatrixOperation.im2col(matrix, kernLen, step);
//输出矩阵
Matrix matrixOut = MatrixOperation.mulMatrix(im2col, nerveMatrix);
//输出矩阵重新排序
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
double nub = activeFunction.function(matrixOut.getNumber(i * y + j, 0));
myMatrix.setNub(i, j, nub);
}
}
outMatrix = myMatrix;
return myMatrix;
}
protected void sendMatrix(long eventId, Matrix parameter, boolean isStudy,
int E, OutBack outBack) throws Exception {
if (!son.isEmpty()) {
for (Nerve nerve : son.get(0)) {
nerve.inputMatrix(eventId, parameter, isStudy, E, outBack);
}
} else {
throw new Exception("this layer is lastIndex");
}
}
private void backSendMessage(long eventId, boolean fromOutNerve, int[] storeys, int index) throws Exception {//反向传播
if (!father.isEmpty()) {//要先判定是不是可以继续往后传
List<Nerve> nerveList = null;
if (storeys == null) {//常规依次回退
nerveList = father.get(0);
} else if (index > 0) {//可以继续向后传递
nerveList = father.get(storeys[index]);
if (nerveList == null) {
throw new Exception("向后->要查找的层数不存在链接,序列:" + index + "目标层数:" + storeys[index]
+ ",当前所在层数:" + depth + ",我的身份:" + name);
}
index--;
}
if (nerveList != null) {
for (int i = 0; i < nerveList.size(); i++) {
nerveList.get(i).backGetMessage(wg.get(i + 1), eventId, fromOutNerve, storeys, index);
}
}
}
}
private void backMatrixMessage(Matrix g) throws Exception {//反向传播矩阵
if (!father.isEmpty()) {
for (Nerve nerve : father.get(0)) {
nerve.backMatrix(g);
}
}
}
protected void input(long eventId, double parameter, boolean isStudy
, Map<Integer, Double> E, OutBack imageBack, boolean isEmbedding, Matrix rnnMatrix
, int[] storeys, int index) throws Exception {//输入参数
}
protected void inputMatrix(long eventId, Matrix matrix, boolean isKernelStudy, int E, OutBack outBack) throws Exception {//输入动态矩阵
}
private void backGetMessage(double parameter, long eventId, boolean fromOutNerve, int[] storeys, int index) throws Exception {//反向传播
backNub++;
sigmaW = sigmaW + parameter;
int number;
if (fromOutNerve) {
number = outNerveNub;
} else {
number = hiddenNerveNub;
}
if (backNub == number) {//进行新的梯度计算
backNub = 0;
gradient = activeFunction.functionG(outNub) * sigmaW;
updatePower(eventId, storeys, index);//修改阈值
}
}
protected void backMatrix(Matrix g) throws Exception {//回传梯度
//对g进行重新排序
int x = g.getX();
int y = g.getY();
Matrix yc = new Matrix(x * y, 1);
int index = 0;
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
double error = g.getNumber(i, j);
double out = outMatrix.getNumber(i, j);
error = error * activeFunction.functionG(out) * studyPoint;
yc.setNub(index, 0, error);
index++;
}
}
//计算权重变化量
Matrix trx = MatrixOperation.transPosition(im2col);
Matrix wSub = MatrixOperation.mulMatrix(trx, yc);
//给权重变化wSub增加正则项抑制权重变化量
//计算x变化量
x = im2col.getX();
y = im2col.getY() - 1;
for (int i = 0; i < x; i++) {
double ySub = yc.getNumber(i, 0);
for (int j = 0; j < y; j++) {
double k = nerveMatrix.getNumber(j, 0) * ySub;
im2col.setNub(i, j, k);
}
}
Matrix gNext = MatrixOperation.reverseIm2col(im2col, kernLen, step, xInput, yInput);
//更新权重
nerveMatrix = MatrixOperation.add(nerveMatrix, wSub);
//将梯度继续回传
backMatrixMessage(gNext);
}
protected void updatePower(long eventId, int[] storeys, int index) throws Exception {//修改阈值
double h = gradient * studyPoint;
threshold = threshold - h;
updateW(h, eventId);
sigmaW = 0;//求和结果归零
backSendMessage(eventId, fromOutNerve, storeys, index);
}
private double regularization(double w, double param) {//正则化类型
double re = 0.0;
if (rzType != RZ.NOT_RZ) {
if (rzType == RZ.L2) {
re = param * -w;
} else if (rzType == RZ.L1) {
if (w > 0) {
re = -param;
} else if (w < 0) {
re = param;
}
}
}
return re;
}
private void updateW(double h, long eventId) {//h是学习率 * 当前g梯度
List<Double> list = features.get(eventId);
double param = studyPoint * lParam / dendrites.size();
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 = bn * h;
double dm = w * gradient;
double regular = regularization(w, param);//正则化抑制权重s
w = w + regular;
w = w + wp;
wg.put(key, dm);//保存上一层权重与梯度的积
dendrites.put(key, w);//保存修正结果
}
features.remove(eventId); //清空当前上层输入参数参数
}
protected boolean insertParameter(long eventId, double parameter) throws Exception {//添加参数
boolean allReady = false;
List<Double> featuresList;
if (features.containsKey(eventId)) {
featuresList = features.get(eventId);
} else {
featuresList = new ArrayList<>();
features.put(eventId, featuresList);
}
featuresList.add(parameter);
if (featuresList.size() == myUpNumber) {
allReady = true;
} else if (featuresList.size() > myUpNumber) {
throw new Exception("接收参数数量异常");
}
return allReady;
}
protected void destroyParameter(long eventId) {//销毁参数
features.remove(eventId);
}
protected double getWOne(long eventId) {
List<Double> featuresList = features.get(eventId);
double wt = 0;
for (int i = 0; i < featuresList.size(); i++) {
double value = featuresList.get(i);
double w = dendrites.get(i + 1);//当value不为0的时候把w取出来
if (value > 0.5) {
wt = w;
break;
}
}
return wt;
}
protected double calculation(long eventId) {//计算当前输出结果
double sigma = 0;
List<Double> featuresList = features.get(eventId);
for (int i = 0; i < featuresList.size(); i++) {
double value = featuresList.get(i);
double w = dendrites.get(i + 1);//当value不为0的时候把w取出来
sigma = w * value + sigma;
}
return sigma - threshold;
}
private void initPower(boolean init, boolean isDynamic) throws Exception {//初始化权重及阈值
Random random = new Random();
if (!isDynamic) {//静态神经元
//设置初始化权重范围收缩系数
if (name.equals("HiddenNerve")) {//隐层神经元
myUpNumber = sensoryNerveNub;
} else if (name.equals("OutNerve")) {//输出神经元
myUpNumber = hiddenNerveNub;
} else {//softmax
myUpNumber = outNerveNub;
}
if (myUpNumber > 0) {//输入个数
double sh = Math.sqrt(myUpNumber);
for (int i = 1; i < myUpNumber + 1; i++) {
double nub = 0;
if (init) {
nub = random.nextDouble() / sh;
}
dendrites.put(i, nub);//random.nextDouble()
}
//生成随机阈值
double nub = 0;
if (init) {
nub = random.nextDouble() / sh;
}
threshold = nub;
}
} else {//动态神经元
int nerveNub = kernLen * kernLen;
double sh = Math.sqrt(2D / nerveNub);
double nub;
nerveMatrix = new Matrix(nerveNub + 1, 1);
for (int i = 0; i < nerveMatrix.getX(); i++) {
nub = 0;
if (init) {
nub = random.nextDouble() * sh;
}
nerveMatrix.setNub(i, 0, nub);
}
}
}
public int getId() {
return id;
}
public void connect(int depth, List<Nerve> nerveList) {
son.put(depth, nerveList);//连接下一层
}
public void connectOut(List<Nerve> nerveList) {
rnnOut.addAll(nerveList);
}
public void connectFather(int depth, List<Nerve> nerveList) {
father.put(depth, nerveList);
}
}

View File

@ -0,0 +1,144 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NerveCenter {//神经中枢
private final int depth;//该神经中枢的深度
private final double powerTh;//权重阈值
private final List<Nerve> nerveList;//该神经中枢控制的对应隐层神经元集合
private final List<NerveCenter> nerveCenterList;//所有神经中枢
private final Map<Long, List<MyPower>> myPowerMap = new HashMap<>();//接收前方各层输出层返回权重
public int getDepth() {
return depth;
}
public NerveCenter(int depth, List<Nerve> nerveList, List<NerveCenter> nerveCenterList, double powerTh) {
this.depth = depth;
this.nerveList = nerveList;
this.nerveCenterList = nerveCenterList;
this.powerTh = powerTh;
}
public void backPower(long eventId, double parameter, int fromDepth, List<Integer> storeys, Matrix featureMatrix, OutBack outBack) throws Exception {
//System.out.println("开始回传给指定中枢,本层为:" + depth + ",中枢集合数量为:" + nerveCenterList.size());
for (NerveCenter nerveCenter : nerveCenterList) {
if (nerveCenter.getDepth() == fromDepth) {
//System.out.println("回传结果:" + fromDepth + ",我的深度为:" + depth);
nerveCenter.collectPower(eventId, parameter, storeys, depth, featureMatrix, outBack);
break;
}
}
}
private void go(long eventId, int fromDepth, Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
//神经中枢收到传递命令 将命令传递给本层神经元
for (Nerve nerve : nerveList) {//将信息发送给目标层隐层神经元
nerve.sendMyTestMessage(eventId, fromDepth, featureMatrix, storeys, outBack);
}
}
private void clearAllDate(long eventId) {
if (depth > 0) {
for (Nerve nerve : nerveList) {//将信息发送给目标层神经中枢
nerve.clearData(eventId);
}
}
}
private void toDepthNerveCenter(long eventId, int fromDepth, Matrix featureMatrix, List<Integer> storeys, OutBack outBack) throws Exception {
for (NerveCenter nerveCenter : nerveCenterList) {//将信息发送给目标层神经中枢
if (nerveCenter.getDepth() == fromDepth) {
nerveCenter.go(eventId, fromDepth, featureMatrix, storeys, outBack);
break;
}
}
}
private void clearData(long eventId) {
for (NerveCenter nerveCenter : nerveCenterList) {
nerveCenter.clearAllDate(eventId);
}
}
private int getToDepth(List<MyPower> myPowerList) {
int toDepth = -1;
int size = myPowerList.size();
double allPower = 0;
for (MyPower myPower : myPowerList) {
allPower = allPower + myPower.power;
}
double avg = 0;// allPower / size;
for (int i = 0; i < size; i++) {
MyPower myPower = myPowerList.get(i);
if (myPower.power >= avg) {
toDepth = myPower.depth;
break;
}
}
return toDepth;
}
private void collectPower(long eventId, double parameter, List<Integer> storeys, int fromDepth, Matrix featureMatrix, OutBack outBack) throws Exception {
MyPower myPower = new MyPower();
myPower.depth = fromDepth;
myPower.power = parameter;
if (myPowerMap.containsKey(eventId)) {
List<MyPower> myPowerList = myPowerMap.get(eventId);
myPowerList.add(myPower);
if (myPowerList.size() == featureMatrix.getX() - 1 - depth) {//进行跃层判断
int toDepth = getToDepth(myPowerList);
myPowerMap.remove(eventId);
if (myPowerList.size() == 1) {//终止继续传递并清除内存数据
if (toDepth > 0) {
storeys.add(toDepth);
}
//System.out.println("权重结果:" + storeys);
outBack.backPower(storeys, eventId);//输出权重路径
//TODO 清除内存
clearData(eventId);
} else {//通知toDepth隐层继续传递
storeys.add(toDepth);
if (featureMatrix.getX() - 1 == toDepth) {
myPowerMap.remove(eventId);
//System.out.println("权重结果:" + storeys);
outBack.backPower(storeys, eventId);//输出权重路径
//TODO 清除内存
clearData(eventId);
} else {
//System.out.println("隐层继续传递:" + storeys);
toDepthNerveCenter(eventId, toDepth, featureMatrix, storeys, outBack);
}
}
}
} else {
List<MyPower> myPowerList = new ArrayList<>();
myPowerList.add(myPower);
myPowerMap.put(eventId, myPowerList);
if (featureMatrix.getX() == 2 + depth) {//此时也要进行结算
myPowerMap.remove(eventId);
if (parameter >= powerTh) {
storeys.add(fromDepth);
}
//System.out.println("权重结果:" + storeys);
outBack.backPower(storeys, eventId);//输出权重路径
//TODO 清除内存
clearData(eventId);
}
}
}
static class MyPower {
int depth;
double power;
}
}

View File

@ -0,0 +1,30 @@
package org.wlld.rnnJumpNerveEntity;
import java.util.HashMap;
import java.util.Map;
/**
* @author lidapeng
* @description
* @date 3:36 下午 2020/1/8
*/
public class NerveStudy {
private Map<String, Double> dendrites = new HashMap<>();//上一层权重(需要取出)
private double threshold;//此神经元的阈值需要取出
public Map<String, Double> getDendrites() {
return dendrites;
}
public void setDendrites(Map<String, Double> dendrites) {
this.dendrites = dendrites;
}
public double getThreshold() {
return threshold;
}
public void setThreshold(double threshold) {
this.threshold = threshold;
}
}

View File

@ -0,0 +1,139 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.ActiveFunction;
import org.wlld.i.OutBack;
import java.util.List;
import java.util.Map;
/**
* @author lidapeng
* 输出神经元
* &#064;date 11:25 上午 2019/12/21
*/
public class OutNerve extends Nerve {
private Map<Integer, Matrix> matrixMapE;//主键与期望矩阵的映射
private NerveCenter nerveCenter;//该输出层对应的神经中枢
private final boolean isShowLog;
private final boolean isSoftMax;
public OutNerve(int id, double studyPoint, boolean init,
ActiveFunction activeFunction, boolean isDynamic, boolean isShowLog,
int rzType, double lParam, boolean isSoftMax, int step, int kernLen,
int sensoryNerveNub, int hiddenNerveNub, int outNerveNub, int allDepth) throws Exception {
super(id, "OutNerve", studyPoint, init, activeFunction, isDynamic, rzType, lParam, step, kernLen,
sensoryNerveNub, hiddenNerveNub, outNerveNub, allDepth);
this.isShowLog = isShowLog;
this.isSoftMax = isSoftMax;
}
public void setNerveCenter(NerveCenter nerveCenter) {
this.nerveCenter = nerveCenter;
}
void getGBySoftMax(double g, long eventId, int[] storeys, int index) throws Exception {//接收softMax层回传梯度
gradient = g;
updatePower(eventId, storeys, index);
}
public void setMatrixMap(Map<Integer, Matrix> matrixMap) {
matrixMapE = matrixMap;
}
@Override
protected void sendAppointTestMessage(long eventId, double parameter, int fromDepth, Matrix featureMatrix, List<Integer> storeys
, OutBack outBack) throws Exception {
//计算出结果返回给对应的层的神经中枢
boolean allReady = insertParameter(eventId, parameter);
if (allReady) {//所有参数集齐
double sigma = calculation(eventId);//计算结果返回
double out = activeFunction.function(sigma);
destroyParameter(eventId);
nerveCenter.backPower(eventId, out, fromDepth, storeys, featureMatrix, outBack);
}
}
@Override
public void input(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E
, OutBack outBack, boolean isEmbedding, Matrix rnnMatrix, int[] storeys, int index) throws Exception {
boolean allReady = insertParameter(eventId, parameter);
if (allReady) {//参数齐了开始计算 sigma - threshold
double sigma = calculation(eventId);
if (isSoftMax) {
if (!isStudy) {
destroyParameter(eventId);
}
sendSoftMax(eventId, sigma, isStudy, E, outBack, rnnMatrix, storeys, index);
} else {
double out = activeFunction.function(sigma);
if (isStudy) {//输出结果并进行BP调整权重及阈值
outNub = out;
if (E.containsKey(getId())) {
this.E = E.get(getId());
} else {
this.E = 0;
}
if (isShowLog) {
System.out.println("E==" + this.E + ",out==" + out + ",nerveId==" + getId());
}
gradient = outGradient();//当前梯度变化
//调整权重 修改阈值 并进行反向传播
updatePower(eventId, storeys, index);
} else {//获取最后输出
destroyParameter(eventId);
if (outBack != null) {
outBack.getBack(out, getId(), eventId);
} else {
throw new Exception("not find outBack");
}
}
}
}
}
@Override
protected void inputMatrix(long eventId, Matrix matrix, boolean isKernelStudy
, int E, OutBack outBack) throws Exception {
Matrix myMatrix = conv(matrix);
if (isKernelStudy) {//回传
Matrix matrix1 = matrixMapE.get(E);
if (isShowLog) {
System.out.println("E========" + E);
System.out.println(myMatrix.getString());
}
if (matrix1.getX() == myMatrix.getX() && matrix1.getY() == myMatrix.getY()) {
Matrix g = getGradient(myMatrix, matrix1);
//System.out.println("error:" + g.getString() + ",hope:" + matrix1.getString());
backMatrix(g);
} else {
throw new Exception("Wrong size setting of image in templateConfig");
}
} else {//卷积层输出
if (outBack != null) {
outBack.getBackMatrix(myMatrix, eventId);
} else {
throw new Exception("not find outBack");
}
}
}
private Matrix getGradient(Matrix matrix, Matrix E) throws Exception {
Matrix matrix1 = new Matrix(matrix.getX(), matrix.getY());
for (int i = 0; i < E.getX(); i++) {
for (int j = 0; j < E.getY(); j++) {
double nub = E.getNumber(i, j) - matrix.getNumber(i, j);
//ArithUtil.sub(E.getNumber(i, j), matrix.getNumber(i, j));
matrix1.setNub(i, j, nub);
}
}
return matrix1;
}
private double outGradient() {//生成输出层神经元梯度变化
//上层神经元输入值 * 当前神经元梯度*学习率 =该上层输入的神经元权重变化
//当前梯度神经元梯度变化 *学习旅 * -1 = 当前神经元阈值变化
return activeFunction.functionG(outNub) * (E - outNub);
}
}

View File

@ -0,0 +1,54 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.List;
public class PowerBack implements OutBack {
private double out;
private int id;
private List<Integer> powerList;
public List<Integer> getPowerList() {
return powerList;
}
public PowerBack() {
}
public PowerBack(int id) {
this.id = id;
}
public int getId() {
return id;
}
public double getOut() {
return out;
}
@Override
public void getBack(double out, int id, long eventId) {
if (id == this.id) {
this.out = out;
}
}
@Override
public void backPower(List<Integer> powerList, long eventId) {
this.powerList = powerList;
}
@Override
public void getBackMatrix(Matrix matrix, long eventId) {
}
@Override
public void getWordVector(int id, double w) {
}
}

View File

@ -0,0 +1,24 @@
package org.wlld.rnnJumpNerveEntity;
import java.util.List;
public class RnnOutNerveBody {
private int depth;//深度
private List<Nerve> outNerves;//输出神经元集合
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public List<Nerve> getOutNerves() {
return outNerves;
}
public void setOutNerves(List<Nerve> outNerves) {
this.outNerves = outNerves;
}
}

View File

@ -0,0 +1,53 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.i.OutBack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 感知神经元输入层
*
* @author lidapeng
* @date 9:29 上午 2019/12/21
*/
public class SensoryNerve extends Nerve {
public SensoryNerve(int id, int allDepth) throws Exception {
super(id, "SensoryNerve", 0, false, null, false, 0, 0,
0, 0, 0, 0, 0, allDepth);
depth = 0;
}
/**
* @param eventId 唯一的事件id
* @param parameter 输入点的数据
* @param isStudy 是否是学习 (学习状态没有输出)
* @param E 标注
* @param outBack 回调结果
*/
public void postMessage(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E
, OutBack outBack, boolean isEmbedding, Matrix rnnMatrix, int[] storeys) throws Exception {//感知神经元输出
sendMessage(eventId, parameter, isStudy, E, outBack, isEmbedding, rnnMatrix, storeys, 0);
}
public void postPowerMessage(long eventId, double parameter, Matrix featureMatrix, OutBack outBack) throws Exception {
//发送权重网络
List<Integer> storeys = new ArrayList<>();
storeys.add(0);
sendTestMessage(eventId, parameter, depth, featureMatrix, storeys, outBack);
}
public void postMatrixMessage(long eventId, Matrix parameter, boolean isKernelStudy
, int E, OutBack outBack) throws Exception {
sendMatrix(eventId, parameter, isKernelStudy, E, outBack);
}
@Override
public void connect(int depth, List<Nerve> nerveList) {//连接第一层隐层神经元
super.connect(depth, nerveList);
}
}

View File

@ -0,0 +1,72 @@
package org.wlld.rnnJumpNerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.config.RZ;
import org.wlld.i.OutBack;
import java.util.List;
import java.util.Map;
public class SoftMax extends Nerve {
private final OutNerve outNerve;
private final boolean isShowLog;
public SoftMax(int id, boolean isDynamic, OutNerve outNerve, boolean isShowLog
, int sensoryNerveNub, int hiddenNerveNub, int outNerveNub, int allDepth) throws Exception {
super(id, "softMax", 0, false, null, isDynamic
, RZ.NOT_RZ, 0, 0, 0, sensoryNerveNub, hiddenNerveNub, outNerveNub, allDepth);
this.outNerve = outNerve;
this.isShowLog = isShowLog;
}
@Override
protected void input(long eventId, double parameter, boolean isStudy, Map<Integer, Double> E, OutBack outBack, boolean isEmbedding
, Matrix rnnMatrix, int[] storeys, int index) throws Exception {
boolean allReady = insertParameter(eventId, parameter);
if (allReady) {
double out = softMax(eventId);//输出值
if (isStudy) {//学习
outNub = out;
if (E.containsKey(getId())) {
this.E = E.get(getId());
} else {
this.E = 0;
}
if (isShowLog) {
System.out.println("softMax==" + this.E + ",out==" + out + ",nerveId==" + getId());
}
gradient = -outGradient();//当前梯度变化 把梯度返回
features.remove(eventId); //清空当前上层输入参数参数
outNerve.getGBySoftMax(gradient, eventId, storeys, index);
} else {//输出
destroyParameter(eventId);
if (outBack != null) {
outBack.getBack(out, getId(), eventId);
} else {
throw new Exception("not find outBack");
}
}
}
}
private double outGradient() {//生成输出层神经元梯度变化
double g = outNub;
if (E == 1) {
g = g - 1;
}
return g;
}
private double softMax(long eventId) {//计算当前输出结果
double sigma = 0;
List<Double> featuresList = features.get(eventId);
double self = featuresList.get(getId() - 1);
double eSelf = Math.exp(self);
for (double value : featuresList) {
sigma = Math.exp(value) + sigma;
}
return eSelf / sigma;
}
}

View File

@ -1,26 +0,0 @@
package org.wlld.rnnNerveCenter;
import org.wlld.entity.TypeMapping;
import java.util.List;
public class RandomModel {
private List<RandomModelParameter> randomModelParameters;
private List<TypeMapping> typeMappings;
public List<TypeMapping> getTypeMappings() {
return typeMappings;
}
public void setTypeMappings(List<TypeMapping> typeMappings) {
this.typeMappings = typeMappings;
}
public List<RandomModelParameter> getRandomModelParameters() {
return randomModelParameters;
}
public void setRandomModelParameters(List<RandomModelParameter> randomModelParameters) {
this.randomModelParameters = randomModelParameters;
}
}

View File

@ -1,281 +0,0 @@
package org.wlld.rnnNerveCenter;
import org.wlld.MatrixTools.Matrix;
import org.wlld.MatrixTools.MatrixOperation;
import org.wlld.config.RZ;
import org.wlld.config.SentenceConfig;
import org.wlld.entity.TypeMapping;
import org.wlld.entity.WordBack;
import org.wlld.function.Tanh;
import org.wlld.i.OutBack;
import org.wlld.naturalLanguage.word.Trust;
import org.wlld.naturalLanguage.word.TypeBody;
import org.wlld.naturalLanguage.word.TypeSort;
import org.wlld.naturalLanguage.word.WordEmbedding;
import org.wlld.rnnNerveEntity.SensoryNerve;
import java.util.*;
public class RandomNerveManager {//随机神经网络管理
private final WordEmbedding wordEmbedding;
private final List<RandomNerveBody> randomNerveBodyList = new ArrayList<>();
private final Map<Integer, Integer> mapping = new HashMap<>();//主键是真实id,值是映射识别用id
private final int typeNub;//分类数量
private final int vectorDimension;//特征纵向维度
private final int maxFeatureLength;//特征最长长度
private final double studyPoint;//词向量学习学习率
private final boolean showLog;//是否输出学习数据
private int randomNumber;//随机数量
private int nerveNumber = 4;//神经元数量
private final int dateAug;//数据增广
private final int topNumber;//去最高几种类别
public RandomNerveManager(SentenceConfig config, WordEmbedding wordEmbedding) throws Exception {
if (config.getNerveDeep() > 3) {
nerveNumber = config.getNerveDeep();
}
if (config.getTypeNub() > 0 && config.getMaxWordLength() > nerveNumber && config.getRandomNumber() > 1) {
this.wordEmbedding = wordEmbedding;
this.dateAug = config.getDateAug();
this.topNumber = config.getTopNumber();
this.typeNub = config.getTypeNub();
this.vectorDimension = config.getWordVectorDimension();
this.maxFeatureLength = config.getMaxWordLength();
this.studyPoint = config.getWeStudyPoint();
this.showLog = config.isShowLog();
this.randomNumber = config.getRandomNumber();
} else {
throw new Exception("parameter invalid,typeNub must be greater than 0 and maxFeatureLength greater than " + nerveNumber + " and randomNumber than 1");
}
}
private NerveManager initNerveManager(boolean initPower) throws Exception {
NerveManager typeNerveManger = new NerveManager(vectorDimension, vectorDimension, typeNub, nerveNumber - 1, new Tanh(), false,
studyPoint, RZ.L1, studyPoint * 0.2);
typeNerveManger.initRnn(initPower, showLog);
return typeNerveManger;
}
private void studyNerve(long eventId, List<SensoryNerve> sensoryNerves, List<Double> featureList, Matrix rnnMatrix, Map<Integer, Double> E, boolean isStudy, OutBack convBack) throws Exception {
studyMyNerve(eventId, sensoryNerves, featureList, rnnMatrix, E, isStudy, convBack);
}
public static void studyMyNerve(long eventId, List<SensoryNerve> sensoryNerves, List<Double> featureList, Matrix rnnMatrix, Map<Integer, Double> E, boolean isStudy, OutBack convBack) throws Exception {
if (sensoryNerves.size() == featureList.size()) {
for (int i = 0; i < sensoryNerves.size(); i++) {
sensoryNerves.get(i).postMessage(eventId, featureList.get(i), isStudy, E, convBack, false, rnnMatrix);
}
} else {
throw new Exception("size not equals,feature size:" + featureList.size() + "," +
"sensorySize:" + sensoryNerves.size());
}
}
public void insertModel(RandomModel randomModel) throws Exception {
List<RandomModelParameter> randomModelParameters = randomModel.getRandomModelParameters();
List<TypeMapping> typeMappings = randomModel.getTypeMappings();
for (TypeMapping typeMapping : typeMappings) {
mapping.put(typeMapping.getType(), typeMapping.getMapping());
}
randomNumber = randomModelParameters.size();
for (RandomModelParameter modelParameter : randomModelParameters) {
RandomNerveBody randomNerveBody = new RandomNerveBody();
int[] featureIndexes = modelParameter.getFeatureIndexes();
randomNerveBody.setKey(modelParameter.getKey());
randomNerveBody.setFeatureIndexes(featureIndexes);
NerveManager nerveManager = initNerveManager(false);
nerveManager.insertModelParameter(modelParameter.getModelParameter());
randomNerveBody.setNerveManager(nerveManager);
randomNerveBodyList.add(randomNerveBody);
}
}
private RandomModel getModel() throws Exception {//获取模型
RandomModel randomModel = new RandomModel();
List<RandomModelParameter> randomModelParameters = new ArrayList<>();
randomModel.setRandomModelParameters(randomModelParameters);
for (RandomNerveBody randomNerveBody : randomNerveBodyList) {
RandomModelParameter randomModelParameter = new RandomModelParameter();
randomModelParameter.setKey(randomNerveBody.getKey());
randomModelParameter.setFeatureIndexes(randomNerveBody.getFeatureIndexes());
randomModelParameter.setModelParameter(randomNerveBody.getNerveManager().getModelParameter());
randomModelParameters.add(randomModelParameter);
}
return randomModel;
}
private int balance(Map<Integer, List<String>> model) {//强行均衡
int maxNumber = dateAug;
int index = 1;
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {//查找最大数量
mapping.put(entry.getKey(), index);
if (entry.getValue().size() > maxNumber) {
maxNumber = entry.getValue().size();
}
index++;
}
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {
int size = entry.getValue().size();
if (maxNumber > size) {
int times = maxNumber / size - 1;//循环几次
int sub = maxNumber % size;//余数
List<String> list = entry.getValue();
List<String> otherList = new ArrayList<>(list);
for (int i = 0; i < times; i++) {
list.addAll(otherList);
}
list.addAll(otherList.subList(0, sub));
}
}
return maxNumber;
}
public Trust getType(String word, long eventId) throws Exception {
Matrix myFeature = wordEmbedding.getEmbedding(word, eventId);//全部特征
Trust trust = study(myFeature, null, false, eventId);
List<Integer> keys = trust.getKeys();
List<Integer> myKeys = new ArrayList<>();
for (int key : keys) {
int id = -1;
for (Map.Entry<Integer, Integer> entry : mapping.entrySet()) {
if (entry.getValue() == key) {
id = entry.getKey();
break;
}
}
myKeys.add(id);
}
trust.setKeys(myKeys);
return trust;
}
public RandomModel studyType(Map<Integer, List<String>> model) throws Exception {//学习类别
int maxNumber = balance(model);//平衡样本
int index = 0;
Map<Integer, Double> E = new HashMap<>();
do {
for (Map.Entry<Integer, List<String>> entry : model.entrySet()) {
System.out.println("index====================================" + index);
E.clear();
List<String> sentence = entry.getValue();
E.put(mapping.get(entry.getKey()), 1D);
String word = sentence.get(index);
if (word.length() > maxFeatureLength) {
word = word.substring(0, maxFeatureLength);
}
study(wordEmbedding.getEmbedding(word, 1), E, true, 1);
}
index++;
} while (index < maxNumber);
RandomModel randomModel = getModel();
List<TypeMapping> typeMappings = new ArrayList<>();
randomModel.setTypeMappings(typeMappings);
for (Map.Entry<Integer, Integer> entry : mapping.entrySet()) {
TypeMapping typeMapping = new TypeMapping();
typeMapping.setType(entry.getKey());
typeMapping.setMapping(entry.getValue());
typeMappings.add(typeMapping);
}
return randomModel;
}
private void insertValue(List<TypeBody> typeBodies, int key, double value) {
boolean init = true;
for (TypeBody typeBody : typeBodies) {
if (typeBody.getType() == key) {
typeBody.setPower(typeBody.getPower() + value);
init = false;
break;
}
}
if (init) {
TypeBody typeBody = new TypeBody();
typeBody.setType(key);
typeBody.setPower(value);
typeBodies.add(typeBody);
}
}
private Trust study(Matrix feature, Map<Integer, Double> E, boolean isStudy, long eventId) throws Exception {
List<TypeBody> typeBodies = new ArrayList<>();
Trust trust = null;
int myNumber = 0;
for (int i = 0; i < randomNumber; i++) {
RandomNerveBody randomNerveBody = randomNerveBodyList.get(i);
int[] features = randomNerveBody.getFeatureIndexes();
NerveManager typeNerveManager = randomNerveBody.getNerveManager();
Matrix myFeature = null;
List<Double> firstFeature = null;
int times = 0;
//不一定取的到前提是有这个序列
for (int index : features) {
if (feature.getX() > index) {//能找的到
times++;
if (myFeature == null) {
myFeature = feature.getRow(index);
firstFeature = MatrixOperation.rowVectorToList(myFeature);//首行特征
} else {
myFeature = MatrixOperation.pushVector(myFeature, feature.getRow(index), true);
}
} else {//直接跳出
break;
}
}
if (firstFeature != null && times > 1) {
myNumber++;
WordBack wordBack = null;
if (!isStudy) {
wordBack = new WordBack();
}
studyNerve(eventId, typeNerveManager.getSensoryNerves(), firstFeature, myFeature, E, isStudy, wordBack);
if (wordBack != null) {
int id = wordBack.getId();
double value = wordBack.getOut();
insertValue(typeBodies, id, value);
}
}
}
if (!isStudy) {
trust = new Trust();
typeBodies.sort(new TypeSort());
if (topNumber < typeBodies.size()) {
typeBodies = typeBodies.subList(0, topNumber);
}
List<Integer> keys = new ArrayList<>();
for (TypeBody typeBody : typeBodies) {
keys.add(typeBody.getType());
}
trust.setKeys(keys);
trust.setTrust(myNumber / (double) randomNumber);
}
return trust;
}
public void init() throws Exception {
Random random = new Random();
for (int i = 0; i < randomNumber; i++) {
RandomNerveBody randomNerveBody = new RandomNerveBody();
int[] featureIndexes = new int[nerveNumber];
randomNerveBody.setKey(i + 1);
randomNerveBody.setFeatureIndexes(featureIndexes);
randomNerveBody.setNerveManager(initNerveManager(true));
randomNerveBodyList.add(randomNerveBody);
if (i > 0) {
List<Integer> list = new ArrayList<>();
for (int k = 0; k < maxFeatureLength; k++) {
list.add(k);
}
for (int j = 0; j < nerveNumber; j++) {
int index = random.nextInt(list.size());
featureIndexes[j] = list.get(index);
list.remove(index);
}
} else {//第一组rnn进行特征自增选取保证短句输入
for (int j = 0; j < nerveNumber; j++) {
featureIndexes[j] = j;
}
}
}
}
}