机器学习基础 多层感知机

文章目录

  • 机器学习基础 多层感知机
  • 1. 多层感知机
    • 1.1 线性模型的失效
    • 1.2 感知机
    • 1.3 感知机的收敛定理
    • 1.4 从线性到非线性
    • 1.5 多层感知机的定义和实现
  • 参考

1. 多层感知机

1.1 线性模型的失效

​ 在李沐《动手学深度学习》中有这样的描述:

​ 我们想要根据体温预测死亡率。 对体温高于37摄氏度的人来说,温度越高风险越大。 然而,对体温低于37摄氏度的人来说,温度越高风险就越低。 在这种情况下,我们也可以通过一些巧妙的预处理来解决问题。 例如,我们可以使用与37摄氏度的距离作为特征。

​ 有些现实问题确实可以通过线性关系来近似建模,甚至在一些简单的非线性场景中可以通过特征工程,如取对数、取绝对差进一步解决。但在如图像分类等复杂场景中,线性模型就失效了。

​ 比如,在对猫和狗的图像进行分类时,如果我改变图像中的一个像素(比如让它更亮),是否总是会让这张图片更像狗,或者更像猫呢?在线性模型中,假设每个像素对分类结果的影响是独立的、直接的、线性的,可以简单地将所有像素的加权和相加就能做出判断。但显然,在图像分类中行不通,这是因为任何像素的重要性都以复杂的方式取决于该像素的上下文。比如,一小块黑色像素在狗的鼻子上,可能很重要。但一模一样的小块黑色像素在背景上,可能毫无用处。

​ 那么,我们或许可以找到一种更加高级的特征表达,比如“边缘”、“形状”、“局部结构”,分类可能会更简单。然而,这种高级特征的表示我们难以像之前说的特征工程那样设计出来,因为太复杂了。

1.2 感知机

​ 感知机是一种简单的线性模型,给定输入 x \boldsymbol{x} x,权重 w \boldsymbol{w} w 和偏移 b b b,感知机的输出为:
o = σ ( ⟨ w , x ⟩ + b ) , (1) o=\sigma(\lang \boldsymbol{w},\boldsymbol{x}\rang +b),\tag{1} o=σ(⟨w,x+b),(1)

σ ( x ) { 1 , if x > 0 , − 1 , otherwise. (2) \sigma(x) \begin{cases} 1,&\text{if}\quad x>0,\\[4pt] -1,&\text{otherwise.} \end{cases}\tag{2} σ(x){1,1,ifx>0,otherwise.(2)在这里插入图片描述

在这里插入图片描述

图1 感知机示意图.

​ 感知机的训练是这样的,首先初始化一个样本的权重 w w w 和偏移 b b b 都为0,然后重复以下操作:如果 :
y i [ ⟨ w , x i ⟩ + b ] ≤ 0 , (3) y_i[\lang w,x_i\rang+b]\le 0,\tag{3} yi[⟨w,xi+b]0,(3)
那么使用以下方式更新参数:
w ← w + y i x i , b ← b + y i , (4) w\leftarrow w+y_ix_i,\quad b\leftarrow b+y_i,\tag{4} ww+yixi,bb+yi,(4)
直到所有类别都分类正确。

​ 感知机等价于批量大小为 1 的梯度下降,因为每次都一个样本进行梯度下降。感知机的损失函数为:
l ( y , x , w ) = max ⁡ ( 0 , − y ⟨ w , x ⟩ ) . (5) \mathscr{l}(y,\boldsymbol{x},\boldsymbol{w})=\max(0,-y\lang\boldsymbol{w},\boldsymbol{x}\rang).\tag{5} l(y,x,w)=max(0,yw,x⟩).(5)

在这里插入图片描述

图2 线性可分示意图.

​ 如图 2 所示,感知机拟合出来的是一条直线,每次加入一个训练样本,每次都去调整这条直线。那么,如何证明对于一个线性可分的数据集,感知机经过有限次迭代可以得到一个将训练数据集完全正确划分的分离超平面呢?

1.3 感知机的收敛定理

​ 定义如下训练样本:
T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } , (6) T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\},\tag{6} T={(x1,y1),(x2,y2),,(xN,yN)},(6)
每个输入向量 x i ∈ R n x_i\in\mathbb{R}^n xiRn y i ∈ { − 1 , + 1 } y_i\in\{-1,+1\} yi{1,+1} i = 1 , 2 , ⋯ , N i=1,2,\cdots,N i=1,2,,N,把偏置 b b b 合并进权重向量,定义:
x ^ i = ( x i 1 ) ∈ R n + 1 . (7) \hat{x}_i= \begin{pmatrix} x_i\\[4pt]1 \end{pmatrix}\in\mathbb{R}^{n+1}.\tag{7} x^i=(xi1)Rn+1.(7)
​ 同样,将权重向量 w ∈ R n w\in\mathbb{R}^n wRn 与偏置 b ∈ R b\in\mathbb{R} bR 合并为:
w ^ = ( w b ) ∈ R n + 1 . (8) \hat{w}= \begin{pmatrix} w\\[4pt]b \end{pmatrix}\in\mathbb{R}^{n+1}.\tag{8} w^=(wb)Rn+1.(8)
​ 分类决策依赖于符号函数:
f ( x ) = sign ( w T x + b ) = sign ( w ^ T x ^ ) . (9) f(x)=\text{sign}(w^Tx+b)=\text{sign}(\hat{w}^T\hat{x}).\tag{9} f(x)=sign(wTx+b)=sign(w^Tx^).(9)
​ 假设数据集线性可分,那么一定存在一个超平面,使得对所有的 i i i 都有:
y i ( w o p t T x i + b o p t ) > 0. (10) y_i(w_{opt}^Tx_i+b_{opt})>0.\tag{10} yi(woptTxi+bopt)>0.(10)
​ 可以把最优解 ( w o p t , b o p t ) (w_{opt},b_{opt}) (wopt,bopt) 规范化,使得 ∥ w ^ o p t ∥ = 1 \lVert \hat{w}_{opt} \rVert=1 w^opt=1,定义间隔 γ \gamma γ 为:
γ = min ⁡ 1 ≤ i ≤ N y i ( w ^ o p t T x ^ i ) > 0 , (11) \gamma = \underset{1\le i\le N}{\min}\ y_i(\hat{w}_{opt}^T\hat{x}_i)>0,\tag{11} γ=1iNmin yi(w^optTx^i)>0,(11)
这表示所有样本到超平面的“带符号距离”的最小值,间隔越大,分类越“稳健”。

​ 定义样本半径 R R R 为:
R = max ⁡ 1 ≤ i ≤ N ∥ x ^ i ∥ , (12) R=\underset{1\le i\le N}{\max}\ \lVert \hat{x}_i \rVert,\tag{12} R=1iNmax x^i,(12)
可知,样本半径是离原点最远的样本点到原点的距离。

​ 在初始化阶段,令 w ^ 0 = 0 \hat{w}_0=0 w^0=0,在第 k k k 步,如果样本 ( x i , y i ) (x_i,y_i) (xi,yi) 被误分类,则:
y i ( w ^ k − 1 T x ^ i ) ≤ 0. (13) y_i(\hat{w}_{k-1}^T\hat{x}_i)\le 0.\tag{13} yi(w^k1Tx^i)0.(13)
​ 对误分类样本 ( x i , y i ) (x_i,y_i) (xi,yi) 进行更新:
w ^ t = w ^ k − 1 + η y i x ^ i , (14) \hat{w}_t=\hat{w}_{k-1}+\eta y_i\hat{x}_i,\tag{14} w^t=w^k1+ηyix^i,(14)
其中, η > 0 \eta>0 η>0 是学习率,需注意的是,在每 k k k 轮,感知机都随机取一个样本对参数进行更新,而不是取批量的样本更新。

​ 我们要证明的是,误分类次数 k k k 是有限的,并且满足:
k ≤ ( R γ ) 2 . (15) k\le (\frac{R}{\gamma})^2.\tag{15} k(γR)2.(15)
​ 第一步需要证明方向增益下界:
w ^ k ⋅ w ^ o p t ≥ k η γ . (16) \hat{w}_k\cdot \hat{w}_{opt}\ge k\eta \gamma.\tag{16} w^kw^optkηγ.(16)
​ 由于:
w ^ k T w ^ o p t = w ^ k − 1 T w ^ o p t + η y i x ^ i T w ^ o p t , (17) \hat{w}_k^T\hat{w}_{opt}=\hat{w}_{k-1}^T\hat{w}_{opt}+\eta y_i \hat{x}_{i}^T\hat{w}_{opt},\tag{17} w^kTw^opt=w^k1Tw^opt+ηyix^iTw^opt,(17)
由式 (11) 可知, γ \gamma γ 被定义为所有样本 y i ( w ^ o p t T x ^ i ) y_i(\hat{w}_{opt}^T\hat{x}_i) yi(w^optTx^i) 的最小值,由于数据集线性可分,则必然存在一个超平面使得:
y i ( w ^ o p t T x ^ i ) ≥ γ > 0 , ∀ i , (18) y_i(\hat{w}_{opt}^T\hat{x}_i)\ge \gamma>0,\quad \forall i,\tag{18} yi(w^optTx^i)γ>0,i,(18)
具体地, w ^ o p t T x ^ i \hat{w}_{opt}^T\hat{x}_i w^optTx^i 的几何意义为样本点 x ^ i \hat{x}_i x^i 到超平面的距离的投影,用来衡量距离超平面有多远。至于为什么这是点到超平面的距离,可以回忆一下高中的距离公式,结合前面的向量合并就可以理解了:
d = ∣ w ⋅ x i + b ∣ ∥ w ∥ . (19) d=\frac{\lvert w\cdot x_i+b\rvert}{\lVert w \rVert}.\tag{19} d=wwxi+b.(19)
​ 因此,可以把公式 (17) 化简为:
w ^ k T w ^ o p t ≥ w ^ k − 1 T w ^ o p t + η γ , (20) \hat{w}_k^T\hat{w}_{opt}\ge \hat{w}_{k-1}^T\hat{w}_{opt}+\eta \gamma,\tag{20} w^kTw^optw^k1Tw^opt+ηγ,(20)
递推 k k k 次后可得:
w ^ k T w ^ o p t ≥ k η γ . (21) \hat{w}_k^T\hat{w}_{opt}\ge k\eta\gamma.\tag{21} w^kTw^optkηγ.(21)
​ 接下来证明范数增长上界:
∥ w ^ k T ∥ 2 ≤ k η 2 R 2 . (22) \lVert\hat{w}_k^T\rVert^2\le k\eta^2R^2.\tag{22} w^kT2kη2R2.(22)
​ 由公式 (14) 可得:
∥ w ^ k ∥ 2 = ∥ w ^ k − 1 ∥ 2 + 2 η y i w ^ k − 1 T x ^ i + η 2 ∥ x ^ i ∥ 2 , (23) \lVert \hat{w}_k \rVert^2=\lVert \hat{w}_{k-1} \rVert^2+2\eta y_i \hat{w}_{k-1}^T\hat{x}_{i}+\eta^2\lVert \hat{x}_i \rVert^2,\tag{23} w^k2=w^k12+2ηyiw^k1Tx^i+η2x^i2,(23)
上式中,因为 y i 2 = 1 y_i^2=1 yi2=1,所以没写。由于误分类时有:
y i w ^ k − 1 T x ^ i ≤ 0 , (24) y_i\hat{w}_{k-1}^T\hat{x}_i\le 0,\tag{24} yiw^k1Tx^i0,(24)
结合式 (12) 可将上式 (23) 化简为:
∥ w ^ k ∥ 2 ≤ ∥ w ^ k − 1 ∥ 2 + η 2 ∥ x ^ i ∥ 2 ≤ ∥ w ^ k − 1 ∥ 2 + η 2 R 2 . (25) \lVert \hat{w}_k \rVert^2\le\lVert \hat{w}_{k-1} \rVert^2+\eta^2\lVert \hat{x}_i \rVert^2\le \lVert \hat{w}_{k-1} \rVert^2+\eta^2R^2.\tag{25} w^k2w^k12+η2x^i2w^k12+η2R2.(25)
​ 同样迭代 k k k 步可得:
∥ w ^ k ∥ 2 ≤ k η 2 R 2 . (26) \lVert \hat{w}_k \rVert^2\le k\eta^2R^2.\tag{26} w^k2kη2R2.(26)
​ 由柯西 - 施瓦茨不等式得:
w ^ k T w ^ o p t ≤ ∥ w ^ k ∥ ∥ w ^ o p t ∥ , (27) \hat{w}_k^T\hat{w}_{opt}\le \lVert \hat{w}_k \rVert\lVert \hat{w}_{opt} \rVert,\tag{27} w^kTw^optw^kw^opt,(27)
因为我们在之前规范化了 ∥ w ^ o p t ∥ = 1 \lVert \hat{w}_{opt} \rVert=1 w^opt=1,所以:
w ^ k T w ^ o p t ≤ ∥ w ^ k ∥ . (28) \hat{w}_k^T\hat{w}_{opt}\le\lVert \hat{w}_k \rVert.\tag{28} w^kTw^optw^k.(28)
​ 结合式 (16) 和式 (22) 可得:
k η γ ≤ w ^ k T w ^ o p t ≤ ∥ w ^ k ∥ ≤ k η R , (29) k\eta\gamma\le \hat{w}_{k}^T\hat{w}_{opt}\le \lVert \hat{w}_k\rVert\le \sqrt{k}\eta R,\tag{29} kηγw^kTw^optw^kk ηR,(29)
解上面的不等式得:
k η γ ≤ k η R ⇒ k ≤ ( R γ ) 2 . (30) k\eta\gamma\le\sqrt{k}\eta R\Rightarrow k\le(\frac{R}{\gamma})^2.\tag{30} kηγk ηRk(γR)2.(30)

1.4 从线性到非线性

图3 XOR 问题.

​ 对于线性可分的数据集在上个章节进行了充分的讨论,但是对于图 3 这张 XOR 问题,感知机就无法解决了。那么,如何学习 XOR 问题呢?如图 4 所示,学习两个直线:黄线和蓝线,然后取异或得到最后结果。

在这里插入图片描述

图4 学习 XOR 问题.

​ 对于感知机,如何实现这一点呢?答案是加入隐藏层,变成多层感知机。

1.5 多层感知机的定义和实现

​ 假设现在是一个单分类问题,输入为 x ∈ R n \boldsymbol{x}\in \mathbb{R}^n xRn,隐藏层 W 1 ∈ R m × n \boldsymbol{W}_1\in\mathbb{R}^{m\times n} W1Rm×n b 1 ∈ R m \boldsymbol{b}_1\in\mathbb{R}^m b1Rm,这里的 m m m 是隐藏层的数量,输出层 w 2 ∈ R m \boldsymbol{w}_2\in\mathbb{R}^m w2Rm b 2 ∈ R b_2\in\mathbb{R} b2R,有以下定义:
h = σ ( W 1 x + b 1 ) , o = w 2 T h + b 2 , (31) \begin{align} \boldsymbol{h}&=\sigma(\boldsymbol{W}_1\boldsymbol{x}+\boldsymbol{b}_1),\\[4pt] o&=\boldsymbol{w}_2^T\boldsymbol{h}+b_2, \end{align}\tag{31} ho=σ(W1x+b1),=w2Th+b2,(31)
其中, σ \sigma σ 是按元素的激活函数。

​ 可知,隐藏表示 h ∈ R m \boldsymbol{h}\in\mathbb{R}^{m} hRm o ∈ R o\in\mathbb{R} oR

图5 多层感知机示意图.

​ 多分类也是同理,变换一下维度即可推导出来。代码实现来源于李沐《动手学深度学习》:4.1. 多层感知机。

import torchvision
import torch
from torch import nn
from torchvision import transforms
from torch.utils.data import DataLoadertrans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)batch_size = 256
train_iter = DataLoader(mnist_train, batch_size=batch_size, shuffle=True)
test_iter = DataLoader(mnist_test, batch_size=batch_size, shuffle=False)
#%%
num_inputs, num_outputs, hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(num_inputs, hiddens, requires_grad=True))
b1 = nn.Parameter(torch.zeros(hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(hiddens, num_outputs, requires_grad=True))
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))params = [W1, b1, W2, b2]
# Q:为什么W1和W2不是初始化为0,而是随机?
# A:因为如果初始化为 0,梯度下降会导致每个神经元的权重更新相同,无法学习到有效的特征。随机初始化可以打破对称性,使得每个神经元学习到不同的特征。
#%%
def relu(X):a = torch.zeros_like(X) # 创建一个与X形状相同的全零张量return torch.max(X, a)  # 元素级别的比较,返回每个元素与0的最大值
#%%
def net(X):X = X.reshape((-1, num_inputs))  # 展平输入H = relu(X @ W1 + b1)  # 第一层的线性变换和ReLU激活return H @ W2 + b2  # 第二层的线性变换loss = nn.CrossEntropyLoss()
# Q:H = relu(X @ W1 + b1) 中的 @ 符号表示什么?
# A: @ 符号表示矩阵乘法(点积),它是 PyTorch 中用于进行矩阵乘法的运算符。
# Q:不可以用*嘛?
# A: * 符号表示元素级别的乘法,而 @ 符号表示矩阵乘法。在神经网络中,我们通常需要进行矩阵乘法来计算线性变换。
#%%
def accuracy(y_hat, y):if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = y_hat.argmax(axis=1)# 确保 y 是 Tensorif not isinstance(y, torch.Tensor):y = torch.tensor(y)cmp = y_hat.type(y.dtype) == yreturn float(cmp.type(torch.float).sum().item())
#%%
class Accumulator:def __init__(self, n):self.data = [0.0] * ndef add(self, *args):for i, arg in enumerate(args):self.data[i] += argdef reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]
#%%
def evaluate_accuracy(net, data_iter):if isinstance(net, torch.nn.Module):net.eval()  # 设置为评估模式metric = Accumulator(2)  # (正确预测数, 总样本数)for X, y in data_iter:with torch.no_grad():y_hat = net(X)acc = accuracy(y_hat, y)metric.add(acc, y.numel())  # y 必须是 Tensorreturn metric[0] / metric[1]
#%%
def train_epoch_ch3(net, train_iter, loss, updater):if isinstance(net, torch.nn.Module):net.train()  # 设置为训练模式metric = Accumulator(3)  # 累加器,用于计算总损失、正确预测的数量和总样本数for X, y in train_iter:y_hat = net(X)  # 前向传播l = loss(y_hat, y).sum()  # 计算损失if isinstance(updater, torch.optim.Optimizer):updater.zero_grad()  # 清零梯度l.backward()  # 反向传播updater.step()  # 更新参数else:l.sum().backward()  # 手动反向传播updater(X.shape[0])  # 更新参数metric.add(l.item(), accuracy(y_hat, y), y.numel())  # 累加损失、正确预测数量和样本数return metric[0] / metric[2], metric[1] / metric[2]  # 返回平均损失和准确率
#%%
def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):for epoch in range(num_epochs):train_metrics = train_epoch_ch3(net, train_iter, loss, updater)  # 训练一个epochtest_acc = evaluate_accuracy(net, test_iter)  # 在测试集上评估准确率print(f'epoch {epoch + 1}, loss {train_metrics[0]:f}, 'f'train acc {train_metrics[1]:f}, test acc {test_acc:f}')
#%%
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)

参考

[1] 李沐《动手学机器学习》

[2] 李航《统计学习方法》

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

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

相关文章

关于安装Ollama大语言模型本地部署工具

一、Ollama 安装方法概述 Ollama 是一个开源的大型语言模型(LLM)本地部署工具,支持在 Windows、macOS 和 Linux 系统上运行。它简化了在本地计算机上运行和管理大语言模型的流程,让开发者能够轻松部署各种开源模型。 Windows 系统安装步骤 访问 Ollam…

html配置rem实现页面自适应

1.在js文件使用,建议放到全局js中 // 全局js文件 $(function () {// 设置根目录字体大小var baseSize 16; // 设计稿的基准字体大小,通常是16pxvar baseWidth 750; // 设计稿的基准宽度,通常是750pxfunction adjustFontSize() {const widt…

POI实现文档的图片的提取和替换

1. 简介 在日常办公自动化开发中,常常需要对 Word 文档中的图片进行批量提取、保存,甚至将图片替换为自定义的文本或链接。Apache POI 是一款强大的 Java 开源库,支持对 Microsoft Office 文档(包括 Word、Excel、PowerPoint 等&…

毫米波雷达 – 深度学习

目录 数据表示 公开数据库 未来发展方向 稀疏点云 + 深度学习 直接处理点云 (1/2) 候选生成+特征提取+候选分类(DL* ) 候选生成+特征提取+候选分类(DL) 直接处理点云 (2/2) 候选生成+特征提取(DL)+候选分类(DL) 网格数据+端对端检测(DL) 稠密数据块 + 深度学习 直接…

Redis——常用指令汇总指南(一)

目录 1.set & get ①set指令 ②get指令 2.keys 3.del 4.expire & setex & psetex 5.ttl 6.exists 7.setnx 8.flushall 9.object encoding 10. type 1.set & get set & get指令中key和value都是字符串,但是不需要加单引号或双引号。 …

PDF处理控件Aspose.PDF教程:在 Java 中删除 PDF 页面

您是否需要使用 Java 从PDF文档中删除特定页面?无论您是要清理空白页、删除机密部分,还是仅仅在分发前调整内容,以编程方式操作 PDF 页面的能力都将大有裨益。本指南将向您展示如何借助Aspose.PDF仅用几行代码删除不需要的页面。让我们深入了…

RediSearch 字段类型与配置选项

1. 数值字段(NUMERIC) 用途:存储整数或浮点数,可进行范围查询与排序。 选项: SORTABLE:允许用 SORTBY 排序NOINDEX:不参与索引,仅供返回 定义语法 FT.CREATE idx ON HASH PREFIX…

PHP Yii2 安装SQL Server扩展-MAC M4 Pro芯片

MAC M4 Pro芯片版本,千锤百炼编译十几次终于成功 # 设置基础镜像并强制使用 x86_64 架构(适配 M4 芯片) FROM --platformlinux/amd64 php:8.1-fpm-alpine3.18WORKDIR /var/www/html# 可选:设置时区 ARG TZAsia/Shanghai ENV TZ${…

HTML初学者第二天

<1>HTML的语法规范 1.1标签 -双标签&#xff1a;如 <html></html> 前面的叫开始标签&#xff0c;后面的叫结束标签。 -单标签&#xff1a;如 <br /> 1.2基本语法概述 -HTML标签是由尖括号包围的关键词&#xff0c;例如<html>。 -HTML标…

【加解密与C】HASH系列(二) SHA

SHA&#xff08;安全散列算法&#xff09;简介 SHA&#xff08;Secure Hash Algorithm&#xff09;是由美国国家安全局&#xff08;NSA&#xff09;设计的一系列密码散列函数&#xff0c;用于将任意长度的数据转换为固定长度的散列值。SHA家族包括SHA-1、SHA-2&#xff08;含S…

【Python】进阶 - 数据结构与算法

系列篇章&#x1f389; No.文章1【Python】基础知识&#xff08;详细&#xff09;&#x1f680;2【Python】基础 - 循环、容器类型&#x1f680;3【Python】基础 - 推导式、函数&#x1f680;4【Python】基础 - 文件、异常、模块&#x1f680;5【Python】进阶 - 面向对象&…

【如何实现分布式压测中间件】

分布式压测中间件的原理及其实现 原理全链路追踪框架&#xff08;Trace&#xff09;MQ中间件数据库分布式缓存中间件&#xff08;Redis&#xff09;分库分表中间件 原理 通过大量阅读中间件源码&#xff0c;开源社区调研&#xff0c;得到设计原理&#xff1a; &#xff08;1&a…

Qt进程间保活方案:详解如何实现进程间通信与自动保活机制

目录 摘要 一、进程间保活的基本原理 二、具体步骤及代码示例 三、常见问题与优化 四、总体方案 摘要 在一些需要长时间运行的应用程序中&#xff0c;确保进程在意外退出时能够自动重启是一项非常重要的任务。尤其是在嵌入式开发、后台服务以及需要高可用性的场景下&#x…

Python-内置数据结构-list-tuple-bubble-字符串-bytes-bytesarray-切片-学习笔记

欠4年前自己的一份笔记&#xff0c;献给今后的自己。 分类 数值型 int、float、complex、bool 序列对象 字符串 str 列表 list tuple 键值对 集合set 字典dict 数值型 int、float、complex、bool都是class&#x…

利用事务钩子函数解决业务异步发送问题

利用事务钩子函数解决业务异步发送问题 一、问题背景二、实现方案1、生产者代码2、消费者代码 三、测试与验证1、未开启事务场景2、开启事务场景 四、项目结构及源码 一、问题背景 在某项业务中&#xff0c;需要在事务完成后&#xff0c;写入日志到某数据库中。需要要么都成功&…

uniapp选择相册

概述 一款针对Android平台下的图片选择器&#xff0c;支持从相册获取图片、视频、音频&拍照&#xff0c;支持裁剪(单图or多图裁剪)、压缩、主题自定义配置等功能&#xff0c;支持动态获取权限&适配Android 5.0系统的开源图片选择框架。 支持Uniapp和Uniapp X下的Vue2、…

MAC 多应用切换技巧,单应用切换技巧

在 Mac 上&#xff0c;有几种快捷键可以帮助你快速切换应用程序窗口&#xff1a; 1. Command (⌘) Tab - 这是最常用的快捷键&#xff0c;用于在打开的应用程序之间进行循环切换。按住 Command 键不放&#xff0c;然后反复按下 Tab 键可以选择下一个应用程序。当你松开 Comm…

SpringBoot+本地部署大模型实现知识库功能

SpringBoot本地部署大模型实现RAG知识库功能 1、Linux系统部署本地大模型1.1 安装ollama1.2 启动ollama1.3 下载deepseek模型 2、Springboot代码调用本地模型实现基础问答功能3、集成向量数据库4、知识库数据喂取5、最终实现RAG知识库功能 1、Linux系统部署本地大模型 1.1 安装…

嵌入式原理与应用篇---ARM

ARM 架构的 STM32 系列微控制器广泛应用于嵌入式系统开发&#xff0c;理解其汇编语言指令对于优化性能、访问硬件底层非常重要。下面详细解释常见的 ARM 汇编指令及其使用实例。 数据处理指令 1. MOV&#xff08;移动&#xff09; 功能&#xff1a;将立即数或寄存器值复制到…

【RHCSA-Linux考试题目笔记(自用)】servera的题目

一、开始 1、启动rhcsa环境 2、点击题目&#xff0c;看题 3、通过控制器来启动所有虚拟机 控制器 打开后点start&#xff0c;然后ok 之后进入一个有classroom、servera、serverb&#xff08;考试不一定叫这些名&#xff0c;但大差不差&#xff09;什么之类的界面&#xff0c;…