概率图模型(1)--隐马尔科夫模型(1)
定义
隐马尔可夫模型是结构最简单的动态贝叶斯网,是一种著名的有向图模型,主要用于时序建模,在语音识别、自然语言处理领域有广泛应用。
隐马尔可夫模型是关于时序的概率模型,描述由一个隐藏的马尔科夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测随机序列的过程。
上图中箭头表示了变量间的依赖关系。在任一时刻,观测变量的取值仅依赖于状态变量,即 xtx_txt 由 yty_tyt 确定,与其他状态变量及观测变量的取值无关。同时,ttt 时刻的状态 yty_tyt 仅依赖 t−1t-1t−1 时刻的状态 yt−1y_{t-1}yt−1 ,与此前 t−2t-2t−2 个状态无关。这就是“马尔科夫链”,即系统下一时刻的状态仅由当前状态决定,不依赖于以往的任何状态。基于这种依赖关系,所有变量的联合概率分布为:
P(x1,y1,...,xn,yn)=P(y1)P(x1∣y1)∏i=2nP(yi∣yi−1)P(xi∣yi)(1)P(x_1,y_1,...,x_n, y_n)=P(y_1)P(x_1|y_1) \prod\limits_{i=2}^n P(y_i|y_{i-1})P(x_i|y_i) \tag{1}P(x1,y1,...,xn,yn)=P(y1)P(x1∣y1)i=2∏nP(yi∣yi−1)P(xi∣yi)(1)
除了结构信息,确定一个隐马尔可夫模型还需要下面三个参数:
状态转移概率:模型在各个状态间转换的概率,通常记为矩阵 A=[aij]N×NA=[a_{ij}]_{N \times N}A=[aij]N×N ,其中
aij=P(yt+1=sj∣yt=si),1≤i,j≤Na_{ij}=P(y_{t+1}=s_j|y_t=s_i), \quad 1 \le i,j \le Naij=P(yt+1=sj∣yt=si),1≤i,j≤N
输出观测概率:模型根据当前状态获得各个观测值的概率,通常记为矩阵 B=[bij]N×MB=[b_{ij}]_{N \times M}B=[bij]N×M,其中
bij=P(xt=oj∣yt=si),1≤i≤N,1≤j≤Mb_{ij} = P(x_t=o_j|y_t=s_i), \quad 1 \le i \le N ,1 \le j \le Mbij=P(xt=oj∣yt=si),1≤i≤N,1≤j≤M
表示任意时刻 ttt ,若状态为 sis_isi ,则观测值 ojo_joj 被获取的概率
初始状态概率:模型在初始时刻各状态出现的概率,通常记为 π=(π1,π2,...,πN)\pi = (\pi_1,\pi_2,...,\pi_N)π=(π1,π2,...,πN) ,其中
πi=P(y1=si),1≤i≤N\pi_i=P(y_1=s_i),\quad 1 \le i \le Nπi=P(y1=si),1≤i≤N
通过指定状态空间、观测空间和上述三组参数就能确定一个隐马尔可夫模型,通常用其参数 λ=[A,b,π]\lambda = [A,b,\pi]λ=[A,b,π] 来指代。
观测序列生成
给定隐马尔可夫模型 λ\lambdaλ ,它按照如下过程产生观测序列 x1,x2,...,xn{x_1, x_2,...,x_n}x1,x2,...,xn。
- 设置 t=1t=1t=1 ,并根据初始状态概率 π\piπ 选择初始状态 y1y_1y1
- 根据状态 yty_tyt 和输出观测概率 BBB 选择观测变量取值 xtx_txt
- 根据状态 yty_tyt 和状态转移矩阵 AAA 转移模型状态,即确定 yt+1y_{t+1}yt+1
- 若 t<nt < nt<n ,设置 t=t+1t = t+1t=t+1 ,并转到第2步,否则停止
三个基本问题
在实际应用中,人们常关注隐马尔可夫模型的三个基本问题:
- 给定模型 λ=[A,B,π]\lambda =[A,B,\pi]λ=[A,B,π] ,如何有效计算其产生的观测序列 x={x1,x2,...,xn}x=\{x_1,x_2,...,x_n\}x={x1,x2,...,xn} 的概率 P(x∣λ)P(x | \lambda)P(x∣λ) ?换言之,如何评估模型与观测序列之间的匹配程度?
- 给定模型 λ=[A,B,π]\lambda =[A,B,\pi]λ=[A,B,π] 和观测序列 x={x1,x2,...,xn}x=\{x_1,x_2,...,x_n\}x={x1,x2,...,xn} ,如何找到与此观测序列最匹配的状态序列 y={y1,y2,...,yn}y=\{y_1,y_2,...,y_n\}y={y1,y2,...,yn} ?换言之,如何根据观测序列推断隐藏的模型状态?
- 给定观测序列 x={x1,x2,...,xn}x=\{x_1,x_2,...,x_n\}x={x1,x2,...,xn} ,如何调整模型参数 λ=[A,B,π]\lambda =[A,B,\pi]λ=[A,B,π] 使得该序列出现的概率 P(x∣λ)P(x | \lambda)P(x∣λ) 最大?换言之,如何训练模型使其能最好地描述观测数据?
概率计算算法
如何计算观测序列概率 P(O∣λ)P(O|\lambda)P(O∣λ) 呢?
直接计算法
我们可以列举出所有可能出现的长度为 TTT 的隐藏序列 I={i1,i2,...,iT}I = \{i_1,i_2,...,i_T\}I={i1,i2,...,iT} ,分布求出这些隐藏序列与观测序列 O={o1,o2,...oT}O =\{o_1,o_2,...o_T\}O={o1,o2,...oT} 的联合概率分布 P(O,I∣λ)P(O,I|\lambda)P(O,I∣λ) ,这样我们就可以很容易的求出边缘分布 P(O∣λ)P(O|\lambda)P(O∣λ) 了。
首先,任意一个隐藏序列 I={i1,i2,...,iT}I = \{i_1,i_2,...,i_T\}I={i1,i2,...,iT} 出现的概率是:
P(I∣λ)=πi1ai1i2ai2i3...aiT−1iTP(I|\lambda) = \pi_{i_1} a_{i_1i_2} a_{i_2i_3}... a_{i_{T-1}\;\;i_T}P(I∣λ)=πi1ai1i2ai2i3...aiT−1iT
对于固定的状态序列 I={i1,i2,...,iT}I = \{i_1,i_2,...,i_T\}I={i1,i2,...,iT},我们要求的观察序列 O={o1,o2,...oT}O =\{o_1,o_2,...o_T\}O={o1,o2,...oT} 出现的概率是:
P(O∣I,λ)=bi1(o1)bi2(o2)...biT(oT)P(O|I, \lambda) = b_{i_1}(o_1)b_{i_2}(o_2)...b_{i_T}(o_T)P(O∣I,λ)=bi1(o1)bi2(o2)...biT(oT)
则 $O $ 和 III 联合出现的概率是:
P(O,I∣λ)=P(I∣λ)P(O∣I,λ)=πi1bi1(o1)ai1i2bi2(o2)...aiT−1iTbiT(oT)P(O,I|\lambda) = P(I|\lambda)P(O|I, \lambda) = \pi_{i_1}b_{i_1}(o_1)a_{i_1i_2}b_{i_2}(o_2)...a_{i_{T-1}\;\;i_T}b_{i_T}(o_T)P(O,I∣λ)=P(I∣λ)P(O∣I,λ)=πi1bi1(o1)ai1i2bi2(o2)...aiT−1iTbiT(oT)
然后求边缘概率分布,即可得到观测序列 OOO 在模型 λ\lambdaλ 下出现的条件概率 P(O∣λ)P(O|\lambda)P(O∣λ) :
P(O∣λ)=∑IP(O,I∣λ)=∑i1,i2,...iTπi1bi1(o1)ai1i2bi2(o2)...aiT−1iTbiT(oT)P(O|\lambda) = \sum\limits_{I}P(O,I|\lambda) = \sum\limits_{i_1,i_2,...i_T}\pi_{i_1}b_{i_1}(o_1)a_{i_1i_2}b_{i_2}(o_2)...a_{i_{T-1}\;\;i_T}b_{i_T}(o_T)P(O∣λ)=I∑P(O,I∣λ)=i1,i2,...iT∑πi1bi1(o1)ai1i2bi2(o2)...aiT−1iTbiT(oT)
虽然上述方法有效,但是如果我们的隐藏状态数 N 非常多的那就麻烦了,此时我们预测状态有 NTN^TNT 种组合,算法的时间复杂度是 O(TNT)O(TN^T)O(TNT) 阶的。因此对于一些隐藏状态数极少的模型,我们可以用暴力求解法来得到观测序列出现的概率,但是如果隐藏状态多,则上述算法太耗时,我们需要寻找其他简洁的算法。
前向算法
前向后向算法是前向算法和后向算法的统称,这两个算法都可以用来求HMM观测序列的概率。我们先来看看前向算法是如何求解这个问题的。
前向算法本质上属于动态规划的算法,也就是我们要通过找到局部状态递推的公式,这样一步步的从子问题的最优解拓展到整个问题的最优解。
在前向算法中,前向概率:定义时刻 ttt 时隐藏状态为 qiq_iqi, 观测状态的序列为 o1,o2,...oto_1,o_2,...o_to1,o2,...ot 的概率为前向概率。记为:
αt(i)=P(o1,o2,...ot,it=qi∣λ)\alpha_t(i) = P(o_1,o_2,...o_t, i_t =q_i | \lambda)αt(i)=P(o1,o2,...ot,it=qi∣λ)
可以递推地求得前向概率 αt(i)\alpha_t(i)αt(i) 及观测序列概率 P(O∣λ)P(O|\lambda)P(O∣λ)
从下图可以看出,我们可以基于时刻 ttt 时各个隐藏状态的前向概率,再乘以对应的状态转移概率,即 αt(j)aji\alpha_t(j)a_{ji}αt(j)aji 就是在时刻 t 观测到 o1,o2,...oto_1,o_2,...o_to1,o2,...ot ,并且时刻 t 隐藏状态 qjq_jqj, 时刻 t+1t+1t+1 隐藏状态 qiq_iqi 的概率。如果将想下面所有的线对应的概率求和,即 ∑j=1Nαt(j)aji\sum\limits_{j=1}^N\alpha_t(j)a_{ji}j=1∑Nαt(j)aji 就是在时刻 t 观测到 o1,o2,...oto_1,o_2,...o_to1,o2,...ot ,并且时刻 t+1 隐藏状态 qiq_iqi 的概率。继续一步,由于观测状态 ot+1o_{t+1}ot+1 只依赖于 t+1 时刻隐藏状态 qiq_iqi , 这样 [∑j=1Nαt(j)aji]bi(ot+1)[\sum\limits_{j=1}^N\alpha_t(j)a_{ji}]b_i(o_{t+1})[j=1∑Nαt(j)aji]bi(ot+1) 就是在在时刻 t+1 观测到 o1,o2,...ot,ot+1o_1,o_2,...o_t,o_{t+1}o1,o2,...ot,ot+1 ,并且时刻 t+1 隐藏状态 qiq_iqi 的概率。而这个概率,恰恰就是时刻 t+1 对应的隐藏状态ii的前向概率,这样我们得到了前向概率的递推关系式如下:
αt+1(i)=[∑j=1Nαt(j)aji]bi(ot+1)\alpha_{t+1}(i) = \Big[\sum\limits_{j=1}^N\alpha_t(j)a_{ji}\Big]b_i(o_{t+1})αt+1(i)=[j=1∑Nαt(j)aji]bi(ot+1)
我们的动态规划从时刻1开始,到时刻 T 结束,由于 αT(i)\alpha_T(i)αT(i) 表示在时刻 T 观测序列为 o1,o2,...oto_1,o_2,...o_to1,o2,...ot ,并且时刻 T 隐藏状态 qiq_iqi 的概率,我们只要将所有隐藏状态对应的概率相加,即 ∑i=1NαT(i)\sum\limits_{i=1}^N\alpha_T(i)i=1∑NαT(i) 就得到了在时刻 T 观测序列为 o1,o2,...oto_1,o_2,...o_to1,o2,...ot 的概率。
总结下前向算法
输入:HMM模型 λ=(A,B,Π)\lambda = (A, B, \Pi)λ=(A,B,Π) ,观测序列 O=(o1,o2,...oT)O=(o_1,o_2,...o_T)O=(o1,o2,...oT)
输出:观测序列概率 P(O∣λ)P(O|\lambda)P(O∣λ)
- 计算时刻1的各个隐藏状态前向概率:
α1(i)=πibi(o1),i=1,2,...N\alpha_1(i) = \pi_ib_i(o_1),\; i=1,2,...Nα1(i)=πibi(o1),i=1,2,...N
- 递推时刻 2,3,...T2,3,...T2,3,...T 时刻的前向概率:
αt+1(i)=[∑j=1Nαt(j)aji]bi(ot+1),i=1,2,...N\alpha_{t+1}(i) = \Big[\sum\limits_{j=1}^N\alpha_t(j)a_{ji}\Big]b_i(o_{t+1}),\; i=1,2,...Nαt+1(i)=[j=1∑Nαt(j)aji]bi(ot+1),i=1,2,...N
- 计算最终结果:
P(O∣λ)=∑i=1NαT(i)P(O|\lambda) = \sum\limits_{i=1}^N\alpha_T(i)P(O∣λ)=i=1∑NαT(i)
从递推公式可以看出,我们的算法时间复杂度是 O(TN2)O(TN^2)O(TN2),比暴力解法的时间复杂度 O(TNT)O(TN^T)O(TNT) 少了几个数量级。
后向算法
后向算法和前向算法非常类似,都是用的动态规划,唯一的区别是选择的局部状态不同,后向算法用的是“后向概率”,那么后向概率是如何定义的呢?
定义时刻 t 时隐藏状态为 qiq_iqi , 从时刻 t+1 到最后时刻 T 的观测状态的序列为 ot+1,ot+2,...oTo_{t+1},o_{t+2},...o_Tot+1,ot+2,...oT 的概率为后向概率。记为:
βt(i)=P(ot+1,ot+2,...oT∣it=qi,λ)\beta_t(i) = P(o_{t+1},o_{t+2},...o_T| i_t =q_i , \lambda)βt(i)=P(ot+1,ot+2,...oT∣it=qi,λ)
后向概率的动态规划递推公式和前向概率是相反的。现在我们假设我们已经找到了在时刻 t+1 时各个隐藏状态的后向概率 βt+1(j)\beta_{t+1}(j)βt+1(j),现在我们需要递推出时刻 t 时各个隐藏状态的后向概率。如下图,我们可以计算出观测状态的序列为 ot+2,ot+3,...oTo_{t+2},o_{t+3},...o_Tot+2,ot+3,...oT,t 时隐藏状态为 qiq_iqi , 时刻 t+1 隐藏状态为 qjq_jqj 的概率为 aijβt+1(j)a_{ij}\beta_{t+1}(j)aijβt+1(j) , 接着可以得到观测状态的序列为 ot+1,ot+2,...oTo_{t+1},o_{t+2},...o_Tot+1,ot+2,...oT ,t 时隐藏状态为 qiq_iqi , 时刻 t+1 隐藏状态为 qjq_jqj 的概率为 aijbj(ot+1)βt+1(j)a_{ij}b_j(o_{t+1})\beta_{t+1}(j)aijbj(ot+1)βt+1(j) , 则把下面所有线对应的概率加起来,我们可以得到观测状态的序列为 ot+1,ot+2,...oTo_{t+1},o_{t+2},...o_Tot+1,ot+2,...oT,t 时隐藏状态为 qiq_iqi 的概率为 ∑j=1Naijbj(ot+1)βt+1(j)\sum\limits_{j=1}^{N}a_{ij}b_j(o_{t+1})\beta_{t+1}(j)j=1∑Naijbj(ot+1)βt+1(j) ,这个概率即为时刻 t 的后向概率。
这样我们得到了后向概率的递推关系式如下:
βt(i)=∑j=1Naijbj(ot+1)βt+1(j)\beta_{t}(i) = \sum\limits_{j=1}^{N}a_{ij}b_j(o_{t+1})\beta_{t+1}(j)βt(i)=j=1∑Naijbj(ot+1)βt+1(j)
现在我们总结下后向算法的流程,注意下和前向算法的相同点和不同点:
输入:HMM模型 λ=(A,B,Π)\lambda = (A, B, \Pi)λ=(A,B,Π) ,观测序列 O=(o1,o2,...oT)O=(o_1,o_2,...o_T)O=(o1,o2,...oT)
输出:观测序列概率 P(O∣λ)P(O|\lambda)P(O∣λ)
- 初始化时刻 T 的各个隐藏状态后向概率:
βT(i)=1,i=1,2,...N\beta_T(i) = 1,\; i=1,2,...NβT(i)=1,i=1,2,...N
- 递推时刻 T−1,T−2,...1T-1,T-2,...1T−1,T−2,...1 时刻的后向概率:
βt(i)=∑j=1Naijbj(ot+1)βt+1(j),i=1,2,...N\beta_{t}(i) = \sum\limits_{j=1}^{N}a_{ij}b_j(o_{t+1})\beta_{t+1}(j),\; i=1,2,...Nβt(i)=j=1∑Naijbj(ot+1)βt+1(j),i=1,2,...N
- 计算最终结果:
P(O∣λ)=∑i=1Nπibi(o1)β1(i)P(O|\lambda) = \sum\limits_{i=1}^N\pi_ib_i(o_1)\beta_1(i)P(O∣λ)=i=1∑Nπibi(o1)β1(i)
此时我们的算法时间复杂度仍然是 O(TN2)O(TN^2)O(TN2)。
HMM常用概率的计算
利用前向概率和后向概率,我们可以计算出HMM中单个状态和两个状态的概率公式。
1)给定模型 λ\lambdaλ 和观测序列 O ,在时刻 t 处于状态 qiq_iqi 的概率记为:
γt(i)=P(it=qi∣O,λ)=P(it=qi,O∣λ)P(O∣λ)\gamma_t(i) = P(i_t = q_i | O,\lambda) = \frac{P(i_t = q_i ,O|\lambda)}{P(O|\lambda)}γt(i)=P(it=qi∣O,λ)=P(O∣λ)P(it=qi,O∣λ)
利用前向概率和后向概率的定义可知
P(it=qi,O∣λ)=αt(i)βt(i)P(i_t = q_i ,O|\lambda) = \alpha_t(i)\beta_t(i)P(it=qi,O∣λ)=αt(i)βt(i)
于是我们得到:
γt(i)=αt(i)βt(i)∑j=1Nαt(j)βt(j)\gamma_t(i) = \frac{ \alpha_t(i)\beta_t(i)}{\sum\limits_{j=1}^N \alpha_t(j)\beta_t(j)}γt(i)=j=1∑Nαt(j)βt(j)αt(i)βt(i)
2)给定模型 λ\lambdaλ 和观测序列 O ,在时刻 t 处于状态 qiq_iqi ,且时刻 t+1 处于状态 qjq_jqj 的概率记为:
ξt(i,j)=P(it=qi,it+1=qj∣O,λ)=P(it=qi,it+1=qj,O∣λ)P(O∣λ)\xi_t(i,j) = P(i_t = q_i, i_{t+1}=q_j | O,\lambda) = \frac{ P(i_t = q_i, i_{t+1}=q_j , O|\lambda)}{P(O|\lambda)}ξt(i,j)=P(it=qi,it+1=qj∣O,λ)=P(O∣λ)P(it=qi,it+1=qj,O∣λ)
而 P(it=qi,it+1=qj,O∣λ)P(i_t = q_i, i_{t+1}=q_j , O|\lambda)P(it=qi,it+1=qj,O∣λ) 可以由前向后向概率来表示为:
P(it=qi,it+1=qj,O∣λ)=αt(i)aijbj(ot+1)βt+1(j)P(i_t = q_i, i_{t+1}=q_j , O|\lambda) = \alpha_t(i)a_{ij}b_j(o_{t+1})\beta_{t+1}(j)P(it=qi,it+1=qj,O∣λ)=αt(i)aijbj(ot+1)βt+1(j)
从而最终我们得到 ξt(i,j)\xi_t(i,j)ξt(i,j) 的表达式如下:
ξt(i,j)=αt(i)aijbj(ot+1)βt+1(j)∑r=1N∑s=1Nαt(r)arsbs(ot+1)βt+1(s)\xi_t(i,j) = \frac{\alpha_t(i)a_{ij}b_j(o_{t+1})\beta_{t+1}(j)}{\sum\limits_{r=1}^N\sum\limits_{s=1}^N\alpha_t(r)a_{rs}b_s(o_{t+1})\beta_{t+1}(s)}ξt(i,j)=r=1∑Ns=1∑Nαt(r)arsbs(ot+1)βt+1(s)αt(i)aijbj(ot+1)βt+1(j)
- 将 γt(i)\gamma_t(i)γt(i) 和 ξt(i,j)\xi_t(i,j)ξt(i,j) 在各个时刻 t 求和,可以得到:
在观测序列 O 下状态ii出现的期望值 ∑t=1Tγt(i)\sum\limits_{t=1}^T\gamma_t(i)t=1∑Tγt(i)
在观测序列 O 下由状态ii转移的期望值 ∑t=1T−1γt(i)\sum\limits_{t=1}^{T-1}\gamma_t(i)t=1∑T−1γt(i)
在观测序列 O 下由状态ii转移到状态jj的期望值 ∑t=1T−1ξt(i,j)\sum\limits_{t=1}^{T-1}\xi_t(i,j)t=1∑T−1ξt(i,j)
上面这些常用的概率值在求解HMM问题二,即求解HMM模型参数的时候需要用到。我们在这个系列的第三篇来讨论求解HMM参数的问题和解法。
参考
https://www.cnblogs.com/pinard/p/6955871.html
周志华《机器学习》
概率图模型(1)--隐马尔科夫模型(1)相关推荐
- 时序模型:隐马尔科夫模型(HMM)
1. 隐马尔科夫模型的定义 隐马尔科夫模型(hidden Markov model,HMM),描述由一个隐藏的马尔科夫链随机生成不可观测的状态随机序列,再由各个状态(state)生成一个观测(obse ...
- 机器学习之概率图模型(贝叶斯概率,隐马尔科夫模型)
一.贝叶斯公式 在学习概率图模型之前先要了解贝叶斯公式: 由公式(1),(2)可得: 这便是贝叶斯公式,其中条件概率P(A/B)称为后验概率,概率P(A),P(B)称为先验概率,条件概率P(B/A), ...
- 【深度】从朴素贝叶斯到维特比算法:详解隐马尔科夫模型
详解隐马尔科夫模型 作者:David S. Batista 选自:机器之心 本文首先简要介绍朴素贝叶斯,再将其扩展到隐马尔科夫模型.我们不仅会讨论隐马尔科夫模型的基本原理,同时还从朴素贝叶斯的角度讨论 ...
- 第九章 隐马尔科夫模型HMM
文章目录 1 隐马尔科夫模型定义 2 概率计算算法 2.1 前向概率 2.2 概率计算 3 学习算法 3.1 EM算法 3.2EM在HMM 4 预测算法 1 隐马尔科夫模型定义 隐马尔科夫模型是一个s ...
- 10_隐马尔科夫模型HMM1_统计学习方法
文章目录 一.几个基本概念 1.隐马尔可夫模型 2.马尔科夫链 3.随机过程 4.马尔科夫性质 二.隐马尔科夫模型 1.隐马尔科夫模型的引入 2.隐马尔科夫模型定义 3.隐马尔科夫模型的两个假设 4. ...
- 统计学习方法十:隐马尔科夫模型
一.基本概念 1.马尔科夫假设:当前的状态只与之前的状态有关 2.马尔科夫过程:当前的状态只与前n个状态有关,被称为n阶马尔科夫模型. 3.马尔科夫链:可以理解为带有概率的状态转移链 3.一阶马尔科夫 ...
- 隐马尔科夫模型一(概念理解)
前言 由于前一段时间在看CTC论文,里面用到了HMM中的前向后向算法,推公式的时候·一脸懵逼,所以又来学习HMM的思想,所以写篇博客做个笔记.本部分博客分为两篇,第一篇主要介绍一些基本的概念和思想,第 ...
- NLP入门概览(4)—— 序列标注a:隐马尔科夫模型(HMM)
在这一部分中,我们将要介绍NLP领域最常见的一类问题:序列标注. 1. 序列标注 在NLP领域中,有许多的任务可以转化为"将输入的语言序列转化为标注序列"来解决问题.比如, ...
- 强化学习(一)-->隐马尔科夫模型HMM-->HMM模型基础
隐马尔科夫模型HMM 隐马尔科夫模型算是比较经典的机器学习模型了,在自然语言处理.语言识别.模型识别等这些领域也得到了广泛的应用.在深度学习的崛起,尤其是RNN.LSTM等神经网络序列模型的火热,HM ...
最新文章
- Linux LVM 收藏
- centos7 xfce 中文字体输入法
- Spring MVC中jsessionid所引起的问题 和解决
- 赶快卸载!微软新公布了18个流氓浏览器插件!
- 【Java】浅谈JavaDoc文档注释
- powerbi内部部署安装指导
- oracle windows 优化工具,使用Windows工具管理Nt上的Oracle数据库
- Win10环境下,SecureCRT连接不上虚拟机,显示连接超时Connection time out. 而且网络连接里没有网络适配器VMnet1和VMnet8,互ping也不同。...
- Linux系统如何把一个文件传递到另一个机器上
- 测试手机芯片体质软件,高通cpu体质测试软件
- XJOI字符串的大小关系1级19段
- HashMap和HashTable的异同点
- 如何使用Chrome浏览器,打包生成自己的插件(crx格式文件)?
- 为什么有时优盘是只读模式_如何设置U盘为只读模式
- apt-get 离线包安装
- 两个或多个有序数组合并为一个有序数组
- 单片机转嵌入式Linux的思考
- English interview。。。
- Java-SpringBoot-养老驿站管理系统-毕业设计
- 【自学Docker 】Docker export命令