目录

1 张量

1)张量的初始化和属性

2)张量操作

3)使用 NumPy 进行桥接

2 torch.autograd

1)背景

2)在 PyTorch 中的使用

3)Autograd 的微分机制

4)计算图原理

5)从计算图中排除

3 神经网络

1)定义网络

2)损失函数

3)反向传播

4)权重更新


本篇是笔者基于官方文档所做的学习笔记,在完整保留文档技术要点的同时提供辅助备注,也可作为官方文档的中文参考译文阅读。如需了解如何安装和运行 PyTorch 可移步《PyTorch 入门学习笔记》。

PyTorch 是由 Meta(原 Facebook) 开源的深度学习框架,是基于 Python 的科学计算包,主要服务于两大用途:(1)作为 NumPy 的替代方案,支持 GPU其他硬件加速器的高性能计算,显著提升张量运算效率;(2)作为自动微分库,为神经网络训练提供高效的梯度计算反向传播支持。

1 张量

张量(Tensor)是 PyTorch 中多维数据的主要载体,类似于 NumPy 的 ndarray,但支持 GPU 加速计算自动微分功能,是神经网络中数据和梯度计算基础单位

1)张量的初始化和属性

张量有以下几种创建方式直接数据创建,用 numpy 数组创建,用另一个张量创建,用常量或随机值创建。例如:

import torch
import numpy as np# 用数据创建
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)# 用数组创建
np_array = np.array(data)
x_np = torch.from_numpy(np_array)# 用另一个张量创建
x_ones = torch.ones_like(x_data) # 保持 x_data 的属性
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # 覆盖 x_data 的类型
print(f"Random Tensor: \n {x_rand} \n")# 用常量或随机值次创建
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

运行结果如下:

张量属性描述了它们的形状、数据类型和存储它们的设备。

tensor = torch.rand(3, 4)print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

运行结果如下:

2)张量操作

PyTorch 提供了超过100种张量操作,涵盖数学运算、线性代数、数据切片等常见需求。这些操作均可在 GPU 上运行,且速度通常远快于 CPU。如果您使用的是 Colab,可以通过 Edit —— Notebook Settings 来分配。

# 将张量移动到 GPU 上(如果支持)
if torch.cuda.is_available():tensor = tensor.to('cuda')print(f"Device tensor is stored on: {tensor.device}")

尝试一些操作(如果您熟悉 NumPy API,则会发现 Tensor API 使用起来相对更容易):

# 类似 numpy 的标准索引和切片
tensor = torch.ones(4, 4)
tensor[:,1] = 0
print(tensor)# 可以用 torch.cat 将张量沿指定维度连接起来(还有类似功能 torch.stack)
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)# 计算元素级乘积
print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n")
# 也可以这样写
print(f"tensor * tensor \n {tensor * tensor}")# 计算两个张量之间的矩阵乘法
print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n")
# 也可以这样写
print(f"tensor @ tensor.T \n {tensor @ tensor.T}")# 原地操作,带有 _ 后缀的操作是原地操作(例如 x.copy_(y) 和 x.t_() 会直接修改 x 的值)
print(tensor, "\n")
tensor.add_(5)
print(tensor)

运行结果如下:

3)使用 NumPy 进行桥接

CPU 上的张量和 NumPy 数组可以共享它们的底层内存位置,更改其中一个将会更改另一个。

# 张量转换为 NumPy 数组
t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")# 张量的变化会反映在 NumPy 数组上
t.add_(1)
print(f"t: {t}")
print(f"n: {n}")# NumPy 数组转张量
n = np.ones(5)
t = torch.from_numpy(n)# NumPy 数组的修改会同步到张量
np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")

运行结果如下:

2 torch.autograd

torch.autograd 是 PyTorch 的自动微分引擎,为神经网络训练提供核心支持

1)背景

神经网络(Neural Networks, NNs)是由一系列嵌套函数组成的计算模型,这些函数对输入数据执行运算。这些函数由参数(包括权重偏置)定义,在 PyTorch 中,这些参数以张量的形式存储。

神经网络的训练过程分为两个阶段

  • 前向传播(Forward Propagation)

    在前向传播过程中,神经网络基于输入数据计算其预测输出。数据依次经过网络中的每一层函数,最终生成预测结果。

  • 反向传播(Backward Propagation)

    在反向传播过程中,神经网络根据预测误差按比例调整参数。具体做法是从输出层开始反向遍历网络,计算误差关于各层参数的导数(即梯度,并利用梯度下降法优化参数。

如果把前向传播就类比成按菜谱做菜,反向传播则是根据成品味道反推和调整菜谱配方。

2)在 PyTorch 中的使用

来看一个简单的训练示例,本例从 torchvision 加载一个预训练的 resnet18 模型创建一个随机数据张量来模拟一张3通道、高宽均为64的图像,并初始化其对应的标签为随机值。预训练模型中的标签形状为(1,1000)。注意:本教程仅适用于 CPU 环境,无法在 GPU 设备上运行(即使将张量移至 CUDA)。

import torch
from torchvision.models import resnet18, ResNet18_Weights
model = resnet18(weights=ResNet18_Weights.DEFAULT)
data = torch.rand(1, 3, 64, 64)
labels = torch.rand(1, 1000)

将输入数据传入模型,经过每一层的计算得到预测结果——这就是前向传播

prediction = model(data) # 前向传播

然后计算误差(损失值),也就是计算预测值与真实标签之间的差异度量。然后再将这个误差反向传播到整个网络中。调用 .backward() 方法会触发反向传播过程。此时 Autograd 引擎会自动计算每个模型参数的梯度梯度表示函数在某一点的导数或偏导数,描述了张量随着其输入变化的变化率),并将它们存储在参数的 .grad 属性中。

loss = (prediction - labels).sum() # 计算损失
loss.backward() # 反向传播

接下来加载一个优化器,优化器的技术本质是一个能自动调整模型参数的算法,目标是让预测结果越来越准,通俗点说就是告诉模型怎么改、改多少。这个例子中使用了随机梯度下降法(SGD),并设置学习率为0.01,动量参数为0.9。我们要将模型的所有参数都注册到该优化器中。

optim = torch.optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)

然后调用 .step() 方法来执行梯度下降。优化器会根据每个参数存储在 .grad 属性中的梯度值来调整这些参数。

optim.step()  # 执行梯度下降

以上就是训练神经网络所需的所有基本步骤

3)Autograd 的微分机制

autograd 是如何收集梯度的呢?创建两个张量 a 和 b,并设置 requires_grad=True。这相当于告诉 autograd:跟踪所有对这两个张量的运算

import torcha = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([6., 4.], requires_grad=True)

接着用 a 和 b 生成新张量 Q:

Q = 3*a**3 - b**2

假设 a 和 b 是神经网络的参数,Q 是误差值。在训练神经网络时,我们需要计算误差关于参数的梯度(a 的梯度应为9倍 a 的平方,b 的梯度应为-2倍的 b)

当调用 Q.backward() 时,autograd 会计算梯度并将结果存储在各个张量的 .grad 属性中。

由于 Q 是向量,这里需要显式传入一个 gradient 参数。这个参数是与 Q 形状相同的张量,代表 Q 对自身的梯度,即:

等价的做法是将 Q 聚合为标量再隐式调用 backward,例如 Q.sum().backward()。

external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)

现在梯度已存入 a.gradb.grad 中:

# 验证梯度是否正确
print(9*a**2 == a.grad)  # 检查 a 的梯度
print(-2*b == b.grad)    # 检查 b 的梯度

运行结果如下:

4)计算图原理

autograd 通过有向无环图(DAG记录数据(张量)和执行的所有运算(包括生成的新张量)。这个 DAGFunction 对象构成:

  • 叶子节点:输入张量(如初始参数)

  • 根节点:输出张量(如损失值)

通过从根节点回溯到叶子节点,autograd 能利用链式法则自动计算梯度

前向传播,autograd 会同步完成两件事:

  • 执行运算:计算输出张量

  • 维护 DAG:记录运算对应的梯度函数(grad_fn)

反向传播,当调用 .backward() 时,autograd 会:

  • 从每个 grad_fn 计算梯度
  • 将梯度累加到对应张量的 .grad 属性中
  • 通过链式法则一直传播到叶子张量

下图是本示例中 DAG 的可视化表示,箭头指向向前传递的方向,节点表示每个操作的反向函数。蓝色叶子节点表示张量 a 和 b。

5)从计算图中排除

torch.autograd 会跟踪所有设置 requires_grad 为 True 的张量的运算,对于不需要梯度计算的张量,requires_grad 设为 False 即可将其排除在梯度计算图(DAG)之外。

x = torch.rand(5, 5)
y = torch.rand(5, 5)
z = torch.rand((5, 5), requires_grad=True)a = x + y
print(f"Does `a` require gradients?: {a.requires_grad}")
b = x + z
print(f"Does `b` require gradients?: {b.requires_grad}")

运行结果如下:

在神经网络中,不计算梯度的参数通常被称为冻结参数。如果事先知道某些参数不需要计算梯度(通过减少自动微分计算提升性能),那么“冻结”模型的一部分就会非常有用。在微调时,我们通常会冻结模型的大部分参数,仅修改分类器层以适配新的标签预测。如下是一个小示例(需要先安装依赖 pip install torchvision。和之前一样,先加载一个预训练的 resnet18 模型,并冻结其所有参数。

from torch import nn, optimmodel = resnet18(weights=ResNet18_Weights.DEFAULT)# 冻结网络中的所有参数
for param in model.parameters():param.requires_grad = False

假设我们需要在一个包含10个类别的新数据集上对模型进行微调。在 resnet 中,分类器模型中负责最终分类预测的层,如全连接层)是最后的全连接层 model.fc。可以直接将其替换为一个新的全连接层(默认情况下未被冻结),作为我们的分类器。

model.fc = nn.Linear(512, 10)

现在模型中除 model.fc 的参数外,其余所有参数均被冻结。唯一需要计算梯度的参数是 model.fc 的权重偏置项

# 只优化分类器
optimizer = optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)

尽管在优化器中注册了所有参数,但实际计算梯度(在梯度下降中会被更新)的只有分类器的权重和偏置项。同样的参数排除功能也可以通过上下文管理器 torch.no_grad() 实现。

3 神经网络

可以使用 torch.nn 包来构建神经网络。nn 模块是基于 autograd 来定义模型并进行微分计算的。一个 nn.Module 包含若干网络层,以及一个 forward(input) 方法,该方法返回网络的输出结果。

下图是一个用于手写数字图像分类的网络示意图:

这是一个简单的前馈神经网络常见的神经网络还有:卷积神经网络、循环神经网络等。它接收输入数据,依次通过多个网络层进行处理,最终产生输出结果。神经网络的标准训练流程通常包括以下步骤:

  • 定义包含可训练参数(或称权重)的神经网络结构

  • 遍历输入数据集

  • 输入数据送入网络进行前向传播

  • 计算损失值(输出结果与正确结果的偏差

  • 梯度反向传播至网络各参数

  • 使用简单更新规则调整网络权重权重 = 权重 - 学习率 × 梯度(梯度下降算法的核心表达式)

1)定义网络
import torch
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()# 输入图像通道数1(灰度图),输出通道数6,5x5卷积核self.conv1 = nn.Conv2d(1, 6, 5)# 输入通道数6,输出通道数16,5x5卷积核self.conv2 = nn.Conv2d(6, 16, 5)# 全连接层(仿射变换):y = Wx + b# 输入维度16*5*5(16个通道,5x5特征图),输出120维self.fc1 = nn.Linear(16 * 5 * 5, 120) # 5*5来自图像维度# 全连接层:120维输入,84维输出self.fc2 = nn.Linear(120, 84)# 输出层:84维输入,10维输出(对应10个类别)self.fc3 = nn.Linear(84, 10)def forward(self, input):# 卷积层C1:1输入通道,6输出通道,5x5卷积核# 使用ReLU激活函数,输出张量尺寸为(N, 6, 28, 28),N是批次大小c1 = F.relu(self.conv1(input))# 下采样层S2:2x2最大池化,无参数# 输出张量尺寸为(N, 6, 14, 14)s2 = F.max_pool2d(c1, (2, 2))# 卷积层C3:6输入通道,16输出通道,5x5卷积核# 使用ReLU激活函数,输出张量尺寸为(N, 16, 10, 10)c3 = F.relu(self.conv2(s2))# 下采样层S4:2x2最大池化,无参数# 输出张量尺寸为(N, 16, 5, 5)s4 = F.max_pool2d(c3, 2)# 展平操作:无参数,输出(N, 400)张量s4 = torch.flatten(s4, 1)# 全连接层F5:输入(N, 400),输出(N, 120)# 使用ReLU激活函数f5 = F.relu(self.fc1(s4))# 全连接层F6:输入(N, 120),输出(N, 84)# 使用ReLU激活函数f6 = F.relu(self.fc2(f5))# 输出层:输入(N, 84),输出(N, 10)output = self.fc3(f6)return output# 实例化网络
net = Net()
print(net)

运行结果如下:

你只需定义前向传播函数反向传播函数(用于计算梯度)将通过 autograd 自动定义。在前向传播中,可以使用任何张量运算。

net.parameters() 返回模型的所有可训练参数:

params = list(net.parameters()) # 返回可训练参数(权重和偏置)并转为 list
print(len(params))
print(params[0].size()) # conv1 的权重大小

运行结果如下:

现在尝试输入一个随机的32×32矩阵。注意:该网络(LeNet)的预期输入尺寸为32×32。若要将此网络用于 MNIST 数据集,请将数据集中的图像尺寸调整为32×32。

input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)

运行结果如下:

将所有参数的梯度缓冲区清零,并使用随机梯度进行反向传播:

net.zero_grad()
out.backward(torch.randn(1, 10))

注意:torch.nn 模块仅支持小批量输入样本(不能是单个样本)。例如,nn.Conv2d 层需要接收一个4维张量,其维度为:样本数×通道数×高度×宽度。若只有单个样本,只需使用 input.unsqueeze(0) 来添加一个虚拟的批次维度

回顾一下目前学到的类:

  • torch.Tensor:支持自动求导运算的多维数组,如 backward() ,同时存储着张量的梯度信息。
  • nn.Module:神经网络模块。封装参数的便捷方式,提供将参数移至 GPU、导出、加载等辅助功能。
  • nn.Parameter:张量的一种,当被赋值给 Module 的属性时,会自动注册为模型参数
  • autograd.Function:实现自动求导运算前向和反向定义。每个张量运算至少会创建一个Function 节点,该节点会记录创建该张量的函数并编码其运算历史。
2)损失函数

损失函数接受入参 (output, target) ,并计算一个值,该值估计输出与目标的差距。nn 包下有几个不同的损失函数,一个简单的损失函数是:nn.MSELoss,计算输出和目标之间的均方误差。例如:

output = net(input)
target = torch.randn(10) # 创建一个假目标
target = target.view(1, -1) # 使其与输出的形状相同
criterion = nn.MSELoss()loss = criterion(output, target)
print(loss)

运行结果如下:

现在,如果你反向跟踪 loss 函数,使用它的 .grad_fn 属性,你会看到一个如下所示的计算图:

因此,当我们调用 loss.backward() 时,整个计算图会相对于神经网络参数进行微分,图中所有 requires_grad=True 的张量都会累积梯度值到它们的 .grad 张量中。反向追踪几个步骤:

print(loss.grad_fn) # 输出 MSE 损失函数的梯度计算节点
print(loss.grad_fn.next_functions[0][0]) # 输出线性层的梯度计算节点
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])  # 输出 ReLU 激活层的梯度计算节点

运行结果如下:

3)反向传播

要实现误差反向传播,只需执行 loss.backward()。但注意需要清除已有梯度,否则梯度会累积到现有梯度之上。通过如下代码观察反向传播前后 conv1 层偏置的梯度变化:

net.zero_grad() # 将所有参数的梯度缓冲区置零print('conv1.bias.grad 反向传播之前')
print(net.conv1.bias.grad)loss.backward()print('conv1.bias.grad 反向传播之后')
print(net.conv1.bias.grad)

运行结果如下:

4)权重更新

实践中最简单的更新规则是随机梯度下降法(简称 SGD)

weight = weight - learning_rate * gradient# 可以通过简单的 Python 代码实现:
learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)

在使用神经网络时,我们可以使用各种不同的更新规则(SGD、 Nesterov-SGD、 Adam、 RMSProp 等。可以通过一个小软件包 torch.optim实现所有这些方法:

import torch.optim as optim# 创建优化器
optimizer = optim.SGD(net.parameters(), lr=0.01)# 训练循环中的操作
optimizer.zero_grad() # 清空梯度缓冲
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # 执行更新

注意:观察梯度缓冲区是如何使用 optimizer.zero_grad() 手动设置为零的(如前面所述,梯度是累积的

【本节完&持续更新】

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

King’s LIMS 系统引领汽车检测实验室数字化转型

随着汽车保有量的持续攀升和车龄的增长,消费者对汽车的需求已悄然转变,从最初对外观和性能的追求,逐渐深化为对安全性、可靠性、耐久性、性能与舒适性以及智能化功能的全方位关注。这无疑让汽车检测行业在保障车辆质量、满足市场需求方面肩负…

Neo4j常见语句-merge

merge用法&#xff1a;MERGE 是 Neo4j 中一个强大的操作符&#xff0c;用于确保图中存在特定的节点或关系。它的核心逻辑是&#xff1a;如果目标存在则匹配&#xff0c;不存在则创建 基本语法与逻辑&#xff1a; MERGE <pattern> [ON CREATE <create_clause>] //…

Mem0多级记忆实现机制详解

在人工智能交互场景中,记忆能力是实现个性化服务与智能决策的关键。Mem0 通过设计分层记忆架构,实现了对用户、会话和智能体状态的多级管理。各层级记忆既相互独立存储,又通过精密的关联机制协同运作,确保在不同场景下都能提供精准的上下文支持,显著提升 AI 交互的智能性与…

Python 爬虫入门 Day 5 - 使用 XPath 进行网页解析(lxml + XPath)

Python 第二阶段 - 爬虫入门 &#x1f3af; 今日目标 掌握 XPath 的基本语法使用 lxml.etree 解析 HTML&#xff0c;提取数据与 BeautifulSoup 比较&#xff1a;谁更强&#xff1f; &#x1f4d8; 学习内容详解 ✅ 安装依赖 pip install lxml&#x1f9e9; XPath 简介 XPa…

变幻莫测:CoreData 中 Transformable 类型面面俱到(六)

概述 各位似秃似不秃小码农们都知道&#xff0c;在苹果众多开发平台中 CoreData 无疑是那个最简洁、拥有“官方认证”且最具兼容性的数据库框架。使用它可以让我们非常方便的搭建出 App 所需要的持久存储体系。 不过&#xff0c;大家是否知道在 CoreData 中还存在一个 Transfo…

Vuex(一) —— 集中式的状态管理仓库

目录 Vue组件间通信方式回顾 组件内的状态管理流程组件间通信方式 父组件给子组件传值 (最简单的一种方式)子组件给父组件传值不相关组件之间传值其他常见方式($ref) 简易的状态管理方案 上面组件间通信方式的问题集中式的状态管理方案 Vuex 什么是Vuex?什么情况下使用Vuex?…

操作系统---内存管理上

文章目录 1. 内存的基础知识1.1 什么是内存&#xff0c;有何作用1.2 进程运行的基本原理1.2.1 指令的工作原理1.2.2 逻辑地址 VS 物理地址 1.3 如何实现地址转换&#xff08;逻辑 -> 物理&#xff09;1.3.1 绝对装入1.3.2 可重定位装入&#xff08;静态重定位&#xff09;1.…

医学图像处理期末复习

目录 考试范围第1章 绪论1.1 数字图像处理的概念1.2 数字图像处理的应用领域1、医学领域2、其他领域 1.3 数字图像处理基础1.4 数字图像基础运算 第2章 医学图像灰度变换与空间滤波2.1 医学图像灰度变换线性灰度变换非线性灰度变换 2.2 直方图均衡化√2.3 空间平滑滤波线性空间…

类图:软件世界的“建筑蓝图”

本文来自「大千AI助手」技术实战系列&#xff0c;专注用真话讲技术&#xff0c;拒绝过度包装。 类图&#xff08;Class Diagram&#xff09;&#xff1a;软件世界的“建筑蓝图” 类图&#xff08;Class Diagram&#xff09;是统一建模语言&#xff08;UML&#xff09; 中最重要…

利用DevEco Studio对RK3588的HiHopesOS-4.1.110(OpenHarmony)进行Qt程序编写

文章目录 热身准备添加Qt库运行qml程序 热身 可以先看我这篇文章【DevEco Studio中使用Qt&#xff0c;编写HarmonyOS程序】 准备 板子的主要信息 目前由于系统版本&#xff08;API 11&#xff09;及其他原因&#xff0c;只能用4.1版本的DevEcoStudio来编写&#xff0c;更高…

设计模式精讲 Day 5:原型模式(Prototype Pattern)

【设计模式精讲 Day 5】原型模式&#xff08;Prototype Pattern&#xff09; 文章内容 在“设计模式精讲”系列的第5天&#xff0c;我们将深入讲解原型模式&#xff08;Prototype Pattern&#xff09;。作为创建型设计模式之一&#xff0c;原型模式通过复制已有对象来创建新对…

深度学习——第2章习题2-1分析为什么平方损失函数不适用于分类问题

深度学习——第2章习题2-1 《神经网络与深度学习》——邱锡鹏 2-1 分析为什么平方损失函数不适用于分类问题。 平方损失函数&#xff08;Quadratic Loss Function&#xff09;经常用在预测标签y为实数值的任务中&#xff0c;定义为 L ( y , f ( x ; θ ) ) 1 2 ( y − f (…

【Linux】运行脚本后打屏同时保存到本地

命令&#xff1a; sh run.sh 2>&1 | tee output.log sh run.sh 2>&1 | tee output_$(date "%Y%m%d%H%M").log作用&#xff1a;运行脚本&#xff0c;并同时将输出&#xff08;包括标准输出和错误输出&#xff09;显示到终端&#xff0c;并保存到文件中…

Spark 在小众日常场景中的实战应用:从小店数据到社区活动

Spark 在小众日常场景中的实战应用&#xff1a;从小店数据到社区活动​ 提起 Spark&#xff0c;大家往往会联想到大型互联网公司的数据处理、金融行业的复杂分析。但实际上&#xff0c;Spark 在许多小众、贴近生活的场景中也能大显身手。结合学习与实践&#xff0c;我探索了 S…

mysql 执行计划 explain命令 详解

explain id &#xff1a;select查询的序列号&#xff0c;包含一组数字&#xff0c;表示查询中执行select子句或操作表的顺序select_type&#xff1a;查询类型 或者是 其他操作类型table &#xff1a;正在访问哪个表partitions &#xff1a;匹配的分区type &#xff1a;访问的类…

让大模型“更懂人话”:对齐训练(RLHF DPO)全流程实战解析

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

GO 原子操作面试题及参考答案

Go 的 sync/atomic 包和 sync.Mutex 的根本区别是什么&#xff1f; Go 语言中的 sync/atomic 包和 sync.Mutex 都用于处理并发编程中的同步问题&#xff0c;但它们的实现机制、应用场景和性能特性存在根本差异。理解这些差异对于编写高效、安全的并发代码至关重要。 sync/atomi…

MATLAB 山脊图绘制全解析:从数据生成到可视化进阶

一、引言&#xff1a;当数据分布拥有「层次感」—— 山脊图的魅力​ 在数据可视化的世界里&#xff0c;我们常常需要同时展示多个分布的形态差异。传统的重叠密度图虽然能呈现整体趋势&#xff0c;但当分布数量较多时&#xff0c;曲线交叠会让画面变得杂乱。这时候&#xff0c…

跨境电商每周资讯—6.16-6.20

1. Instagram 在亚太地区逐渐超越 TikTok 在整个亚太地区&#xff0c;Instagram用户数量正逐渐超过TikTok。预计2025年日本Instagram用户数量将增至4440万&#xff0c;印度今年用户数量将增长10%&#xff0c;领跑亚太。与之形成对比的是&#xff0c;TikTok在一些国家增长速度放…

计算机网络 网络层:数据平面(一)

前一节学习了运输层依赖于网络层的主机到主机的通信服务&#xff0c;提供各种形式的进程到进程的通信。了解这种主机到主机通信服务的真实情况&#xff0c;是什么使得它工作起来的。 在本章和下一章&#xff0c;将学习网络层实际是怎样实现主机到主机的通信服务。与运输层和应用…