mirror of
https://gitee.com/dromara/easyAi.git
synced 2024-11-30 02:37:42 +08:00
对中文语义分类性能进行优化
This commit is contained in:
parent
46b9a14b52
commit
cb7dbffdf0
2
pom.xml
2
pom.xml
@ -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 -->
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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;//末尾下标
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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
|
||||
* @description 学习结果
|
||||
* @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;
|
||||
}
|
||||
}
|
468
src/main/java/org/wlld/rnnJumpNerveCenter/NerveJumpManager.java
Normal file
468
src/main/java/org/wlld/rnnJumpNerveCenter/NerveJumpManager.java
Normal 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
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
198
src/main/java/org/wlld/rnnJumpNerveCenter/RRNerveManager.java
Normal file
198
src/main/java/org/wlld/rnnJumpNerveCenter/RRNerveManager.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/org/wlld/rnnJumpNerveCenter/RandomModel.java
Normal file
27
src/main/java/org/wlld/rnnJumpNerveCenter/RandomModel.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
21
src/main/java/org/wlld/rnnJumpNerveEntity/DymNerveStudy.java
Normal file
21
src/main/java/org/wlld/rnnJumpNerveEntity/DymNerveStudy.java
Normal 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;
|
||||
}
|
||||
}
|
83
src/main/java/org/wlld/rnnJumpNerveEntity/HiddenNerve.java
Normal file
83
src/main/java/org/wlld/rnnJumpNerveEntity/HiddenNerve.java
Normal 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
|
||||
* 隐层神经元
|
||||
* @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);
|
||||
}
|
||||
}
|
27
src/main/java/org/wlld/rnnJumpNerveEntity/MyWordFeature.java
Normal file
27
src/main/java/org/wlld/rnnJumpNerveEntity/MyWordFeature.java
Normal 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;
|
||||
}
|
||||
}
|
476
src/main/java/org/wlld/rnnJumpNerveEntity/Nerve.java
Normal file
476
src/main/java/org/wlld/rnnJumpNerveEntity/Nerve.java
Normal 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
|
||||
* 神经元,所有类别神经元都要继承的类,具有公用属性
|
||||
* @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);
|
||||
}
|
||||
}
|
144
src/main/java/org/wlld/rnnJumpNerveEntity/NerveCenter.java
Normal file
144
src/main/java/org/wlld/rnnJumpNerveEntity/NerveCenter.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
30
src/main/java/org/wlld/rnnJumpNerveEntity/NerveStudy.java
Normal file
30
src/main/java/org/wlld/rnnJumpNerveEntity/NerveStudy.java
Normal 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;
|
||||
}
|
||||
}
|
139
src/main/java/org/wlld/rnnJumpNerveEntity/OutNerve.java
Normal file
139
src/main/java/org/wlld/rnnJumpNerveEntity/OutNerve.java
Normal 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
|
||||
* 输出神经元
|
||||
* @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);
|
||||
}
|
||||
}
|
54
src/main/java/org/wlld/rnnJumpNerveEntity/PowerBack.java
Normal file
54
src/main/java/org/wlld/rnnJumpNerveEntity/PowerBack.java
Normal 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) {
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
53
src/main/java/org/wlld/rnnJumpNerveEntity/SensoryNerve.java
Normal file
53
src/main/java/org/wlld/rnnJumpNerveEntity/SensoryNerve.java
Normal 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);
|
||||
}
|
||||
}
|
72
src/main/java/org/wlld/rnnJumpNerveEntity/SoftMax.java
Normal file
72
src/main/java/org/wlld/rnnJumpNerveEntity/SoftMax.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user