本章上一篇可见链接
https://blog.csdn.net/Raine_Yang/article/details/128682091?spm=1001.2014.3001.5501
梯度下降法(gradient descend)
神经网络学习的目标是找到使损失函数最小的参数(权重和偏置)。通过求得损失函数(总损失关于权重和偏置的函数)梯度,寻找梯度下降的发现,即可找到函数最小值。
注意利用梯度下降发得到的不一定是最小值,而仅仅为一个极小值,及梯度为0.另外,当函数呈扁平状,学习可能会进入一个平坦区域,难以进展,被称为学习高原
梯度法即为从当前函数取值沿梯度方向前进一定距离,然后重新求梯度,再继续迭代。其中每一步前进步幅被称为学习率(learning rate)
用公式表示如下:
梯度下降法程序实现:
import numpy as np
def gradient_descent(f, init_x, lr = 0.01, step_num = 100):
x = init_x;
for i in range(step_num):
grad = numerical_gradient(f, x)
x -= lr * grad
return x
注:f 要优化的函数,init_x初始值,lr学习率,step_num函数重复次数
numerical_gradient(f, x)为求梯度函数,代码实现在上一篇文章
学习率这样的参数被称为超参数。超参数不由神经网络自己训练获得,而必须人工设定。超参数一般要尝试多个值才能找到一个合适的设定
学习率过大会导致训练不精确,而过小会导致学习速度慢
神经网络的梯度
神经网络的梯度值损失函数关于权重参数的梯度,如对于一个2 * 3的神经网络权重W,损失函数为L,梯度即为∂L/∂W
梯度中每一个值的意义即为当该权重值变化时,损失函数的变化率。梯度的形状和W形状相同
使用梯度下降法处理神经网络的输出
# coding: utf-8
import sys, os
sys.path.append('D:\AI learning source code') # 为了导入父目录中的文件而进行的设定
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
class 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 loss
x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])
net = simpleNet()
f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)
print(dW)
1
def __init__(self):
self.W = np.random.randn(2,3)
初始化隐藏层,权重设为随机值
2
def predict(self, x):
return np.dot(x, self.W)
将输入值x和权重W相乘,得到神经网络第一层输出
3
def loss(self, x, t):
z = self.predict(x)
y = softmax(z)
loss = cross_entropy_error(y, t)
return loss
使用softmax函数求得分类结果,使用交叉熵得到损失函数
4
f = lambda w: net.loss(x, t)
这里使用了lambda表达式。python里的lambda表达式可以便捷创建简单函数。该式子的意思为 f(W) = net.loss(x, t) 这里网络权重W为一个伪参数。我们将net.loss(x, t)的值定义为 f 关于 W 的函数。
注:神经网络损失函数是关于网络输出输出的函数,而网络输出又是关于W的函数,所有损失函数也为关于W的函数
5
dW = numerical_gradient(f, net.W)
求得损失函数梯度,本例中结果为:
[[ 0.05613215 0.3069528 -0.36308495]
[ 0.08419822 0.4604292 -0.54462742]]