当前位置: 首页 > news >正文

深入浅出梯度下降与反向传播

文章目录

  • 1. 前言
  • 2. 基本概念
    • 2.1 一元函数的导数
    • 2.2 偏导数
    • 2.3 方向导数
    • 2.4 梯度
    • 2.5 均方误差
  • 3. 梯度下降
    • 3.1 梯度下降的公式
    • 3.2 梯度下降的类型(优化器)
  • 4. 反向传播
    • 4.1 反向传播的基本步骤
    • 4.2 反向传播的数学推导
  • 5. 实战
    • 5.1 手动求导
    • 5.2 自动求导
    • 5.3 过程可视化

1. 前言

  在深度学习中,梯度下降和反向传播是两个至关重要的概念。它们共同作用于优化神经网络,使其能够从数据中学习到有用的模式。尽管它们是深度学习的核心,但很多人对这两个概念仍然感到困惑。本博客将深入讲解梯度下降和反向传播的基本原理,并通过一个简单的示例来加以说明。

2. 基本概念

2.1 一元函数的导数

  如果有一个函数 f ( x ) f(x) f(x),它的导数 f ′ ( x ) f^′(x) f(x) 给出了函数在点 x 0 x_0 x0 处沿着 x x x 轴的变化速率,即:
f ′ ( x 0 ) = lim ⁡ Δ x → 0 f ( x 0 + Δ x ) − f ( x 0 ) Δ x f ^\prime (x_0) = \lim_{\Delta x \to 0} \frac {f(x_0 + \Delta x) - f(x_0)} {{\Delta x}} f(x0)=Δx0limΔxf(x0+Δx)f(x0)  这个导数告诉我们,沿着 x x x轴方向,函数的变化快慢情况。

2.2 偏导数

  对于多变量函数 f ( x 1 , x 2 , … , x n ) f(x_1, x_2, \dots, x_n) f(x1,x2,,xn),偏导数描述了函数在某一维度(即某个变量)上变化的速率。例如,函数 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2 的偏导数为:
∂ f ∂ x = 2 x , ∂ f ∂ y = 2 y \frac{\partial f}{\partial x} = 2x, \quad \frac{\partial f}{\partial y} = 2y xf=2x,yf=2y  这些偏导数分别表示函数在 x x x轴方向和 y y y轴方向的变化速率。

2.3 方向导数

  描述了一个多变量函数在某一点沿任意给定方向的变化率。对于一个函数 f ( x 1 , x 2 , … , x n ) f(x_1, x_2, \dots, x_n) f(x1,x2,,xn),在点 x 0 \mathbf{x_0} x0 处沿着单位向量 v \mathbf{v} v 方向的方向导数表示为:
D v f ( x 0 ) = ∇ f ( x 0 ) ⋅ v D_{\mathbf{v}} f(\mathbf{x_0}) = \nabla f(\mathbf{x_0}) \cdot \mathbf{v} Dvf(x0)=f(x0)v其中, ∇ f ( x 0 ) \nabla f(\mathbf{x_0}) f(x0) 是函数在点 x 0 \mathbf{x_0} x0 的梯度。
  方向导数的几何意义:方向导数给出了函数在某一点沿某个方向的变化速率。它可以看作是沿着某个方向的切线变化率,而不仅仅是沿坐标轴的变化率。
  即在某一点 x 0 \mathbf{x_0} x0,如果我们沿着某个方向 v \mathbf{v} v 走,方向导数告诉我们,沿着这个方向走时,函数值变化的快慢。如果方向导数为正,说明函数值在增加;如果为负,说明函数值在减少;如果为零,说明函数值在这个方向上没有变化。

2.4 梯度

  在一个多变量的标量函数 f ( x 1 , x 2 , … , x n ) f(x_1, x_2, \dots, x_n) f(x1,x2,,xn) 中,梯度是一个向量,表示函数在某一点的最速上升方向。梯度不仅告诉我们函数的变化率,还告诉我们该变化率最大的方向。具体来说,梯度是函数的所有偏导数组成的向量:
∇ f ( x 1 , x 2 , … , x n ) = ( ∂ f ∂ x 1 , ∂ f ∂ x 2 , … , ∂ f ∂ x n ) \nabla f(x_1, x_2, \dots, x_n) = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \dots, \frac{\partial f}{\partial x_n} \right) f(x1,x2,,xn)=(x1f,x2f,,xnf)  梯度的方向:梯度的方向指向函数值增加最快的方向。
  梯度的大小:梯度的模长(即向量的长度)表示沿着这个方向,函数变化的速率。

  可以把梯度看作是一个“指示器”,它告诉我们在某一点,函数增长最快的方向。换句话说,梯度指向了“上坡”的方向。

2.5 均方误差

  均方误差(Mean Squared Error, MSE),是一种常用的衡量模型预测值与实际值之间差异的指标,尤其是回归任务中,MSE的计算公式如下:
M S E = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 MSE = \frac {1} {n} \sum _{i=1} ^ n (y_i - \hat y_i) ^ 2 MSE=n1i=1n(yiy^i)2其中, n n n是样本数量, y i y_i yi是第 i i i个样本的真实值, y ^ i \hat y_i y^i是模型对第 i i i个样本的预测值。

  均方误差也叫做最小二乘法。

3. 梯度下降

  梯度下降(Gradient Descent, GD)是一种优化算法,用于最小化(或最大化)一个函数,通常用来训练机器学习模型。在神经网络中,我们的目标是通过调整模型的参数(例如权重和偏置)来最小化损失函数。损失函数衡量了模型的预测与实际标签之间的差异,目标是让这个损失函数的值尽可能小。
  梯度下降的核心思想是,沿着损失函数的梯度(偏导数)下降,不断更新参数,直到达到最小值。

3.1 梯度下降的公式

  梯度下降的更新规则如下:
θ = θ − η ⋅ ∇ θ L ( θ ) \theta = \theta - \eta \cdot \nabla_\theta L(\theta) θ=θηθL(θ)其中:
   θ \theta θ 是模型的参数(例如权重和偏置)。
   η \eta η 是学习率(learning rate),控制每次更新的步长。
   ∇ θ L ( θ ) \nabla_\theta L(\theta) θL(θ) 是损失函数 L L L 关于参数 θ \theta θ 的梯度。
  梯度 ∇ θ L ( θ ) \nabla_\theta L(\theta) θL(θ) 告诉我们,沿着哪个方向更新参数能使损失函数下降得更快。

3.2 梯度下降的类型(优化器)

  1. 批量梯度下降(Batch Gradient Descent):每次使用整个数据集来计算梯度和更新参数。虽然准确性高,但计算开销大,尤其是在数据量很大的时候。
  2. 随机梯度下降(Stochastic Gradient Descent, SGD):每次只用一个样本来计算梯度和更新参数。虽然更新速度快,但可能会导致参数更新不稳定。
  3. 小批量梯度下降(Mini-Batch Gradient Descent):每次使用数据集中的一个小批量样本来计算梯度和更新参数。这种方法结合了批量和随机梯度下降的优点。
  当然,还有很多类型的优化,比如AdamRMSpropAdaW等,这里不再细述。

4. 反向传播

  反向传播(Back Propagation, BP)是用于计算神经网络中每一层的梯度的算法。它是梯度下降的一部分,特别用于计算和传播每个参数对损失函数的贡献。
  反向传播算法依赖于链式法则(Chain Rule),通过链式法则可以将损失函数对模型参数的梯度逐层传播回去,从而更新每一层的参数。

  即从输出层一步步传播到输入层。

4.1 反向传播的基本步骤

假设我们有一个包含多个层的神经网络,每一层都有权重 W W W 和偏置 b b b。反向传播的步骤如下:
  1. 前向传播:从输入层开始,将输入数据传递到输出层,并计算出预测值。
  2. 计算损失:根据模型的输出与真实标签计算损失函数。
  3. 反向传播:
    (1)计算输出层的梯度,即损失函数关于输出的偏导数。
    (2)逐层计算隐藏层的梯度,即损失函数关于每一层的输入、权重和偏置的偏导数。
  4. 更新权重和偏置:根据梯度下降规则更新每一层的权重和偏置。

4.2 反向传播的数学推导

  假设神经网络有两层,每层的输出分别为 a 1 a_1 a1 a 2 a_2 a2,损失函数为 L L L。反向传播的目标是计算 ∂ L ∂ W 1 \frac{\partial L}{\partial W_1} W1L ∂ L ∂ W 2 \frac{\partial L}{\partial W_2} W2L,即每一层权重的梯度。
  1. 输出层梯度计算:
∂ L ∂ a 2 = ∂ L ∂ y ⋅ ∂ y ∂ a 2 \frac{\partial L}{\partial a_2} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial a_2} a2L=yLa2y其中 y y y是输出层的预测值。
  2. 隐藏层梯度计算:
∂ L ∂ a 1 = ∂ L ∂ a 2 ⋅ ∂ a 2 ∂ a 1 \frac{\partial L}{\partial a_1} = \frac{\partial L}{\partial a_2} \cdot \frac{\partial a_2}{\partial a_1} a1L=a2La1a2然后,我们使用链式法则计算每一层的权重梯度。
  3. 参数更新:根据计算出来的梯度使用梯度下降更新权重和偏置。

5. 实战

5.1 手动求导

  我们来构建一个简单的神经网络,做一个线性回归:

在这里插入图片描述

  模型的输入为2维数据,输出为1维数据,该模型的函数表达式可以表示为:
y ∗ = w 5 ⋅ ( w 1 ⋅ x 1 + w 3 ⋅ x 2 ) + w 6 ⋅ ( w 2 ⋅ x 1 + w 4 ⋅ x 2 ) y^* = w_5 \cdot (w_1 \cdot x_1 + w_3 \cdot x_2) + w_6 \cdot (w_2 \cdot x_1 + w_4 \cdot x_2) y=w5(w1x1+w3x2)+w6(w2x1+w4x2)  我们使用MSE来作为损失函数,来优化我们的网络,即
L o s s = 1 n ∑ i = 1 n ( y i − y i ∗ ) 2 Loss = \frac {1} {n} \sum _{i=1} ^ n (y_i - y^*_i) ^ 2 Loss=n1i=1n(yiyi)2
  假设初始时模型的权重为:
w 1 = 1.0 , w 2 = 0.5 , w 3 = 0.5 , w 4 = 0.7 w_1=1.0,w_2=0.5,w_3=0.5,w_4=0.7 w1=1.0w2=0.5w3=0.5w4=0.7 w 5 = 1.0 , w 6 = 2.0 w_5=1.0,w_6=2.0 w5=1.0w6=2.0  已知一个样本数据:
x 1 = 0.5 , x 2 = 1.0 , y = 0.8 x_1=0.5,x_2=1.0,y=0.8 x1=0.5x2=1.0y=0.8  按照上述公式,计算一次前向传播,得到 y ∗ = 2.9 y^*=2.9 y=2.9,与真实值 y y y 的偏差可以通过 l o s s loss loss 计算得到, l o s s = ( y − y ∗ ) 2 = 4.41 loss = (y - y^*) ^ 2 = 4.41 loss=(yy)2=4.41。然后我们通过梯度下降的方式来更新 w 5 w_5 w5,需要先计算出在点 ( x 1 , x 2 ) (x_1,x_2) (x1,x2)的梯度:
∇ = ∂ L ∂ w 1 = ∂ L ∂ y ∗ ⋅ ∂ y ∗ ∂ w 5 \nabla = \frac {\partial L} {\partial w_1} = \frac {\partial L} {\partial y^*} \cdot \frac {\partial y^*} {\partial w_5} =w1L=yLw5y ∂ L ∂ y ∗ = − 2 ( y − y ∗ ) = 4.2 \frac {\partial L} {\partial y^*} = -2 (y- y^*) = 4.2 yL=2(yy)=4.2 ∂ y ∗ ∂ w 5 = w 1 ⋅ x 1 + w 3 ⋅ x 2 = 1.0 \frac {\partial y^*} {\partial w_5} = w_1 \cdot x_1 + w_3 \cdot x_2 = 1.0 w5y=w1x1+w3x2=1.0
  所以梯度为:
∂ L ∂ w 1 = 4.2 \frac {\partial L} {\partial w_1} = 4.2 w1L=4.2  假设,学习率为 0.01 0.01 0.01,根据梯度下降算法 θ = θ − η ⋅ ∇ θ L ( θ ) \theta = \theta - \eta \cdot \nabla_{\theta} L(\theta) θ=θηθL(θ) 更新 w 5 w5 w5:
w 5 = w 5 − η ∂ L ∂ w 5 = 0.958 w_5 = w_5 - \eta \frac {\partial L} {\partial w_5} = 0.958 w5=w5ηw5L=0.958  同理,可以更新 w 1 w_1 w1
∂ y ∗ ∂ w 1 = w 5 x 1 = 0.5 \frac {\partial y^*} {\partial w_1} = w_5x_1 = 0.5 w1y=w5x1=0.5 ∂ L ∂ w 1 = ∂ L ∂ y ∗ ⋅ ∂ y ∗ ∂ w 1 = 2.1 \frac {\partial L} {\partial w_1} = \frac {\partial L} {\partial y^*} \cdot \frac {\partial y^*} {\partial w_1} = 2.1 w1L=yLw1y=2.1 w 1 = w 1 − η ∂ L ∂ w 1 = 0.979 w_1 = w_1 - \eta \frac {\partial L} {\partial w_1} = 0.979 w1=w1ηw1L=0.979

5.2 自动求导

  将上面模型的表达式形式化,即
y ∗ = ( x T ⋅ W h ) ⋅ W o y* = (x^T \cdot W_h) \cdot W_o y=(xTWh)Wo其中,
x = [ x 1 x 2 ] , W h = [ w 1 w 2 w 3 w 4 ] , W o = [ w 5 w 6 ] x = \begin{bmatrix} x_1 \\ x_2\end{bmatrix},W_h = \begin{bmatrix} w_{1} & w_{2} \\ w_{3} & w_{4} \end{bmatrix},W_o = \begin{bmatrix} w_{5} & w_{6} \end{bmatrix} x=[x1x2]Wh=[w1w3w2w4]Wo=[w5w6]  这样,我们就可以使用pytorch来构建上述神经网络了,具体如下:

# -*- coding: utf-8 -*-
# Author  : liyanpeng
# Email   : yanpeng.li@cumt.edu.cn
# Datetime: 2024/11/29 17:38
# Filename: chain_rule.py
import torch
import torch.nn as nn
import torch.optim as optimdef func_y():x1 = torch.tensor(0.5, dtype=torch.float32)x2 = torch.tensor(1.0, dtype=torch.float32)w1 = torch.tensor(1.0, dtype=torch.float32)w2 = torch.tensor(0.5, dtype=torch.float32)w3 = torch.tensor(0.5, dtype=torch.float32)w4 = torch.tensor(0.7, dtype=torch.float32)w5 = torch.tensor(1.0, dtype=torch.float32)w6 = torch.tensor(2.0, dtype=torch.float32)y = w5 * (w1 * x1 + w2 * x2) + w6 * (w3 * x1 + w4 * x2)print(y)class SimpleNeuralNetwork(nn.Module):def __init__(self):super().__init__()self.linear1 = nn.Linear(in_features=2, out_features=2, bias=False)self.linear2 = nn.Linear(in_features=2, out_features=1, bias=False)self.linear1.weight.data = torch.tensor([[1.0, 0.5], [0.5, 0.7]], dtype=torch.float32)self.linear2.weight.data = torch.tensor([[1.0, 2.0]], dtype=torch.float32)def forward(self, x):x = self.linear1(x)y = self.linear2(x)return ydef grad_hook(grad):print('grad:', grad[0][0])if __name__ == '__main__':x = torch.tensor([0.5, 1.0], dtype=torch.float32)y = torch.tensor(0.8, dtype=torch.float32)model = SimpleNeuralNetwork()criterion = nn.MSELoss()optimizer = optim.SGD(model.parameters(), lr=0.01)hook_list = []for name, param in model.named_parameters():if param.requires_grad:hook = param.register_hook(grad_hook)hook_list.append(hook)y_pred = model(x)loss = criterion(y_pred, y)optimizer.zero_grad()   # 清空梯度loss.backward()         # 反向传播optimizer.step()        # 更新权重for hook in hook_list:hook.remove()print('更新后的w1:', model.linear1.weight.data[0, 0])print('更新后的w5:', model.linear2.weight.data[0, 0])

  打印结果如下,与手动计算的结果一致:

grad: tensor(4.2000)
grad: tensor(2.1000)
更新后的w1: tensor(0.9790)
更新后的w5: tensor(0.9580)

5.3 过程可视化

  再加入一些可视化代码,看一下权重更新的轨迹:

# -*- coding: utf-8 -*-
# Author  : liyanpeng
# Email   : yanpeng.li@cumt.edu.cn
# Datetime: 2024/11/29 17:38
# Filename: chain_rule.py
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as npif __name__ == '__main__':x = torch.tensor([0.5, 1.0], dtype=torch.float32)y = torch.tensor(0.8, dtype=torch.float32)model = SimpleNeuralNetwork()criterion = nn.MSELoss()optimizer = optim.SGD(model.parameters(), lr=0.01)loss_list = []w1_list = []w2_list = []for epoch in range(5):y_pred = model(x)loss = criterion(y_pred, y)optimizer.zero_grad()   # 清空梯度loss.backward()         # 反向传播optimizer.step()        # 更新权重loss_list.append(loss.item())w1_list.append(model.linear1.weight.data[0, 0].item())w2_list.append(model.linear2.weight.data[0, 0].item())fig = plt.figure(figsize=(8, 6))# 3D曲面图和等高线图ax1 = fig.add_subplot(111, projection='3d')ax1.set_title("3D Loss Surface with Contours and Trajectory")# 将损失值、权重映射到X, Y, Z轴ax1.plot_trisurf(w1_list, w2_list, loss_list, cmap='viridis', alpha=0.7)# 生成网格数据,用于绘制等高线图w1_range = np.linspace(min(w1_list), max(w1_list), 100)w2_range = np.linspace(min(w2_list), max(w2_list), 100)W1, W2 = np.meshgrid(w1_range, w2_range)np.random.seed(42)x_train = np.random.rand(100, 2)noise = np.random.randn(100, 1)# f(x, y) = 2x^2 + y^2 - 0.7 + noisey_train = 2 * x_train[:, 0] * x_train[:, 0] + x_train[:, 1] * x_train[:, 1] - 0.7 + noise# 计算每个网格点的损失值loss_grid = np.zeros(W1.shape)for i in range(W1.shape[0]):for j in range(W1.shape[1]):model.linear1.weight.data[0, 0] = W1[i, j]model.linear2.weight.data[0, 0] = W2[i, j]y_pred = model(torch.tensor(x_train, dtype=torch.float32))loss_grid[i, j] = criterion(y_pred, torch.tensor(y_train, dtype=torch.float32)).item()# 绘制等高线图ax1.contour(W1, W2, loss_grid, levels=20, cmap='viridis', offset=min(loss_list))# 绘制权重更新轨迹ax1.plot(w1_list, w2_list, loss_list, 'k-', marker='o', markersize=5, label="Weight Update Trajectory")ax1.plot(w1_list, w2_list, [min(loss_list)] * len(w1_list), 'r-', marker='o', markersize=5, label="Trajectory on Contours")# 在等高线图上标记权重更新的坐标for i in range(len(w1_list)):ax1.text(w1_list[i], w2_list[i], min(loss_list),f'({w1_list[i]:.4f}, {w2_list[i]:.4f})',color='red', fontsize=8, ha='center', va='center')ax1.set_xlabel('Linear1 Weight (First Element)')ax1.set_ylabel('Linear2 Weight (First Element)')ax1.set_zlabel('Loss')ax1.legend()plt.tight_layout()plt.show()

  绘制的效果图如下:

在这里插入图片描述
  损失函数从右侧至左侧逐渐收敛,最右侧的点是我们第一次更新时 w 1 w_1 w1 w 2 w_2 w2的权重。

相关文章:

深入浅出梯度下降与反向传播

文章目录 1. 前言2. 基本概念2.1 一元函数的导数2.2 偏导数2.3 方向导数2.4 梯度2.5 均方误差 3. 梯度下降3.1 梯度下降的公式3.2 梯度下降的类型(优化器) 4. 反向传播4.1 反向传播的基本步骤4.2 反向传播的数学推导 5. 实战5.1 手动求导5.2 自动求导5.3…...

PLC(01)

一.职业规划 电路----------------->电工------------------>电气-------------------plc---------------------DCS--------------------> 机器人 二.交流电直流电的概念 1.交流电AC alternating current 大小方向随时间发生周期性变化 2.直流电 Direct current…...

如何通过本地部署的DIFY辅助学习算法(PS可以辅助帮你学习任何想学习的资料)

如何通过本地部署的DIFY辅助学习算法(PS可以辅助帮你学习任何想学习的资料 一 提升知识库的大小容量1.1 调大知识库的基础配置修改.env文件1.2 通过docker compose 重启加载最新配置1.3 重新上传知识库 二 搭建算法知识库的学习助手2.1 text embedding 模型对比2.1.1 如何选择合…...

深入探讨服务器虚拟化:架构、技术与应用

1. 引言 在现代IT基础设施中,服务器虚拟化已成为一种不可或缺的技术。它不仅提高了资源利用率,还增强了系统的灵活性和可管理性。随着企业对高效、灵活和可扩展IT环境的需求不断增加,服务器虚拟化技术的应用愈发广泛。本文将深入探讨服务器虚…...

C++笔记之尾后迭代器

C笔记之尾后迭代器 code review! 参考笔记 1.C笔记之尾后迭代器 2.C笔记之迭代器失效问题处理 在C中,尾后迭代器(通常称为 past-the-end iterator)是指指向容器中最后一个元素之后的位置的迭代器。它并不指向任何有效的元素,而是…...

2024年总结【第五年了】

2024年总结 北国绕院扫雪,南方围炉烹茶,且饮一杯无? 执笔温暖不曾起舞日子里的点点滴滴,誊写一段回忆,还以光阴一段副本。 那么你要听一支新故事吗?第五年总结的片碎。 衣单天寒,走趟流星孤骑&#xf…...

EasyExcel(环境搭建以及常用写入操作)

文章目录 EasyExcel环境搭建1.创建模块 easyexcel-demo2.引入依赖3.启动类创建 EasyExcel写1.最简单的写入1.模板2.方法3.结果 Write01.xlsx 2.指定字段不写入Excel1.模板2.方法3.结果 Write02.xlsx 3.指定字段写入excel1.模板2.方法3.结果 Write03.xlsx 4.按照index顺序写入ex…...

JVM类加载器

什么是类加载器 类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。 类加载器只参与加载过程中的字节码获取并加载到内存这一部分 类加载器的分类 类加载器分为两类,一类是Java代码中实现的&#xff0…...

druid连接池参数配置

最近发现生产环境经常有数据库连接超时的问题,排查发现是druid连接池参数设置不合理导致 总结问题如下: 为了防止僵尸连接,k8s ipvs做了连接超时限制,如果TCP连接闲置超过900s(15分钟),客户端再尝试通过这个连接去发起…...

【机器学习】Kaggle实战信用卡反欺诈预测(场景解析、数据预处理、特征工程、模型训练、模型评估与优化)

构建信用卡反欺诈预测模型 建模思路 本项目需解决的问题 本项目通过利用信用卡的历史交易数据,进行机器学习,构建信用卡反欺诈预测模型,提前发现客户信用卡被盗刷的事件。 项目背景 数据集包含由欧洲持卡人于2013年9月使用信用卡进行交的…...

Linux(Ubuntu)下ESP-IDF下载与安装完整流程(2)

接前一篇文章:Linux(Ubuntu)下ESP-IDF下载与安装完整流程(1) 本文主要看参考官网说明,如下: 快速入门 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 Linux 和 macOS 平台工具链的标准设置 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 一、安装准备 1. Linux用...

SpringBoot3 快速启动框架

文章目录 1 SpringBoot3 介绍 1.1 SpringBoot3 简介1.2 快速入门1.3 入门总结 2 SpringBoot3 配置文件 2.1 统一配置管理概述2.2 属性配置文件使用2.3 YAML配置文件使用2.4 批量配置文件注入2.5 多环境配置和使用 3 SpringBoot 整合 springMVC 3.1 实现过程3.2 web相关配置3.3…...

Enum枚举类,静态常量类,静态类的区别

Enum枚举类,静态常量类,静态类的区别 Enum枚举类静态常量类静态类Enum枚举类,静态常量类,静态类的区别 Enum枚举类 Enum枚举类的结构组成和用法使用可以查阅 Enum枚举类与静态变量和静态数组的区别 静态常量类 public class St…...

解锁专利世界的钥匙 ——famiwei 网

在知识经济的时代,专利作为创新成果的重要体现,无论是对于企业、科研人员乃至整个社会的发展都具有举足轻重的意义。而在众多的专利网站中,famiwei 网为用户提供了一个全面、精准且高效的专利信息交流与服务的舞台。 一、卓越功能,开启专利探索之门 famiwei 网拥有一套强大的专…...

金融租赁系统的创新与发展推动行业效率提升

金融租赁系统的技术升级与创新 在当今快速发展的金融市场中,金融租赁系统的技术升级与创新充满了无限可能。想象一下,传统的租赁方式就像一位沉闷的老师,而新兴技术就如同一位活泼的学生,不断追求新鲜事物。通过自动化、人工智能…...

SQL-Server链接服务器访问Oracle数据

SQL Server 链接服务器访问 Oracle 离线安装 .NET Framework 3.5 方法一:使用 NetFx3.cab 文件 下载 NetFx3.cab 文件,并将其放置在 Windows 10 系统盘的 C:Windows 文件夹中。 以管理员身份运行命令提示符,输入以下命令并回车: …...

Sonic:开源Go语言开发的高性能博客平台

Sonic:一个用Go语言开发的高性能博客平台 简介 Sonic,一个以其速度如声速般快速而命名的博客平台,是一个用Go语言开发的高性能博客系统。正如其名字所暗示的,Sonic旨在提供一个简单而强大的博客解决方案。这个项目受到了Halo项目…...

【react】常见的性能优化 1

目录 常见的 React 性能优化手段 1. 使用 useMemo 和 useCallback 缓存数据和函数 2. 使用 React.memo 缓存组件 3. 组件懒加载 4. 合理使用 key 5. 在组件销毁时清除定时器/事件 6. 使用 Suspense 和 Lazy 拆分组件 7. 使用 Fragment 避免额外标记 8. 避免使用内联函…...

SpringCloud源码-openFeign

LoadBalancer默认只有nacos服务发现器 openFeign与springcloud loadbalancer的结合点...

QLabel添加点击处理

在QLabel中添加点击事件有三种方式,分别是 使用LinkActivated信号连接槽函数(有缺限)注册事件分发器eventFilter创建类重写鼠标事件 1. 使用LinkActivated信号 QLabel类中有LinkActivated信号,是当标签中的链接被点击的时候触发…...

Markdown表格的使用

Markdown表格的使用 前言语法详解定义表格设定表格列内容的对齐方式 使用场景及实例小结其他文章快来试试吧 Markdown表格的使用👈点击这里也可查看 前言 表格通常作为一种布局的形式,用于结构化的数据展示。 Markdown表格包含三个部分:表头…...

时间序列预测算法介绍

时间序列预测是根据时间序列数据的历史变化规律,对未来数据进行预测的方法。在给定的代码中,使用的是自回归(AR)模型中的AR(4)模型来预测光伏功率。以下将详细解释这种算法: 1. 自回归模型(AR模型&#xf…...

加密流量TLS1.2 和TLS1.3的握手区别

加密流量TLS1.2 和TLS1.3的握手区别 TLS1.2 握手均是明文 1)Client Hello 2)Server Hello 3)Certificate TLS1.3 握手中Client Hello是明文,而Server Hello中Extensions以及后面的握手信息不可见 1)Client Hello…...

MySQL数据库——主从复制

本文详细介绍 MySQL的主从复制,从原理到配置再到同步过程。 文章目录 简介核心组件主从复制的原理作用主从复制的线程模型主从复制的模式形式复制的方式设计复制机制主从复制的配置步骤优化和改进总结 简介 MySQL 主从复制(Replication)是一…...

详细说明嵌入式linux中bootcmd与bootargs差异

bootcmd 和 bootargs 是在嵌入式系统开发,特别是基于U-Boot(一个广泛应用的开源引导加载程序)环境中常见的两个重要参数,它们的区别如下: 功能用途 bootcmd: 定义:bootcmd 是U-Boot中的一个环…...

【UE5】UnrealEngine源码构建2:windows构建unreal engine 5.3.2

参考大神知乎的文章:UE5 小白也能看懂的源码编译指南 据说会耗费400G的空间。 代码本身并不大,可能是依赖特别多,毕竟看起来UE啥都能干,核心还是c++的, 【UE5】UnrealEngine源码构建1:tag为5.3.2源码clone 本着好奇+ 学习的态度,想着也许有机会能更为深入的熟悉UE的机制…...

【YOLO算法改进】ALSS-YOLO:无人机热红外图像|野生动物小目标检测

目录 论文信息 论文创新点 1.自适应轻量通道分割和洗牌(ALSS)模块 2.轻量坐标注意力(LCA)模块 3.单通道聚焦模块 4.FineSIOU损失函数 摘要 架构设计 轻量高效网络架构 - ALSS模块 LCA模块 单通道聚焦模块 损失函数优…...

时间序列预测算法---LSTM

文章目录 一、前言1.1、深度学习时间序列一般是几维数据?每个维度的名字是什么?通常代表什么含义?1.2、为什么机器学习/深度学习算法无法处理时间序列数据?1.3、RNN(循环神经网络)处理时间序列数据的思路?1.4、RNN存在哪些问题?…...

【QT】:QT图形化界面概述

Qt背景介绍 1.1 什么是Qt Qt 是⼀个跨平台的C图形⽤⼾界⾯应⽤程序框架。它为应⽤程序开发者提供了建⽴艺术级图形 界⾯所需的所有功能。它是完全⾯向对象的,很容易扩展。Qt为开发者提供了⼀种基于组件的开发模 式,开发者可以通过简单的拖拽和组合来实现…...

[论文笔记]Representation Learning with Contrastive Predictive Coding

引言 今天带来论文 Representation Learning with Contrastive Predictive Coding的笔记。 提出了一种通用的无监督学习方法从高维数据中提取有用表示,称为对比预测编码(Contrastive Predictive Coding,CPC)。使用了一种概率对比损失, 通过使用负采样使…...

Redis相关

Redis相关 什么是redis?redis可以干什么? Redis是一个c语言编写的nosql数据库(不仅仅是sql,泛指非关系型数据库,一般把非关系型数据库称为nosql数据库),数据在内存中以键值对的形式存储,读写速度快,提供数据持久化方式. 常常被广泛应用到做缓存 Redis使用场景 1.缓存 2…...

【优选算法】Binary-Blade:二分查找的算法刃(上)

文章目录 1.概念解析2.二分查找的简单模版3.二分查找的进阶模版4.x的平方根5.搜索插入位置希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 本篇是优选算法之二分查找算法,该算法是一种高效的在有序数组中查找特定元素的搜索算法 1.概…...

Docker--Docker Network(网络)

Docker Network(网络)是Docker容器之间和容器与外部网络之间的通信和连接的一种机制。以下是对Docker Network的详细解释: 一、Docker网络的重要性 Docker容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作…...

转化率是衡量网页设计的一个重要指标,请问如何做?

AARRR是互联网产品运营中一个非常重要的模型,这些模型的每一个步骤都涉及到转化率问题,那么AARRR是是什么呢?转化漏斗是什么吗?转化率为什么重要?设计师在做网页设计的时候,如何提升转化率呢?本…...

运维工具之syncthing工具的安装和使用

一、syncthing工具简介 Syncthing是一款开源的文件同步工具,采用Go语言编写。它支持在多个操作系统上运行,包括Windows、macOS和Linux,以及BSD、Solaris和Android等。以下是对这款软件的详细介绍,主要功能: 实时文件同…...

国产数据库-崖山使用介绍

本文档基于崖山数据库23.3 个人版本,单机(主备)部署模式的情况下的使用介绍。 数据库实例状态: NOMOUNT:仅读取参数文件,不加载数据库 MOUNT:读取控制文件,加载数据库&#xff…...

primevue的<Menu>组件

1.使用场景 2.代码 1.给你的menu组件起个引用名 2.<Menu>组件需要一个MenuItem[] 3.你要知道MenuItem[ ]的特殊的数据格式&#xff0c;就像TreeNode[ ]一样&#xff0c;数据格式不对是不渲染的。。。。 常用的属性就这几种&#xff0c;js语言和java不一样&#xff0c;J…...

【玩转23种Java设计模式】行为型模式篇:备忘录模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

便捷饭店点餐小程序的设计与实现ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…...

微信小程序Uniapp

使用命令行创建项目&#xff08;vuets&#xff09; npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project然后用HBX打开项目 再安装依赖 npm i 再运行开发版本&#xff0c;生成dist目录 pnpm dev:mp-weixin 注意要设置APPid 再用微信小程序打开...

Android GameActivity(NativeActivity)读写文件

最近研究native android相关内容&#xff0c;其中最棘手的就是文件读写问题&#xff0c;最主要的是相关的文档很少。这里写下我所知道的方法。 由于本人使用的是Android14[arm64-v8a]版本的设备,能访问的路径相当有限&#xff0c;如果想要访问更多的路径&#xff0c;就不得不申…...

《计算机网络A》单选题-复习题库解析-2

目录 51、下列关于以太网网卡地址特点的说法中&#xff0c;不正确的是&#xff08; &#xff09;。 52、当一个Web Browser向一个使用标准服务器端口的Web Server提出请求时&#xff0c;那么在服务返回的响应包中&#xff0c;所使用的源端口是&#xff08; &#xff0…...

GPU 进阶笔记(二):华为昇腾 910B GPU

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 1 术语 1.1 与 NVIDIA 术语对应关系1.2 缩写2 产品与机器 2.1 GPU 产品2.2 训练机器 底座 CPU功耗操作系统2.3 性能3 实探&#xff1a;鲲鹏底座 8*910B GPU 主机 3.1 CPU3.2 网卡和网络3.3 GPU 信息 3.3…...

如何利用 ClickHouse 实现高级分析:MySQL 到 ClickHouse 实时数据同步指南

在数据驱动的时代&#xff0c;企业必须依靠先进的数据分析能力来提升竞争力。随着数据量的激增和业务需求的复杂化&#xff0c;传统的关系型数据库已经无法满足高效处理和实时分析的需求。ClickHouse 作为一款高性能的列式数据库&#xff0c;凭借其卓越的查询性能和可扩展性&am…...

Python读取TIF文件

在Python中&#xff0c;逐帧读取TIFF文件&#xff08;尤其是多页TIFF文件&#xff09;可以使用tifffile库或Pillow库。以下是两种方法的示例&#xff1a; 方法 1&#xff1a;使用 tifffile 逐帧读取 tifffile 是一个专门用于处理TIFF文件的库&#xff0c;支持多页TIFF文件的逐…...

vue3+ts+element-plus 表单el-form取消回车默认提交

问题描述&#xff1a;在表单el-form中的el-input中按回车后&#xff0c;页面会刷新&#xff0c;url也会改变&#xff0c; 回车前&#xff1a; 回车后&#xff1a; 相关代码&#xff1a; 解决方法1&#xff1a;在 el-form 上阻止默认的 submit 事件&#xff0c;增加 submit.pre…...

面试经典150题——滑动窗口

文章目录 1、长度最小的子数组1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、无重复字符的最长子串2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、串联所有单词的子串3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、最小覆盖子串4.1 题目链接4.2 题目描…...

目标检测之DINO详解

相关链接 论文:[2203.03605] DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detectionhttps://arxiv.org/abs/2203.03605 代码:...

Linux指令

1. 将一个文件夹中的前5000张图片移动到另一个文件夹 可以使用 find 和 mv 命令来实现将一个文件夹 folder1 中的前 5000 张 jpg 图片移动到另一个文件夹 folder2。下面是具体的步骤&#xff1a; 首先&#xff0c;确保 folder2 存在。如果不存在&#xff0c;可以使用 mkdir 命…...

groovy:多线程 简单示例

在Groovy中&#xff0c;多线程编程与Java非常相似&#xff0c;因为Groovy运行在Java虚拟机&#xff08;JVM&#xff09;上&#xff0c;并且可以利用Java的所有并发工具。以下是一些在Groovy中实现多线程编程的方法&#xff1a; class MyThread extends Thread {Overridevoid…...