box 边框改成K均值聚类来学习 优化速度

pull/1/head
lidapeng 5 years ago
parent bb91041b42
commit f14fb57468

@ -6,8 +6,8 @@
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="myBrain" />
<module name="ImageMarket" />
<module name="myBrain" />
</profile>
</annotationProcessing>
</component>

@ -1,64 +0,0 @@
package org.wlld.imageRecognition;
import org.wlld.MatrixTools.Matrix;
import org.wlld.MatrixTools.MatrixOperation;
import org.wlld.tools.ArithUtil;
/**
* @author lidapeng
* @description K
* @date 9:05 2020/2/1
*/
public class KMatrix {
private Matrix sigmaMatrix;//矩阵和
private int nub;//加和次数
private boolean isFinish = false;//是否结算
KMatrix(int x, int y) {
sigmaMatrix = new Matrix(x, y);
}
public boolean isFinish() {
return isFinish;
}
public void setFinish(boolean finish) {
isFinish = finish;
}
public Matrix getSigmaMatrix() {
return sigmaMatrix;
}
public double getEDist(Matrix matrix) throws Exception {//返回欧式距离
if (isFinish && matrix.getX() == sigmaMatrix.getX()
&& matrix.getY() == sigmaMatrix.getY()) {
double sigma = 0;
for (int i = 0; i < matrix.getX(); i++) {
for (int j = 0; j < matrix.getY(); j++) {
double sub = ArithUtil.sub(matrix.getNumber(i, j), sigmaMatrix.getNumber(i, j));
sigma = ArithUtil.add(Math.pow(sub, 2), sigma);
}
}
sigma = Math.sqrt(sigma);
return sigma;
} else {
throw new Exception("K is not finish or matrix not equal");
}
}
public void addMatrix(Matrix matrix) throws Exception {
sigmaMatrix = MatrixOperation.add(sigmaMatrix, matrix);
nub++;
}
public void getK() throws Exception {//结算K均值
if (nub != 0) {
double aNub = ArithUtil.div(1, nub);
MatrixOperation.mathMul(sigmaMatrix, aNub);
isFinish = true;
} else {
throw new Exception("not value");
}
}
}

@ -135,9 +135,9 @@ public class Operation {//进行计算
intoNerve2(eventId, frameBody.getMatrix(), templeConfig.getConvolutionNerveManager().getSensoryNerves(),
false, -1, matrixBack);
Matrix myMatrix = matrixBack.getMatrix();
//卷积层输出即边框回归的输入的特征向量
//卷积层输出即边框回归的输入的特征向量 TODO 这地有BUG 要改
frameBody.setEndMatrix(myMatrix);
int id = getClassificationId(myMatrix);
int id = getClassificationId2(myMatrix);
frameBody.setId(id);
}
return toPosition(frameBodies, frame.getWidth(), frame.getHeight());
@ -186,6 +186,21 @@ public class Operation {//进行计算
return map;
}
private Matrix getBoxMatrix(Matrix matrix, Map<Integer, Box> boxMap) throws Exception {
Matrix positionMatrix = null;
double endDist = 0;
for (Map.Entry<Integer, Box> entry : boxMap.entrySet()) {
Box box = entry.getValue();
Matrix boxMatrix = box.getMatrix();
double dist = MatrixOperation.getEDist(matrix, boxMatrix);
if (endDist == 0 || dist < endDist) {
endDist = dist;
positionMatrix = box.getMatrixPosition();
}
}
return positionMatrix;
}
//获得预测边框
private void getBox(FrameBody frameBody, int width, int height) throws Exception {
if (templeConfig.isBoxReady()) {
@ -193,24 +208,16 @@ public class Operation {//进行计算
int id = frameBody.getId();
int x = frameBody.getX();
int y = frameBody.getY();
Map<Integer, BorderBody> borderBodyMap = templeConfig.getBorderBodyMap();
BorderBody borderBody = borderBodyMap.get(id);
//都是列向量将参数转化为行向量最后再加1
Matrix xw = borderBody.getxW();
Matrix yw = borderBody.getyW();
Matrix hw = borderBody.gethW();
Matrix ww = borderBody.getwW();
KClustering kClustering = templeConfig.getkClusteringMap().get(id);
Map<Integer, Box> boxMap = kClustering.getPositionMap();
//将矩阵化为向量
matrix = MatrixOperation.matrixToVector(matrix, true);
//最后加一层池化
matrix = MatrixOperation.getPoolVector(matrix);
//将参数矩阵的末尾填1
matrix = MatrixOperation.push(matrix, 1, true);
Matrix positionMatrix = getBoxMatrix(matrix, boxMap);
//锚点坐标及长宽预测值
double tx = MatrixOperation.mulMatrix(matrix, xw).getNumber(0, 0);
double ty = MatrixOperation.mulMatrix(matrix, yw).getNumber(0, 0);
double th = MatrixOperation.mulMatrix(matrix, hw).getNumber(0, 0);
double tw = MatrixOperation.mulMatrix(matrix, ww).getNumber(0, 0);
double tx = positionMatrix.getNumber(0, 0);
double ty = positionMatrix.getNumber(0, 1);
double th = positionMatrix.getNumber(0, 3);
double tw = positionMatrix.getNumber(0, 2);
//修正相对位置
double realX = ArithUtil.add(ArithUtil.mul(tx, height), x);
double realY = ArithUtil.add(ArithUtil.mul(ty, width), y);
@ -304,22 +311,6 @@ public class Operation {//进行计算
return id;
}
private int getClassificationId(Matrix myMatrix) throws Exception {
int id = 0;
double distEnd = 0;
Map<Integer, KMatrix> kMatrixMap = templeConfig.getkMatrixMap();
for (Map.Entry<Integer, KMatrix> entry : kMatrixMap.entrySet()) {
int key = entry.getKey();
KMatrix kMatrix = entry.getValue();
double dist = kMatrix.getEDist(myMatrix);
if (distEnd == 0 || dist < distEnd) {
id = key;
distEnd = dist;
}
}
return id;
}
private List<Double> sub(Matrix matrix) throws Exception {//
List<Double> list = new ArrayList<>();
int x = matrix.getX() - 1;

@ -5,9 +5,7 @@ import org.wlld.MatrixTools.MatrixOperation;
import org.wlld.config.StudyPattern;
import org.wlld.function.ReLu;
import org.wlld.function.Sigmod;
import org.wlld.imageRecognition.border.BorderBody;
import org.wlld.imageRecognition.border.Frame;
import org.wlld.imageRecognition.border.LVQ;
import org.wlld.imageRecognition.border.*;
import org.wlld.nerveCenter.NerveManager;
import org.wlld.nerveEntity.ModelParameter;
import org.wlld.nerveEntity.SensoryNerve;
@ -29,14 +27,18 @@ public class TempleConfig {
private int classificationNub = 1;//分类的数量
private int studyPattern;//学习模式
private boolean isHavePosition = false;//是否需要锁定物体位置
private Map<Integer, BorderBody> borderBodyMap = new HashMap<>();//border特征集合
private Map<Integer, KMatrix> kMatrixMap = new HashMap<>();//K均值矩阵集合
private LVQ lvq;
private Frame frame;//先验边框
private double th = 0.6;//标准阈值
private boolean boxReady = false;//边框已经学习完毕
private double iouTh = 0.5;//IOU阈值
private int lvqNub = 50;//lvq循环次数默认50
//边框聚类集合
private Map<Integer, KClustering> kClusteringMap = new HashMap<>();
public Map<Integer, KClustering> getkClusteringMap() {
return kClusteringMap;
}
public int getLvqNub() {
return lvqNub;
@ -74,20 +76,6 @@ public class TempleConfig {
this.frame = frame;
}
public Map<Integer, BorderBody> getBorderBodyMap() {
return borderBodyMap;
}
public Map<Integer, KMatrix> getkMatrixMap() {
return kMatrixMap;
}
public void clustering() throws Exception {//进行聚类结算
for (Map.Entry<Integer, KMatrix> kMatrixEntry : kMatrixMap.entrySet()) {
kMatrixEntry.getValue().getK();
}
}
public void startLvq() throws Exception {//进行量化
lvq.start();
}
@ -96,34 +84,15 @@ public class TempleConfig {
return lvq;
}
private void border(BorderBody borderBody) throws Exception {
Matrix parameter = borderBody.getX();//参数矩阵
Matrix tx = borderBody.getTx();
Matrix ty = borderBody.getTy();
Matrix th = borderBody.getTh();
Matrix tw = borderBody.getTw();
borderBody.setxW(MatrixOperation.getLinearRegression(parameter, tx));
borderBody.setyW(MatrixOperation.getLinearRegression(parameter, ty));
borderBody.setwW(MatrixOperation.getLinearRegression(parameter, tw));
borderBody.sethW(MatrixOperation.getLinearRegression(parameter, th));
boxReady = true;
}
public void boxStudy() throws Exception {//边框回归 学习结束之后最后进行调用
if (borderBodyMap.size() > 0) {
for (Map.Entry<Integer, BorderBody> entry : borderBodyMap.entrySet()) {
border(entry.getValue());
if (isHavePosition) {
for (Map.Entry<Integer, KClustering> entry : kClusteringMap.entrySet()) {
entry.getValue().start();
}
} else {
throw new Exception("boder not study");
}
}
public void setBorderBodyMap(Map<Integer, BorderBody> borderBodyMap) {
this.borderBodyMap = borderBodyMap;
}
public NerveManager getNerveManager() {
return nerveManager;
}
@ -152,6 +121,11 @@ public class TempleConfig {
, int classificationNub) throws Exception {//初始化配置模板
this.classificationNub = classificationNub;
this.studyPattern = studyPattern;
if (isHavePosition) {
for (int i = 1; i < classificationNub + 1; i++) {
kClusteringMap.put(i, new KClustering(20));
}
}
switch (studyPattern) {
case StudyPattern.Speed_Pattern://速度学习模式
initModelVision(initPower, width, height);
@ -195,10 +169,8 @@ public class TempleConfig {
//加载各识别分类的期望矩阵
matrixMap.put(0, new Matrix(height, width));
double nub = 10;//每个分类期望参数的跨度
kMatrixMap.put(0, new KMatrix(height, width));
for (int k = 0; k < classificationNub; k++) {
Matrix matrix = new Matrix(height, width);//初始化期望矩阵
kMatrixMap.put(k + 1, new KMatrix(height, width));
double t = (k + 1) * nub;//期望矩阵的分类参数数值
for (int i = 0; i < height; i++) {//给期望矩阵注入期望参数
for (int j = 0; j < width - 1; j++) {
@ -241,19 +213,13 @@ public class TempleConfig {
ModelParameter modelParameter1 = convolutionNerveManager.getModelParameter();
modelParameter.setDymNerveStudies(modelParameter1.getDymNerveStudies());
modelParameter.setDymOutNerveStudy(modelParameter1.getDymOutNerveStudy());
Map<Integer, List<Double>> matrixMap = new HashMap<>();
for (Map.Entry<Integer, KMatrix> entry : kMatrixMap.entrySet()) {
List<Double> list = getFeatureList(entry.getValue().getSigmaMatrix());
matrixMap.put(entry.getKey(), list);
}
modelParameter.setkMatrixList(matrixMap);
} else if (studyPattern == StudyPattern.Speed_Pattern) {
ModelParameter modelParameter1 = nerveManager.getModelParameter();
modelParameter.setDepthNerves(modelParameter1.getDepthNerves());
modelParameter.setOutNevers(modelParameter1.getOutNevers());
}
if (isHavePosition) {//存在边框学习模型参数
modelParameter.setBorderBodyMap(borderBodyMap);
modelParameter.setFrame(frame);
}
return modelParameter;
@ -293,24 +259,10 @@ public class TempleConfig {
public void insertModel(ModelParameter modelParameter) throws Exception {
if (studyPattern == StudyPattern.Accuracy_Pattern) {
convolutionNerveManager.insertModelParameter(modelParameter);
Map<Integer, List<Double>> kMatrixs = modelParameter.getkMatrixList();
if (kMatrixs != null && kMatrixs.size() == kMatrixMap.size()) {
for (Map.Entry<Integer, KMatrix> entry : kMatrixMap.entrySet()) {
KMatrix kMatrix = entry.getValue();
insertKMatrix(kMatrix.getSigmaMatrix(), kMatrixs.get(entry.getKey()));
kMatrix.setFinish(true);
}
}
} else if (studyPattern == StudyPattern.Speed_Pattern) {
nerveManager.insertModelParameter(modelParameter);
}
Frame frame = modelParameter.getFrame();
Map<Integer, BorderBody> borderBodyMap = modelParameter.getBorderBodyMap();
if (frame != null && borderBodyMap != null && borderBodyMap.size() > 0) {
isHavePosition = true;
this.frame = frame;
this.borderBodyMap = borderBodyMap;
}
}
public void setCutThreshold(double cutThreshold) {

@ -48,51 +48,23 @@ public class Border {
public void end(Matrix matrix, int id) throws Exception {//长宽
height = maxX - minX;
width = maxY - minY;
Map<Integer, BorderBody> borderBodyMap = templeConfig.getBorderBodyMap();
BorderBody borderBody = borderBodyMap.get(id);
if (borderBody == null) {
borderBody = new BorderBody();
borderBodyMap.put(id, borderBody);
}
//拿到参数矩阵
Matrix matrixX = borderBody.getX();
Matrix matrixTx = borderBody.getTx();
Matrix matrixTy = borderBody.getTy();
Matrix matrixTw = borderBody.getTw();
Matrix matrixTh = borderBody.getTh();
KClustering kClustering = templeConfig.getkClusteringMap().get(id);
Matrix positionMatrix = new Matrix(1, 4);
//多元线性回归的四个输出值
double tx = ArithUtil.div(minX, modelHeight);
double ty = ArithUtil.div(minY, modelWidth);
double tw = Math.log(ArithUtil.div(width, modelWidth));
double th = Math.log(ArithUtil.div(height, modelHeight));
Box box = new Box();
//进行参数汇集 矩阵转化为行向量
matrix = MatrixOperation.matrixToVector(matrix, true);
//最后给一层池化层
matrix = MatrixOperation.getPoolVector(matrix);
//将参数矩阵的末尾填1
matrix = MatrixOperation.push(matrix, 1, true);
if (matrixX == null) {//如果是第一次直接赋值
matrixX = matrix;
matrixTx = new Matrix(1, 1);
matrixTy = new Matrix(1, 1);
matrixTw = new Matrix(1, 1);
matrixTh = new Matrix(1, 1);
matrixTx.setNub(0, 0, tx);
matrixTy.setNub(0, 0, ty);
matrixTw.setNub(0, 0, tw);
matrixTh.setNub(0, 0, th);
} else {//将新的参数矩阵添加到原来的末尾
matrixX = MatrixOperation.pushVector(matrixX, matrix, true);
matrixTx = MatrixOperation.push(matrixTx, tx, false);
matrixTy = MatrixOperation.push(matrixTy, ty, false);
matrixTw = MatrixOperation.push(matrixTw, tw, false);
matrixTh = MatrixOperation.push(matrixTh, th, false);
}
borderBody.setX(matrixX);
borderBody.setTh(matrixTh);
borderBody.setTw(matrixTw);
borderBody.setTx(matrixTx);
borderBody.setTy(matrixTy);
positionMatrix.setNub(0, 0, tx);
positionMatrix.setNub(0, 1, ty);
positionMatrix.setNub(0, 2, tw);
positionMatrix.setNub(0, 3, th);
box.setMatrix(matrix);
box.setMatrixPosition(positionMatrix);
kClustering.setMatrixList(box);
}
}

@ -1,93 +0,0 @@
package org.wlld.imageRecognition.border;
import org.wlld.MatrixTools.Matrix;
/**
* @author lidapeng
* @description
*
* @date 8:49 2020/1/24
*/
public class BorderBody {
private Matrix xW;//平移X权重
private Matrix yW;//平移Y权重
private Matrix wW;//缩放宽度权重
private Matrix hW;//缩放高度权重
private Matrix x;//参数矩阵
private Matrix tx;//X轴偏移量
private Matrix ty;//Y轴偏移量
private Matrix tw;//W缩放量
private Matrix th;//H缩放量
public Matrix getxW() {
return xW;
}
public void setxW(Matrix xW) {
this.xW = xW;
}
public Matrix getyW() {
return yW;
}
public void setyW(Matrix yW) {
this.yW = yW;
}
public Matrix getwW() {
return wW;
}
public void setwW(Matrix wW) {
this.wW = wW;
}
public Matrix gethW() {
return hW;
}
public void sethW(Matrix hW) {
this.hW = hW;
}
public Matrix getX() {
return x;
}
public void setX(Matrix x) {
this.x = x;
}
public Matrix getTx() {
return tx;
}
public void setTx(Matrix tx) {
this.tx = tx;
}
public Matrix getTy() {
return ty;
}
public void setTy(Matrix ty) {
this.ty = ty;
}
public Matrix getTw() {
return tw;
}
public void setTw(Matrix tw) {
this.tw = tw;
}
public Matrix getTh() {
return th;
}
public void setTh(Matrix th) {
this.th = th;
}
}

@ -9,7 +9,7 @@ import org.wlld.MatrixTools.Matrix;
*/
public class Box {
private Matrix matrix;//特征向量
private Matrix matrixFather;//坐标向量
private Matrix matrixPosition;//坐标向量
public Matrix getMatrix() {
return matrix;
@ -19,11 +19,11 @@ public class Box {
this.matrix = matrix;
}
public Matrix getMatrixFather() {
return matrixFather;
public Matrix getMatrixPosition() {
return matrixPosition;
}
public void setMatrixFather(Matrix matrixFather) {
this.matrixFather = matrixFather;
public void setMatrixPosition(Matrix matrixPosition) {
this.matrixPosition = matrixPosition;
}
}

@ -17,13 +17,14 @@ public class KClustering {
private int speciesQuantity;//种类数量
private Matrix[] matrices;//均值K
private Map<Integer, List<Box>> clusterMap = new HashMap<>();//簇
private Map<Integer, Box> positionMap = new HashMap<>();
private boolean isReady = false;
public Matrix[] getMatrices() {
return matrices;
}
public Map<Integer, List<Box>> getClusterMap() {
return clusterMap;
public Map<Integer, Box> getPositionMap() throws Exception {
if (!isReady) {
throw new Exception("not ready");
}
return positionMap;
}
public KClustering(int speciesQuantity) {
@ -76,6 +77,29 @@ public class KClustering {
return matrices2;
}
private Matrix averagePosition(List<Box> boxes) throws Exception {
double nub = ArithUtil.div(1, boxes.size());
Matrix matrix = new Matrix(1, 4);
for (Box box : boxes) {
matrix = MatrixOperation.add(matrix, box.getMatrixPosition());
}
MatrixOperation.mathMul(matrix, nub);
return matrix;
}
private void position() throws Exception {
for (Map.Entry<Integer, List<Box>> entry : clusterMap.entrySet()) {
List<Box> boxList = entry.getValue();
int key = entry.getKey();
Box box = new Box();
Matrix position = averagePosition(boxList);
Matrix kMatrix = matrices[key];
box.setMatrix(kMatrix);
box.setMatrixPosition(position);
positionMap.put(key, box);
}
}
private void clear() {
for (Map.Entry<Integer, List<Box>> entry : clusterMap.entrySet()) {
entry.getValue().clear();
@ -116,7 +140,8 @@ public class KClustering {
while (!isEqual);
//聚类结束,进行坐标均值矩阵计算
System.out.println("聚类循环次数:" + nub);
position();
isReady = true;
} else {
throw new Exception("matrixList number less than 2");
}

@ -1,8 +1,5 @@
package org.wlld.nerveEntity;
import org.wlld.MatrixTools.Matrix;
import org.wlld.imageRecognition.KMatrix;
import org.wlld.imageRecognition.border.BorderBody;
import org.wlld.imageRecognition.border.Frame;
import java.util.ArrayList;
@ -21,26 +18,8 @@ public class ModelParameter {
private List<NerveStudy> outNevers = new ArrayList<>();//输出神经元
private List<DymNerveStudy> dymNerveStudies = new ArrayList<>();//动态神经元隐层
private DymNerveStudy dymOutNerveStudy = new DymNerveStudy();//动态神经元输出层
private Map<Integer, BorderBody> borderBodyMap = new HashMap<>();//border特征集合
private Map<Integer, List<Double>> kMatrixList = new HashMap<>();//K均值矩阵集合
private Frame frame;//先验边框
public Map<Integer, List<Double>> getkMatrixList() {
return kMatrixList;
}
public void setkMatrixList(Map<Integer, List<Double>> kMatrixList) {
this.kMatrixList = kMatrixList;
}
public Map<Integer, BorderBody> getBorderBodyMap() {
return borderBodyMap;
}
public void setBorderBodyMap(Map<Integer, BorderBody> borderBodyMap) {
this.borderBodyMap = borderBodyMap;
}
public Frame getFrame() {
return frame;
}

@ -2,9 +2,6 @@ package org.wlld;
import org.wlld.MatrixTools.Matrix;
import org.wlld.MatrixTools.MatrixOperation;
import org.wlld.imageRecognition.border.BorderBody;
import java.util.Random;
/**
* @author lidapeng

Loading…
Cancel
Save