开源一个基于Storm 分布式BP神经网络的Demo(Java版)
该demo有3个缺点
1、代码性能一般,有一定的优化空间。由于是Demo,当时写的时候只考虑功能,没考虑性能
2、神经细胞层数被写死了,只有2层,如果要添加细胞层需要改源码。
3、训练任然是串行的,没有充分利用分布式框架并行计算优势。但是后续的计算任然是并行的,只要添加DRPC Client或者自定义DSpout就行了
帖子里我就不介绍Storm和神经网络原理了
我会单独写一篇博文介绍,预计本周内完成,连接:http://blog.csdn.net/tntzbzc/article/details/19974515
Spout启动+Drpc Client 训练++Drpc Client 计算
三个我放在一个main中了
第一个是服务端job 启动
第二个是训练(串行),测试的训练数据是任意整数,把它转成32个由0或1组成的double数组作为输入参数(input),以及一个double[4]的结果值(real)
real[4]:1 0 0 0 正奇数 0 1 0 0 正偶数 0 0 1 0 负奇数 0 0 0 1 负偶数
两层细胞的权重weight是随机生成的
随机生成了1000个样本,训练2000次
第三个是计算,如果想实现分布式并行计算,可以自己添加Client
public class DrpcClient {
/****************************************
* by CSDN 撸大湿 Email : tntzhou@hotmail.com
****************************************/
public static void main(String[] args) throws Exception {
int InputHideCount = 32; /* Input Hide输入数量 */
int HideOutCount = 10; /* Hide Bolt输出数量,等于是Out Bolt的输入数量 */
int OutCount = 4; /* Out输出数量,等于Real的数量 */
TopologyBuilder builder = new TopologyBuilder();
DRPCSpout drpcSpout = new DRPCSpout("BPTrain");
builder.setSpout("drpcSpout", drpcSpout, 1);
builder.setBolt("hide", new HideBolt(), HideOutCount).allGrouping("drpcSpout");
// OutBolt的传参 必须等于 HideBolt的个数
builder.setBolt("out", new OutBolt(HideOutCount), OutCount).allGrouping("hide");
// TrainBPFinsh的传参 必须等于 OutBolt的个数
builder.setBolt("finsh", new TrainBPFinsh(OutCount), 1).allGrouping("out");
builder.setBolt("return", new ReturnResults(), 1).allGrouping("finsh");
Config conf = new Config();
conf.setNumWorkers(Integer.parseInt(args[1]));
StormSubmitter.submitTopology(args[0], conf, builder.createTopology());
String hideweight = getWeightStr(InputHideCount + 1, HideOutCount); // 隐藏层的权重
String outweight = getWeightStr(HideOutCount + 1, OutCount);// 输出层的权重
DRPCClient client = new DRPCClient("mynode001", 3772);
int[] ranInt = new int[1000];
for (int i = 0; i < ranInt.length; i++) {
ranInt[i] = new java.util.Random().nextInt();
}
int Num = 0;
System.out.println("开始训练");
for (int i = 0; i < 2000; i++) {
double r = 0d;
for (int j = 0; j < ranInt.length; j++) {//
RandomNum MyRandom = new RandomNum(ranInt[j]);
String input = MyRandom.getInputDataStr();
String real = MyRandom.getRealDataStr();
String[] result = client.execute(
"BPTrain",
String.valueOf(Num) + "::" + input + "::" + real + "::" + hideweight + "::"
+ outweight).split("::");
// 参数传入全部靠一个字符串,收取也是字符串,最基本的DRPC Client调用
hideweight = result[0];
outweight = result[1];
r = Double.parseDouble(result[2]);
if (j % 100 == 0)
System.out.println(r); // 输出收敛度
}
if (r < 0.005) {
System.out.println("训练结束");
break;
}
}
while (true) {
byte[] input = new byte[10];
System.in.read(input);
int value = 0;
try {
value = Integer.parseInt(new String(input).trim());
} catch (Exception e) {
break;
}
RandomNum rawVal = new RandomNum(value);
String[] resultstr = client.execute(
"BPTrain",
String.valueOf(++Num) + "::" + rawVal.getInputDataStr() + "::"
+ rawVal.getRealDataStr() + "::" + hideweight + "::" + outweight).split("::");
double max = -Integer.MIN_VALUE;
int idx = -1;
String[] result = resultstr[3].split(",");
for (int i = 0; i != result.length; i++) {
if (Double.valueOf(result[i]) > max) {
max = Double.valueOf(result[i]);
idx = i;
}
}
switch (idx) {
case 0:
System.out.format("%d是一个正奇数\n", value);
break;
case 1:
System.out.format("%d是一个正偶数\n", value);
break;
case 2:
System.out.format("%d是一个负奇数\n", value);
break;
case 3:
System.out.format("%d是一个负偶数\n", value);
break;
}
}
}
static String getWeightStr(int inCount, int outCount) {
StringBuilder Wgt = new StringBuilder();
for (int i = 0; i < outCount; i++) {
for (int j = 0; j < inCount; j++) {
Random random = new Random();
double v = random.nextDouble();
double rand = random.nextDouble() > 0.5 ? v : -v;
Wgt.append(rand / 2);
if (j != inCount - 1)
Wgt.append(",");
}
if (i != outCount - 1)
Wgt.append(":");
}
// System.out.println(Wgt.toString().split(":")[0].split(",").length);
return Wgt.toString();
}
}
隐藏层神经细胞 Hide Bolt
public class HideBolt implements IRichBolt {
/****************************************
* by CSDN 撸大湿 Email : tntzhou@hotmail.com
****************************************/
private static final long serialVersionUID = -3242401692275116210L;
OutputCollector collector;
int TaskID = 0;
@SuppressWarnings("rawtypes")
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector _collector) {
collector = _collector;
TaskID = context.getThisTaskIndex(); // 每个Bolt代表一个神经细胞
// Bolt TaskID == 细胞 id
}
@Override
public void execute(Tuple tuple) {
String[] t = tuple.getString(0).split("::");
String jobID = tuple.getString(1); // jobid,drpc rid
int TNum = Integer.valueOf(t[0]); // tuple id
String[] inputstr = t[1].split(",");
double[] input = new double[inputstr.length]; // 传入值
String[] hideweightstr = t[3].split(":");
double[][] hideweight = new double[hideweightstr.length][input.length + 1]; // 隐藏层的权重
for (int i = 0; i < inputstr.length; i++) {
input[i] = Double.parseDouble(inputstr[i]);
}
for (int i = 0; i < hideweightstr.length; i++) {
String[] tmpw = hideweightstr[i].split(",");
for (int j = 0; j < tmpw.length; j++) {
hideweight[i][j] = Double.parseDouble(tmpw[j]);
}
}
double inputsum = 0;
/****************************************
* 计算输出
****************************************/
for (int i = 0; i < input.length; i++) {
inputsum += hideweight[TaskID][i] * input[i];
}
inputsum += hideweight[TaskID][input.length];
double HideOut = 1.0 / (1.0 + Math.exp(-inputsum));
String[] realstr = t[2].split(",");
double[] real = new double[realstr.length];
for (int i = 0; i < realstr.length; i++) {
real[i] = Double.parseDouble(realstr[i]);
}
String[] outweightstr = t[4].split(":");
double[][] outweight = new double[outweightstr.length][outweightstr[0].split(",").length];
for (int i = 0; i < outweightstr.length; i++) {
String[] tmpw = outweightstr[i].split(",");
for (int j = 0; j < tmpw.length; j++) {
outweight[i][j] = Double.parseDouble(tmpw[j]);
}
}
collector.emit(new Values(TNum, TaskID, input, HideOut, real, hideweight, outweight, jobID));
collector.ack(tuple);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("tnum", "HideTaskID", "Input", "HideOut", "Real", "HideWeight",
"OutWeight", "jobID"));
}
@Override
public void cleanup() {
}
@Override
public Map<String, Object> getComponentConfiguration() {
return null;
}
}
输出层神经细胞
public class OutBolt implements IRichBolt {
/****************************************
* by CSDN 撸大湿 Email : tntzhou@hotmail.com
****************************************/
private static final long serialVersionUID = -7483206983562705977L;
OutputCollector collector;
int TaskID = 0;
HashMap<Integer, double[]> HideOutMap = new HashMap<Integer, double[]>();
HashMap<Integer, ArrayList<Tuple>> MyTuple = new HashMap<Integer, ArrayList<Tuple>>();
int HideTaskCount = 0;
public OutBolt(int _hidetaskcount) {
this.HideTaskCount = _hidetaskcount;
}
@SuppressWarnings("rawtypes")
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector _collector) {
collector = _collector;
TaskID = context.getThisTaskIndex();
}
@Override
public void execute(Tuple tuple) {
int TNum = tuple.getInteger(0);
int HideTaskID = tuple.getInteger(1);
double hideout = tuple.getDouble(3);
if (!HideOutMap.containsKey(TNum)) {
HideOutMap.put(TNum, new double[HideTaskCount]);
MyTuple.put(TNum, new ArrayList<Tuple>());
}
HideOutMap.get(TNum)[HideTaskID] = hideout;
MyTuple.get(TNum).add(tuple);
double[] input = null;
double[] real = null;
double[][] hideweight = null;
double[][] outweight = null;
String jobID = null;
outweight = (double[][]) tuple.getValue(6);
jobID = tuple.getString(7);
if (MyTuple.get(TNum).size() == HideTaskCount) {
input = (double[]) tuple.getValue(2);
real = (double[]) tuple.getValue(4);
hideweight = (double[][]) tuple.getValue(5);
/****************************************
* 计算输出
****************************************/
Double sum = 0d;
for (int i = 0; i < HideOutMap.get(TNum).length; i++) {
sum += HideOutMap.get(TNum)[i] * outweight[TaskID][i];
}
sum += outweight[TaskID][HideOutMap.get(TNum).length];
double Out = 1.0 / (1.0 + Math.exp(-sum));
collector.emit(new Values(TNum, TaskID, input, HideOutMap.get(TNum), Out, real,
hideweight, outweight, jobID));
HideOutMap.remove(TNum);
MyTuple.remove(TNum);
}
collector.ack(tuple);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("tnum", "OutTaskID", "Input", "HideOut", "Out", "Real",
"HideWeight", "OutWeight", "jobID"));
}
@Override
public void cleanup() {
// TODO Auto-generated method stub
}
@Override
public Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return null;
}
}
相关推荐
【信息科学与工程学】计算机科学与自动化—第十五篇 云计算 11 算法篇01
编号类型领域问题问题的数学分析(含几何学/拓扑学/代数学/数论/集合论/离散数学/概率论/统计学/其他)及数值分析及算法分析及参数列表及参数数值设计C/C++/rust/python代码软件(含编译器)及硬件资源需求(CPU/GPU/内存【NAND/DRAM/HBM/其他】/HBM、HDD、SSD、RAID卡、其他)关联知识1工作负载调度数据中心最小化总完成时间/成本。
无人机手势控制数据集46176张VOC+YOLO格式.zip
数据集格式:VOC格式+YOLO格式 压缩包内含:3个文件夹,分别存储图片、xml、txt文件 JPEGImages文件夹中jpg图片总计:46176 Annotations文件夹中xml文件总计:46176 labels文件夹中txt文件总计:46176 标签种类数:8 标签名称:["follow","follow_hand","land","land_hand","null","object","takeoff","takeoff-hand"] 每个标签的框数(注意yolo格式类别顺序不和这个对应,而以labels文件夹classes.txt为准): follow 框数 = 22056 follow_hand 框数 = 4038 land 框数 = 7609 land_hand 框数 = 3300 null 框数 = 2642 object 框数 = 2 takeoff 框数 = 3494 takeoff-hand 框数 = 3645 总框数:46786 图片清晰度(分辨率:像素):清晰 图片是否增强:否 标签形状:矩形框,用于目标检测识别 重要说明:暂无 特别声明:本数据集不对训练的模型或者权重文件精度作任何保证,数据集只提供准确且合理标注
三相光伏发电系统中MPPT和并网控制策略的研究(Simulink仿真实现)
内容概要:本文系统研究了三相光伏发电系统中的最大功率点跟踪(MPPT)与并网控制策略,深入分析光伏阵列在不同光照和温度条件下的输出特性,设计并实现了基于Simulink的完整仿真模型。该模型涵盖光伏阵列、DC-DC变换器、MPPT控制器、逆变器及锁相环等关键模块,重点验证了系统在动态环境变化下实现高效能量转换的能力,并确保并网电流符合电能质量标准。研究对比了多种MPPT算法的动态响应与稳定性表现,优化了并网控制策略以提升整体系统性能,为光伏系统的设计与控制提供了理论依据与仿真支持。; 适合人群:具备电力电子、自动控制或新能源发电基础知识的高校研究生、科研人员及从事光伏系统设计与仿真的工程技术人员。; 使用场景及目标:①用于教学与科研中深入理解光伏发电系统的MPPT原理与并网控制机制;②指导实际工程项目中光伏逆变器控制策略的设计与仿真验证;③为撰写相关学术论文或完成课程设计提供可复现的Simulink模型与理论支持。; 阅读建议:建议读者结合文中提供的Simulink仿真文件,逐步搭建系统模型,调试MPPT与并网控制参数,观察关键波形如光伏电压、电流、功率及并网电流的变化,加深对控制逻辑的理解。同时可尝试改进算法以进一步提升系统动态响应与鲁棒性。
无人驾驶网约车服务:全球市场规模、竞争格局与未来发展趋势.docx
无人驾驶网约车服务:全球市场规模、竞争格局与未来发展趋势
开绕组永磁同步电机模型FOC矢量控制SVPWM仿真Simulink模型
内容概要:本文系统解读了一套完整的多机器人路径规划(MAPF)MATLAB代码库,聚焦于优先级规划算法的工程实现。该框架采用四层架构设计(几何、拓扑、调度与呈现),实现了从地图解析、Petri网建模、基于动态边权膨胀的路径规划,到时间同步冲突消解及动画可视化的全流程。核心创新包括动态边权膨胀机制、节点预留历史查表优化、几何惩罚驱动的局部同步策略以及Petri网双阶段优化方法,有效提升了大规模场景下的求解效率与可行性。文章详细阐述了各模块之间的接口契约与不变量,对比分析了三种时间同步策略的适用场景,并强调了信息前移、模块解耦与可维护性设计的重要性,为MAPF的研究与教学提供了可复现、可批判的参考文本。; 适合人群:具备一定MATLAB编程基础,从事机器人路径规划、智能调度、自动化控制等相关领域的科研人员与研究生。; 使用场景及目标:① 学习并复现多机器人路径规划中的优先级规划算法及其工程实现细节;② 深入理解动态边权膨胀、节点预留历史、局部同步等核心机制的设计原理与性能优化策略;③ 掌握Petri网建模与整数规划在路径调度中的应用,以及多智能体系统冲突消解与可视化的方法。; 阅读建议:此资源以工程化框架形式呈现,不仅关注算法逻辑,更重视模块化设计与系统集成。建议读者按照数据流顺序逐步学习,结合代码调试理解各层交互,并尝试替换不同同步策略以评估其对效率与解质量的影响,从而深入掌握大规模MAPF问题的求解范式。


