JavaScript: 梯度下降法拟合函数
novakon2016/09/04软件综合 IP:广东

环境是node 4.x

先定义一个函数: y = f(x) = 3x^2 + 2x

然后在 [-50,50) 上采样一组数据,并添加白噪声。

<code class="language-js">function target(x){
  return 3 * x * x + 2 * x  // y = 3x^2 + 2x
}

var input = [], output = []

for(i=-50;i<50;i++){ fill test data input.push(i) output.push(target(i)+math.random()*3) with random errors } < code></50;i++){></code>

此时,input数组包含[-50,50)上的一组输入值,output数组包含对应的输出值。


问题:已知原函数的形式是 y = f(x) = ax^2 + bx,求 a 和 b。

首先定义我们的假设:y = p0x^2 + p1x,接受x为输入,以及params为参数数组。

<code class="language-js">function hypothesis(x,params){
  return params[0] * x * x + params[1] * x
}
</code>

然后给待求参数指定一个初始值 (p0,p1) = (0,0)

<code class="language-js">var solution = [0,0]
</code>

然后我们定义误差函数。误差的定义是[给定参数下,函数的输出值(output)和实际输出值的RMSE]

<code class="language-js">function error_of_hypothesis(params){
  var total_square_err = 0.0;
  for(i in input){
    var x = input[i]
    var difference = hypothesis(x,params) - output[i]

    total_square_err += difference * difference
  }
  return Math.sqrt(total_square_err/input.length) //RMSE
}
</code>

然后定义[梯度计算及下降]函数。[梯度]就是误差函数在点(p1,p2)处对p1,p2分别求偏导得到的矢量。说白了就是求那个点的“上坡方向”的矢量。

此处求偏导使用了数值方法。

<code class="language-js">function calculate_gradient_and_descend(stepsize){
  // calculate error(p0,p1)
  var err = error_of_hypothesis(solution)

  // calculate gradient of error(p0,p1)
  var delta = 0.00000001
  var gradient = []

  for(i in solution){
    // calculate partial derivative of error(p0,p1)
    var delta_solution = []
    delta_solution[0] = solution[0]
    delta_solution[1] = solution[1]

    delta_solution[i] += delta
    gradient[i] = (error_of_hypothesis(delta_solution) - err)/delta
  }

  // descend (p0,p1)
  for(i in solution){
    solution[i] -= gradient[i]*stepsize
  }

  return err
}
</code>

上面可以看到:每运行一次下降函数,solution矢量就会朝当前梯度方向的反方向前进stepsize距离。

这会让我们越来越接近谷底。

下面定义我们的梯度下降循环:

<code class="language-js">function run_descent(iterations,stepsize){
  for(var i=0;i<iterations;i++){ var err="calculate_gradient_and_descend(stepsize)" if(i%(iterations 10)="=0||i">iterations-10){
      console.log('-------------');
      console.log('gradient descent iteration',i);
      console.log('RMSE=',err);
      console.log('solution:',solution,'after descent.');
    }
  }
  return err
}

run_descent(1000,0.001)
run_descent(1000,0.0001)
run_descent(1000,0.00001)
run_descent(10000,0.000001)
</iterations;i++){></code>

结果:

<code class="language-plaintext">-------------
gradient descent iteration 9997
RMSE= 1.2756225981845384
solution: [ 3.001084043830482, 2.001937055426506 ] after descent.
-------------
gradient descent iteration 9998
RMSE= 1.275622596459923
solution: [ 3.0010840438762454, 2.001937096928974 ] after descent.
-------------
gradient descent iteration 9999
RMSE= 1.275622594737627
solution: [ 3.0010840439171016, 2.0019371384060625 ] after descent.
</code>
来自:计算机科学 / 软件综合
4
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
张静茹
7年8个月前 IP:江苏
825393
最近看了一个三次样条拟合,用在浓度与检测值转换上
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
Cirno
7年8个月前 IP:美国
825405
Is there any matrix calculation packages for JavaScript? Just Like Numpy for Python
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
nkc
7年8个月前 IP:广东
825596
引用 Cirno:
Is there any matrix calculation packages for JavaScript? Just Like Numpy for Python
ConvnetJS by Andrej Karparthy
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
zxf8665905
7年8个月前 IP:上海
825898
js 有求梯度的库么?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
novakon
学者 机友 笔友
文章
1256
回复
8385
学术分
16
2008/03/29注册,2年3个月前活动

已走,勿送

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}