Python_day48随机函数与广播机制
在继续讲解模块消融前,先补充几个之前没提的基础概念
尤其需要搞懂张量的维度、以及计算后的维度,这对于你未来理解复杂的网络至关重要
一、 随机张量的生成
在深度学习中经常需要随机生成一些张量,比如权重的初始化,或者计算输入纬度经过模块后输出的维度,都可以用一个随机函数来实现需要的张量格式,而无需像之前一样必须加载一张真实的图片。
随机函数的种类很多,我们了解其中一种即可,毕竟目的主要就是生成,对分布要求不重要。
1.1 torch.randn函数
在 PyTorch 中,torch.randn()是一个常用的随机张量生成函数,它可以创建一个由标准正态分布(均值为 0,标准差为 1)随机数填充的张量。这种随机张量在深度学习中非常实用,常用于初始化模型参数、生成测试数据或模拟输入特征。
torch.randn(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
- size:必选参数,表示输出张量的形状(如(3, 4)表示 3 行 4 列的矩阵)。
- dtype:可选参数,指定张量的数据类型(如torch.float32、torch.int64等)。
- device:可选参数,指定张量存储的设备(如'cpu'或'cuda')。
- requires_grad:可选参数,是否需要计算梯度(常用于训练模型时)。
import torch
# 生成标量(0维张量)
scalar = torch.randn(())
print(f"标量: {scalar}, 形状: {scalar.shape}")
标量: -1.6167410612106323, 形状: torch.Size([])
# 生成向量(1维张量)
vector = torch.randn(5) # 长度为5的向量
print(f"向量: {vector}, 形状: {vector.shape}")
向量: tensor([-1.9524, 0.5900, 0.7467, -1.8307, 0.4263]), 形状: torch.Size([5])
# 生成矩阵(2维张量)
matrix = torch.randn(3, 4) # 3行4列的矩阵
print(f"矩阵:{matrix},矩阵形状: {matrix.shape}")
矩阵:tensor([[ 0.0283, 0.7692, 0.2744, -1.6120],[ 0.3726, 1.5382, -1.0128, 0.4129],[ 0.4898, 1.4782, 0.2019, 0.0863]]),矩阵形状: torch.Size([3, 4])
# 生成3维张量(常用于图像数据的通道、高度、宽度)
tensor_3d = torch.randn(3, 224, 224) # 3通道,高224,宽224
print(f"3维张量形状: {tensor_3d.shape}") # 输出: torch.Size([3, 224, 224])
3维张量形状: torch.Size([3, 224, 224])
# 生成4维张量(常用于批量图像数据:[batch, channel, height, width])
tensor_4d = torch.randn(2, 3, 224, 224) # 批量大小为2,3通道,高224,宽224
print(f"4维张量形状: {tensor_4d.shape}") # 输出: torch.Size([2, 3, 224, 224])
4维张量形状: torch.Size([2, 3, 224, 224])
1.2 其他随机函数
除了这些随机函数还有很多,自行了解,主要是生成数据的分布不同。掌握一个即可,掌握多了参数也记不住。
torch.rand():生成在 [0, 1) 范围内均匀分布的随机数。
x = torch.rand(3, 2) # 生成3x2的张量
print(f"均匀分布随机数: {x}, 形状: {x.shape}")
均匀分布随机数: tensor([[0.2089, 0.7786],[0.1043, 0.1573],[0.9637, 0.0397]]), 形状: torch.Size([3, 2])
torch.randint():生成指定范围内的随机整数
x = torch.randint(low=0, high=10, size=(3,)) # 生成3个0到9之间的整数
print(f"随机整数: {x}, 形状: {x.shape}")
随机整数: tensor([3, 5, 7]), 形状: torch.Size([3])
torch.normal():生成指定均值和标准差的正态分布随机数。
mean = torch.tensor([0.0, 0.0])
std = torch.tensor([1.0, 2.0])
x = torch.normal(mean, std) # 生成两个正态分布随机数
print(f"正态分布随机数: {x}, 形状: {x.shape}")
正态分布随机数: tensor([ 0.1419, -1.5212]), 形状: torch.Size([2])
# 一维张量与二维张量相加
a = torch.tensor([[1, 2, 3], [4, 5, 6]]) # 形状: (2, 3)
b = torch.tensor([10, 20, 30]) # 形状: (3,)# 广播后:b被扩展为[[10, 20, 30], [10, 20, 30]]
result = a + b
result
tensor([[11, 22, 33],[14, 25, 36]])
1.3 输出维度测试
import torch
import torch.nn as nn# 生成输入张量 (批量大小, 通道数, 高度, 宽度)
input_tensor = torch.randn(1, 3, 32, 32) # 例如CIFAR-10图像
print(f"输入尺寸: {input_tensor.shape}") # 输出: [1, 3, 32, 32]
输入尺寸: torch.Size([1, 3, 32, 32])
二维的卷积和池化计算公式是一致的
# 1. 卷积层操作
conv1 = nn.Conv2d(in_channels=3, # 输入通道数out_channels=16, # 输出通道数(卷积核数量)kernel_size=3, # 卷积核大小stride=1, # 步长padding=1 # 填充
)
conv_output = conv1(input_tensor) # 由于 padding=1 且 stride=1,空间尺寸保持不变
print(f"卷积后尺寸: {conv_output.shape}") # 输出: [1, 16, 32, 32]
卷积后尺寸: torch.Size([1, 16, 32, 32])
# 2. 池化层操作 (减小空间尺寸)
pool = nn.MaxPool2d(kernel_size=2, stride=2) # 创建一个最大池化层
pool_output = pool(conv_output)
print(f"池化后尺寸: {pool_output.shape}") # 输出: [1, 16, 16, 16]
池化后尺寸: torch.Size([1, 16, 16, 16])
# 3. 将多维张量展平为向量
flattened = pool_output.view(pool_output.size(0), -1)
print(f"展平后尺寸: {flattened.shape}") # 输出: [1, 4096] (16*16*16=4096)
展平后尺寸: torch.Size([1, 4096])
# 4. 线性层操作
fc1 = nn.Linear(in_features=4096, # 输入特征数out_features=128 # 输出特征数
)
fc_output = fc1(flattened)
print(f"线性层后尺寸: {fc_output.shape}") # 输出: [1, 128]
线性层后尺寸: torch.Size([1, 128])
# 5. 再经过一个线性层(例如分类器)
fc2 = nn.Linear(128, 10) # 假设是10分类问题
final_output = fc2(fc_output)
print(f"最终输出尺寸: {final_output.shape}") # 输出: [1, 10]
print(final_output)
最终输出尺寸: torch.Size([1, 10]) tensor([[-0.3018, -0.4308, 0.3248, 0.2808, 0.5109, -0.0881, -0.0787, -0.0700,-0.1004, -0.0580]], grad_fn=<AddmmBackward>)
多分类问题通常使用Softmax,二分类问题用Sigmoid
# 使用Softmax替代Sigmoid
softmax = nn.Softmax(dim=1) # 在类别维度上进行Softmax
class_probs = softmax(final_output)
print(f"Softmax输出: {class_probs}") # 总和为1的概率分布
print(f"Softmax输出总和: {class_probs.sum():.4f}")
Softmax输出: tensor([[0.0712, 0.0626, 0.1332, 0.1275, 0.1605, 0.0882, 0.0890, 0.0898, 0.0871,0.0909]], grad_fn=<SoftmaxBackward>) Softmax输出总和: 1.0000
通过这种方法,可以很自然的看到每一层输出的shape,实际上在pycharm等非交互式环境ipynb时,可以借助断点+调试控制台不断测试维度信息,避免报错。
二、广播机制
什么叫做广播机制
PyTorch 的广播机制(Broadcasting)是一种强大的张量运算特性,允许在不同形状的张量之间进行算术运算,而无需显式地扩展张量维度或复制数据。这种机制使得代码更简洁高效,尤其在处理多维数据时非常实用。
当对两个形状不同的张量进行运算时,PyTorch 会自动调整它们的形状,使它们在维度上兼容。具体规则如下:
从右向左比较维度:PyTorch 从张量的最后一个维度开始向前比较,检查每个维度的大小是否相同或其中一个为 1。 维度扩展规则: 如果两个张量的某个维度大小相同,则继续比较下一个维度。 如果其中一个张量的某个维度大小为 1,则该维度会被扩展为另一个张量对应维度的大小。 如果两个张量的某个维度大小既不相同也不为 1,则会报错。
2.1 PyTorch 广播机制
PyTorch 的广播机制(Broadcasting)是一种高效的张量运算特性,允许在不同形状的张量之间执行元素级操作(如加法、乘法),而无需显式扩展或复制数据。这种机制通过自动调整张量维度来实现形状兼容,使代码更简洁、计算更高效。
当对两个形状不同的张量进行运算时,PyTorch 会按以下规则自动处理维度兼容性:
- 从右向左比较维度:PyTorch 从张量的最后一个维度(最右侧)开始向前逐维比较。
- 维度扩展条件:
- 相等维度:若两个张量在某一维度上大小相同,则继续比较下一维度。
- 一维扩展:若其中一个张量在某一维度上大小为 1,则该维度会被扩展为另一个张量对应维度的大小。
- 不兼容错误:若某一维度大小既不相同也不为 1,则抛出
RuntimeError
。-----维度必须满足广播规则,否则会报错。
- 维度补全规则:若一个张量的维度少于另一个,则在其左侧补 1 直至维度数匹配。
关注2个信息
- 广播后的尺寸变化
- 扩展后的值变化
2.1.1 加法的广播机制
1二维张量与一维向量相加
import torch# 创建原始张量
a = torch.tensor([[10], [20], [30]]) # 形状: (3, 1)
b = torch.tensor([1, 2, 3]) # 形状: (3,)result = a + b
# 广播过程
# 1. b补全维度: (3,) → (1, 3)
# 2. a扩展列: (3, 1) → (3, 3)
# 3. b扩展行: (1, 3) → (3, 3)
# 最终形状: (3, 3)print("原始张量a:")
print(a)print("\n原始张量b:")
print(b)print("\n广播后a的值扩展:")
print(torch.tensor([[10, 10, 10],[20, 20, 20],[30, 30, 30]])) # 实际内存中未复制,仅逻辑上扩展print("\n广播后b的值扩展:")
print(torch.tensor([[1, 2, 3],[1, 2, 3],[1, 2, 3]])) # 实际内存中未复制,仅逻辑上扩展print("\n加法结果:")
print(result)
原始张量a: tensor([[10],[20],[30]])原始张量b: tensor([1, 2, 3])广播后a的值扩展: tensor([[10, 10, 10],[20, 20, 20],[30, 30, 30]])广播后b的值扩展: tensor([[1, 2, 3],[1, 2, 3],[1, 2, 3]])加法结果: tensor([[11, 12, 13],[21, 22, 23],[31, 32, 33]])
2三维张量与二维张量相加
# 创建原始张量
a = torch.tensor([[[1], [2]], [[3], [4]]]) # 形状: (2, 2, 1)
b = torch.tensor([[10, 20]]) # 形状: (1, 2)# 广播过程
# 1. b补全维度: (1, 2) → (1, 1, 2)
# 2. a扩展第三维: (2, 2, 1) → (2, 2, 2)
# 3. b扩展第一维: (1, 1, 2) → (2, 1, 2)
# 4. b扩展第二维: (2, 1, 2) → (2, 2, 2)
# 最终形状: (2, 2, 2)result = a + b
print("原始张量a:")
print(a)print("\n原始张量b:")
print(b)print("\n广播后a的值扩展:")
print(torch.tensor([[[1, 1],[2, 2]],[[3, 3],[4, 4]]])) # 实际内存中未复制,仅逻辑上扩展print("\n广播后b的值扩展:")
print(torch.tensor([[[10, 20],[10, 20]],[[10, 20],[10, 20]]])) # 实际内存中未复制,仅逻辑上扩展print("\n加法结果:")
print(result)
原始张量a: tensor([[[1],[2]],[[3],[4]]])原始张量b: tensor([[10, 20]])广播后a的值扩展: tensor([[[1, 1],[2, 2]],[[3, 3],[4, 4]]])广播后b的值扩展: tensor([[[10, 20],[10, 20]],[[10, 20],[10, 20]]])加法结果: tensor([[[11, 21],[12, 22]],[[13, 23],[14, 24]]])
3二维张量与标量相加
# 创建原始张量
a = torch.tensor([[1, 2], [3, 4]]) # 形状: (2, 2)
b = 10 # 标量,形状视为 ()# 广播过程
# 1. b补全维度: () → (1, 1)
# 2. b扩展第一维: (1, 1) → (2, 1)
# 3. b扩展第二维: (2, 1) → (2, 2)
# 最终形状: (2, 2)result = a + b
print("原始张量a:")
print(a)
# 输出:
# tensor([[1, 2],
# [3, 4]])print("\n标量b:")
print(b)
# 输出: 10print("\n广播后b的值扩展:")
print(torch.tensor([[10, 10],[10, 10]])) # 实际内存中未复制,仅逻辑上扩展print("\n加法结果:")
print(result)
# 输出:
# tensor([[11, 12],
# [13, 14]])
原始张量a: tensor([[1, 2],[3, 4]])标量b: 10广播后b的值扩展: tensor([[10, 10],[10, 10]])加法结果: tensor([[11, 12],[13, 14]])
4高维张量与低维张量相加
# 创建原始张量
a = torch.tensor([[[1, 2], [3, 4]]]) # 形状: (1, 2, 2)
b = torch.tensor([[5, 6]]) # 形状: (1, 2)# 广播过程
# 1. b补全维度: (1, 2) → (1, 1, 2)
# 2. b扩展第二维: (1, 1, 2) → (1, 2, 2)
# 最终形状: (1, 2, 2)result = a + b
print("原始张量a:")
print(a)
# 输出:
# tensor([[[1, 2],
# [3, 4]]])print("\n原始张量b:")
print(b)
# 输出:
# tensor([[5, 6]])print("\n广播后b的值扩展:")
print(torch.tensor([[[5, 6],[5, 6]]])) # 实际内存中未复制,仅逻辑上扩展print("\n加法结果:")
print(result)
# 输出:
# tensor([[[6, 8],
# [8, 10]]])
原始张量a: tensor([[[1, 2],[3, 4]]])原始张量b: tensor([[5, 6]])广播后b的值扩展: tensor([[[5, 6],[5, 6]]])加法结果: tensor([[[ 6, 8],[ 8, 10]]])
关键总结
- 尺寸变化:广播后的形状由各维度的最大值决定(示例 2 中最终形状为 (2, 2, 2))。
- 值扩展:维度为 1 的张量通过复制扩展值(示例 1 中 b 从 [1, 2, 3] 扩展为三行相同的值)。
- 内存效率:扩展是逻辑上的,实际未复制数据,避免了内存浪费。
2.1.2 乘法的广播机制
矩阵乘法(@)的特殊规则
矩阵乘法除了遵循通用广播规则外,还需要满足矩阵乘法的维度约束:
最后两个维度必须满足:A.shape[-1] == B.shape[-2](即 A 的列数等于 B 的行数)
其他维度(批量维度):遵循通用广播规则
1批量矩阵与单个矩阵相乘
import torch# A: 批量大小为2,每个是3×4的矩阵
A = torch.randn(2, 3, 4) # 形状: (2, 3, 4)# B: 单个4×5的矩阵
B = torch.randn(4, 5) # 形状: (4, 5)# 广播过程:
# 1. B补全维度: (4, 5) → (1, 4, 5)
# 2. B扩展第一维: (1, 4, 5) → (2, 4, 5)
# 矩阵乘法: (2, 3, 4) @ (2, 4, 5) → (2, 3, 5)
result = A @ B # 结果形状: (2, 3, 5)print("A形状:", A.shape) # 输出: torch.Size([2, 3, 4])
print("B形状:", B.shape) # 输出: torch.Size([4, 5])
print("结果形状:", result.shape) # 输出: torch.Size([2, 3, 5])
A形状: torch.Size([2, 3, 4]) B形状: torch.Size([4, 5]) 结果形状: torch.Size([2, 3, 5])
2批量矩阵与批量矩阵相乘(部分广播)
# A: 批量大小为3,每个是2×4的矩阵
A = torch.randn(3, 2, 4) # 形状: (3, 2, 4)# B: 批量大小为1,每个是4×5的矩阵
B = torch.randn(1, 4, 5) # 形状: (1, 4, 5)# 广播过程:
# B扩展第一维: (1, 4, 5) → (3, 4, 5)
# 矩阵乘法: (3, 2, 4) @ (3, 4, 5) → (3, 2, 5)
result = A @ B # 结果形状: (3, 2, 5)print("A形状:", A.shape) # 输出: torch.Size([3, 2, 4])
print("B形状:", B.shape) # 输出: torch.Size([1, 4, 5])
print("结果形状:", result.shape) # 输出: torch.Size([3, 2, 5])
A形状: torch.Size([3, 2, 4]) B形状: torch.Size([1, 4, 5]) 结果形状: torch.Size([3, 2, 5])
3三维张量与二维张量相乘(高维广播)
# A: 批量大小为2,通道数为3,每个是4×5的矩阵
A = torch.randn(2, 3, 4, 5) # 形状: (2, 3, 4, 5)# B: 单个5×6的矩阵
B = torch.randn(5, 6) # 形状: (5, 6)# 广播过程:
# 1. B补全维度: (5, 6) → (1, 1, 5, 6)
# 2. B扩展第一维: (1, 1, 5, 6) → (2, 1, 5, 6)
# 3. B扩展第二维: (2, 1, 5, 6) → (2, 3, 5, 6)
# 矩阵乘法: (2, 3, 4, 5) @ (2, 3, 5, 6) → (2, 3, 4, 6)
result = A @ B # 结果形状: (2, 3, 4, 6)print("A形状:", A.shape) # 输出: torch.Size([2, 3, 4, 5])
print("B形状:", B.shape) # 输出: torch.Size([5, 6])
print("结果形状:", result.shape) # 输出: torch.Size([2, 3, 4, 6])
A形状: torch.Size([2, 3, 4, 5]) B形状: torch.Size([5, 6]) 结果形状: torch.Size([2, 3, 4, 6])
知识点回顾:
- 随机张量的生成:torch.randn函数
- 卷积和池化的计算公式(可以不掌握,会自动计算的)
- pytorch的广播机制:加法和乘法的广播机制
ps:numpy运算也有类似的广播机制,基本一致
作业:
自己多借助ai举几个例子帮助自己理解即可
一、随机张量生成:torch.randn 函数
功能
生成服从 标准正态分布(均值为 0,方差为 1) 的随机张量。
常见用法与示例
python
运行
import torch# 示例1:生成形状为 (3, 4) 的随机张量(2维)
tensor1 = torch.randn(3, 4)
print("tensor1 shape:", tensor1.shape)
print("tensor1内容:\n", tensor1)# 示例2:生成形状为 (2, 3, 5) 的随机张量(3维,常用于图像批次)
tensor2 = torch.randn(2, 3, 5) # 假设 batch_size=2,通道数=3,尺寸=5x5
print("\ntensor2 shape:", tensor2.shape)
print("tensor2内容:\n", tensor2)# 示例3:生成指定数据类型的张量(如 float64)
tensor3 = torch.randn(2, 2, dtype=torch.float64)
print("\ntensor3 dtype:", tensor3.dtype)
输出说明
plaintext
tensor1 shape: torch.Size([3, 4])
tensor1内容:
tensor([[ 0.123, -0.456, 0.789, -1.012],
[-2.345, 3.456, -4.567, 5.678],
[-6.789, 7.890, -8.901, 9.012]])
tensor2 shape: torch.Size([2, 3, 5])
tensor2内容:
tensor([[[-0.111, 0.222, -0.333, 0.444, -0.555],
[ 0.666, -0.777, 0.888, -0.999, 1.010],
[ 1.111, -1.222, 1.333, -1.444, 1.555]],
[[-1.666, 1.777, -1.888, 1.999, -2.010],
[ 2.111, -2.222, 2.333, -2.444, 2.555],
[-2.666, 2.777, -2.888, 2.999, -3.010]]])
tensor3 dtype: torch.float64
二、PyTorch 广播机制(加法和乘法)
核心规则
当两个张量形状不同时,PyTorch 会自动扩展维度较小的张量,使其形状与另一个张量兼容,前提是:
- 从后往前(右到左)对比维度,每个维度要么相等,要么其中一个为 1。
- 扩展的维度会被 “复制”,以匹配另一个张量的形状。
示例 1:加法广播(维度互补)
python
运行
# 张量A:形状 (3, 1),张量B:形状 (1, 4)
A = torch.tensor([[1], [2], [3]]) # shape (3, 1)
B = torch.tensor([[1, 2, 3, 4]]) # shape (1, 4)
C = A + B # 广播后形状变为 (3, 4)
print("A + B 的结果:\n", C)
广播过程分析
- A 的形状:(3, 1) → 从右到左维度为 [1, 3](注意 PyTorch 按 (dim0, dim1) 存储,这里从后往前是 dim1=1, dim0=3)。
- B 的形状:(1, 4) → 从右到左维度为 [4, 1]。
- 对比维度:最后一维(列):A 的维度是 1,B 的维度是 4 → 兼容,A 的列会被复制为 4 列。
- 第一维(行):A 的维度是 3,B 的维度是 1 → 兼容,B 的行会被复制为 3 行。
- 结果形状:(3, 4)。
输出结果
plaintext
A + B 的结果:
tensor([[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7]])
示例 2:乘法广播(维度为 1 的扩展)
python
运行
# 张量X:形状 (2, 3, 4),张量Y:形状 (4,)
X = torch.randn(2, 3, 4) # shape (2, 3, 4)
Y = torch.tensor([1, 2, 3, 4]) # shape (4,) → 等价于 (1, 1, 4)
Z = X * Y # 广播后Y形状变为 (1, 1, 4),与X的 (2, 3, 4) 兼容
print("X * Y 的形状:", Z.shape)
广播过程分析
- Y 的形状:(4,) → 视为 (1, 1, 4)(补前两个维度为 1)。
- 对比维度:最后一维(4):相等,无需扩展。
- 前两维(1 和 1):与 X 的 (2, 3) 兼容,Y 会被复制为 (2, 3, 4)。
- 结果形状:(2, 3, 4)。
三、Numpy 广播机制(与 PyTorch 基本一致)
示例:Numpy 加法广播
python
运行
import numpy as np# 数组A:形状 (3, 1),数组B:形状 (1, 4)
A = np.array([[1], [2], [3]])
B = np.array([[1, 2, 3, 4]])
C = A + B # 结果与 PyTorch 示例1完全一致
print("Numpy A + B 的结果:\n", C)
输出结果
plaintext
Numpy A + B 的结果:
[[2 3 4 5]
[3 4 5 6]
[4 5 6 7]]
四、卷积和池化(自动计算,无需手动公式)
在 PyTorch 中,卷积和池化通过定义层(如 nn.Conv2d, nn.MaxPool2d)实现,框架会自动计算输出形状。以下是简单示例:
示例:2D 卷积层
python
运行
import torch.nn as nn# 输入:batch_size=1,通道数=1,尺寸=5x5
x = torch.randn(1, 1, 5, 5)
# 卷积层:输入通道=1,输出通道=2,卷积核=3x3,步长=1,填充=0
conv_layer = nn.Conv2d(in_channels=1, out_channels=2, kernel_size=3)
output = conv_layer(x) # 输出形状:(1, 2, 3, 3)(自动计算:(5-3+1)=3)
print("卷积输出形状:", output.shape)
示例:最大池化层
python
运行
# 池化层:核大小=2x2,步长=2
pool_layer = nn.MaxPool2d(kernel_size=2, stride=2)
pooled = pool_layer(output) # 输出形状:(1, 2, 1, 1)(3//2=1)
print("池化输出形状:", pooled.shape)
@浙大疏锦行
相关文章:
Python_day48随机函数与广播机制
在继续讲解模块消融前,先补充几个之前没提的基础概念 尤其需要搞懂张量的维度、以及计算后的维度,这对于你未来理解复杂的网络至关重要 一、 随机张量的生成 在深度学习中经常需要随机生成一些张量,比如权重的初始化,或者计算输入…...

【QT】qtdesigner中将控件提升为自定义控件后,css设置样式不生效(已解决,图文详情)
目录 0.背景 1.解决思路 2.详细代码 0.背景 实际项目中遇到的问题,描述如下: 我在qtdesigner用界面拖了一个QTableView控件,object name为【tableView_electrode】,然后【提升为】了自定义的类【Steer_Electrode_Table】&…...

【Docker 02】Docker 安装
🌈 一、各版本的平台支持情况 ⭐ 1. Server 版本 Server 版本的 Docker 就只有个命令行,没有界面。 Platformx86_64 / amd64arm64 / aarch64arm(32 - bit)s390xCentOs√√Debian√√√Fedora√√Raspbian√RHEL√SLES√Ubuntu√√√√Binaries√√√ …...
【大厂机试题+算法可视化】最长的指定瑕疵度的元音子串
题目 开头和结尾都是元音字母(aeiouAEIOU)的字符串为元音字符串,其中混杂的非元音字母数量为其瑕疵度。比如: “a” 、 “aa”是元音字符串,其瑕疵度都为0 “aiur”不是元音字符串(结尾不是元音字符) “…...
【免杀】C2免杀技术(十五)shellcode混淆uuid/ipv6/mac
针对 shellcode 混淆(Shellcode Obfuscation) 的实战手段还有很多,如下表所示: 类型举例目的编码 / 加密XOR、AES、RC4、Base64、Poly1305、UUID、IP/MAC改变字节特征,避开静态签名或 YARA结构伪装PE Stub、GIF/PNG 嵌入、RTF OLE、UUID、IP/MAC看起来像合法文件/数据,弱…...
Java严格模式withResolverStyle解析日期错误及解决方案
在Java中使用DateTimeFormatter并启用严格模式(ResolverStyle.STRICT)时,解析日期字符串"2025-06-01"报错的根本原因是:模式字符串中的年份格式yyyy被解释为YearOfEra(纪元年份),而非…...
Async-profiler 内存采样机制解析:从原理到实现
引言 在 Java 性能调优的工具箱中,async-profiler 是一款备受青睐的低开销采样分析器。它不仅能分析 CPU 热点,还能精确追踪内存分配情况。本文将深入探讨 async-profiler 实现内存采样的多种机制,结合代码示例解析其工作原理。 为什么需要内…...
C++ 使用 ffmpeg 解码 rtsp 流并获取每帧的YUV数据
一、简介 FFmpeg 是一个开源的多媒体处理框架,非常适用于处理音视频的录制、转换、流化和播放。 二、代码 示例代码使用工作线程读取rtsp视频流,自动重连,支持手动退出,解码并将二进制文件保存下来。 注意: 代…...
Java毕业设计:办公自动化系统的设计与实现
JAVA办公自动化系统 一、系统概述 本办公自动化系统基于Java EE平台开发,实现了企业日常办公的数字化管理。系统包含文档管理、流程审批、会议管理、日程安排、通讯录等核心功能模块,采用B/S架构设计,支持多用户协同工作。系统使用Spring B…...

论文笔记:Large Language Models for Next Point-of-Interest Recommendation
SIGIR 2024 1 intro 传统的基于数值的POI推荐方法在处理上下文信息时存在两个主要限制 需要将异构的LBSN数据转换为数字,这可能导致上下文信息的固有含义丢失仅依赖于统计和人为设计来理解上下文信息,缺乏对上下文信息提供的语义概念的理解 ——>使用…...

LeetCode 2894.分类求和并作差
目录 题目: 题目描述: 题目链接: 思路: 思路一详解(遍历 判断): 思路二详解(数学规律/公式): 代码: Java思路一(遍历 判断&a…...
n8n:解锁自动化工作流的无限可能
在当今快节奏的数字时代,无论是企业还是个人,都渴望提高工作效率,减少重复性任务的繁琐操作。而 n8n,这个强大的开源自动化工具,就像一位智能的数字助手,悄然走进了许多人的工作和生活,成为提升…...
链结构与工作量证明7️⃣:用 Go 实现比特币的核心机制
链结构与工作量证明:用 Go 实现比特币的核心机制 如果你用 Go 写过区块、算过哈希,也大致理解了非对称加密、数据序列化这些“硬核知识”,那么恭喜你,现在我们终于可以把这些拼成一条完整的“区块链”。 不过别急,这一节我们重点搞懂两件事: 区块之间是怎么连接成“链”…...
CMake系统学习笔记
CMake系统学习笔记 基础操作 最基本的案例 // code #include <iostream>int main() {std::cout << "hello world " << std::endl;return 0; }// CMakeLists.txt cmake_minimum_required(VERSION 3.0)# 定义当前工程名称 project(demo)add_execu…...

CCF 开源发展委员会 “开源高校行“ 暨红山开源 + OpenAtom openKylin 高校行活动在西安四所高校成功举办
点击蓝字 关注我们 CCF Opensource Development Committee CCF开源高校行 暨红山开源 openKylin 高校行 西安站 5 月 26 日至 28 日,CCF 开源发展委员会 "开源高校行" 暨红山开源 OpenAtom openKylin 高校行活动在西安四所高校(西安交通大学…...
【Go语言基础【6】】字符串格式化说明
文章目录 零、格式化常用场景一、Go 字符串格式化核心概念二、常用格式化占位符1. 整数类型2. 浮点数类型3. 字符串与布尔类型4. 指针与通用类型 三、宽度与精度控制1. 宽度控制2. 精度控制(浮点数/字符串) 零、格式化常用场景 数值转字符串:…...
调试快捷键 pycharm vscode
目录 调试快捷键 pycharm vscode 修改快捷键 方法 1:通过菜单打开 方法 2:用快捷键打开 调试快捷键 pycharm Resume Program F9 Step Over F8 两个离的比较近,比较方便,比vscode的好。 vscode Continue F5 改为F9 S…...

RabbitMQ work模型
Work 模型是 RabbitMQ 最基础的消息处理模式,核心思想是 多个消费者竞争消费同一个队列中的消息,适用于任务分发和负载均衡场景。同一个消息只会被一个消费者处理。 当一个消息队列绑定了多个消费者,每个消息消费的个数都是平摊的&a…...

基于微信小程序的作业管理系统源码数据库文档
作业管理系统 摘 要 随着社会的发展,社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用java语言技术和微信小程序来完成对系统的…...
C++参数传递 a与a的区别
在 C 中,&a(引用)和 a(值传递) 的关键区别在于 参数如何传递给函数,以及由此引发的 性能、语义和安全问题。 最核心的在于你想不想传入的参数被改变,如果想,就用参数传递&#…...

CSS(2)
文章目录 Emmet语法快速生成HTML结构语法 Snipaste快速生成CSS样式语法快速格式化代码 快捷键(VScode)CSS 的复合选择器什么是复合选择器交集选择器后代选择器(重要)子选择器(重要)并集选择器(重要)**链接伪类选择器**focus伪类选…...
Linux--vsFTP配置篇
一、vsFTP 简介 vsftpd(Very Secure FTP Daemon)是 Linux 下常用的 FTP 服务程序,具有安全性高、效率高和稳定性好等特点。支持匿名访问、本地用户登录、虚拟用户等多种认证方式,并可灵活控制权限。 二、安装与启动 1. 检查是否已…...

【RabbitMQ】- Channel和Delivery Tag机制
在 RabbitMQ 的消费者代码中,Channel 和 tag 参数的存在是为了实现消息确认机制(Acknowledgment)和精细化的消息控制。 Channel 参数 作用 Channel 是 AMQP 协议的核心操作接口,通过它可以直接与 RabbitMQ 交互: 手…...
.Net Framework 4/C# 面向对象编程进阶
一、继承 (一)使用继承 子类可以继承父类原有的属性和方法,也可以增加原来父类不具备的属性和方法,或者直接重写父类中的某些方法。 C# 中使用“:”来表示两个类的继承。子类不能访问父类的私有成员,但是可以访问其公有成员,即只要使用 public 声明类成员,就既可以让一…...

NLP学习路线图(三十四): 命名实体识别(NER)
一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…...

【HTML】HTML 与 CSS 基础教程
作为 Java 工程师,掌握 HTML 和 CSS 也是需要的,它能让你高效与前端团队协作、调试页面元素,甚至独立完成简单页面开发。本文将用最简洁的方式带你掌握核心概念。 一、HTML,网页骨架搭建 核心概念:HTML通过标签定义内…...
【NLP】 38. Agent
什么是 Agent? 一个 Agent 就是能够 理解、思考,并且进行世界交互 的模型系统,并不是纯粹的 prompt 返回器。 它可以: 读取外部数据(文件/API)使用记忆进行上下文维持用类Chain-of-Thought (CoT)方式进行…...

Windows开机自动启动中间件
WinSW(Windows Service Wrapper 是一个开源的 Windows 服务包装器,它可以帮助你将应用程序打包成系统服务,并实现开机自启动的功能。 一、下载 WinSW 下载 WinSW-x64.exe v2.12.0 (⬇️ 更多版本下载) 和 sample-minimal.xml 二、配置 WinS…...
AIGC 基础篇 Python基础 02
1.bool类型 书接上回,我们上次最后讲了三大数据类型,除了这三个之外,Python也有bool类型,也就是True和False。 a 2 print(a1) print(a2) 像这里,输出的内容第一个是False,因为a的值为2,而第…...

【图片转AR场景】Tripo + Blender + Kivicube 实现图片转 AR 建模
总览 1.将 2D 图片转为立体建模 2. 3. 一、将 2D 图片转为立体建模 1.工具介绍 Tripo 网站 2.找图片 找的图片必须是看起来能够让 AI 有能力识别和推理的,因为现在的AI虽然可以补全但是能力还没有像人的想象力那么丰富。 比如上面这张图片,看起来虽…...