最近了解到的一些神经网络的东西

引言

因为对于毕设是一头雾水,所以趁着最近比较闲,了解了一些神经网络的东西。我的毕设题目是《面向慕课学习数据的智能分析系统设计实现》,看着貌似有点高大上,实际上就是使用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);
  }

上述拟合效果还可以,毕设就决定使用这两个库了。

总结

计算机的发展,不仅仅需要软件、硬件的发展,数学学科的发展也是至关重要的。如果你想成为一个优秀的程序员,首先你不应该是一个蹩脚的数学学者。

发表评论

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据