【机器学习】深入解析 PCA 与三元组损失:从理论推导到实践应用

深入解析 PCA 与三元组损失:从理论推导到实践应用

  • PCA (Principal Component Analysis) 主成分分析详解
    • 1. 基本概念
      • 1.1 什么是 PCA?
      • 1.2 核心目标
      • 1.3 应用场景
    • 2. 数学原理详解
      • 2.1 问题形式化
      • 2.2 数据预处理
      • 2.3 协方差矩阵的计算
      • 2.4 特征值分解
      • 2.5 最大方差推导
      • 2.6 数据降维
    • 3. 重要指标
      • 3.1 方差贡献率
      • 3.2 累积方差贡献率
    • 总结
  • PCA降维实战
    • 代码
    • 运行结果
  • 三元组损失 (Triplet Loss) 的详解
    • 1. 基本概念
    • 2. 数学公式与推导
      • 2.1 损失函数定义
      • 2.2 损失函数分段表示
      • 2.3 优化目标的几何解释
    • 3. 公式推导过程
      • 3.1 欧几里得距离的展开
      • 3.2 损失函数表达式的代入
    • 4. 模型训练与样本构造
      • 4.1 三元组样本选择
      • 4.2 训练过程
    • 5. 重要性质与参数选择
      • 5.1 边际值 \(\alpha\)
      • 5.2 嵌入空间维度
    • 总结
  • 三元组损失函数实战
    • 代码
    • 结果分析
  • 总结

PCA (Principal Component Analysis) 主成分分析详解

PCA 是一种强大的线性降维技术,广泛应用于机器学习和数据分析领域,其目标是通过线性变换将高维数据映射到低维空间,同时尽可能保留数据的主要信息。以下是 PCA 的理论基础与数学原理的详细解析。


1. 基本概念

1.1 什么是 PCA?

主成分分析 (PCA) 的核心思想是通过线性变换找到数据中“变化最大”的方向(即主成分),并将数据投影到这些方向上。这样可以实现数据降维,同时尽可能保留原始数据的信息。

其关键特性包括:

  • 降维:将 (n) 维数据映射到 (k) 维 ((k < n)),减少数据维度。
  • 保留方差:投影方向按数据方差大小排序,优先保留方差最大的方向。
  • 正交性:主成分彼此正交,保证信息不冗余。

1.2 核心目标

PCA 的目标是找到一组新的坐标轴,使得:

  1. 数据在这些轴上的投影方差最大。
  2. 新坐标轴之间相互正交。

1.3 应用场景

PCA 常用于以下场景:

  • 降维:减少数据维度,去掉冗余特征。
  • 可视化:将高维数据映射到 2D 或 3D 空间,便于观察。
  • 噪声过滤:通过忽略小方差的主成分来去除噪声。
  • 特征提取:用少量无关的主成分代替原始特征。

2. 数学原理详解

2.1 问题形式化

假设我们有一个 (m \times n) 的数据矩阵 (X),其中 (m) 为样本数,(n) 为特征数:
X = [ x 11 x 12 ⋯ x 1 n x 21 x 22 ⋯ x 2 n ⋮ ⋮ ⋱ ⋮ x m 1 x m 2 ⋯ x m n ] . X = \begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1n} \\ x_{21} & x_{22} & \cdots & x_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ x_{m1} & x_{m2} & \cdots & x_{mn} \end{bmatrix}. X= x11x21xm1x12x22xm2x1nx2nxmn .

PCA 的目标是将数据从原始空间变换到一个新的低维空间 (Y),并且新空间中的每个维度都是原特征的线性组合。


2.2 数据预处理

  1. 中心化 (Mean Removal)

为确保结果不受原始特征取值范围的影响,需要对数据进行中心化操作,即将每个特征减去其均值:
μ = 1 m ∑ i = 1 m x i , X ′ = X − μ . \mu = \frac{1}{m} \sum_{i=1}^m x_i, \quad X' = X - \mu. μ=m1i=1mxi,X=Xμ.

其中,(\mu) 是一个 (1 \times n) 的向量,表示每列的均值。中心化后的数据矩阵 (X’) 满足每列特征的均值为零。

  1. 标准化 (Optional)

如果不同特征的尺度差异较大(如身高以厘米为单位,体重以公斤为单位),还需要进行标准化处理:
x i j ′ = x i j − μ j σ j , σ j = 1 m ∑ i = 1 m ( x i j − μ j ) 2 . x'_{ij} = \frac{x_{ij} - \mu_j}{\sigma_j}, \quad \sigma_j = \sqrt{\frac{1}{m} \sum_{i=1}^m (x_{ij} - \mu_j)^2}. xij=σjxijμj,σj=m1i=1m(xijμj)2 .
标准化后的每列特征具有均值 0 和方差 1。


2.3 协方差矩阵的计算

中心化后的数据矩阵 (X’) 的协方差矩阵 (C) 用于表示不同特征之间的线性相关性:
C = 1 m − 1 X ′ T X ′ . C = \frac{1}{m-1} X'^T X'. C=m11XTX.

协方差矩阵 (C) 是一个 (n \times n) 的对称矩阵,元素 (C_{ij}) 表示特征 (i) 和特征 (j) 的协方差:
C i j = 1 m − 1 ∑ k = 1 m ( x k i ′ ⋅ x k j ′ ) . C_{ij} = \frac{1}{m-1} \sum_{k=1}^m (x'_{ki} \cdot x'_{kj}). Cij=m11k=1m(xkixkj).


2.4 特征值分解

PCA 的核心在于对协方差矩阵进行特征值分解。

  1. 特征值和特征向量

解以下特征值问题:
C v = λ v , Cv = \lambda v, Cv=λv,
其中:

  • (v \in \mathbb{R}^n) 为特征向量;
  • (\lambda \in \mathbb{R}) 为特征值。

特征值表示在对应特征向量方向上的数据方差大小。所有特征值和特征向量构成一组正交基。

  1. 排序

将特征值按降序排列:
λ 1 ≥ λ 2 ≥ ⋯ ≥ λ n . \lambda_1 \geq \lambda_2 \geq \cdots \geq \lambda_n. λ1λ2λn.
对应的特征向量为 (v_1, v_2, \dots, v_n)。


2.5 最大方差推导

投影方向 (w) 的方差可表示为:
Var ( X w ) = w T C w , \text{Var}(Xw) = w^T C w, Var(Xw)=wTCw,
约束条件为:
∥ w ∥ = 1. \|w\| = 1. w=1.

通过拉格朗日乘子法求解最大方差问题:
L ( w , α ) = w T C w − α ( w T w − 1 ) , L(w, \alpha) = w^T C w - \alpha (w^T w - 1), L(w,α)=wTCwα(wTw1),
对 (w) 求导:
∂ L ∂ w = 2 C w − 2 α w = 0. \frac{\partial L}{\partial w} = 2Cw - 2\alpha w = 0. wL=2Cw2αw=0.
化简得:
C w = α w . Cw = \alpha w. Cw=αw.
由此可见,最优投影方向 (w) 即为协方差矩阵的特征向量。


2.6 数据降维

选择前 (k) 个最大的特征值对应的特征向量构成投影矩阵:
W = [ v 1 , v 2 , … , v k ] , W = [v_1, v_2, \dots, v_k], W=[v1,v2,,vk],
其中 (W \in \mathbb{R}^{n \times k})。

降维后的数据为:
Y = X ′ W , Y = X' W, Y=XW,
其中 (Y \in \mathbb{R}^{m \times k}) 为降维后的数据。


3. 重要指标

3.1 方差贡献率

方差贡献率用于衡量每个主成分在数据中所占的信息比例:
ρ i = λ i ∑ j = 1 n λ j . \rho_i = \frac{\lambda_i}{\sum_{j=1}^n \lambda_j}. ρi=j=1nλjλi.

3.2 累积方差贡献率

累积方差贡献率衡量前 (k) 个主成分所包含的信息比例:
R k = ∑ i = 1 k λ i ∑ j = 1 n λ j . R_k = \frac{\sum_{i=1}^k \lambda_i}{\sum_{j=1}^n \lambda_j}. Rk=j=1nλji=1kλi.

当 (R_k) 接近 1 时,表示前 (k) 个主成分已包含绝大部分信息。


总结

PCA 是一个基于线性代数的优雅降维工具,它通过特征值分解或奇异值分解,将数据映射到低维空间,同时保留数据的主要信息。通过数学公式和描述性语言的结合,我们可以清晰地理解其原理及实际应用。

PCA降维实战

接下来演示使用PCA降维对MNIST数据集中的图片进行降维可视化展示

代码

import numpy as np
from sklearn.datasets import fetch_openml
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler, MinMaxScaler# 加载MNIST数据集
mnist = fetch_openml('mnist_784', version=1, as_frame=False)
X, y = mnist.data, mnist.target# 选择数字0的90张图片
digit_0_indices = np.where(y == '0')[0][:90]
X_0 = X[digit_0_indices]# 选择数字1-9各10张图片
X_others = []
y_others = []
for digit in range(1, 10):indices = np.where(y == str(digit))[0][:10]X_others.append(X[indices])y_others.extend([digit] * 10)# 合并所有数据
X_selected = np.vstack([X_0] + X_others)
y_selected = np.array(['0']*90 + y_others)# 更强的数据预处理
# 1. MinMax缩放到[0,1]
minmax_scaler = MinMaxScaler()
X_minmax = minmax_scaler.fit_transform(X_selected)
# 2. 标准化处理
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_minmax)# 应用PCA降维
pca = PCA(n_components=2, random_state=42)
X_pca = pca.fit_transform(X_scaled)# 计算类别中心点
centers = {}
for digit in range(10):mask = y_selected == str(digit)centers[digit] = np.mean(X_pca[mask], axis=0)# 可视化结果
plt.figure(figsize=(12, 8))
plt.style.use('default')  # 使用默认样式# 修改颜色方案:红色表示0,蓝色表示其他所有数字
colors = ['#FF0000', '#1f77b4']  # 红色和蓝色# 绘制连接线(从每个点到类别中心)
# 先画其他数字(1-9)的连接线
for digit in range(1, 10):mask = y_selected == str(digit)points = X_pca[mask]center = centers[digit]for point in points:plt.plot([point[0], center[0]], [point[1], center[1]], color=colors[1], alpha=0.1)# 画数字0的连接线
mask = y_selected == '0'
points = X_pca[mask]
center = centers[0]
for point in points:plt.plot([point[0], center[0]], [point[1], center[1]], color=colors[0], alpha=0.1)# 先绘制其他数字(1-9)的散点
for digit in range(1, 10):mask = y_selected == str(digit)plt.scatter(X_pca[mask, 0], X_pca[mask, 1], c=[colors[1]], label='Other digits (1-9)' if digit == 1 else "",alpha=0.8,s=150,edgecolors='white',linewidth=1)# 绘制数字0的散点
mask = y_selected == '0'
plt.scatter(X_pca[mask, 0], X_pca[mask, 1], c=[colors[0]], label='Digit 0',alpha=0.8,s=150,edgecolors='white',linewidth=1)# 绘制类别中心点
for digit in range(10):plt.scatter(centers[digit][0], centers[digit][1], c=[colors[0] if digit == 0 else colors[1]], s=300,marker='*',edgecolors='black',linewidth=1.5)plt.title('MNIST Data PCA Visualization (2D)', fontsize=14, pad=20)
plt.xlabel(f'First Principal Component (Variance Ratio: {pca.explained_variance_ratio_[0]:.3f})', fontsize=12)
plt.ylabel(f'Second Principal Component (Variance Ratio: {pca.explained_variance_ratio_[1]:.3f})', fontsize=12)
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=10)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('pca_visualization_enhanced.png', dpi=300, bbox_inches='tight')
plt.close()
# 打印解释方差信息
print(f"第一主成分解释的方差比例: {pca.explained_variance_ratio_[0]:.4f}")
print(f"第二主成分解释的方差比例: {pca.explained_variance_ratio_[1]:.4f}")
print(f"累计解释的方差比例: {sum(pca.explained_variance_ratio_):.4f}")

运行结果

PCA降维结果
通过图片可以出,是将数字0渲染为红色,其他数字均为蓝色,数字0一共有90张图片,其他数字每一个数字10张图片。

三元组损失 (Triplet Loss) 的详解

三元组损失(Triplet Loss)是一种广泛应用于深度学习中的度量学习方法,特别是在人脸识别、图像检索等任务中效果显著。它通过直接优化样本在嵌入空间中的几何关系,使得相似样本距离更近,不相似样本距离更远,从而学习到有判别力的特征表示。


1. 基本概念

三元组损失的核心思想是基于样本的三元组构造:

  1. Anchor (A):目标样本。
  2. Positive §:与 Anchor 属于同一类的样本。
  3. Negative (N):与 Anchor 属于不同类的样本。

目标是:

  • 使 Anchor 和 Positive 之间的距离尽可能接近。
  • 使 Anchor 和 Negative 之间的距离尽可能远。

数学上,三元组损失的优化目标可以用如下方式描述:
∥ f ( A ) − f ( P ) ∥ 2 2 + α < ∥ f ( A ) − f ( N ) ∥ 2 2 , \|f(A) - f(P)\|_2^2 + \alpha < \|f(A) - f(N)\|_2^2, f(A)f(P)22+α<f(A)f(N)22,
其中:

  • (f(x)) 是样本 (x) 的特征嵌入向量;
  • (|\cdot|_2^2) 表示欧几里得距离的平方;
  • (\alpha) 是一个正的边际值(margin),用来确保不同类别之间的样本距离有一定的间隔。

2. 数学公式与推导

2.1 损失函数定义

三元组损失的形式化定义为:
L ( A , P , N ) = max ⁡ { 0 , ∥ f ( A ) − f ( P ) ∥ 2 2 − ∥ f ( A ) − f ( N ) ∥ 2 2 + α } . L(A, P, N) = \max\{0, \|f(A) - f(P)\|_2^2 - \|f(A) - f(N)\|_2^2 + \alpha\}. L(A,P,N)=max{0,f(A)f(P)22f(A)f(N)22+α}.

其中:

  • (|f(A) - f§|_2^2):Anchor 和 Positive 的欧几里得距离平方;
  • (|f(A) - f(N)|_2^2):Anchor 和 Negative 的欧几里得距离平方;
  • (\max{0, \cdot}):表示当距离关系符合约束时(即损失值为负时),损失记为 0;
  • (\alpha):超参数,用来控制正负样本之间的最小距离差。

2.2 损失函数分段表示

三元组损失可以理解为一种分段函数:
L ( A , P , N ) = { 0 , if  ∥ f ( A ) − f ( P ) ∥ 2 2 + α < ∥ f ( A ) − f ( N ) ∥ 2 2 , ∥ f ( A ) − f ( P ) ∥ 2 2 − ∥ f ( A ) − f ( N ) ∥ 2 2 + α , otherwise . L(A, P, N) = \begin{cases} 0, & \text{if } \|f(A) - f(P)\|_2^2 + \alpha < \|f(A) - f(N)\|_2^2, \\ \|f(A) - f(P)\|_2^2 - \|f(A) - f(N)\|_2^2 + \alpha, & \text{otherwise}. \end{cases} L(A,P,N)={0,f(A)f(P)22f(A)f(N)22+α,if f(A)f(P)22+α<f(A)f(N)22,otherwise.

这表明,当样本嵌入满足约束条件时,损失值为 0;当约束条件被违反时,损失函数的值取决于当前样本距离与边际值的差异。


2.3 优化目标的几何解释

三元组损失的优化目标是最小化:

  1. Anchor 和 Positive 的距离:使得相似样本被拉近。
  2. Anchor 和 Negative 的距离加上边际值 (\alpha):使得非相似样本被推远。

其几何含义如下:

  • 优化前:
    • 相似样本和非相似样本的距离可能存在交叠,无法区分类别。
  • 优化后:
    • 相似样本的嵌入点在高维空间中聚集,非相似样本的嵌入点彼此分离。

3. 公式推导过程

3.1 欧几里得距离的展开

首先定义任意两个嵌入向量之间的欧几里得距离平方为:
∥ f ( x 1 ) − f ( x 2 ) ∥ 2 2 = ∑ i = 1 d ( f ( x 1 ) i − f ( x 2 ) i ) 2 , \|f(x_1) - f(x_2)\|_2^2 = \sum_{i=1}^d (f(x_1)_i - f(x_2)_i)^2, f(x1)f(x2)22=i=1d(f(x1)if(x2)i)2,
其中 (f(x_1)_i) 表示 (x_1) 在第 (i) 个维度的嵌入值。

对于三元组损失中的两个距离:

  • (d_{AP} = |f(A) - f§|_2^2);
  • (d_{AN} = |f(A) - f(N)|_2^2)。

展开形式为:
d A P = ∥ f ( A ) − f ( P ) ∥ 2 2 = ∑ i = 1 d ( f ( A ) i − f ( P ) i ) 2 , d_{AP} = \|f(A) - f(P)\|_2^2 = \sum_{i=1}^d (f(A)_i - f(P)_i)^2, dAP=f(A)f(P)22=i=1d(f(A)if(P)i)2,
d A N = ∥ f ( A ) − f ( N ) ∥ 2 2 = ∑ i = 1 d ( f ( A ) i − f ( N ) i ) 2 . d_{AN} = \|f(A) - f(N)\|_2^2 = \sum_{i=1}^d (f(A)_i - f(N)_i)^2. dAN=f(A)f(N)22=i=1d(f(A)if(N)i)2.

3.2 损失函数表达式的代入

将上述距离代入三元组损失的定义:
L ( A , P , N ) = max ⁡ { 0 , d A P − d A N + α } . L(A, P, N) = \max\{0, d_{AP} - d_{AN} + \alpha\}. L(A,P,N)=max{0,dAPdAN+α}.

其中:

  • (d_{AP} = |f(A) - f§|_2^2);
  • (d_{AN} = |f(A) - f(N)|_2^2);

对于违反约束的情况 ((d_{AP} + \alpha \geq d_{AN})),展开得:
L ( A , P , N ) = ∥ f ( A ) − f ( P ) ∥ 2 2 − ∥ f ( A ) − f ( N ) ∥ 2 2 + α . L(A, P, N) = \|f(A) - f(P)\|_2^2 - \|f(A) - f(N)\|_2^2 + \alpha. L(A,P,N)=f(A)f(P)22f(A)f(N)22+α.


4. 模型训练与样本构造

4.1 三元组样本选择

三元组损失的性能依赖于训练样本的选择,通常有以下策略:

  1. 随机选择:随机选取 Anchor、Positive 和 Negative,但可能包含大量“易分类”的样本,对模型优化帮助不大。
  2. 困难样本挖掘 (Hard Negative Mining)
    • Positive:选择与 Anchor 距离最大的同类样本。
    • Negative:选择与 Anchor 距离最小的异类样本。
  3. 半困难样本挖掘 (Semi-Hard Mining)
    • Negative:选择与 Anchor 距离小于 Positive 的样本,但不违反约束条件。

4.2 训练过程

  1. 前向传播

    • 输入样本三元组 (A, P, N);
    • 使用神经网络计算嵌入特征 (f(A), f§, f(N));
    • 计算损失 (L(A, P, N))。
  2. 反向传播

    • 计算损失对嵌入向量的梯度;
    • 更新模型参数,优化嵌入网络。

5. 重要性质与参数选择

5.1 边际值 (\alpha)

  • (\alpha) 控制正负样本之间的最小距离差,常取 0.1 到 1.0。
  • (\alpha) 太小可能导致正负样本间距离差异不明显,影响模型判别能力。
  • (\alpha) 太大会使优化问题过于严格,导致模型难以收敛。

5.2 嵌入空间维度

嵌入空间的维度 (d) 决定了模型的表征能力:

  • (d) 太低可能不足以区分复杂数据。
  • (d) 太高会增加计算复杂度,且可能导致过拟合。

总结

三元组损失通过直接优化样本间的几何关系,使得嵌入空间具有良好的区分能力。在实际应用中,结合困难样本挖掘和适当的边际值设定,三元组损失可以显著提升模型性能。公式化的定义与几何推导为其提供了坚实的理论基础,广泛用于深度学习领域的多种任务中。

三元组损失函数实战

根据前面我们的PCA降维数据,使用cnn网络,结合三元组损失函数,我们设计一个可以进行二分类的分类器。

代码

import numpy as np
from sklearn.datasets import fetch_openml
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import torch
import torch.nn as nn
import torch.optim as optim# 加载MNIST数据集
mnist = fetch_openml('mnist_784', version=1, as_frame=False)
X, y = mnist.data, mnist.target# 选择数字0的90张图片
digit_0_indices = np.where(y == '0')[0][:90]
X_0 = X[digit_0_indices]# 选择数字1-9各10张图片
X_others = []
y_others = []
for digit in range(1, 10):indices = np.where(y == str(digit))[0][:10]X_others.append(X[indices])y_others.extend([digit] * 10)# 合并所有数据
X_selected = np.vstack([X_0] + X_others)
y_selected = np.array(['0']*90 + y_others)# 数据预处理
minmax_scaler = MinMaxScaler()
X_minmax = minmax_scaler.fit_transform(X_selected)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_minmax)# 转换为PyTorch张量
X_tensor = torch.FloatTensor(X_scaled)
y_tensor = torch.LongTensor([int(label) for label in y_selected])# 定义Triplet Loss
class TripletLoss(nn.Module):def __init__(self, margin=1.0):super(TripletLoss, self).__init__()self.margin = margindef forward(self, anchor, positive, negative):distance_positive = (anchor - positive).pow(2).sum(1)distance_negative = (anchor - negative).pow(2).sum(1)losses = torch.relu(distance_positive - distance_negative + self.margin)return losses.mean()# 生成三元组
def get_triplets(X, y):triplets = []for i in range(len(X)):anchor = X[i]anchor_label = y[i]# 获取正例(同类样本)pos_indices = torch.where(y == anchor_label)[0]pos_indices = pos_indices[pos_indices != i]  # 排除anchor本身if len(pos_indices) == 0:continuepositive = X[pos_indices[torch.randint(len(pos_indices), (1,))]]# 获取负例(不同类样本)neg_indices = torch.where(y != anchor_label)[0]negative = X[neg_indices[torch.randint(len(neg_indices), (1,))]]triplets.append((anchor, positive, negative))return triplets# 训练过程
criterion = TripletLoss(margin=2.0)
embedding = nn.Linear(784, 2, bias=False)  # 直接学习到2维表示
optimizer = optim.Adam(embedding.parameters(), lr=0.001)# 训练循环
n_epochs = 100
for epoch in range(n_epochs):triplets = get_triplets(X_tensor, y_tensor)epoch_loss = 0for anchor, positive, negative in triplets:optimizer.zero_grad()# 前向传播anchor_emb = embedding(anchor)positive_emb = embedding(positive)negative_emb = embedding(negative)# 计算损失loss = criterion(anchor_emb, positive_emb, negative_emb)epoch_loss += loss.item()# 反向传播loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f'Epoch [{epoch+1}/{n_epochs}], Loss: {epoch_loss/len(triplets):.4f}')# 使用训练好的embedding进行降维
with torch.no_grad():X_embedded = embedding(X_tensor).numpy()# 可视化结果
plt.figure(figsize=(12, 8))
plt.style.use('default')# 修改颜色方案:红色表示0,蓝色表示其他所有数字
colors = ['#FF0000', '#1f77b4']# 计算类别中心点
centers = {}
for digit in range(10):mask = y_selected == str(digit)centers[digit] = np.mean(X_embedded[mask], axis=0)# 绘制连接线
for digit in range(1, 10):mask = y_selected == str(digit)points = X_embedded[mask]center = centers[digit]for point in points:plt.plot([point[0], center[0]], [point[1], center[1]], color=colors[1], alpha=0.1)# 画数字0的连接线
mask = y_selected == '0'
points = X_embedded[mask]
center = centers[0]
for point in points:plt.plot([point[0], center[0]], [point[1], center[1]], color=colors[0], alpha=0.1)# 绘制散点
for digit in range(1, 10):mask = y_selected == str(digit)plt.scatter(X_embedded[mask, 0], X_embedded[mask, 1], c=[colors[1]], label='Other digits (1-9)' if digit == 1 else "",alpha=0.8,s=150,edgecolors='white',linewidth=1)# 绘制数字0
mask = y_selected == '0'
plt.scatter(X_embedded[mask, 0], X_embedded[mask, 1], c=[colors[0]], label='Digit 0',alpha=0.8,s=150,edgecolors='white',linewidth=1)# 绘制类别中心点
for digit in range(10):plt.scatter(centers[digit][0], centers[digit][1], c=[colors[0] if digit == 0 else colors[1]], s=300,marker='*',edgecolors='black',linewidth=1.5)plt.title('MNIST Data Triplet-Enhanced Visualization (2D)', fontsize=14, pad=20)
plt.xlabel('First Dimension', fontsize=12)
plt.ylabel('Second Dimension', fontsize=12)
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=10)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('triplet_visualization.png', dpi=300, bbox_inches='tight')
plt.close()

结果分析

三元组损失函数分类
可以看出,将数据成功的分为了两类。

总结

本文对 PCA(主成分分析)三元组损失(Triplet Loss) 的理论和实践进行了梳理和总结。通过对 PCA 的数学推导和应用实例的讲解,我们展示了其在数据降维和特征提取中的强大能力,同时结合三元组损失的几何直观和实际案例,探讨了其在构建判别性嵌入空间中的重要作用。尽管这些方法已经广泛应用于机器学习领域,但在具体实践中,仍存在如非线性数据处理或困难样本选择的挑战。相信未来这些方法的结合和改进能为数据分析和深度学习提供更多可能。

作为刚开始学习相关技术的初学者,文中内容难免存在理解或描述不够准确的地方。如果您发现任何不足或有更好的见解,欢迎随时提出并一起探讨,非常期待和大家交流学习,共同进步!

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

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

相关文章

记录:ubuntu 使用chattts的过程。

你知道什么是穷人吗&#xff1f;穷人就是没钱还想学习。 git GitHub - 2noise/ChatTTS: A generative speech model for daily dialogue. 因为所以。cosyvoice&#xff0c;gpt-s . 0.先找一个目录吧。 1.命令行模式 duyichengduyicheng-computer:~/gitee$ git clone https:…

开源 - Ideal库 - Excel帮助类,ExcelHelper实现(五)

书接上回&#xff0c;我们继续来聊聊ExcelHelper的具体实现。 01、读取Excel到DataSet单元测试 在上一章我们主要讲解了读取Excel到DataSet的三个重载方法具体实现&#xff0c;还没来得及做单元测试&#xff0c;因此我们首先对这三个方法做个单元测试。具体代码如下&#xff1…

CCF-GESP 编程能力认证 C++ 七级 2024年9月份选择题详细解析

第 1 题 已知小写字母 b 的 ASCII 码为 98 &#xff0c;下列 C 代码的输出结果是&#xff08;B&#xff09;。 #include <iostream> using namespace std; int main() {char a b;a;cout << a;return 0; } A. b B. c C. 98 D. 99 【这题很简单&#xff0c;我们只…

Oceanbase离线集群部署

准备工作 两台服务器 服务器的配置参照官网要求来 服务器名配置服务器IPoceanbase116g8h192.168.10.239oceanbase216g8h192.168.10.239 这里选oceanbase1作为 obd机器 oceanbase安装包 选择社区版本的时候自己系统的安装包 ntp时间同步rpm包 联网机器下载所需的软件包 …

动手学深度学习d2l包M4芯片 gpu加速

conda创建环境 CONDA_SUBDIRosx-arm64 conda create -n ml python3.9 -c conda-forge conda env config vars set CONDA_SUBDIRosx-arm64 conda activate mlpip安装包 pip install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/n…

Y20030046 Java+JSP+SpringBoot+MYSQL+LW+实验室管理系统的设计与实现 源码

实验室管理系统 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 伴随互联网的快速发展&#xff0c;国家对当前教育行业实行了新的改革&#xff0c;科学教育要培养更多的技术型人才&#xff0c;2020年全球爆发的新冠疫情&#xff0c;更是推动了科…

AG32 MCU与STM32 等MCU有哪些不同

STM32 MCU的特点 STM32一般是M0,M3, M4等内核的ARM Cortex内核的MCU&#xff0c;仅仅作为MCU使用&#xff0c;没有内置CPLD/FPGA的功能。 2. AG32的特点 AG32是AGM近2年来推出的差异化设计的SOC。以下我们了解以下AG32的特点。 &#xff08;1&#xff09;. 芯片结构&#xff…

【vscode】如何在项目中分享插件?

文章目录 前言一、如何获取插件名称呢&#xff1f;二、项目应用 前言 分享插件&#xff0c;除了将插件名字告诉你的小伙伴&#xff0c;当然还有其他的办法 项目根目录下创建.vscode 文件夹添加extensions.json文件 如下图 一、如何获取插件名称呢&#xff1f; 二、项目应用 …

【css】基础(一)

本专栏内容为&#xff1a;前端专栏 记录学习前端&#xff0c;分为若干个子专栏&#xff0c;html js css vue等 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;css专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &a…

Qt学习笔记第51到60讲

第51讲 记事本实现打开功能 回到第24个功能文件Notepad&#xff0c;给UI中的各个控件添加槽函数。 ①开始按钮 void Widget::on_btnOpen_clicked() {QString fileNameQFileDialog::getOpenFileName(this,tr("Open File"),"E:\\6_Qt Projects\\24_Notepad\\fi…

WPS解决Word文件引入excel对象文件无法打开提示“不能启动此对象...”的问题

一、问题现象 接收到了一份 Word文件&#xff0c;里面引入了一个Excel对象文件&#xff0c;双击时候&#xff0c;wps出现卡顿&#xff0c;过一会之后弹出错误提示&#xff1a;不能启动此对象... 二、解决方法 1.点击WPS左上角图标&#xff0c;并打开右上角设置&#xff0c;萱蕚…

# issue 8 TCP内部原理和UDP编程

TCP 通信三大步骤&#xff1a; 1 三次握手建立连接; 2 开始通信&#xff0c;进行数据交换; 3 四次挥手断开连接&#xff1b; 一、TCP内部原理--三次握手 【第一次握手】套接字A∶"你好&#xff0c;套接字B。我这儿有数据要传给你&#xff0c;建立连接吧。" 【第二次…

什么是人工智能?(Chapter 2)

Chapter 2&#xff1a; 大家到底在争论什么&#xff1f; 2022 年末&#xff0c;OpenAI 发布 ChatGPT 后不久&#xff0c;网上开始流传一个新的备忘录&#xff0c;它比其他任何东西都更能捕捉到这项技术的诡异之处。在大多数版本中&#xff0c;一个名为 "食人魔"&am…

OpenCV-平滑图像

二维卷积(图像滤波) 与一维信号一样&#xff0c;图像也可以通过各种低通滤波器&#xff08;LPF&#xff09;、高通滤波器&#xff08;HPF&#xff09;等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…

如何使用 Docker Compose 安装 Memos 自托管笔记应用

简介 Memos是一个自托管的开源笔记应用程序&#xff0c;专为个人组织和信息管理而设计。它允许用户高效地创建、存储和管理笔记&#xff0c;提供如Markdown支持、用户友好的界面和注重隐私的设计等功能。Memos可以在各种平台上运行&#xff0c;但使用Docker Compose可以简化部…

西部地区生活物资保供与城郊大仓基地高质量建设运营论坛西安市成功举办

2024 年 12 月 5日&#xff0c;由中国商业联合会、陕西省商务厅指导&#xff0c;中国商业联合会商贸物流与供应链分会、西安市发改委、西安市商务局主办&#xff0c;中企盟&#xff08;北京&#xff09;电商物流技术研究院、西安商业联合会、陕西省商贸物流供应链协会承办的“西…

[笔记] Windows 上 Git 安装详细教程:从零开始,附带每个选项解析

Git 是目前最流行的分布式版本控制系统之一&#xff0c;广泛应用于软件开发和项目管理中。对于 Windows 用户来说&#xff0c;正确安装和配置 Git 是开始使用 Git 的第一步。本文提供一份详细的指南&#xff0c;帮助你在 Windows 系统上顺利安装 Git&#xff0c;并解释每个安装…

五天SpringCloud计划——DAY3之服务治理(Nacos+OpenFeign+OKHttp)

一、引言 在微服务架构中&#xff0c;一个项目通常会被分为多个模块来降低耦合&#xff0c;但是通常情况下&#xff0c;一个项目中总会出现一种情况——一个模块内的方法需要调用另一个模块内的方法。本文就来使用NacosOpenFeignOKHttp帮助大家解决这个问题。 二、Nacos的使用…

go-blueprint create exit status 1

1. 异常信息 2024/12/06 10:59:19 Could not initialize go.mod in new project exit status 1 2024/12/06 10:59:19 Problem creating files for project. exit status 1 Error: exit status 12. 排查思路 手动进行go mod init查看手动的报错解决报错 3. 解决问题 发现是GO11…

Socket编程-tcp

1. 前言 在tcp套接字编程这里&#xff0c;我们将完成两份代码&#xff0c;一份是基于tcp实现普通的对话&#xff0c;另一份加上业务&#xff0c;client输入要执行的命令&#xff0c;server将执行结果返回给client 2. tcp_echo_server 与udp类似&#xff0c;前两步&#xff1…