【机器学习基础】机器学习入门核心算法:隐马尔可夫模型 (HMM)

news2025/6/3 8:57:46

在这里插入图片描述

机器学习入门核心算法:隐马尔可夫模型 (HMM)

  • 一、算法逻辑与核心思想
  • 二、算法原理与数学推导
      • 核心问题与算法推导
  • 三、模型评估
  • 四、应用案例
      • 1. 语音识别 (Speech Recognition)
      • 2. 自然语言处理 (Natural Language Processing - NLP)
      • 3. 手写体识别 (Handwriting Recognition)
      • 4. 金融时间序列分析 (Financial Time Series Analysis)
      • 5. 网络入侵检测 (Network Intrusion Detection)
  • 五、面试题示例
      • 1. 基础概念题:
      • 2. 模型与计算题:
      • 3. 算法实现题:
      • 4. 优缺点与应用题:
  • 六、详细的优缺点
  • 总结

一、算法逻辑与核心思想

隐马尔可夫模型是一种用于建模时序数据的概率图模型。其核心思想在于假设:

  1. 存在一个不可直接观测的隐藏状态序列:该序列遵循马尔可夫性质,即当前状态仅依赖于前一状态。
  2. 存在一个可观测的输出序列:每个观测值由其对应的隐藏状态生成。
  3. 状态转移和观测生成都是随机的:由概率分布控制。

逻辑流程:

  • 系统在 t=1 时刻处于某个隐藏状态 q₁(由初始状态概率分布决定)。
  • 隐藏状态 q₁ 根据观测概率分布生成一个观测值 o₁
  • 系统根据状态转移概率分布,从状态 q₁ 转移到下一个隐藏状态 q₂
  • 隐藏状态 q₂ 生成观测值 o₂
  • 此过程持续进行,产生隐藏状态序列 Q = (q₁, q₂, ..., q_T) 和对应的观测序列 O = (o₁, o₂, ..., o_T)

关键点:我们只能看到观测序列 O,而隐藏状态序列 Q 是未知的(“隐”的由来)。

二、算法原理与数学推导

一个标准的 HMM 由以下五元组参数 λ = (A, B, π) 定义:

  1. 状态集合:S = {s₁, s₂, ..., s_N},共有 N 个可能的隐藏状态。
  2. 观测集合:V = {v₁, v₂, ..., v_M},共有 M 个可能的观测符号。
  3. 状态转移概率矩阵:A = [aᵢⱼ],其中 aᵢⱼ = P(qₜ₊₁ = sⱼ | qₜ = sᵢ)。表示在时刻 t 处于状态 sᵢ 时,下一时刻 t+1 转移到状态 sⱼ 的概率。
    • 性质:∑_{j=1}^N aᵢⱼ = 1, ∀ i
  4. 观测概率矩阵(发射概率矩阵):B = [bⱼ(k)],其中 bⱼ(k) = P(oₜ = vₖ | qₜ = sⱼ)。表示在时刻 t 处于状态 sⱼ 时,生成观测符号 vₖ 的概率。
    • 性质:∑_{k=1}^M bⱼ(k) = 1, ∀ j
  5. 初始状态概率分布:π = [πᵢ],其中 πᵢ = P(q₁ = sᵢ)。表示在 t=1 时刻系统处于状态 sᵢ 的概率。
    • 性质:∑_{i=1}^N πᵢ = 1

核心问题与算法推导

HMM 主要解决三个基本问题,对应三个经典算法:

  1. 评估问题 (Evaluation Problem):给定模型 λ = (A, B, π) 和观测序列 O = (o₁, o₂, ..., o_T),计算该观测序列出现的概率 P(O | λ)

    • 目的:判断模型产生给定观测序列的可能性,用于模型选择、异常检测等。
    • 算法:前向算法 (Forward Algorithm)
      • 定义前向概率:αₜ(i) = P(o₁, o₂, ..., oₜ, qₜ = sᵢ | λ)。表示在时刻 t,观测到前 t 个符号 (o₁, ..., oₜ) 且当前状态为 sᵢ 的联合概率。
      • 初始化 (t=1): α₁(i) = πᵢ * bᵢ(o₁), i = 1, 2, ..., N
      • 递归 (t = 2, 3, ..., T):
        α t ( j ) = [ ∑ i = 1 N α t − 1 ( i ) ⋅ a i j ] ⋅ b j ( o t ) , j = 1 , 2 , … , N \alpha_{t}(j) = \left[ \sum_{i=1}^{N} \alpha_{t-1}(i) \cdot a_{ij} \right] \cdot b_{j}(o_{t}), \quad j = 1, 2, \ldots, N αt(j)=[i=1Nαt1(i)aij]bj(ot),j=1,2,,N
      • 终止:
        P ( O ∣ λ ) = ∑ i = 1 N α T ( i ) P(O | \lambda) = \sum_{i=1}^{N} \alpha_{T}(i) P(Oλ)=i=1NαT(i)
      • 原理:利用动态规划,避免直接枚举所有可能的状态路径 (O(N^T) 复杂度),将复杂度降低到 O(N²T)αₜ(j) 的计算依赖于前一个时刻 t-1 所有状态 i 的前向概率 αₜ₋₁(i) 转移到状态 j 的概率 aᵢⱼ,再乘以状态 j 生成当前观测 oₜ 的概率 bⱼ(oₜ)
  2. 解码问题 (Decoding Problem):给定模型 λ = (A, B, π) 和观测序列 O = (o₁, o₂, ..., o_T),寻找最有可能(概率最大)产生该观测序列的隐藏状态序列 Q* = (q₁*, q₂*, ..., q_T*)

    • 目的:揭示观测数据背后最可能的状态序列,如词性标注、语音识别中的音素序列。
    • 算法:维特比算法 (Viterbi Algorithm)
      • 定义维特比概率:δₜ(i) = max_{q₁, q₂, ..., qₜ₋₁} P(q₁, q₂, ..., qₜ₋₁, qₜ = sᵢ, o₁, o₂, ..., oₜ | λ)。表示在时刻 t,沿着一条路径到达状态 sᵢ 并观测到 (o₁, ..., oₜ) 的最大概率。
      • 定义回溯指针:ψₜ(j) 用于记录在时刻 t 到达状态 sⱼ 的最优路径中,前一个时刻 t-1 的状态。
      • 初始化 (t=1):
        δ₁(i) = πᵢ * bᵢ(o₁), i = 1, 2, ..., N
        ψ₁(i) = 0 (无前驱状态)
      • 递归 (t = 2, 3, ..., T):
        δ t ( j ) = max ⁡ 1 ≤ i ≤ N [ δ t − 1 ( i ) ⋅ a i j ] ⋅ b j ( o t ) , j = 1 , 2 , … , N \delta_{t}(j) = \max_{1 \leq i \leq N} \left[ \delta_{t-1}(i) \cdot a_{ij} \right] \cdot b_{j}(o_{t}), \quad j = 1, 2, \ldots, N δt(j)=1iNmax[δt1(i)aij]bj(ot),j=1,2,,N
        ψ t ( j ) = arg ⁡ max ⁡ 1 ≤ i ≤ N [ δ t − 1 ( i ) ⋅ a i j ] , j = 1 , 2 , … , N \psi_{t}(j) = \arg\max_{1 \leq i \leq N} \left[ \delta_{t-1}(i) \cdot a_{ij} \right], \quad j = 1, 2, \ldots, N ψt(j)=arg1iNmax[δt1(i)aij],j=1,2,,N
      • 终止:
        P ∗ = max ⁡ 1 ≤ i ≤ N δ T ( i ) P^{*} = \max_{1 \leq i \leq N} \delta_{T}(i) P=1iNmaxδT(i)
        q T ∗ = arg ⁡ max ⁡ 1 ≤ i ≤ N δ T ( i ) q_{T}^{*} = \arg\max_{1 \leq i \leq N} \delta_{T}(i) qT=arg1iNmaxδT(i)
      • 路径回溯 (t = T-1, T-2, ..., 1):
        qₜ* = ψₜ₊₁(qₜ₊₁*)
      • 原理:同样是动态规划,但与前向算法的关键区别在于使用 max 操作代替 sum 操作。δₜ(j) 记录的是到达 (t, sⱼ) 的单条最优路径的概率,ψₜ(j) 记录这条最优路径是从哪个前驱状态 i 转移过来的。
  3. 学习问题 (Learning Problem):给定观测序列 O = (o₁, o₂, ..., o_T)(有时可能需要多个观测序列),估计模型参数 λ = (A, B, π),使得该模型产生该观测序列的概率 P(O | λ) 最大。

    • 目的:从观测数据中学习模型,是 HMM 应用的关键步骤。
    • 算法:Baum-Welch 算法 (前向-后向算法) - 一种期望最大化 (EM) 算法。
      • 定义后向概率:βₜ(i) = P(oₜ₊₁, oₜ₊₂, ..., o_T | qₜ = sᵢ, λ)。表示在时刻 t 处于状态 sᵢ 的条件下,观测到从 t+1T 的剩余观测序列的概率。
        • 初始化 (t=T): β_T(i) = 1, i = 1, 2, ..., N (约定空序列概率为1)
        • 递归 (t = T-1, T-2, ..., 1):
          β t ( i ) = ∑ j = 1 N a i j ⋅ b j ( o t + 1 ) ⋅ β t + 1 ( j ) , i = 1 , 2 , … , N \beta_{t}(i) = \sum_{j=1}^{N} a_{ij} \cdot b_{j}(o_{t+1}) \cdot \beta_{t+1}(j), \quad i = 1, 2, \ldots, N βt(i)=j=1Naijbj(ot+1)βt+1(j),i=1,2,,N
      • 定义两个关键概率:
        • ξₜ(i, j) = P(qₜ = sᵢ, qₜ₊₁ = sⱼ | O, λ):给定模型和整个观测序列,时刻 t 处于状态 sᵢ 且时刻 t+1 处于状态 sⱼ 的概率。
          ξ t ( i , j ) = α t ( i ) ⋅ a i j ⋅ b j ( o t + 1 ) ⋅ β t + 1 ( j ) P ( O ∣ λ ) = α t ( i ) ⋅ a i j ⋅ b j ( o t + 1 ) ⋅ β t + 1 ( j ) ∑ i = 1 N ∑ j = 1 N α t ( i ) ⋅ a i j ⋅ b j ( o t + 1 ) ⋅ β t + 1 ( j ) \xi_{t}(i, j) = \frac{\alpha_{t}(i) \cdot a_{ij} \cdot b_{j}(o_{t+1}) \cdot \beta_{t+1}(j)}{P(O | \lambda)} = \frac{\alpha_{t}(i) \cdot a_{ij} \cdot b_{j}(o_{t+1}) \cdot \beta_{t+1}(j)}{\sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_{t}(i) \cdot a_{ij} \cdot b_{j}(o_{t+1}) \cdot \beta_{t+1}(j)} ξt(i,j)=P(Oλ)αt(i)aijbj(ot+1)βt+1(j)=i=1Nj=1Nαt(i)aijbj(ot+1)βt+1(j)αt(i)aijbj(ot+1)βt+1(j)
        • γₜ(i) = P(qₜ = sᵢ | O, λ):给定模型和整个观测序列,时刻 t 处于状态 sᵢ 的概率。它是 ξₜ(i, j)j 的求和:
          γ t ( i ) = ∑ j = 1 N ξ t ( i , j ) \gamma_{t}(i) = \sum_{j=1}^{N} \xi_{t}(i, j) γt(i)=j=1Nξt(i,j)
      • Baum-Welch 重估公式 (M步):利用 ξₜ(i, j)γₜ(i) 计算新的模型参数 λ̄ = (Ā, B̄, π̄)
        • 初始状态概率:
          π ˉ i = γ 1 ( i ) \bar{\pi}_{i} = \gamma_{1}(i) πˉi=γ1(i)
        • 状态转移概率:
          a ˉ i j = ∑ t = 1 T − 1 ξ t ( i , j ) ∑ t = 1 T − 1 γ t ( i ) \bar{a}_{ij} = \frac{\sum_{t=1}^{T-1} \xi_{t}(i, j)}{\sum_{t=1}^{T-1} \gamma_{t}(i)} aˉij=t=1T1γt(i)t=1T1ξt(i,j) (分子:从 i 转移到 j 的期望次数;分母:处于 i 的期望次数)
        • 观测概率:
          b ˉ j ( k ) = ∑ t = 1 T γ t ( j ) ⋅ 1 ( o t = v k ) ∑ t = 1 T γ t ( j ) \bar{b}_{j}(k) = \frac{\sum_{t=1}^{T} \gamma_{t}(j) \cdot \mathbf{1}(o_{t} = v_{k})}{\sum_{t=1}^{T} \gamma_{t}(j)} bˉj(k)=t=1Tγt(j)t=1Tγt(j)1(ot=vk) (分子:在状态 j 观测到符号 vₖ 的期望次数;分母:处于状态 j 的期望次数;𝟏(·) 是指示函数,当 oₜ = vₖ 时为1,否则为0)
      • 原理:Baum-Welch 算法是 EM 算法在 HMM 上的具体实现。
        • E步:利用当前参数 λ 和观测序列 O,计算期望统计量 ξₜ(i, j)γₜ(i)(需要前向和后向算法)。
        • M步:基于 E 步计算出的期望统计量,最大化似然函数,更新参数 λ̄
        • 迭代执行 E 步和 M 步,直到参数收敛(P(O | λ) 增长很小或达到最大迭代次数)。该算法保证 P(O | λ) 在每次迭代中非递减,最终收敛到局部极大值点。

三、模型评估

评估训练好的 HMM 性能是应用的关键环节,常用方法包括:

  1. 似然值 (Likelihood):使用 前向算法 计算测试观测序列 O_test 在模型 λ 下的概率 P(O_test | λ)。值越大,说明模型描述该序列的能力越强。常用于比较不同模型或同一模型的不同超参数(如状态数)对特定序列的拟合程度。
  2. 困惑度 (Perplexity):常用于语言模型等序列生成任务,是似然值的几何平均的倒数,信息论中衡量概率模型预测能力的指标。对于一个长度为 T 的测试序列:
    Perplexity ( O test ∣ λ ) = 1 P ( O test ∣ λ ) T \text{Perplexity}(O_{\text{test}} | \lambda) = \sqrt[T]{\frac{1}{P(O_{\text{test}} | \lambda)}} Perplexity(Otestλ)=TP(Otestλ)1
    困惑度越低,表示模型对序列的预测越确定(越好)。
  3. 分类准确率 (Classification Accuracy):如果 HMM 用于分类任务(例如,每个类别对应一个 HMM),将测试序列输入所有模型,选择产生最高似然值 P(O_test | λ_c) 的类别 c 作为预测结果。计算预测正确的测试序列比例即为分类准确率。
  4. 序列标注准确率 (Labeling Accuracy):
    • 状态级准确率 (State Accuracy):使用 维特比算法 解码出最可能的状态序列 Q*,与真实状态序列 Q_true 比较,计算状态正确预测的比例。
    • 序列级准确率 (Sequence Accuracy):计算整个状态序列预测正确的比例(要求序列中所有状态都预测正确)。通常比状态级准确率低。
  5. 交叉验证 (Cross-Validation):尤其当训练数据有限时,将数据分成 k 折,轮流用 k-1 折训练模型,在剩余 1 折上评估(使用似然或准确率),最后取平均评估结果。有助于更可靠地估计模型泛化能力。
  6. 模型选择准则 (AIC/BIC):在模型复杂度(如状态数 N)不同时,仅比较似然值会偏向选择更复杂的模型。赤池信息准则 (AIC) 和贝叶斯信息准则 (BIC) 在似然值基础上加入了对模型参数数量的惩罚:
    • AIC = -2 * log(P(O | λ)) + 2 * k
    • BIC = -2 * log(P(O | λ)) + k * log(T)
      (其中 k 是模型参数数量,T 是观测序列长度)选择 AIC 或 BIC 值较小的模型,能在拟合优度和模型复杂度之间取得平衡。

四、应用案例

HMM 因其强大的时序建模能力,在众多领域有广泛应用:

1. 语音识别 (Speech Recognition)

  • 经典应用。每个单词或音素 (phoneme) 通常建模为一个 HMM。
    • 状态:表示发音过程中的不同阶段(如音素的开始、中间、结束)。
    • 观测:从语音信号中提取的短时频谱特征向量(如 MFCC)。
    • 训练 (学习):使用大量标注了音素/单词的语音数据训练 HMM 参数。
    • 解码 (识别):给定一段语音的观测特征序列,使用 Viterbi 算法在所有候选单词/句子的 HMM 组合中找到最可能产生该观测序列的状态序列(即对应的单词/句子序列)。

2. 自然语言处理 (Natural Language Processing - NLP)

  • 词性标注 (Part-of-Speech Tagging):
    • 状态:词性标签(名词、动词、形容词等)。
    • 观测:句子中的单词序列。
    • 模型学习词性之间的转移概率 (A) 和特定词性生成特定单词的概率 (B)。给定一个句子(单词序列),Viterbi 算法解码出最可能的词性标签序列。
    • 命名实体识别 (Named Entity Recognition - NER):类似词性标注,状态代表实体类别(人名、地名、组织名、非实体)。
  • 基因查找 / CpG岛检测 (Bioinformatics):
    • 状态:代表基因组序列的不同功能区域(例如,编码区、非编码区、CpG岛、非CpG岛)。CpG岛是富含CpG二核苷酸的区域,常与基因调控相关。
    • 观测:DNA序列中的核苷酸(A, C, G, T)。
    • HMM 学习不同状态下生成各种核苷酸的概率。给定一段DNA序列,Viterbi算法可以预测其最可能的功能区域划分(如识别出CpG岛的位置)。

3. 手写体识别 (Handwriting Recognition)

  • 处理随时间或空间(从左到右)变化的笔迹轨迹。
    • 状态:可能表示字符、字符的部分或书写笔划。
    • 观测:笔的坐标、速度、方向或从图像中提取的特征。

4. 金融时间序列分析 (Financial Time Series Analysis)

  • 对股票价格、汇率等建模。
    • 状态:代表市场的隐含“状态”或“模式”(如“牛市”、“熊市”、“震荡市”)。
    • 观测:价格变动、交易量、技术指标等。
    • 可用于:状态识别(当前市场处于什么模式?)、预测(基于当前状态预测未来走势概率)、异常检测(观测序列概率极低可能表示异常事件)。

5. 网络入侵检测 (Network Intrusion Detection)

  • 建模正常的网络流量模式。
    • 状态:表示不同的网络活动类型或连接状态。
    • 观测:网络数据包特征(源/目的 IP、端口、协议、包大小、时间间隔等)。
    • 训练 HMM 学习正常流量模式。当新的流量序列 OP(O | λ_normal) 低于某个阈值时,触发入侵警报。

五、面试题示例

1. 基础概念题:

  • 什么是隐马尔可夫模型 (HMM)?它的两个基本假设是什么?核心五元组参数是什么?
  • 解释 HMM 的三个基本问题及其对应的经典算法。
  • 前向算法和 Viterbi 算法的核心思想是什么?它们的主要区别在哪里?(提示:sum vs max
  • Baum-Welch 算法属于什么类型的算法?简述其 E 步和 M 步主要做了什么。

2. 模型与计算题:

  • 场景:假设有一个非常简单的天气 HMM。
    • 隐藏状态:S = {Sunny, Rainy}
    • 观测:V = {Walk, Shop, Clean}(根据天气进行的活动)
    • 已知模型参数 λ
      • π = [0.6 (Sunny), 0.4 (Rainy)]
      • A = [[0.7, 0.3], [0.4, 0.6]] (行:当前状态 Sunny/Rainy;列:下一状态 Sunny/Rainy)
      • B = [[0.1, 0.4, 0.5], [0.6, 0.3, 0.1]] (行:状态 Sunny/Rainy;列:观测 Walk/Shop/Clean)
    • 问题 1 (评估):给定观测序列 O = (Walk, Shop, Clean),计算 P(O | λ)。要求写出前向概率 αₜ(i) 的计算过程。
    • 问题 2 (解码):对于同一个观测序列 O = (Walk, Shop, Clean),找出最可能的天气状态序列 Q*。要求写出维特比概率 δₜ(i) 和回溯指针 ψₜ(i) 的计算过程。
    • 问题 3 (学习):假设我们只有观测序列 O = (Walk, Shop, Clean),但没有状态序列和初始参数。简述如何使用 Baum-Welch 算法来估计参数 λ(说明需要计算的中间量 α, β, γ, ξ 和重估公式)。

3. 算法实现题:

  • 请用伪代码或熟悉的编程语言描述 Viterbi 算法的实现。
  • 如何高效地计算 Baum-Welch 算法中的 ξₜ(i, j)γₜ(i)

4. 优缺点与应用题:

  • 分析 HMM 的主要优点和局限性。
  • 为什么 HMM 在语音识别中曾经非常成功?现在是否仍然主流?它面临哪些挑战?
  • 除了提到的例子,还能列举 HMM 的其他应用场景吗?

六、详细的优缺点

特性优点缺点
建模能力专门为时序数据建模设计,结构直观。马尔可夫假设限制:状态仅依赖前一状态,难以捕捉长距离依赖关系。
能够有效处理观测与状态非确定性关联的问题。状态独立性假设:观测仅依赖当前状态,忽略了相邻观测之间的直接关联。
作为生成式模型,能模拟数据生成过程,生成新的序列。参数形式限制:观测概率 B 通常是离散或特定连续分布(如高斯混合),灵活性受限。
算法效率动态规划算法(前向、后向、Viterbi)高效,时间复杂度 O(N²T)训练复杂度:Baum-Wch 算法是迭代的 EM 过程,计算 ξ, γ 开销大,训练可能较慢,尤其状态/序列多时。
理论基础基于坚实的概率论和统计学基础。局部最优:Baum-Welch 只能收敛到局部极大值,结果依赖于初始参数选择。
可解释性状态和参数通常具有一定的物理或语义含义(如语音中的音素、NLP中的词性)。状态数选择:最优隐藏状态数 N 通常需要经验或通过模型选择准则(AIC/BIC)确定,非平凡问题。
应用广度在语音识别、NLP、生物信息学等序列标注、识别、分析领域历史悠久且成功。处理变长输入:虽然天然处理序列,但模型结构(状态数)通常是固定的,对复杂变长模式建模能力有限。
与深度学习对比训练数据量要求相对较低,参数较少,有时在小数据集上表现更好。表示学习能力弱:缺乏深度学习(如 RNN, LSTM, Transformer)强大的自动特征学习和层次化表示能力。
难以处理高维/复杂观测:如图像、视频等,需要复杂的特征工程。而深度学习擅长处理原始或高维数据。

总结

HMM 是时序数据分析的经典且强大的概率模型。其核心优势在于清晰的时序建模框架、高效的动态规划推理算法(解决评估、解码问题)以及基于 EM 的参数学习算法(解决学习问题)。在语音识别、自然语言处理(词性标注、命名实体识别)、生物信息学(基因序列分析)等领域取得了巨大成功。

然而,HMM 的严格假设(马尔可夫性、观测独立性)限制了其捕捉复杂依赖关系的能力。参数形式(离散或简单连续分布)的局限性和 Baum-Welch 易陷入局部最优也是其弱点。最重要的是,随着深度学习,特别是循环神经网络(RNN、LSTM、GRU)和 Transformer 的崛起,它们在处理复杂时序数据、自动特征学习、捕捉长距离依赖方面展现出更强大的能力,逐渐取代 HMM 成为许多领域(尤其是语音识别和 NLP)的主流技术。尽管如此,理解 HMM 的原理、算法和思想,仍然是学习时序建模和概率图模型的重要基础。它在计算效率、可解释性和小数据场景下仍有其应用价值。

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

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

相关文章

Leetcode 2819. 购买巧克力后的最小相对损失

1.题目基本信息 1.1.题目描述 现给定一个整数数组 prices,表示巧克力的价格;以及一个二维整数数组 queries,其中 queries[i] [ki, mi]。 Alice 和 Bob 去买巧克力,Alice 提出了一种付款方式,而 Bob 同意了。 对于…

AI炼丹日志-25 - OpenAI 开源的编码助手 Codex 上手指南

点一下关注吧!!!非常感谢!!持续更新!!! Java篇: MyBatis 更新完毕目前开始更新 Spring,一起深入浅出! 大数据篇 300: Hadoop&…

C# 类和继承(使用基类的引用)

使用基类的引用 派生类的实例由基类的实例和派生类新增的成员组成。派生类的引用指向整个类对象,包括 基类部分。 如果有一个派生类对象的引用,就可以获取该对象基类部分的引用(使用类型转换运算符把 该引用转换为基类类型)。类…

进程间通信(消息队列)

目录 一 原理 二 API 1. ftok 2. msgget 3. msgctl 4. msgsnd 5. msgrcv 三 demo代码 四 基于责任链模式和消息队列对数据处理 1. 什么是责任链模式 2. 下面基于责任链模式来对消息队列获取的消息进行处理 前置 其实system v 版本的进程间通信,设计的接…

Nginx--手写脚本压缩和切分日志(也适用于docker)

原文网址:Nginx--手写脚本压缩和切分日志(也适用于docker)_IT利刃出鞘的博客-CSDN博客 简介 本文介绍nginx如何手写脚本压缩和切分日志。 1.创建切分日志的脚本 创建脚本文件:/work/tmp/nginx-log_sh(后边要用run-…

OpenCv高阶(十八)——dlib人脸检测与识别

文章目录 一、dlib库是什么?二、opencv库与dlib库的优缺点对比1、opencv优缺点2、dlib库优缺点 三、dlib库的安装1、在线安装2、本地安装 四、dlib库的人脸检测器1. 基于 HOG 的检测器2. 基于 CNN 的检测器 五、dlib人脸检测的简单使用1、导入必要库2、初始化人脸检…

中山大学无人机具身导航新突破!FlightGPT:迈向通用性和可解释性的无人机视觉语言导航

作者:Hengxing Cai 1 , 2 ^{1,2} 1,2, Jinhan Dong 2 , 3 ^{2,3} 2,3, Jingjun Tan 1 ^{1} 1, Jingcheng Deng 4 ^{4} 4, Sihang Li 2 ^{2} 2, Zhifeng Gao 2 ^{2} 2, Haidong Wang 1 ^{1} 1, Zicheng Su 5 ^{5} 5, Agachai Sumalee 6 ^{6} 6, Renxin Zhong 1 ^{1} …

WIN11+CUDA11.8+VS2019配置BundleFusion

参考: BundleFusion:VS2019 2017 ,CUDA11.5,win11,Realsense D435i离线数据包跑通,环境搭建 - 知乎 Win10VS2017CUDA10.1环境下配置BundleFusion - 知乎 BundleFusionWIN11VS2019 CUDA11.7环境配置-CSDN博客 我的环境:Win 11…

WPF prism

Prism Prism.Dryloc 包 安装 Nuget 包 - Prism.DryIoc 1. 修改 App.xaml 修改 App.xaml 文件&#xff0c;添加 prism 命名空间, 继承由 Application → PrismApplication&#xff0c;删除默认启动 url, StartupUri“MainWindow.xaml” <dryioc:PrismApplicationx:Class…

[Redis] Redis:高性能内存数据库与分布式架构设计

标题&#xff1a;[Redis] 浅谈分布式系统 水墨不写bug 文章目录 一、什么是Redis&#xff1f;一、核心定位二、核心优势三、典型应用场景四、Redis vs 传统数据库 二、架构选择与设计1、单机架构&#xff08;应用程序 数据库服务器&#xff09;2、应用程序和数据库服务器分离3…

React 第四十九节 Router中useNavigation的具体使用详解及注意事项

前言 useNavigation 是 React Router 中一个强大的钩子&#xff0c;用于获取当前页面导航的状态信息。 它可以帮助开发者根据导航状态优化用户体验&#xff0c;如显示加载指示器、防止重复提交等。 一、useNavigation核心用途 检测导航状态&#xff1a;判断当前是否正在进行…

【JavaEE】Spring事务

目录 一、事务简介二、Spring事务的实现2.1 事务的操作2.2 分类2.2.1 Spring编程式事务2.2.2 Spring 声明式事务 Transactional2.2.2.1 Transactional 详解2.2.2.1.1 rollbackFor2.2.2.1.2 Isolation2.2.2.1.3 propagation 一、事务简介 事务&#xff1a;事务是⼀组操作的集合…

Android15 userdebug版本不能remount

背景描述&#xff1a; 最近调试Android Vendor Hal的时候发现一个奇怪的现象: android userdebug版本刷到设备中&#xff0c;执行adb root没提示错误&#xff0c;但是没有获取到root权限。 Android设备运行的系统版本有三种情况&#xff1a;user版本、userdebug版本和eng版本…

R包安装报错解决案例系列|R包使用及ARM架构解决data.table安装错误问题

有不少同学是Mac系统的&#xff0c;分析过程中会发现部分R包总是安装不成功&#xff0c;这是因为部分R包基于windowsx86架构编译的&#xff0c;最常见的就是含 C/C/Fortran 的包&#xff0c;对于初学者都是建议linux和win去做&#xff0c;Windows 通常直接安装预编译好的二进制…

Linux上安装MongoDB

目录 一、在Linux系统安装MongoDB服务器 1、下载MongoDB 2、上传MongoDB并解压 3、创建必要目录 4、配置环境变量 5、创建配置文件 6、启动命令 7、验证安装 二、在Linux系统安装MongoDB客户端Shell 1、下载MongoDB Shell 2、上传MongoDB Shell并解压 3、配置环境变…

Redis最佳实践——安全与稳定性保障之访问控制详解

Redis 在电商应用的安全与稳定性保障之访问控制全面详解 一、安全访问控制体系架构 1. 多层级防护体系 #mermaid-svg-jpkDj2nKxCq9AXIW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jpkDj2nKxCq9AXIW .error-ico…

【华为开发者空间 x DeepSeek】服务器运行Ollama并在本地调用

文章概述 本文介绍了如何在 华为开发者空间 中快速部署并使用 Ollama 模型运行框架&#xff0c;并结合 deepseek-r1 模型进行本地或远程交互推理。内容涵盖环境准备、模型配置、网卡绑定、内网穿透、API调用等多个环节&#xff0c;适合希望在华为云上快速搭建本地类大模型推理…

STM32之IIC(重点)和OLED屏

内部集成电路概述 基本概念 内部集成电路&#xff08;Inter Integrated Circuit&#xff09;的简称叫做IIC或者I2C&#xff0c;是一种简单的、半双工同步通信的串行通信接口&#xff0c;IIC总线是上世纪80年代&#xff08;1982年&#xff09;由飞利浦公司设计出来&#xff0c…

学习海康VisionMaster之表面缺陷滤波

一&#xff1a;进一步学习了 今天学习下VisionMaster中的表面缺陷滤波&#xff1a;简单、无纹理背景的表面缺陷检测&#xff0c;可以检测表面的异物&#xff0c;缺陷&#xff0c;划伤等 二&#xff1a;开始学习 1&#xff1a;什么表面缺陷滤波&#xff1f; 表面缺陷滤波的核心…

游戏引擎学习第314天:将精灵拆分成多个层

回顾并为今天的工作做准备 我们今天继续昨天开始的工作&#xff0c;现在我们要回到渲染中处理 Z 值的最终环节。我们目前已经有一个我们认为还算合理的排序方式&#xff0c;虽然可能还需要在接下来的过程中进行一些调整&#xff0c;但总体上已经有了一个明确的方向。 我们已经…