代码详解:运用Numpy实现梯度下降优化算法的不同变体

本文详细介绍了如何使用Numpy在Python中实现梯度下降优化算法的不同变体,包括梯度下降、动量法、NAG、小批量和随机梯度下降。通过matplotlib创建动画,可视化这些算法如何更新权重和偏差,以找到神经网络的最佳参数。文章首先定义了一个Sigmoid神经元类,并展示了如何在该类中实现各种梯度下降算法。随后,使用二维和三维图以及动画展示了算法的动态过程,帮助理解不同算法在不同起点和超参数下的行为。
摘要由CSDN通过智能技术生成

全文共14118字,预计学习时长30分钟或更长

 

想了解如何使用numpy在tensorflow或pytorch中实现优化算法,以及如何使用matplotlib创建精美的动画?

本文将讨论如何实现梯度下降优化技术的不同变体,以及如何使用matplotlib将用于这些变体更新规则的运作可视化出来。

本文的内容和结构基于 One-Fourth Labs。

梯度下降是优化神经网络最常用的技术之一。梯度下降算法是通过向相对于网络参数的目标函数梯度的相反方向移动来更新参数。

 

运用Numpy在Python中实现

照片来源:Unsplash,克里斯托弗·高尔

编码部分将讨论以下主题。

• Sigmoid神经元类

• 总体设置——何为数据、模型、任务

• 绘图功能——3D和轮廓图

• 个体算法及其执行方式

在开始实现梯度下降之前,首先需要输入所需的库。从mpl_toolkits.mplot3d输入的Axes3D提供了一些基本的3D绘图(散点、曲面、直线、网格)工具。它并非最快或功能最完整的3D库,而是Matplotlib附带的。还从 Matplotlib输入colors和colormap(cm)。我们想要制作动画图来演示每种优化算法的工作原理,所以我们输入animation和rc来让图表看起来美观。为了显示HTML,在Jupyter Notebook中成线性排列。最后为了计算目的来输入numpy,这项计算任务很繁重。

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

from matplotlib import cm

import matplotlib.colors

from matplotlib import animation, rc

from IPython.display import HTML

import numpy as np

实施Sigmoid神经元

为了实现梯度下降优化技术,以sigmoid神经元(逻辑函数)为例,看看梯度下降的不同变体是如何学习参数“ w”和“ b”的。

Sigmoid神经元复查

Sigmoid神经元类似于感知机神经元(perceptron neuron),因为对于每个输入xi,其都有与输入相关的权重wi。权重表明了输入在决策过程中的重要性。来自sigmoid的输出不同于感知机模型,其输出不是0或1,而是一个介于0到1之间的实数值,可以解释为概率。最常用的sigmoid 函数是逻辑函数,它具有“ S”形曲线的特征。

Sigmoid神经元标注(逻辑函数)

学习算法

学习算法的目标是确定参数(w和b)的最佳可能值,以使模型的整体损失(平方误差损失)尽可能最小化。

 

对w和b进行随机初始化。然后,对数据中的所有观测值进行迭代。使用sigmoid函数找到每个观测值相应的预测结果,并计算均方误差损失。基于损失值,将更新权重,以使在新参数下模型的整体损失将小于模型的当前损失。

Sigmoid神经元类

在开始分析梯度下降算法的不同变体之前,将在名为SN的类中构建模型。

class SN:

#constructor

def __init__(self, w_init, b_init, algo):

self.w = w_init

self.b = b_init

self.w_h = []

self.b_h = []

self.e_h = []

self.algo = algo

#logistic function

def sigmoid(self, x, w=None, b=None):

if w is None:

w = self.w

if b is None:

b = self.b

return 1. / (1. + np.exp(-(w*x + b)))

#loss function

def error(self, X, Y, w=None, b=None):

if w is None:

w = self.w

if b is None:

b = self.b

err = 0

for x, y in zip(X, Y):

err += 0.5 * (self.sigmoid(x, w, b) - y) ** 2

return err

def grad_w(self, x, y, w=None, b=None):

if w is None:

w = self.w

if b is None:

b = self.b

y_pred = self.sigmoid(x, w, b)

return (y_pred - y) * y_pred * (1 - y_pred) * x

def grad_b(self, x, y, w=None, b=None):

if w is None:

w = self.w

if b is None:

b = self.b

y_pred = self.sigmoid(x, w, b)

return (y_pred - y) * y_pred * (1 - y_pred)

def fit(self, X, Y,

epochs=100, eta=0.01, gamma=0.9, mini_batch_size=100, eps=1e-8,

beta=0.9, beta1=0.9, beta2=0.9

):

self.w_h = []

self.b_h = []

self.e_h = []

self.X = X

self.Y = Y

if self.algo == 'GD':

for i in range(epochs):

dw, db = 0, 0

for x, y in zip(X, Y):

dw += self.grad_w(x, y)

db += self.grad_b(x, y)

self.w -= eta * dw / X.shape[0]

self.b -= eta * db / X.shape[0]

self.append_log()

elif self.algo == 'MiniBatch':

for i in range(epochs):

dw, db = 0, 0

points_seen = 0

for x, y in zip(X, Y):

dw += self.grad_w(x, y)

db += self.grad_b(x, y)

points_seen += 1

if points_seen % mini_batch_size == 0:

self.w -= eta * dw / mini_batch_size

self.b -= eta * db / mini_batch_size

self.append_log()

dw, db = 0, 0

elif self.algo == 'Momentum':

v_w, v_b = 0, 0

for i in range(epochs):

dw, db = 0, 0

for x, y in zip(X, Y):

dw += self.grad_w(x, y)

db += self.grad_b(x, y)

v_w = gamma * v_w + eta *

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值