引言
因为对于毕设是一头雾水,所以趁着最近比较闲,了解了一些神经网络的东西。我的毕设题目是《面向慕课学习数据的智能分析系统设计实现》,看着貌似有点高大上,实际上就是使用bp神经网络进行学习,预测学习成绩、选课人数变化趋势等等。而bp神经网络是使用别人的库,也不需要自己写,典型的调参小能手。
bp神经网络
基本BP算法包括信号的前向传播和误差的反向传播两个过程。即计算误差输出时按从输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。
大概就是上图所示,最简单的bp神经网络有三层(一层输入层、一层隐藏层、一层输出层)。迭代的过程:输入层经过激励函数的计算,到达隐藏层,隐藏层也经过激励函数的计算到达输出层。 然后在输出层计算误差,依次调节隐含层到输出层的权重和偏置,输入层到隐含层的权重和偏置 。这里只是大概讲一下过程,至于激励函数的选择、如何调节权重等,这里不做介绍。
一个让我惊讶的表达式
在神经网络的数据预处理中,有一个表达式让我惊讶到了。
就是上面这个表达式。也许乍一看没有什么大不了的,请允许我细细道来。
1、假设有5个数据,分别为:1,2,3,4,5.使用上诉表达式,可以转换为:0,0.25,0.5,0.75,1。将5个数收缩在区间[0,1]中,而神经网络在区间[0,1]中训练效率最好。
2、上述表达式是将数据进行线性变化,也就是进行一次方程的变化。这样变换之前与之后的数据的图像是变化趋势是不改变的,这是让我惊艳到的第二个原因。
将这两个原因分开看,也许不那么让我惊讶。但是,两个原因合在一起,可以说是bp神经网络可以进行曲线拟合的重要原因。这两个原因,在加快bp神经网络降低误差的同时使得拟合的曲线不改变(各点的斜率不改变而不是各点的值不改变),这就是让我感到惊讶的重要原因。
进行曲线拟合的一个实验
在git上找到了一个神经网络的库,星有10.4k,感觉蛮靠谱,就试了试。可视化使用的是highcharts。(仅展示部分bp神经网络代码)。
const config = { binaryThresh: 0.5, hiddenLayers: [8], // 隐藏层的节点数,如[3,4]表示有两个隐藏层,第一层3个节点,第二层4个节点 activation: 'sigmoid', // 激励函数: ['sigmoid', 'relu', 'leaky-relu', 'tanh'], leakyReluAlpha: 0.01, // supported for activation type 'leaky-relu' },options={ iterations: 500000, // 最大迭代的次数(最大训练次数) errorThresh: 0.005, // 训练可以接受的错误百分比 log: true, // console.log是否打印迭代的结果 logPeriod: 20, // 打印的间隔 learningRate: 0.3, // 学习率(0-1) momentum: 0.1, // 动量因子(0-1) callback: null, // 每一次迭代结束的回调函数 callbackPeriod: 10, // 回调函数的调用间隔 timeout: Infinity, // 大于0的数字训练的超时毫秒数 }; const net = new brain.NeuralNetwork(config); var data=[70,80,90,40,30,10,12,40,60,50,10,30,20,10,50,60,10,3].map((item,index)=>{ return { input:[index/17,0/17,10/17,16/17], output:[(item-3)/(90-3)] } }); if(!localStorage.getItem("net")){ net.train(data,options); // localStorage.setItem("net",JSON.stringify(net.toJSON())); }else{ net.fromJSON(JSON.parse(localStorage.getItem("net"))); } const result = []; for(var i=0;i<18;i++){ result.push(net.run([i/17,0/17,10/17,16/17])*(90-3)+3); }
上述拟合效果还可以,毕设就决定使用这两个库了。
总结
计算机的发展,不仅仅需要软件、硬件的发展,数学学科的发展也是至关重要的。如果你想成为一个优秀的程序员,首先你不应该是一个蹩脚的数学学者。