【技术分享】L-BFGS算法的讲解与应用
本文原作者:尹迪,经授权后发布。
1牛顿法
设f(x)
是二次可微实函数,又设$x^{(k)}$是f(x)
一个极小点的估计,我们把f(x)
在$x^{(k)}$处展开成Taylor
级数, 并取二阶近似。
上式中最后一项的中间部分表示f(x)
在$x^{(k)}$处的Hesse
矩阵。对上式求导并令其等于0,可以的到下式:
设Hesse
矩阵可逆,由上式可以得到牛顿法的迭代公式如下 (1.1)
值得注意 , 当初始点远离极小点时,牛顿法可能不收敛。原因之一是牛顿方向不一定是下降方向,经迭代,目标函数可能上升。此外,即使目标函数下降,得到的点也不一定是沿牛顿方向最好的点或极小点。 因此,我们在牛顿方向上增加一维搜索,提出阻尼牛顿法。其迭代公式是 (1.2):
其中,lambda
是由一维搜索(参考文献【1】了解一维搜索)得到的步长,即满足
2 拟牛顿法
2.1 拟牛顿条件
前面介绍了牛顿法,它的突出优点是收敛很快,但是运用牛顿法需要计算二阶偏导数,而且目标函数的Hesse
矩阵可能非正定。为了克服牛顿法的缺点,人们提出了拟牛顿法,它的基本思想是用不包含二阶导数的矩阵近似牛顿法中的Hesse
矩阵的逆矩阵。 由于构造近似矩阵的方法不同,因而出现不同的拟牛顿法。
下面分析怎样构造近似矩阵并用它取代牛顿法中的Hesse
矩阵的逆。上文 (1.2) 已经给出了牛顿法的迭代公式,为了构造Hesse
矩阵逆矩阵的近似矩阵$H_{(k)}$ ,需要先分析该逆矩阵与一阶导数的关系。
设在第k
次迭代之后,得到$x^{(k+1)}$ ,我们将目标函数f(x)
在点$x^{(k+1)}$展开成Taylor
级数, 并取二阶近似,得到
由此可知,在$x^{(k+1)}$附近有,
记
则有
又设Hesse
矩阵可逆,那么上式可以写为如下形式。
这样,计算出p
和q
之后,就可以通过上面的式子估计Hesse
矩阵的逆矩阵。因此,为了用不包含二阶导数的矩阵$H_{(k+1)}$取代牛顿法中Hesse
矩阵的逆矩阵,有理由令$H_{(k+1)}$满足公式 (2.1) :
公式**(2.1)**称为拟牛顿条件。
2.2 秩1校正
当Hesse
矩阵的逆矩阵是对称正定矩阵时,满足拟牛顿条件的矩阵$H_{(k)}$也应该是对称正定矩阵。构造这样近似矩阵的一般策略是,$H_{(1)}$取为任意一个n
阶对称正定矩阵,通常选择n
阶单位矩阵I
,然后通过修正$H_{(k)}$给定$H_{(k+1)}$。 令,
秩1校正公式写为如下公式**(2.2)**形式。
2.3 DFP算法
著名的DFP
方法是Davidon
首先提出,后来又被Feltcher
和Powell
改进的算法,又称为变尺度法。在这种方法中,定义校正矩阵为公式 (2.3)
那么得到的满足拟牛顿条件的DFP
公式如下 (2.4)
查看文献【1】,了解DFP
算法的计算步骤。
2.4 BFGS算法
前面利用拟牛顿条件 (2.1) 推导出了DFP
公式 (2.4) 。下面我们用不含二阶导数的矩阵$B_{(k+1)}$近似Hesse
矩阵,从而给出另一种形式的拟牛顿条件 (2.5) :
将公式 (2.1) 的H
换为B
,p
和q
互换正好可以得到公式 (2.5) 。所以我们可以得到B
的修正公式 (2.6) :
这个公式称关于矩阵B
的BFGS
修正公式,也称为DFP
公式的对偶公式。设$B_{(k+1)}$可逆,由公式 (2.1) 以及 (2.5) 可以推出:
这样可以得到关于H
的BFGS
公式为下面的公式 (2.7):
这个重要公式是由Broyden
,Fletcher
,Goldfard
和Shanno
于1970年提出的,所以简称为BFGS
。数值计算经验表明,它比DFP
公式还好,因此目前得到广泛应用。
2.5 L-BFGS(限制内存BFGS)算法
在BFGS
算法中,仍然有缺陷,比如当优化问题规模很大时,矩阵的存储和计算将变得不可行。为了解决这个问题,就有了L-BFGS
算法。L-BFGS
即Limited-memory BFGS
。 L-BFGS
的基本思想是只保存最近的m
次迭代信息,从而大大减少数据的存储空间。对照BFGS
,重新整理一下公式:
之前的BFGS
算法有如下公式**(2.8)**
那么同样有
将该式子带入到公式**(2.8)**中,可以推导出如下公式
假设当前迭代为k
,只保存最近的m
次迭代信息,按照上面的方式迭代m
次,可以得到如下的公式**(2.9)**
上面迭代的最终目的就是找到k
次迭代的可行方向,即
为了求可行方向r
,可以使用two-loop recursion
算法来求。该算法的计算过程如下,算法中出现的y
即上文中提到的t
:
算法L-BFGS
的步骤如下所示。
2.6 OWL-QN算法
2.6.1 L1 正则化
在机器学习算法中,使用损失函数作为最小化误差,而最小化误差是为了让我们的模型拟合我们的训练数据,此时, 若参数过分拟合我们的训练数据就会有过拟合的问题。正则化参数的目的就是为了防止我们的模型过分拟合训练数据。此时,我们会在损失项之后加上正则化项以约束模型中的参数:
$$J(x) = l(x) + r(x)$$
公式右边的第一项是损失函数,用来衡量当训练出现偏差时的损失,可以是任意可微凸函数(如果是非凸函数该算法只保证找到局部最优解)。 第二项是正则化项。用来对模型空间进行限制,从而得到一个更“简单”的模型。
根据对模型参数所服从的概率分布的假设的不同,常用的正则化一般有L2
正则化(模型参数服从Gaussian
分布)、L1
正则化(模型参数服从Laplace
分布)以及它们的组合形式。
L1
正则化的形式如下
$$J(x) = l(x) + C ||x||_{1}$$
L2
正则化的形式如下
$$J(x) = l(x) + C ||x||_{2}$$
L1
正则化和L2
正则化之间的一个最大区别在于前者可以产生稀疏解,这使它同时具有了特征选择的能力,此外,稀疏的特征权重更具有解释意义。如下图:
图左侧是L2
正则,右侧为L1
正则。当模型中只有两个参数,即$w_1$和$w_2$时,L2
正则的约束空间是一个圆,而L1
正则的约束空间为一个正方形,这样,基于L1
正则的约束会产生稀疏解,即图中某一维($w_2$)为0。 而L2
正则只是将参数约束在接近0的很小的区间里,而不会正好为0(不排除有0的情况)。对于L1
正则产生的稀疏解有很多的好处,如可以起到特征选择的作用,因为有些维的系数为0,说明这些维对于模型的作用很小。
这里有一个问题是,L1
正则化项不可微,所以无法像求L-BFGS
那样去求。微软提出了OWL-QN
(Orthant-Wise Limited-Memory Quasi-Newton
)算法,该算法是基于L-BFGS
算法的可用于求解L1
正则的算法。 简单来讲,OWL-QN
算法是指假定变量的象限确定的条件下使用L-BFGS
算法来更新,同时,使得更新前后变量在同一个象限中(使用映射来满足条件)。
2.6.2 OWL-QN算法的具体过程
- 1 次微分
设$f:I\rightarrow R$是一个实变量凸函数,定义在实数轴上的开区间内。这种函数不一定是处处可导的,例如绝对值函数$f(x)=|x|$。但是,从下面的图中可以看出(也可以严格地证明),对于定义域中的任何$x_0$,我们总可以作出一条直线,它通过点($x_0$, $f(x_0)$),并且要么接触f的图像,要么在它的下方。 这条直线的斜率称为函数的次导数。推广到多元函数就叫做次梯度。
凸函数$f:I\rightarrow R$在点$x_0$的次导数,是实数c
使得:
对于所有I
内的x
。我们可以证明,在点$x_0$的次导数的集合是一个非空闭区间$[a, b]$,其中a
和b
是单侧极限。
它们一定存在,且满足$a \leqslant b$。所有次导数的集合$[a, b]$称为函数f
在$x_0$的次微分。
- 2 伪梯度
利用次梯度的概念推广了梯度,定义了一个符合上述原则的伪梯度,求一维搜索的可行方向时用伪梯度来代替L-BFGS
中的梯度。
其中
我们要如何理解这个伪梯度呢?对于不是处处可导的凸函数,可以分为下图所示的三种情况。
左侧极限小于0:
右侧极限大于0:
其它情况:
结合上面的三幅图表示的三种情况以及伪梯度函数公式,我们可以知道,伪梯度函数保证了在$x_0$处取得的方向导数是最小的。
- 3 映射
有了函数的下降的方向,接下来必须对变量的所属象限进行限制,目的是使得更新前后变量在同一个象限中,定义函数:$\pi: \mathbb{R}^{n} \rightarrow \mathbb{R}^{n}$
上述函数$\pi$直观的解释是若$x$和$y$在同一象限则取$x$,若两者不在同一象限中,则取0。
- 4 线搜索
上述的映射是防止更新后的变量的坐标超出象限,而对坐标进行的一个约束,具体的约束的形式如下:
其中$x^{k} + \alpha p _{k}$是更新公式,$\zeta$表示$x^k$所在的象限,$p^k$表示伪梯度下降的方向,它们具体的形式如下:
上面的公式中,$v^k$为负伪梯度方向,$d^k = H_{k}v^{k}$。
选择$\alpha$的方式有很多种,在OWL-QN
中,使用了backtracking line search
的一种变种。选择常数$\beta, \gamma \subset (0,1)$,对于$n=0,1,2,...$,使得 $\alpha = \beta^{n}$满足:
- 5 算法流程
与L-BFGS
相比,第一步用伪梯度代替梯度,第二、三步要求一维搜索不跨象限,也就是迭代前的点与迭代后的点处于同一象限,第四步要求估计Hessian
矩阵时依然使用损失函数的梯度。
3 源码解析
3.1 BreezeLBFGS
spark Ml
调用breeze
中实现的BreezeLBFGS
来解最优化问题。
val optimizer = new BreezeLBFGS[BDV[Double]]($(maxIter), 10, $(tol))
val states =
optimizer.iterations(new CachedDiffFunction(costFun), initialWeights.toBreeze.toDenseVector)
下面重点分析lbfgs.iterations
的实现。
def iterations(f: DF, init: T): Iterator[State] = {
val adjustedFun = adjustFunction(f)
infiniteIterations(f, initialState(adjustedFun, init)).takeUpToWhere(_.converged)
}
//调用infiniteIterations,其中State是一个样本类
def infiniteIterations(f: DF, state: State): Iterator[State] = {
var failedOnce = false
val adjustedFun = adjustFunction(f)
//无限迭代
Iterator.iterate(state) { state => try {
//1 选择梯度下降方向
val dir = chooseDescentDirection(state, adjustedFun)
//2 计算步长
val stepSize = determineStepSize(state, adjustedFun, dir)
//3 更新权重
val x = takeStep(state,dir,stepSize)
//4 利用CostFun.calculate计算损失值和梯度
val (value,grad) = calculateObjective(adjustedFun, x, state.history)
val (adjValue,adjGrad) = adjust(x,grad,value)
val oneOffImprovement = (state.adjustedValue - adjValue)/(state.adjustedValue.abs max adjValue.abs max 1E-6 * state.initialAdjVal.abs)
//5 计算s和t
val history = updateHistory(x,grad,value, adjustedFun, state)
//6 只保存m个需要的s和t
val newAverage = updateFValWindow(state, adjValue)
failedOnce = false
var s = State(x,value,grad,adjValue,adjGrad,state.iter + 1, state.initialAdjVal, history, newAverage, 0)
val improvementFailure = (state.fVals.length >= minImprovementWindow && state.fVals.nonEmpty && state.fVals.last > state.fVals.head * (1-improvementTol))
if(improvementFailure)
s = s.copy(fVals = IndexedSeq.empty, numImprovementFailures = state.numImprovementFailures + 1)
s
} catch {
case x: FirstOrderException if !failedOnce =>
failedOnce = true
logger.error("Failure! Resetting history: " + x)
state.copy(history = initialHistory(adjustedFun, state.x))
case x: FirstOrderException =>
logger.error("Failure again! Giving up and returning. Maybe the objective is just poorly behaved?")
state.copy(searchFailed = true)
}
}
}
看上面的代码注释,它的流程可以分五步来分析。
3.1.1 选择梯度下降方向
protected def chooseDescentDirection(state: State, fn: DiffFunction[T]):T = {
state.history * state.grad
}
这里的*
是重写的方法,它的实现如下:
def *(grad: T) = {
val diag = if(historyLength > 0) {
val prevStep = memStep.head
val prevGradStep = memGradDelta.head
val sy = prevStep dot prevGradStep
val yy = prevGradStep dot prevGradStep
if(sy < 0 || sy.isNaN) throw new NaNHistory
sy/yy
} else {
1.0
}
val dir = space.copy(grad)
val as = new Array[Double](m)
val rho = new Array[Double](m)
//第一次递归
for(i <- 0 until historyLength) {
rho(i) = (memStep(i) dot memGradDelta(i))
as(i) = (memStep(i) dot dir)/rho(i)
if(as(i).isNaN) {
throw new NaNHistory
}
axpy(-as(i), memGradDelta(i), dir)
}
dir *= diag
//第二次递归
for(i <- (historyLength - 1) to 0 by (-1)) {
val beta = (memGradDelta(i) dot dir)/rho(i)
axpy(as(i) - beta, memStep(i), dir)
}
dir *= -1.0
dir
}
}
非常明显,该方法就是实现了上文提到的two-loop recursion
算法。
3.1.2 计算步长
protected def determineStepSize(state: State, f: DiffFunction[T], dir: T) = {
val x = state.x
val grad = state.grad
val ff = LineSearch.functionFromSearchDirection(f, x, dir)
val search = new StrongWolfeLineSearch(maxZoomIter = 10, maxLineSearchIter = 10) // TODO: Need good default values here.
val alpha = search.minimize(ff, if(state.iter == 0.0) 1.0/norm(dir) else 1.0)
if(alpha * norm(grad) < 1E-10)
throw new StepSizeUnderflow
alpha
}
这一步对应L-BFGS
的步骤的Step 5
,通过一维搜索计算步长。
3.1.3 更新权重
protected def takeStep(state: State, dir: T, stepSize: Double) = state.x + dir * stepSize
这一步对应L-BFGS
的步骤的Step 5
,更新权重。
3.1.4 计算损失值和梯度
protected def calculateObjective(f: DF, x: T, history: History): (Double, T) = {
f.calculate(x)
}
这一步对应L-BFGS
的步骤的Step 7
,使用传人的CostFun.calculate
方法计算梯度和损失值。并计算出s
和t
。
3.1.5 计算s和t,并更新history
//计算s和t
protected def updateHistory(newX: T, newGrad: T, newVal: Double, f: DiffFunction[T], oldState: State): History = {
oldState.history.updated(newX - oldState.x, newGrad :- oldState.grad)
}
//添加新的s和t,并删除过期的s和t
protected def updateFValWindow(oldState: State, newAdjVal: Double):IndexedSeq[Double] = {
val interm = oldState.fVals :+ newAdjVal
if(interm.length > minImprovementWindow) interm.drop(1)
else interm
}
3.2 BreezeOWLQN
BreezeOWLQN
的实现与BreezeLBFGS
的实现主要有下面一些不同点。
3.2.1 选择梯度下降方向
override protected def chooseDescentDirection(state: State, fn: DiffFunction[T]) = {
val descentDir = super.chooseDescentDirection(state.copy(grad = state.adjustedGradient), fn)
// The original paper requires that the descent direction be corrected to be
// in the same directional (within the same hypercube) as the adjusted gradient for proof.
// Although this doesn't seem to affect the outcome that much in most of cases, there are some cases
// where the algorithm won't converge (confirmed with the author, Galen Andrew).
val correctedDir = space.zipMapValues.map(descentDir, state.adjustedGradient, { case (d, g) => if (d * g < 0) d else 0.0 })
correctedDir
}
此处调用了BreezeLBFGS
的chooseDescentDirection
方法选择梯度下降的方向,然后调整该下降方向为正确的方向(方向必须一致)。
3.2.2 计算步长$\alpha$
override protected def determineStepSize(state: State, f: DiffFunction[T], dir: T) = {
val iter = state.iter
val normGradInDir = {
val possibleNorm = dir dot state.grad
possibleNorm
}
val ff = new DiffFunction[Double] {
def calculate(alpha: Double) = {
val newX = takeStep(state, dir, alpha)
val (v, newG) = f.calculate(newX) // 计算梯度
val (adjv, adjgrad) = adjust(newX, newG, v) // 调整梯度
adjv -> (adjgrad dot dir)
}
}
val search = new BacktrackingLineSearch(state.value, shrinkStep= if(iter < 1) 0.1 else 0.5)
val alpha = search.minimize(ff, if(iter < 1) .5/norm(state.grad) else 1.0)
alpha
}
takeStep
方法用于更新参数。
// projects x to be on the same orthant as y
// this basically requires that x'_i = x_i if sign(x_i) == sign(y_i), and 0 otherwise.
override protected def takeStep(state: State, dir: T, stepSize: Double) = {
val stepped = state.x + dir * stepSize
val orthant = computeOrthant(state.x, state.adjustedGradient)
space.zipMapValues.map(stepped, orthant, { case (v, ov) =>
v * I(math.signum(v) == math.signum(ov))
})
}
calculate
方法用于计算梯度,adjust
方法用于调整梯度。
// Adds in the regularization stuff to the gradient
override protected def adjust(newX: T, newGrad: T, newVal: Double): (Double, T) = {
var adjValue = newVal
val res = space.zipMapKeyValues.mapActive(newX, newGrad, {case (i, xv, v) =>
val l1regValue = l1reg(i)
require(l1regValue >= 0.0)
if(l1regValue == 0.0) {
v
} else {
adjValue += Math.abs(l1regValue * xv)
xv match {
case 0.0 => {
val delta_+ = v + l1regValue //计算左导数
val delta_- = v - l1regValue //计算右导数
if (delta_- > 0) delta_- else if (delta_+ < 0) delta_+ else 0.0
}
case _ => v + math.signum(xv) * l1regValue
}
}
})
adjValue -> res
}
参考文献
【1】陈宝林,最优化理论和算法
【2】[Updating Quasi-Newton Matrices with Limited Storage](docs/Updating Quasi-Newton Matrices with Limited Storage.pdf)
【3】[On the Limited Memory BFGS Method for Large Scale Optimization](docs/On the Limited Memory BFGS Method for Large Scale Optimization.pdf)
【4】L-BFGS算法
【5】BFGS算法
【6】逻辑回归模型及LBFGS的Sherman Morrison(SM) 公式推导
【7】Scalable Training of L1-Regularized Log-Linear Models
推荐阅读
-
Oracle 数据库技术分享] BLOB 和 CLOB 的选择与应用
-
【技术分享】L-BFGS算法的讲解与应用
-
深度探索推特开源算法的趣味之旅;应对ChatGPT被封号的策略大集合;全面解析ControlNet技术教程;如何搭建自己的ChatGPT应用程序?建立开源项目阅读工作流程的方法分享 | ShowMeAI日报
-
【摩尔线程+Colossal-AI强强联手】MusaBert登上CLUE榜单TOP10:技术细节揭秘 - 技术实力:摩尔线程凭借"软硬兼备"的技术底蕴,让MusaBert得以从底层优化到顶层。其内置多功能GPU配备AI加速和并行计算模块,提供了全面的AI与科学计算支持,为AI推理和低资源条件下的大模型训练等场景带来了高效、经济且环保的算力。 - 算法层面亮点:依托Colossal-AI AI大模型开发系统,MusaBert在训练过程中展现出了卓越的并行性能与易用性,特别在预处理阶段对DataLoader进行了优化,适应低资源环境高效处理海量数据。同时,通过精细的建模优化、领域内数据增强以及Adan优化器等手段,挖掘和展示了预训练语言模型出色的语义理解潜力。基于MusaBert,摩尔线程自主研发的MusaSim通过对比学习方法微调,结合百万对标注数据,MusaSim在多个任务如语义相似度、意图识别和情绪分析中均表现出色。 - 数据资源丰富:MusaBert除了自家高质量语义相似数据外,还融合了悟道开源200GB数据、CLUE社区80GB数据,以及浪潮公司提供的1TB高质量数据,保证模型即便在较小规模下仍具备良好性能。 当前,MusaBert已成功应用于摩尔线程的智能客服与数字人项目,并广泛服务于语义相似度、情绪识别、阅读理解与声韵识别等领域。为了降低大模型开发和应用难度,MusaBert及其相关高质量模型代码已在Colossal-AI仓库开源,可快速训练优质中文BERT模型。同时,通过摩尔线程与潞晨科技的深度合作,仅需一张多功能GPU单卡便能高效训练MusaBert或更大规模的GPT2模型,显著降低预训练成本,进一步推动双方在低资源大模型训练领域的共享目标。 MusaBert荣登CLUE榜单TOP10,象征着摩尔线程与潞晨科技联合研发团队在中文预训练研究领域的领先地位。展望未来,双方将携手探索更大规模的自然语言模型研究,充分运用上游数据资源,产出更为强大的模型并开源。持续强化在摩尔线程多功能GPU上的大模型训练能力,特别是在消费级显卡等低资源环境下,致力于降低使用大模型训练的门槛与成本,推动人工智能更加普惠。而潞晨科技作为重要合作伙伴,将继续发挥关键作用。
-
探索MADDPG算法的神经网络架构图与Dropout技术应用详解
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
技术分享|RocketMQ 跨集群消息同步(消息路由)的实现与应用
-
openEuler郑州用户组成立!openEuler与hyperfusion携手共建河南地区用户生态 - 开幕致辞 超融合操作系统业务总经理、openEuler委员会成员蒋振华先生为本次活动致辞。 在本次活动的致辞中,他提到,作为openEuler社区早期的成员,超融合见证了openEuler从成立到在各行业商业落地,再到跨越生态拐点的过程,感谢openEuler提供了一个全产业链共同创新的平台,共同推动创新技术的商业落地。 同时,本次活动得到了郑州市郑东新区大数据管理局、郑州中原科技城投资服务局的大力支持。 郑东新区大数据管理局曹光远 在活动致辞中表示,openEuler的应用和*应用设施的深度优化,为郑东新区数字化转型提供了安全、可靠、高性能的技术基础;郑州中原科技城招商服务局王林表示,郑东新区欢迎所有openEuler生态相关企业扎根当地,围绕openEuler社区共同发展,形成合力。 openEuler社区及运维功能介绍 openEuler技术委员会委员胡峰 openEuler技术委员会委员胡峰先生在本次活动中介绍了openEuler社区目前发展的整体情况,并重点从技术层面介绍了openEuler的运维功能。 openEuler 晚会 胡峰先生介绍智能运维工具 A-Ops 和 openEuler gala、 阿波罗 Apollo、智能漏洞管理解决方案等新功能,以及涵盖各种运维场景的精品运维组件。在*交流环节,许多用户就目前使用的 openEuler 在*交流环节,许多用户就自己在使用openEuler过程中遇到的一些问题与胡峰先生进行了进一步的交流。 软硬结合,构建多样化算力操作系统 Hyperfusion 基于 openEuler 的基础上,结合自身软硬件技术积累,推出了富讯服务器操作系统 FusionOS FusionOS. FusionOS 首席架构师张海亮 分享了 FusionOS FusionOS首席架构师张海亮分享了FusionOS的软硬件协同优势、卓越的性能和可靠性,以及FusionOS在金融、运营商、*、互联网等行业的实践案例,引起了众多用户的兴趣,分享结束后,不少参会者就FusionOS的特点向讲师提问并进行了交流。
-
反传销网8月30日发布:视频区块链里的骗子,币里的韭菜,杜子建骂人了!金融大V周召说区块链!——“一小帮骗子玩一大帮小白,被割韭菜,小白还轮流被割,割的就是你!” 什么区块链,统统是骗子 作者:周召(知乎金融领域大V,毕业于上海财经大学,目前任职上海某股权投资基金合伙人) 有人问我,区块链现在这么火,到底是不是骗局? 我的回答是: 是骗局。而且我并不是说数字货币是骗局,而是说所有搞区块链的都是骗局。 -01- 区块链是一种鸡肋技术 人类社会任何技术的发明应用,本质都是为了提高社会的生产效率。而所谓区块链技术本质不过是几种早已成熟的技术的大杂烩,冗余且十分低效,除了提高了洗钱和诈骗的效率以外,对人类社会的进步毫无贡献。 真正意义上的区块链得包含三个要素:分布式系统(包括记账和存储),无法篡改的数据结构,以及共识算法,三者互为基础和因果,就像三体世界一样。看上去挺让人不明觉厉的,而经过几年的瞎折腾,稍微懂点区块链的碰了几次壁后都已经渐渐明白区块链其实并没有什么卵用,区块链技术已经名存实亡,沦为了营销工具和传销组织的画皮。 因为符合上述定义的、以比特币为代表的原教旨区块链技术,是反效率的,从经济学角度来说,不但不是一种帕累托改进,甚至还可以说是一种帕累托倒退。 原教旨区块链技术的效率十分低下,因为要遍历所有节点,只能做非常轻量级的数据应用,一旦涉及到大量的数据传输与更新,区块链就瞎了。 一方面整条链交易速度会极慢,另一方面数据库容量极速膨胀,考虑到人手一份的存储机制,区块链其实是对存储资源和能源的一种极大的浪费。 这里还没有加上为了取得所谓的共识和挖矿消耗的巨大的能源,如果说区块链技术是屎,那么这波区块链投机浪潮可谓人类历史上最大规模的搅屎运动。 区块链也验证不了任何东西。 所谓的智能合约,即不智能,也非合约。我看有人还说,如果有了智能合约,就可以跟老板签一份放区块链上,如果明年销售业绩提升30%,就加薪10%,由于区块链不能篡改,不能抵赖,所以老板必须得执行,说得有板有眼,不懂行的愣一看,好像还真是那么回事。 但仔细一想,问题就来了。首先,在区块链上如何证明你真的达到了30%业绩提升?即便真的达到老板耍赖如何执行? 也就是说,如果区块链真这么厉害,要法院和仲裁干什么。 人类社会真正的符合成本效益原则的是代理制度。之前有人说要用区块链改造注册会计师行业,我不知道他准备怎么设计,我猜想他思路大概是这样的,首先肯定搞去中心化,让所有会计师到链上来,然后一个新人要成为注册会计师就要所有会计师同意并记录在链上。 那我就请问了,我每天上班累死累活,为什么还要花时间去验证一个跟我无关的的人的专业能力?最优做法当然是组织一个委员会,让专门的人来负责,这不就是现在注册会师协会干的事儿吗?区块链的逻辑相当于什么事情都要拿出来公投,这个绝对是扯淡的。 当然这么说都有点抬举区块链了,区块链技术本身根本没有判断是非能力,如果这么高级的人工智能,靠一个无脑分布式记账就能实现的话,我们早就进入共产主义社会了。 虽然EOS等数字货币采用了超级节点,通过再中心化的方式提高效率,有点行业协会的意思,是对区块链原教旨主义的一种修正,但是依然无法突破区块链技术最本质的局限性。有人说,私有链和联盟链是区块链技术的未来,也是扯淡,因为区块链技术没有未来。如果有,说明他是包装成区块链的伪区块链技术。 区块链所涉及的所有底层技术,不管是分布式数据库技术,加密技术,还是点对点传输技术等,基本都是早已存在没什么秘密可言的技术。 比特币系统最重要的特性是封闭性和自洽性,他验证不了任何系统自身以外产生的信息的真实性。 所谓系统自身产生的信息,就是数据库数据的变动信息,有价值的基本上有且只有交易信息。所以说比特币最初不过是中本聪一种炫技的产物,来证明自己对几种技术的掌握,你看我多牛逼,设计出了一个像三体一样的系统。因此,数字货币很有可能是区块链从始至终唯一的杀手应用。 比特币和区块链概念从诞生到今天已经快10年了,很多人说区块链技术在爆发的前夜,但这个前夜好像是不是有点过长了啊朋友,跟三体里的长夜有一拼啊。都说区块链技术像是90年代初的互联网,可是90年代初的互联网在十年发展后,已经出现了一大批伟大的公司,阿里巴巴在99年都成立了,区块链怎么除了币还是币呢? 正规的数字货币未来发展的形式无外乎几种,要么就是论坛币形式,或者类似股票的权益凭证等。问题是论坛币和股票之前,本来也都电子化了,区块链来了到底改变了什么呢? 所有想把TOKEN和应用场景结合起来的人最后都很痛苦,最后他们会发现区块链技术就是脱裤子放屁,自己辛苦搞半天,干嘛不自己作为中心关心门来收钱?最后这些人都产生了价值的虚无感,最终精神崩溃,只能发币疯狂收割韭菜,一边嘴里还说着我是个好人之类的奇怪的话。 因此,之前币圈链圈还泾渭分明,互相瞧不起,但这两年链圈逐渐坐不住了,想着是不是趁着泡沫没彻底破灭之前赶快收割一波,不然可能什么都捞不着了。 前段时间和一个名校毕业的链圈朋友瞎聊天,他说他们“致力于用区块链技术解决数字版权保护问题”,我就问他一个问题,你们如何保证你链的版权所有权声明是真实的,万一盗版者抢先一步把数据放在链上怎么办。他说他们的解决方案是连入国家数字版权保护中心的数据库进行验证…… 所以说区块链技术就是个鸡肋,研究到最后都会落入效率与真实性的黑洞,很多人一头扎进链圈后才发现,真正意义上的区块链技术,其实什么都干不了。 -02- 不是蠢就是坏的区块链媒体 空气币和区块链的造富神话,让区块链自媒体也开始迎风乱扭。一群群根本不知道区块链为何物的妖魔鬼怪纷纷进驻区块链自媒体战场,开始大放厥词胡编乱造。 任何东西,但凡只要和区块,链,分,分布式,记账,加密,验证,可追溯等等这些个关键词沾到哪怕一点点,这些所谓的区块链媒体人就会像狗闻到了屎了一样疯狂地把区块链概念往上套。 这让我想起曾经一度也是热闹非凡的物联网,我曾经去看过江苏一家号称要改变世界的“物联网”企业,过去一看是生产路由器的,我黑人问号脸,对方解释说没有路由器万物怎么互联,我觉得他说得好有道理,竟无言以对。 好,下面让我们进入奇葩共赏析时间,来看看区城链媒体经常有哪些危言耸听的奇谈怪论 区块链(分布式记账)的典型应用是*?? 正如前面所说,真正意义上的区块链分布式记账,不光包括“记”这个动作,还包括分布式存储和共识机制等。而*诞生远远早于区块链这个词的出现,勉强算是“分布式编辑”吧,就被很多区块链媒体拿来强行充当区块链技术应用的典范。 其实事实恰恰相反,*恰恰是去中心化失败的典范,现在如果没有精英和专业人士的编辑和维护,*早就没法看了。 区块链会促进社会分工?? 罗振宇好像就说过类似的话,虽然罗振宇说过很多没有逻辑的话,但这句话绝对是最没逻辑思维的。很多区块链自媒体也常常用这句话来忽悠老百姓,说分工代表效率提高社会进步,而区块链“无疑”会促进分工,他们的理由仅仅是分工和分布式记账都共用一个“分”字,就强行把他们扯到一起。 实际情况恰恰相反,区块链是逆分工的,区块链精神是号召所有人积极地参与到他不擅长也不想掺合的事情里面去。 区块链不能像上帝一样许诺他的子民死后上天国,只能给他们许诺你们是六度人脉中的第一级,我可以赚后面五级人的钱,你处于金字塔的顶端。
-
视频会议场景中的空间音频--为何选择空间音频这一主题? 首先,为什么选择空间音频这一主题?我在视频会议领域工作了近二十年,我们的目标一直是让声音更清晰、视频更清晰。但在过去的 20 年中,视频会议的产品形态并没有发生本质的变化。去年元宇宙比较火,微软、Facebook都在做基于VR和元宇宙的企业协作研究,我们也进行了这方面的探索。 一开始,我们想从纯技术角度研究空间音频技术如何应用于视频会议场景,但在研究过程中,我们发现这是一个非常复杂的场景。因为视频会议本质上是人与人之间的交流。人与人之间的沟通是多维度的信息传递,声音、图像、眼神、肢体语言、触觉都是人与人之间沟通的要素,音频只是其中之一。本次分享从沟通与交流的角度,从视频会议的应用场景出发,分析视频会议产品需要什么样的空间音频技术以及如何实现。 02 空间音频与沉浸式交流