反向传播、梯度下降与学习率:深度学习中的优化艺术

news2024/12/27 7:15:12

目录

反向传播:神经网络的学习机制

梯度下降:优化算法的基石

学习率:平衡速度与稳定性的关键

学习率的调整策略

固定学习率

学习率衰减

自适应学习率

梯度消失与梯度爆炸

结语


在深度学习的领域中,构建一个有效的神经网络模型不仅需要精心设计的架构,还需要通过精确的参数调整来训练模型。本文将探讨反向传播、梯度下降以及学习率这三个核心概念,以及它们如何共同作用于深度学习模型的训练过程中。

反向传播:神经网络的学习机制

反向传播算法是深度学习中用于训练神经网络的核心算法。它通过计算损失函数相对于网络参数的梯度来实现参数的优化。具体来说,反向传播包括两个主要步骤:

  1. 前向传播:输入数据通过网络的每一层,直到输出层,计算出预测结果。这一过程涉及到将输入数据与网络权重相乘,并通过激活函数传递,最终生成输出。这个过程可以用以下代码表示:
import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

def initialize_parameters(layer_dims):
    params = {}
    for l in range(1, len(layer_dims)):
        params['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) * 0.01
        params['b' + str(l)] = np.zeros((layer_dims[l], 1))
    return params

def forward_propagation(X, params):
    caches = {}
    A = X
    for l in range(1, len(params) // 2 + 1):
        A_prev = A
        W = params['W' + str(l)]
        b = params['b' + str(l)]
        Z = np.dot(W, A_prev) + b
        A = sigmoid(Z)
        caches['A' + str(l-1)] = A_prev
        caches['Z' + str(l)] = Z
    return A, caches

# 假设我们有一个简单的两层网络,输入层到隐藏层,隐藏层到输出层
layer_dims = [2, 4, 1]  # 2个输入节点,4个隐藏节点,1个输出节点
params = initialize_parameters(layer_dims)
X = np.array([[1.0, 2.0]])  # 输入数据
Y = np.array([[0.6]])  # 真实标签

# 执行前向传播
A3, caches = forward_propagation(X, params)

在这段代码中,我们首先定义了sigmoid激活函数及其导数,然后初始化了网络参数。forward_propagation函数接受输入数据X和参数params,通过网络的每一层,计算出最终的输出A3和缓存中间结果caches。这个过程是深度学习中的基础,它允许我们根据输入数据计算出模型的预测。

  1. 反向传播:计算输出结果与真实标签之间的损失,然后根据这个损失计算每个参数的梯度。这个梯度告诉我们如何调整参数以减少损失。反向传播的过程可以用以下代码表示:
def compute_loss(A3, Y):
    m = Y.shape[1]
    cost = - (1 / m) * np.sum(Y * np.log(A3) + (1 - Y) * np.log(1 - A3))
    cost = np.squeeze(cost)  # 确保cost是标量
    return cost

def backward_propagation(params, caches, X, Y):
    grads = {}
    m = X.shape[1]
    A1 = caches['A1']
    A2 = caches['A2']
    A3 = caches['A3']
    W1 = params['W2']
    W2 = params['W3']

    dZ3 = A3 - Y
    grads['dW3'] = (1 / m) * np.dot(dZ3, A2.T)
    grads['db3'] = (1 / m) * np.sum(dZ3, axis=1, keepdims=True)

    dA2 = np.dot(W2.T, dZ3)
    dZ2 = dA2 * sigmoid_derivative(A2)
    grads['dW2'] = (1 / m) * np.dot(dZ2, A1.T)
    grads['db2'] = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)

    return grads

# 计算损失
cost = compute_loss(A3, Y)

# 执行反向传播
grads = backward_propagation(params, caches, X, Y)

在这段代码中,我们首先定义了损失函数compute_loss,它计算了预测输出A3和真实标签Y之间的均方误差。然后,backward_propagation函数根据损失计算每个参数的梯度,并存储在grads字典中。这个过程是深度学习中的关键,它允许我们了解如何调整模型参数以减少预测误差。

梯度下降:优化算法的基石

梯度下降是一种优化算法,用于找到函数的最小值。在深度学习中,这个函数通常是损失函数,它衡量模型预测与真实标签之间的差异。梯度下降的更新规则如下:

[ \theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla_\theta J(\theta) ]

其中,(\theta) 代表模型参数,(\eta) 是学习率,而 (\nabla_\theta J(\theta)) 是损失函数 (J) 相对于参数 (\theta) 的梯度。梯度下降通过迭代地更新参数来最小化损失函数。以下是梯度下降算法的简单实现:

def gradient_descent(params, grads, learning_rate):
    params_update = {}
    for key in params:
        params_update[key] = params[key] - learning_rate * grads[key]
    return params_update

# 假设我们的参数是权重和偏置
learning_rate = 0.01
params_update = gradient_descent(params, grads, learning_rate)

在这段代码中,gradient_descent函数接受当前参数params、梯度grads和学习率learning_rate,然后根据梯度下降的规则更新参数。这个过程是深度学习中的基础,它允许我们通过迭代地调整参数来优化模型。

学习率:平衡速度与稳定性的关键

学习率是梯度下降算法中的一个关键超参数,它决定了每次迭代更新参数时的步长。学习率的选择对模型的训练效果至关重要:

  • 过高的学习率可能导致模型在最小值附近“跳过”,甚至发散,无法收敛。这可以通过以下代码示例来说明:
high_learning_rate = 0.1
params = gradient_descent(params, grads, high_learning_rate)

在这段代码中,我们设置了一个较高的学习率high_learning_rate,并使用它来更新参数,这可能会导致模型训练不稳定。过高的学习率可能会导致模型在损失函数的最小值附近“跳过”,甚至发散,无法收敛到最小值。这是因为步长太大,导致模型在每次迭代时跳过了最优解。

  • 过低的学习率则会导致训练过程非常缓慢,可能陷入局部最小值,影响模型性能。这可以通过以下代码示例来说明:
low_learning_rate = 0.0001
params = gradient_descent(params, grads, low_learning_rate)

在这段代码中,我们设置了一个较低的学习率low_learning_rate,并使用它来更新参数,这可能会导致模型训练过程缓慢。过低的学习率可能会导致模型在每次迭代时只做微小的调整,这虽然可以避免跳过最小值,但同时也会导致训练过程非常缓慢,甚至可能陷入局部最小值,影响模型的性能。

因此,合理地调整学习率是训练深度学习模型的关键。学习率的选择需要平衡模型训练的速度和稳定性,以确保模型能够快速且准确地收敛到最优解。

学习率的调整策略

在训练深度学习模型时,学习率的调整对于优化模型性能至关重要。以下是一些常见的学习率调整策略:

固定学习率

固定学习率是最简单的策略,即在整个训练过程中保持学习率不变。这种方法适用于模型对学习率变化不敏感的情况,但在许多情况下可能不是最优选择。

fixed_learning_rate = 0.01
optimizer = optim.SGD(model.parameters(), lr=fixed_learning_rate)

学习率衰减

学习率衰减是一种常见的策略,它允许学习率随着训练的进行逐渐减小,以细化模型的参数调整。

def learning_rate_decay(learning_rate, decay_rate, epoch):
    return learning_rate / (1 + decay_rate * epoch)

# 假设衰减率是0.01,当前是第10个epoch
decay_rate = 0.01
current_epoch = 10
updated_learning_rate = learning_rate_decay(0.1, decay_rate, current_epoch)

自适应学习率

自适应学习率方法,如Adam、RMSprop等优化器,能够根据训练的进展动态调整每个参数的学习率。

optimizer = optim.Adam(model.parameters(), lr=0.001)

梯度消失与梯度爆炸

在深度神经网络中,梯度可能会因为反复乘以接近0或大于1的权重而变得非常小(梯度消失)或非常大(梯度爆炸)。这会影响学习率的选择和模型的训练稳定性。为了解决这些问题,研究者们提出了多种方法,如使用ReLU激活函数、Batch Normalization等技术。

结语

反向传播、梯度下降和学习率是深度学习中不可或缺的三个概念。它们共同构成了深度学习模型训练的基石。理解这些概念及其相互作用对于设计和训练有效的深度学习模型至关重要。随着深度学习技术的不断发展,对这些基础概念的深入理解和创新应用将推动人工智能领域取得更多的突破。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2251787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文笔记(五十九)A survey of robot manipulation in contact

A survey of robot manipulation in contact 文章概括摘要1. 引言解释柔顺性控制的概念:应用实例: 2. 需要接触操控的任务2.1 环境塑造2.2 工件对齐2.3 关节运动2.4 双臂接触操控 3. 接触操控中的控制3.1 力控制3.2 阻抗控制3.3 顺应控制 4. 接触操控中的…

881.救生艇

目录 题目过程 题目 给定数组 people 。people[i]表示第 i 个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。 返回 承载所有人所需的最小船数 。 过程 cla…

【汇编】逻辑指令

文章目录 一、逻辑运算指令(一)各逻辑运算指令格式及操作(1)逻辑非指令 NOT(2)逻辑与指令 AND(3)逻辑或指令 OR(4)异或指令 XOR(5)测试…

网页开发的http基础知识

请求方式-GET:请求参数在请求行中,没有请求体,如:/brand/findAll?nameoPPo&status1。GET请求大小在浏览器中是有限制的请求方式-POST:请求参数在请求体中,POST请求大小是没有限制的 HTTP请求&#xf…

如何做好一份技术文档

如何做好一份技术文档 以下是本人的一些微不足道的经验,希望可以与大家互相交流学习 方向一:技术文档的规划布局 确定整体架构 创建一份优秀技术文档的第一步是规划其整体架构。一个好的架构应能引导读者理解文档的内容,同时提供一个逻辑清…

Springboot——SseEmitter流式输出

文章目录 前言SseEmitter 简介测试demo注意点异常一 ResponseBodyEmitter is already set complete 前言 最近做AI类的开发,看到各大AI模型的输出方式都是采取的一种EventStream的方式实现。 不是通常的等接口处理完成后,一次性返回。 而是片段式的处理…

Java 虚拟机:承载 Java 生态的神奇魔盒

在软件开发的世界里,Java 虚拟机(JVM)就像一位智慧的管家,默默守护着 Java 生态系统的运行。它不仅让 Java 实现了"一次编写,到处运行"的梦想,更是成为了多种编程语言的运行平台。让我们一起走进…

sqlmap详细使用

SQLmap使用详解 SQLmap(常规)使用步骤 1、查询注入点 python sqlmap.py -u http://127.0.0.1/sqli-labs/Less-1/?id12、查询所有数据库 python sqlmap.py -u http://127.0.0.1/sqli-labs/Less-1/?id1 --dbs3、查询当前数据库 python sqlmap.py -u htt…

【Linux】Linux2.6内核进程调度队列与调度原理

目录 一、进程管理中的部分概念二、寄存器三、进程切换四、Linux2.6内核进程调度队列与调度原理结尾 一、进程管理中的部分概念 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务&#…

Qt 详解QRubberBand

文章目录 QRubberBand 简介前言 QRubberBand 的作用QRubberBand 的主要功能QRubberBand 的常用方法QRubberBand 的典型应用场景示例代码总结 QRubberBand 简介 前言 在 Qt 中,QRubberBand 是一个非常实用的控件,它通常用于图形界面中的“选择区域”功能…

python股票数据分析(Pandas)练习

需求: 使用pandas读取一个CSV文件,文件内容包括股票名称、价格和交易量。完成以下任务: 找出价格最高的股票; 计算总交易量; 绘制价格折线图。 代码实现: import pandas as pd import matplotlib.pyplot …

Jenkins Nginx Vue项目自动化部署

目录 一、环境准备 1.1 Jenkins搭建 1.2 NVM和Nodejs安装 1.3 Nginx安装 二、Jenkins配置 2.1 相关插件安装 2.2 全局工具安装 2.3 环境变量配置 2.4 邮箱配置(构建后发送邮件) 2.5 任务配置 三、Nginx配置 3.1 配置路由转发 四、部署项目 …

JUnit介绍:单元测试

1、什么是单元测试 单元测试是针对最小的功能单元编写测试代码(Java 程序最小的功能单元是方法)单元测试就是针对单个Java方法的测试。 2、为什么要使用单元测试 确保单个方法运行正常; 如果修改了代码,只需要确保其对应的单元…

乘积求导法则、除法求导法则和链式求导法则

乘积求导法则、除法求导法则和链式求导法则 1. Constant multiples of functions (函数的常数倍)2. Sums and differences of functions (函数和与函数差)3. Products of functions via the product rule (通过乘积法则求积函数的导数)4. Quotients of functions via the quoti…

飞塔防火墙只允许国内IP访问

飞塔防火墙只允许国内IP访问 方法1 新增地址对象,注意里面已经细分为中国内地、中国香港、中国澳门和中国台湾 方法2 手动新增国内IP的对象组,目前好像一共有8632个,每个对象最多支持600个IP段

深度学习 | pytorch + torchvision + python 版本对应及环境安装

Hi,大家好,我是半亩花海。要让一个基于 torch 框架开发的深度学习模型正确运行起来,配置环境是个重要的问题,本文介绍了 pytorch、torchvision、torchaudio 及 python 的对应版本以及环境安装的相关流程。 目录 一、版本对应 二…

JVM:即时编译器,C2 Compiler,堆外内存排查

1,即时编译器 1.1,基本概念 常见的编译型语言如C,通常会把代码直接编译成CPU所能理解的机器码来运行。而Java为了实现“一次编译,处处运行”的特性,把编译的过程分成两部分,首先它会先由javac编译成通用的…

5G学习笔记之随机接入

目录 1. 概述 2. MSG1 2.1 选择SSB 2.2 选择Preamble Index 2.3 选择发送Preamble的时频资源 2.4 确定RA-RNTI 2.5 确定发送功率 3. MSG2 4. MSG3 5. MSG4 6. 其它 6.1 切换中的随机接入 6.2 SI请求的随机接入 6.3 通过PDCCH order重新建立同步 1. 概述 随机接入…

B站狂神说Mybatis+Spring+SpringMVC整合理解(ssm框架整合)

文章目录 0.写在前面(对mybatis,spring的理解)(不看可跳过)0.1 为什么需要mybatis0.2 为什么需要spring0.3为什么需要springmvc 1.新建ssmbuild数据库2.新建Maven项目3.初始化步骤3.1 配置下载maven依赖,构建资源导出3.2 连接数据库3.3建包&a…

JS的魔法三角:constructor、prototype与__proto__

在JavaScript中,constructor、prototype和__proto__是与对象创建和继承机制紧密相关的三个概念。理解它们之间的关系对于掌握JavaScript的面向对象编程至关重要。下面将详细介绍这个魔法三角: 1. constructor 定义:constructor是一个函数&am…