【机器学习】梯度、梯度法、python实现神经网络的梯度计算

  • 一、python实现求导的代码:
  • 二、what is 梯度
  • 三、使用梯度法寻找神经网络的最优参数
  • 四、神经网络的梯度计算

一、python实现求导的代码:

导数含义也就是:变量x一个微小的变化将导致f(x)的值在多大程度上变化。

def numerical_diff(f, x):h = 1e-4return (f(x+h) - f(x-h)) / (2*h)

偏导数怎么求,对哪个变量求偏导,就把其他变量固定为某个值,然后就像求一元函数导数那样对这个变量求导。

举个例子,对x0^ 2+x1 ^2=y这个二元函数,求x0=3,x1=4时,对x0的偏导数。

代码如下:

def numerical_diff(f, x):h = 1e-4return (f(x+h) - f(x-h)) / (2*h)def func_1(x):return x[0]**2+x[1]**2# 求x0=3,x1=4时,x0的偏导数def func_temp1(x0):return x0**2+4**2if __name__ == '__main__':res = numerical_diff(func_temp1,3.0)print(res)

输出:

6.00000000000378

二、what is 梯度

由全部变量的偏导数汇总而成的向量叫梯度。

求梯度代码如下:

函数 _numerical_gradient_no_batch 的参数f为函数,x为Numpy数组。

grad = np.zeros_like(x)生成一个形状和x相同,所有元素均为0的数组,梯度就存到这里面。

这里面fxh1计算的时候,如果在这(x[0],x[1])这一点对x[0]求编导,变的是x[0],x[1]不变。而且对x[1]求偏导的时候,变的是x[1],x[0]不变。所以,要用tmp_val存变化前的数,并且,在求完偏导后把一切恢复。

下面代码是对x0 ^ 2+x1 ^ 2=y这个二元函数,求点(3,4)处的梯度。

import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as npdef _numerical_gradient_no_batch(f, x):h = 1e-4  # 0.0001grad = np.zeros_like(x)for idx in range(x.size):tmp_val = x[idx]x[idx] = float(tmp_val) + hfxh1 = f(x)  # f(x+h)x[idx] = tmp_val - hfxh2 = f(x)  # f(x-h)grad[idx] = (fxh1 - fxh2) / (2 * h)x[idx] = tmp_val  # 还原值return graddef func_1(x):return x[0]**2+x[1]**2if __name__ == '__main__':#求点(3,4)处的梯度res = _numerical_gradient_no_batch(func_1, np.array([3.0, 4.0]))print(res)

结果:

[6. 8.]

用python画很多点的梯度向量,那么就发现一个很神奇的结果:梯度指向函数最小值,离最小值越远,箭头越大。

严格来讲,梯度指示的方向是各点处函数值减小最多的方向。无法保证梯度所指方向就是函数最小值。

虽然梯度的方向不一定指向最小值,但是沿着它的方向能够最大限度减小函数的值,这就是梯度法

三、使用梯度法寻找神经网络的最优参数

通过不断地沿着梯度方向前进,逐渐减小函数值的过程就是梯度法。

梯度法的数学表示:

η表示更新量,在神经网络的学习中,称为学习率( learningrate)。学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数。

这个数学表示是什么意思,其实就是沿着梯度走,如上图,(x0,x1)取(0,2)时,梯度是(0,4)。这里的x0-η乘f在x0处的偏导,表示沿那个梯度方向走的一小步。学习率小的话,每次走的步子会很小,学习率大的话,步子就大。

用python实现梯度法的代码如下:

f是要进行最优化的函数, init_x是初始值, lr是学习率, step_num是梯度法的重复次数。

gradient_descent函数里面调用了numerical_gradient函数,用来求函数的梯度。gradient_descent函数里面会一直循环step_num次梯度法,每一次都用梯度乘以学习率得到新值,并更新。最后如果梯度法进行的顺利,将走到最小值的位置。

def gradient_descent(f, init_x, lr=0.01, step_num=100):x = init_xx_history = []for i in range(step_num):x_history.append( x.copy() )grad = numerical_gradient(f, x)x -= lr * gradreturn x, np.array(x_history)

下面这个例子,用了梯度法求f(x0,x1)=x0^ 2+x1 ^2的最小值。最终结果接近(0,0),说明我们的结果基本正确,因为最小值确实是在(0,0)点取到。

import numpy as np
import matplotlib.pylab as plt
from gradient_2d import numerical_gradientdef gradient_descent(f, init_x, lr=0.01, step_num=100):x = init_xx_history = []for i in range(step_num):x_history.append( x.copy() )grad = numerical_gradient(f, x)x -= lr * gradreturn x, np.array(x_history)def function_2(x):return x[0]**2 + x[1]**2init_x = np.array([-3.0, 4.0])    lr = 0.1
step_num = 20
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)
print(x)plt.plot( [-5, 5], [0,0], '--b')
plt.plot( [0,0], [-5, 5], '--b')
plt.plot(x_history[:,0], x_history[:,1], 'o')plt.xlim(-3.5, 3.5)
plt.ylim(-4.5, 4.5)
plt.xlabel("X0")
plt.ylabel("X1")
plt.show()

输出:

[-0.03458765  0.04611686]

学习率取的过大或者过小都无法得到好结果。

对上面代码进行修改:

学习率过大的话,结果会发散成一个很大的值。

lr = 10
step_num = 100
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)
print(x)

结果:

[-2.58983747e+13 -1.29524862e+12]

学习率过小,基本上没怎么更新就结束了。

lr = 1e-10
step_num = 100
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)
print(x)

结果:

[-2.99999994  3.99999992]

四、神经网络的梯度计算

神经网络的学习中的梯度,指的是损失函数关于权重参数的梯度。

假设,有一个形状为2*3的权重W的神经网络,损失函数是L,下面是该网络权重和梯度的数学表示。

下面是一个例子,首先要实现一个simpleNet类,这个网络的权重矩阵是2*3的。

最后输出的dw如下,这个是梯度。

[[ 0.12894287  0.31807705 -0.44701992][ 0.19341431  0.47711557 -0.67052988]]

比如,如果w11增加h,那么损失函数的值会增加0.47h。从减小损失函数值的观点看,w11应该向负方向更新。

import sys, os
sys.path.append(os.pardir)  # 为了导入父目录中的文件而进行的设定
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradientclass simpleNet:def __init__(self):self.W = np.random.randn(2,3)def predict(self, x):return np.dot(x, self.W)def loss(self, x, t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y, t)return lossnet = simpleNet()
print(net.W) # 权重参数x = np.array([0.6, 0.9])#输入数据
p = net.predict(x) #由输入经过神经网络得到的输出预测值
print(p)
print(np.argmax(p))#最大值的索引t = np.array([0, 0, 1]) # 正确解标签
print(net.loss(x, t)) #输出损失函数的值def f(W):return net.loss(x, t)
# f = lambda w: net.loss(x, t)dW = numerical_gradient(f, net.W)#求梯度print(dW)

输出:

[[-0.66110535 -2.3121261   0.61870626][-0.43594672  1.66798289 -1.09922476]]
[-0.78901526  0.11390894 -0.61807852]
1
1.366622688011303
[[ 0.12894287  0.31807705 -0.44701992][ 0.19341431  0.47711557 -0.67052988]]

梯度、梯度法、python实现神经网络的梯度计算相关推荐

  1. 批量梯度下降python实现_python实现梯度下降算法的实例详解

    python版本选择 这里选的python版本是2.7,因为我之前用python3试了几次,发现在画3d图的时候会报错,所以改用了2.7. 数据集选择 数据集我选了一个包含两个变量,三个参数的数据集, ...

  2. DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练、预测

    DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练.预测 导读 利用python的numpy计算库,进行自定义搭建2层神经网络TwoLayerN ...

  3. 3.9 神经网络的梯度下降法-深度学习-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 3.8 激活函数的导数 回到目录 3.10 直观理解反向传播 神经网络的梯度下降法 (Gradient Descent for Neural Networks) 在这个视频中 ...

  4. ApacheCN《Sklearn 与 TensorFlow 机器学习实用指南》 第11章 项目训练深层神经网络(梯度消失与梯度爆炸,选择初始化,选择激活函数)

    原文:https://www.jishux.com/p/52b468ceb5722ca5 第11章 训练深层神经网络 来源:ApacheCN<Sklearn 与 TensorFlow 机器学习实 ...

  5. 陈怡然团队最新研究:用复数神经网络提高梯度正则化准确度 | ICML 2021

    博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI 现在,我们可以用虚数来帮助AI算法抵御恶意攻击了! 这就是陈怡然团队提出的复数神经网络(CVNN),论文已被机器学习顶会ICML接收. 在对 ...

  6. 1.8 循环神经网络的梯度消失-深度学习第五课《序列模型》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 1.7 对新序列采样 回到目录 1.9 GRU 单元 循环神经网络的梯度消失 (Vanishing Gradient with RNNs) 你已经了解了RNN时如何工作的了, ...

  7. 【论文解读】ICLR 2021丨当梯度提升遇到图神经网络,“鱼和熊掌”皆可兼得

    论文:https://arxiv.org/pdf/2101.08543.pdf 代码:https://github.com/nd7141/bgnn 无论是分子设计.计算机视觉,还是组合优化和推荐系统等 ...

  8. 一文看懂计算机神经网络与梯度下降

    1. 计算机神经网络与神经元 要理解神经网络中的梯度下降算法,首先我们必须清楚神经元的定义.如下图所示,每一个神经元可以由关系式y=f(∑i=1nwixi+b)y = f(\sum_{i=1}^nw_ ...

  9. 使用反向传播算法计算参数的梯度并用python实现加法和乘法节点的反向传播

    使用反向传播算法计算参数的梯度并用python实现加法和乘法节点的反向传播 一.what is 反向传播 二.乘法节点的反向传播 三.加法节点的反向传播 四.加法层和乘法层混合应用 一.what is ...

最新文章

  1. cad版本在线转换_一套某中学的弱电系统拓扑设计方案(CAD版本)
  2. Ajax拿取JSON格式的数据
  3. chrome禁止三方cookie,网站登录不了怎么办
  4. ModelCoder国产化解决方案已逐步代替国外软件Matlab/Simulink
  5. 【BZOJ1087】【codevs2451】互不侵犯,状压DP
  6. python下标是什么类型_python基本的数据类型
  7. background-color:#e5eecc; border:solid 1px #c3c3c3;
  8. Android IOS WebRTC 音视频开发总结(二二)-- 多人视频架构模式
  9. php mysql敏感词_PHP敏感词处理
  10. gibboncode导入.stl格式模型,进行网格划分
  11. python百度云链接哔哩哔哩弹幕网_python预课05 爬虫初步学习+jieba分词+词云库+哔哩哔哩弹幕爬取示例(数据分析pandas)...
  12. [UOJ198][CTSC2016]时空旅行
  13. python字符映射表和字符替换
  14. strcmp函数(讲解)
  15. 一个敬谦基督徒的生活
  16. Qt5把图片如何导出为pdf再到剪切板
  17. 齐治堡垒机ShtermClient-2.1.1命令执行漏洞(CNVD-2019-09593)分析
  18. 分析:人名搜索Spock会成下个谷歌吗
  19. vue watch使用了immediate之后,handler的this指向问题
  20. Integer最大值2147483647

热门文章

  1. Ajax在请求数据时显示等待动画遮罩
  2. pyqt5让主窗口居中显示(显示在显示器的中间位置)
  3. java比较字符能用等于号码_Java字符串比较,==,等于,匹配,compareTo()之间的差异。...
  4. 数字图像处理基础与应用 第五章
  5. linux用java连接mysql_Java使用JDBC方式连接数据库
  6. java web输出语句到控制台_Java工程师(6).循环结构
  7. 华锋e路航x10升级工具_万商云集:疫情下火爆的电子合同,背后是企业数字化升级的必然...
  8. java向有序数组里插数_Java向有序数组中插入一个元素,,使其仍按有序排列,并求出这个插入元素的下标...
  9. Win7系统无法复制粘贴怎么解决
  10. postman如何发送application/json类的post请求