深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战

介绍一个完完整整的,与我们实际使用一摸一样的多层感知机的反向传播方式

 

多层感知机MLP & 反向传播

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第1张图片

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第2张图片

与多输出感知机相比

有多层节点(绿色的)

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第3张图片

δkk是由Okk和tk得到的

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第4张图片

所以δ一共有k个

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第5张图片

我们此时求的是E对Wjk的导

这是输出节点前的最后一层,前面还有好多层

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第6张图片

也就是我们需要求E对Wij的导数

 

其实δk定义为从当前节点开始,即从k层的节点开始,到最终的输出层的梯度的导数的信息,只要拿到了这个信息,再乘上O节点的输出,就可以得到E对Wjk的导数

假如本层是k层,上一层是j层,知道了δk就可以求δj

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第7张图片

比如我们要求E对Wij的导

 深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第8张图片

只需要知道这一层j层的的δj和上一层的一个节点i的输出Oi

而δj是怎么求出来的呢

当前节点j的输出和下一层k的δk

 

所以,通过这样的顺序,可以从后往前不停地迭代,就可以计算出前面所有层的偏微分的信息,得到之后就可以使用链式法则的梯度更新方式来更新权值W

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第9张图片

 

优化问题实战

2D函数优化实例

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第10张图片

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第11张图片

himmelblau function  专门用来检测优化器的效果

有四个局部最小值,这四个也都是全局最小解,值都是0
 

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import torch

def himmelblau(x):
	return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range: ', x.shape, y.shape)
X, Y = np.meshgrid(x,y)
print('X,Y maps:',X. shape,Y. shape)
Z = himmelblau([X, Y])

fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x') 
ax.set_ylabel('y')
plt.show()

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第12张图片

这个图像是可以转动的

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第13张图片

随机梯度下降法

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import torch

def himmelblau(x):
	return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range: ', x.shape, y.shape)
X, Y = np.meshgrid(x,y)
print('X,Y maps:',X. shape,Y. shape)
Z = himmelblau([X, Y])

fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x') 
ax.set_ylabel('y')
plt.show()



#Gradient Descent
x = torch.tensor([0.,0.], requires_grad=True)  #初始化值设定为0,0
optimizer = torch.optim.Adam([x], lr=1e-3)  #优化器,目标是x,学习率是1e-3
for step in range(20000): 
	pred=himmelblau(x)

	optimizer.zero_grad()  #梯度清零
	pred.backward() #会生成x和y的梯度信息
	optimizer.step() #会将x和y更新为x'和y'

	if step % 2000 == 0: 
		print('step {}: x = {}, f(x) = {}'.format(step, x.tolist(), pred.item()))

我们优化的不是loss(error)了,而是函数的预测值

我们以前是求对W的微分,现在是

 

optimizer = torch.optim.Adam([x], lr=1e-3)

这句话是 优化器,目标是x,学习率是1e-3

意思就是只要你得到梯度以后,这句话就可以自动完成这个操作

        ∇x是x的梯度

只要你下面调用一次optimizer.step() 它就会更新一次这个过程

 

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第14张图片

正确找到一个点

下面我们改变一下初始化

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import torch

def himmelblau(x):
	return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range: ', x.shape, y.shape)
X, Y = np.meshgrid(x,y)
print('X,Y maps:',X. shape,Y. shape)
Z = himmelblau([X, Y])

fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x') 
ax.set_ylabel('y')
plt.show()



#Gradient Descent
x = torch.tensor([4.,0.], requires_grad=True)  #初始化值设定为0,0
optimizer = torch.optim.Adam([x], lr=1e-3)  #优化器,目标是x,学习率是1e-3
for step in range(20000): 
	pred=himmelblau(x)

	optimizer.zero_grad()  #梯度清零
	pred.backward() #会生成x和y的梯度信息
	optimizer.step() #会将x和y更新为x'和y'

	if step % 2000 == 0: 
		print('step {}: x = {}, f(x) = {}'.format(step, x.tolist(), pred.item()))

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第15张图片

找到了另一个局部最小值

 

再改一下

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import torch

def himmelblau(x):
	return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range: ', x.shape, y.shape)
X, Y = np.meshgrid(x,y)
print('X,Y maps:',X. shape,Y. shape)
Z = himmelblau([X, Y])

fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x') 
ax.set_ylabel('y')
plt.show()



#Gradient Descent
x = torch.tensor([-4.,0.], requires_grad=True)  #初始化值设定为0,0
optimizer = torch.optim.Adam([x], lr=1e-3)  #优化器,目标是x,学习率是1e-3
for step in range(20000): 
	pred=himmelblau(x)

	optimizer.zero_grad()  #梯度清零
	pred.backward() #会生成x和y的梯度信息
	optimizer.step() #会将x和y更新为x'和y'

	if step % 2000 == 0: 
		print('step {}: x = {}, f(x) = {}'.format(step, x.tolist(), pred.item()))

深度学习与神经网络(三)——多层感知机 & 反向传播 & 优化实战_第16张图片

又换了一个点

 

你可能感兴趣的:(深度学习,神经网络,多层感知机,反向传播)