梯度的一些笔记

梯度的一些笔记

导数、偏导数、方向导数、梯度的含义
导数

表示函数 f ( x ) f(x) f(x)在该点的变化率。函数值在增量与在该点的自变量的增量的比值的极限存在的话,导数就存在,反应的是变化率的大小,导数的绝对值越大,说明变化幅度越大,变化越剧烈。如果是一元函数,表示的是函数在某一点的切线的斜率,斜率绝对值越大,表示越陡峭,即变化的幅度越大。
如果是时间 t t t 是自变量,位移 s ( t ) s(t) s(t) 是时间 t t t 的函数,那么某一时刻的导数 s ′ ( t ) s\prime(t) s(t) 就是这一时刻的瞬时速度。

偏导数

是个向量,多元函数 f ( x , y ) f(x,y) f(x,y)在点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)对各个坐标轴方向上的导数,例如向量 ( f x ( x 0 , y 0 ) , f y ( x 0 , y 0 ) ) (f_x(x_0,y_0),f_y(x_0,y_0)) (fx(x0,y0),fy(x0,y0))

方向导数

是偏导数概念的推广,是个向量,函数在某点沿着方向向量l的导数,方向向量l的指向有无数种

梯度

梯度也是个向量,数值为方向导数的最大值,方向地偏导数的方向

函数沿着梯度下降的方向,函数值下降的最快,这是很多梯度下降优化的基础。

为什么沿着梯度的反方向是下降最快的方向?

可以参考附录的链接地址,需要理清方向导数和梯度的关系,实际当目标函数 f ( x , y ) f(x,y) f(x,y)对直线 l : ( c o s α , c o s β ) l:(cos\alpha,cos\beta) l:(cosα,cosβ) 的导数的方向与梯度方向一致时,即方向导数与梯度的方向的方向完全一致,目标函数的方向导数取得最大值,即目标函数 f ( x , y ) f(x,y) f(x,y)沿着梯度方向值增长的最快,也就是说,按照梯度的反方向值下降的最快。

应用到机器学习

通常我们要优化的目标函数是一个损失函数 L o s s ( θ 1 , θ 2 , . . . , θ M ) Loss(\theta_1,\theta_2,...,\theta_M) Loss(θ1,θ2,...,θM),极小化这个目标函数,参数是我们要学习的机器学习参数 θ 1 , θ 2 , . . . , θ M \theta_1,\theta_2,...,\theta_M θ1,θ2,...,θM

我们首先计算出目标函数的梯度,然后按梯度反方向更新梯度,这样就可以使得目标函数的函数值以最快的方式下降到极小值。
θ i = θ i − λ ∂ L o s s ( θ 1 , θ 2 , . . . , θ M ) ∂ θ i \theta_i = \theta_i - \lambda \frac{\partial Loss(\theta_1,\theta_2,...,\theta_M)}{\partial \theta_i} θi=θiλθiLoss(θ1,θ2,...,θM) λ 是学习率 \lambda 是学习率 λ是学习率
特别地,如果目标函数是凸函数,那么得到的极小值就是全局最小,此时得到的参数即为全局最优的参数解

梯度下降的示例
给定一批样例数据 x , f ( x ) x, f(x) x,f(x),运用梯度下降求解参数 a , b , c a, b, c a,b,c
f ( x ) = a x 2 + b x + c f(x) = ax^2 + bx+c f(x)=ax2+bx+c

先构造一批数据,然后用梯度下降来求解

#!/usr/bin/python
import numpy as np

data = []
def build_data(a, b, c, num=10000):
	for i in range(num):
		x = np.random.uniform(-10, 10)
		eps = np.random.normal(0, 0.001)
		y = a * (x ** 2) + b * x + c  + eps
		data.append((x, y))


def calc_error(a, b, c):
	error = 0
	for i in data:
		x = i[0]
		y = i[1]
		y_hat = a * (x ** 2) + b * x + c
		error += (y_hat - y) ** 2 / (2 * len(data))
	return error 


def gradient_descent(a, b, c):
	a_gradient = 0
	b_gradient = 0
	c_gradient = 0
	for i in data:
		x = i[0]
		y = i[1]
		bais = a * (x**2) + b * x + c - y
		a_gradient += bais * (x ** 2)
		b_gradient += bais * x
		c_gradient += bais
	a_gradient /= len(data)
	b_gradient /= len(data)
	c_gradient /= len(data)
	return a_gradient, b_gradient, c_gradient


def train():
	build_data(a=1.56,b=3.48,c=2.3)  
	a, b, c = 0, 0, 1
	iter = 4000
	lr = 0.0005
	for i in range(iter):
		error = calc_error(a, b, c)
		a_grad, b_grad, c_grad = gradient_descent(a, b, c)
		a = a - lr * a_grad
		b = b - lr * b_grad
		c = c - lr * c_grad
		print('iter:', i, 'error', error, 'a', a, 'b', b, 'c', c, 'a_grad', a_grad, 'b_grad', b_grad, 'c_grad', c_grad)

train()

在这里插入图片描述

参考
  1. 全微分
  2. 方向导数与梯度
  3. 元函数的极值及其求法
  4. 为什么梯度方向是函数值增大最快的方向
  5. 理解梯度下降——NiuLiangtao
  6. 理解梯度下降——LIU-CHENG XU
  7. 机器学习的数学基础 - 导数、偏导数、方向导数、梯度
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值