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

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

 

多层感知机MLP & 反向传播

与多输出感知机相比

有多层节点(绿色的)

δkk是由Okk和tk得到的

所以δ一共有k个

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

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

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

 

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

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

比如我们要求E对Wij的导

 

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

而δj是怎么求出来的呢

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

 

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

 

优化问题实战

2D函数优化实例

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()

这个图像是可以转动的

随机梯度下降法

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() 它就会更新一次这个过程

 

正确找到一个点

下面我们改变一下初始化

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()))

找到了另一个局部最小值

 

再改一下

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()))

又换了一个点

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值