Tutorial: Mathmatical Derivation of Backpropagation

news2025/1/21 0:56:49

目录

1. 概要

2. Gradient Descent

3. Chain rule 

3.1 单变量基本链式法则

3.2 单变量全微分链式法则

3.3 小贴士:微分、导数、导函数是什么关系?

4. What and why backpropagation?

5. Backpropagation for a simple neural network

5.1 基于链式法则的表达

5.2 输出层的梯度计算

5.3 隐藏层的梯度计算        

5.3.1 f1对w1, b1的梯度

5.3.2 L对f1的梯度

5.3.3 L对w1, b1的梯度

6. Batch Processing

6.1 batch数据集的表示

6.2 forward processing

6.3 backward propagation 

附录: Backpropagation History[3]


1. 概要

        反向传播是神经网络中常用的一种训练算法,其基本思想是通过计算损失函数对每个权重的梯度,然后使用梯度下降法来优化神经网络的权重。

        在神经网络发展的早期,当只有一层网络的时候,梯度下降算法的实现是显而易见的。单层的神经网络(线性回归啊,logistic回归其实都可以看成是单层的神经网络)能做的事情有限。在设计更多层数的神经网络的时候,所遇到的一个根本的难题就是如何(有效地)计算最终的损失函数对除了输出层以外的各层(即隐藏层)的权重参数的梯度。在上世纪八十年代深度学习的先驱们成功地应用反向传播算法解决了这个问题后,深度学习才开始迎来了黄金时代。

        本文简单介绍反向传播的技术要点并基于一个简单的三层分类神经网络(输入层、隐藏层、输出层,如下图所示)例子给出具体的数学推导和python实现。

 

 图1 三层分类神经网络(取自[1])

2. Gradient Descent

        梯度下降是一种常用的优化算法,用于最小化函数的值。该算法的基本思想是沿着函数在当前点的梯度方向(即函数值变化最快的方向)的相反方向下降,直到到达函数的局部最小值或全局最小值。

        梯度下降算法适用于求解具有可导性的函数的最小值,如线性回归、逻辑回归等。它的步骤简单、易于实现,而且可以应用于大量数据的优化问题。

        基本的梯度下降算法(vanilla gradient descent)如下所示:

        假设有一个函数 $f(x)$,我们想要找到一个使得 $f(x)$ 最小的 x 值即argmin_x{f(x)}。梯度下降算法会根据函数的梯度方向来不断更新 x 的值,直到找到最小值。具体步骤如下:

        1. 初始化 x 的值;
        2. 计算函数 $f(x)$ 的梯度 $\frac{\partial f(x)}{\partial x}$
        3. 沿着梯度方向更新 x 的值,即 $x_{new} = x_{old} - \alpha \frac{\partial f(x)}{\partial x}$,其中 \alpha 称为学习率,控制更新步长的大小;
        4. 检查更新后的 x 值是否满足停止条件,若满足则算法结束,否则回到步骤 2。

        通常情况下,梯度下降算法可以分为批量梯度下降(Batch Gradient Descent)、随机梯度下降(Stochastic Gradient Descent)和小批量梯度下降(Mini-Batch Gradient Descent)三种。这些不同的算法采用的更新方式和具体实现方法略有不同,但都遵循了以上基本的梯度下降步骤。

         在深度学习中,各路神仙又在基本的梯度下降算法的基础上(vanilla gradient descent)折腾出各种改进变种,比如说,ADAM,ADAGRAD, 等等。万变不离其宗,其中的根本点都是梯度计算以及验梯度反方向进行参数调节。在各种机器学习和深度学习的框架工具中都有这些各种优化算法的实现,因此通常并不需要自己动手去实现梯度下降算法,但是DIY一次对于透彻地理解算法的精髓的确是必需的,正所谓:纸上得来终觉浅绝知此事须躬行。

        以上基本算法的描述中考虑的是单变量函数的优化,多变量(多元)函数的优化的道理是相同的。

3. Chain rule 

        复合函数求导需要用到链式法则,链式法则是backpropagation的核心之一。

        以下简单介绍backpropagation所需要的链式法则,包括基本链式法则和最关键的全微分链式法则,详细可以参考[2]。

3.1 单变量基本链式法则

        考虑复合函数:y = f(g(x)),求y'=\frac{dy}{dx}

        令(取中间变量)u = g(x), 这样以上复合函数可以重写成:y=f(u), u=g(x)

        这种基本情况下的链式法则为:

                        y = \frac{dy}{du} \frac{du}{dx} \\ y = y_u' u_x' \\ y = f'(g'(x)))               (3-1)

        以上三种写法等价,但是第一种最为明确,不容易出错。

        更深(层级更多的)复合函数的链式法则应用是以上基本情况的自然扩展。比如说,考虑复合函数y=f_1(f_2(f_3(f_4(x)))),y对于x的微分如下所示:

                        \frac{dy}{dx} = \frac{dy}{df_1}\frac{df_1}{df_2}\frac{df_2}{df_3}\frac{df_3}{df_4}\frac{df_4}{dx}        (3-2)

        

3.2 单变量全微分链式法则

        在以上基本情况中,构成复合函数的两层函数都是单变量函数,即y是以u为自变量的单变量函数,u是以x为自变量的单变量函数。其中u是唯一的中间变量。

        如果中间变量不是1个,而是有多个呢,比如说:

                ​​​y = f(u_1(x),u_2(x),...,u_k(x))                           (3-3)

        这种情况下,如何计算y针对于x(考虑x为自变量的话,y是关于x的单变量函数!这里所说的单变量正式指最底层的自变量的个数)的微分呢?这个涉及到多变量微积分中的全微分,故有些作者称为全微分链式法则[2]。

        首先,函数y的全微分可以表示如下:

                dy = \frac{\partial{y}}{\partial{u_1}}du_1 + \frac{\partial{y}}{\partial{u_2}}du_2 + ... = \sum\limits_{k=1}^n \frac{\partial{y}}{\partial{u_k}} du_k      (3-4)

                \frac{dy}{dx} = \frac{\partial{y}}{\partial{u_1}}\frac{\partial{u_1}}{\partial{x}} + \frac{\partial{y}}{\partial{u_2}}\frac{\partial{u_2}}{\partial{x}} + ... = \sum\limits_{k=1}^n \frac{\partial{y}}{\partial{u_k}}\frac{\partial{u_k}}{\partial{x}}        (3-5)

3.3 小贴士:微分、导数、导函数是什么关系?

        微分和导数是紧密相关的概念,但并不完全相同。

        微分是一种数学运算,它表示函数在某一点处的变化率。具体来说,微分就是指在极限意义下函数值的改变量与自变量值的改变量的比值,即函数在某一点的切线斜率。

        而导数是指函数在某一点处的微分值。通过求导可以得到函数在每个点处的导数值,从而得到函数的整体变化趋势和局部特性,如最大值、最小值、拐点等。

        因此,微分和导数是密切相关的,但微分是一个概念,而导数是一个具体的数值。

        微分和导函数比较接近。两者都是指对函数进行微分运算,不过它们所表示的概念略有不同。微分通常指对函数在某一点上的斜率进行精确计算。在数学上,微分的定义是取极限,并且步骤包括计算函数自变量的微小增量,然后将其带入函数中,计算函数的增量,最后求得极限。微分能够精确地计算函数在某一点的切线斜率,因此在求解极值、曲线的弧长、面积等问题时非常重要。导函数则是指函数在每一点上的导数,即函数的变化率。导函数可以理解为对函数的微分结果,用来表示函数在某一点上的变化率。导函数可以用于判断函数的单调性、拐点、极值等性质。因此,微分和导函数虽然在计算过程和概念上略有不同,但它们都是对函数进行微分运算的概念。

        不过,实际工程应用中,一般来说三者就当一回事处理了吧。。。

4. What and why backpropagation?

图2 gradient descent alogorithm concept diagram 

         图1所示的三层神经网络(关于神经网络的层数,不同的作者可能有不同的看法。有些人把输入层计入层数,有些则不计入。上文中当我们说单层神经网络时其实就不把输入层当作一层计数。这里说三层就是把输入层计入了。有点乱,不过无所谓了。。。你懂就行)的基于梯度下降进行训练优化的计算框图如上图所示。其中S()表示softmax函数。

        要进行上图所示的基于梯度下降算法的训练优化,一方面是要计算出损失函数针对每一层的每一个权重参数的梯度‘另一方面就是基于梯度下降算法进行参数微分。很简单。。。嗯,是的,说起来很简单。

        理论上来说,基于上一节所介绍的链式法则,在网络结果(相应的,与之对应的计算图:ocomputation graph)确定后可以直接写出损失函数针对每一个权重参数的梯度(偏微分)表达式,然后针对此进行编程实现即可!但是且慢,现代神经网络几十层、上百层的深度,想象一下按照链式法则把梯度表达式写出来看看,尤其是对于靠前面的网络层级(即离损失函数计算最远的那些地方)。。。简而言之,理论上可以计算并不等于具有实现可行性,要具有实现可行性必需能够在保证性能不会受损失的前提条件下简易高效地实现。

        这就到了反向传播算法登场亮相的时刻了。只有在反向传播算法解决了高效地实现梯度计算的问题,才使得深度神经网络的实现称为可能(当然还得结合其它很多关键技术)。

        

        反向传播算法的精髓在于,它不是一次性地针对所有各层权重参数计算损失函数关于它们的梯度,而是从输出层以倒序的方式逐层计算。假定输出层为第N层,

        首先,计算损失函数针对第N层的权重参数和输入的梯度;

        然后,基于损失函数针对第N层的输入的梯度,计算损失函数针对第N-1层的权重参数和输入的梯度;

        然后,基于损失函数针对第N-1层的输入的梯度,计算损失函数针对第N-2层的权重参数和输入的梯度;

        然后,依此类推,直到计算完第一个隐藏层(输入层之后的第一个有效层)的权重参数的梯度(此时不再需要计算针对第一个隐藏层的输入的梯度)。

        以上除了第N层的梯度计算以外,其它各层的梯度计算都涉及到链式法则。

        所以,反向传播算法可以看作是链式法则的一种应用,关键在于提升计算效率使其具有实现可行性。由于是从最后一层反向地向前一层一层地计算,将中间梯度计算结果逐层地反向向前面的层传播,故得名反向传播。Backpropagation involves the calculation of the gradient proceeding backwards through thefeedforward network from the last layer through to the first. To calculate the gradient at aparticular layer, the gradients of all following layers are combined via the chain rule of calculus。

        反向传播的一个显而易见的好处,它省掉了许多的重复运算。这个在下一章的例子中能更清晰地看出来。

        

        下一章我们将以图2所示简单的三层网络的例子来看看反向传播算法具体是怎么一回事。

5. Backpropagation for a simple neural network

5.1 基于链式法则的表达

        首先,把图2所示神经网络的前向计算用以下一组数学公式表达出来:

        ​​​​​​​        f_1 = w_1 x + b_1 \\ g_1 = \sigma(f_1) \\ f_2 = w_2 g_1 + b_2 \\ \hat{y} = \text{softmax}(f_2) \\ L = - \sum\limits_{i=1}^K y_i log{\hat{y_i}}                (5-1)

        梯度下降算法需要先求出L针对w1,b1,w2,b2的梯度(这里用偏微分表示梯度),其计算公式如下所示:

        上半截是L针对输出层的权重参数w2,b2及其输入g1 的梯度计算。

        下半截是L关于隐藏层的权重参数w1,b1的梯度计算。由于只有两个实质的层,这就是全部了。

        L针对g1的梯度在计算w2和b2的梯度时并不需要,但是在计算前一层的w1和b1的梯度(注意,这里为了简介,说“w1的梯度”实际上意思是L针对w1的梯度,余者类推)需要用到L关于g1的梯度。

        梯度的(反向)传播就是通过损失函数针对各层的数据输入(或者说上一层的数据输出)的梯度来进行传播的。比如说以上的\frac{\partial{L}}{\partial{g_1}}\frac{\partial{L}}{\partial{\hat{y}}}。这样的话,在计算L对w1和b1的梯度时就不必从根子上(比如说\frac{\partial{L}}{\partial{\hat{y}}}\frac{\partial{\hat{y}}}{\partial{f_2}}\frac{\partial{f_2}}{\partial{g_1}}\frac{\partial{g_1}}{\partial{f_1}}\frac{\partial{f_1}}{\partial{g_1}})开始计算。通过这种逐层传递,将长长的梯度计算链条分割成一段段来进行处理,也相当于一种分而治之的策略吧。

        本例只有两层的梯度计算,所以看起来逐层传递的价值和必要性并不是那么大(毕竟蛮力计算也是可以的),想象一下几十上百层的网络时就能体会到这种逐层反向传播的优势(甚至说绝对必要性)所在了。

        接下来完成这个简单的神经网络的具体梯度计算,并给出这个基于反向传播的梯度计算的python实现。

        根据[4]Softmax, Cross-entropy Loss and Gradient derivation and Implementation中的推导我们已经知道(注意,在[4]用l表示logits,对应于本文中所述的S()的输入f_2。注意:f_2是个向量),在采用softmax activation以及cross-entropy loss的前提条件下有:

                \nabla_{f_2}{L} = [\frac{\partial{L}}{\partial{f_{2,1}}},\frac{\partial{L}}{\partial{f_{2,2}}},...,\frac{\partial{L}}{\partial{f_{2,K}}}] \\ \nabla_{f_2}{L} =[\bold{y} - \bold{\hat{y}}]^T         (5-2)

5.2 输出层的梯度计算

        基于(5-1)和(5-2)接下来求L对w2的梯度表达式。向量/矩阵微积分虽然最后结果写出来非常简洁,但是实际上并不是像单变量微积分那样直观。保险的做法是分解为各分量,通过链式法则计算,然后再拼成向量(或矩阵)表达形式。除非你对向量(矩阵)微积分的运算跟对四则运算那样捻熟于心。具体推导过程如下所示(以下如果没有特别提起,缺省的都是矩阵乘法):

        注意,\partial_{i,j}w_{2,(j,i)}的下标关系成转置关系是因为numerator layout的缘故(关于numerator layout vs denominator layout,参见[2])。 

(5-3)

        同样,可以得到:

        ​​​​​​​        \nabla_{b_2}{L} = (\bold{y} - \bold{\hat{y}})^T                        (5-4)

        为了隐藏层的梯度计算,这里还要计算出L对于输出层的输入g_1的梯度。同样可以得到:

        ​​​​​​​        \frac{\partial{L}}{\partial{g_1}} = [\bold{y}-\bold{\hat{y}}]^T w_2                (5-5)

        详细推导过程如下所示:

5.3 隐藏层的梯度计算        

        接下来,要基于\frac{\partial{L}}{\partial{g_1}}计算L对隐藏层的权重参数w1和b1的梯度。

        由前文知道,

        ​​​​​​​        \frac{\partial{L}}{\partial{w_1}} = \frac{\partial{L}}{\partial{f_1}} \frac{\partial{f_1}}{\partial{w_1}} \\ \frac{\partial{L}}{\partial{b_1}} = \frac{\partial{L}}{\partial{f_1}} \frac{\partial{f_1}}{\partial{b_1}}                (5-6)

        如前所述,涉及向量和矩阵的微分再加上链式法则并不是非常直观,除非非常熟悉,否则很难直接以向量和矩阵为单位应用链式法则进行演算。但是从L到(w1,b1)的距离很长(想一想,其实才两层网络而已!),像上一节一样分解为标量形式进行处理,然后再组合会向量/矩阵形式已经非常难以处理了。

        以下采用分而治之的方式来推导看看。首先考虑f_1w_1b_1的梯度。

5.3.1 f1对w1, b1的梯度

 

(5-7) 

        注意,由于f_1是个向量(1阶张量),而 w_1是个矩阵(2阶张量),所以f_1w_1的梯度是一个shape=[M,N,M]的3阶张量!在纸面上很难写出3阶张量,所以以上只给出了f_1的某个分量对w_1的梯度。

        接下来我们计算L对f_1的梯度。

5.3.2 L对f1的梯度

(5-8)  

5.3.3 L对w1, b1的梯度

        有了(5-7),(5-8)是不是直接就可以代入(5-6)求得L对w1, b1的梯度呢?理论上是可以的。首先检查各张量的shape看看是不是符合张量乘法的要求。很容易确认确实是满足要求的。一个非常重要的小技巧是在这种涉及到向量、矩阵、张量的复杂运算中,只要shape匹配,几乎就可以恭喜你大概率是对了(想起一个鸡汤故事,说的是一个老师给一个小孩一张撕烂了的地图,让他重新拼起来。小孩很快就拼完了,大出老师意外。问题原因,说地图的反面是一个人像,按照人像去拼很快就能拼出来了。寓意是人对了世界就对了。套用这句话过来就是,shape匹配了,张量运算就对了)。

        如果是进行程序实现,事实上就可以到此为止了。剩下的事情交给计算机去处理就好了。

        但是,且慢,\frac{\partial{f_1}}{\partial{w_1}}是的3阶张量,而\frac{\partial{L}}{\partial{f_1}}是一个1阶张量,它们乘完后到底会得到什么样的东西(目前只知道会得到一个2阶张量。tips: 一阶张量与其它张量相乘有降后者的阶数降一阶的reduce功效),还能简化吗(好奇心是进步之源)?答案是确实可以。换一种策略进行推导,如下所示:

(5-9) 

        果然可以!就说漂不漂亮!

        当然,L对b1的梯度就很简单了。。。由于b没有与x相乘),所以在每一层中b的梯度都是对应的w的梯度计算式去掉该层的输入数据向量就可以了!

        \frac{\partial{L}}{\partial{b_1}} = \frac{\partial{L}}{\partial{f_1}} \frac{\partial{f_1}}{\partial{b_1}} =\frac{\partial{L}}{\partial{f_1}} \bold{I} = \frac{\partial{L}}{\partial{f_1}}                                        (5-10)

6. Batch Processing

        第5章的推导是针对一个数据样本x(被视为一个列向量)的,但是在实际机器学习或者深度学习中通常数据是以batch的方式进行处理。所以,为了能够平滑地过度到实际的实现中去,需要将以上推导进行进一步扩展,使得高效得batch processing得以变得可能。

6.1 batch数据集的表示

6.2 forward processing

6.3 backward propagation 

        欲知后事如何且听下回分解!

附录: Backpropagation History[3]

In 1847, the French mathematician Baron Augustin-Louis Cauchy developed a method of gradient descent for solving simultaneous equations. He was interested in solving astronomic calculations in many variables, and had the idea of taking the derivative of a function and taking small steps to minimize an error term.

Over the following century, gradient descent methods were used across disciplines to solve difficult problems numerically, where an exact algebraic solution would have been impossible or computationally intractable.

In 1970, the Finnish master's student Seppo Linnainmaa described an efficient algorithm for error backpropagation in sparsely connected networks in his master's thesis at the University of Helsinki, although he did not refer to neural networks specifically.

In 1986, the American psychologist David Rumelhart and his colleagues published an influential paper applying Linnainmaa's backpropagation algorithm to multi-layer neural networks. The following years saw several breakthroughs building on the new algorithm, such as Yann LeCun's 1989 paper applying backpropagation in convolutional neural networks for handwritten digit recognition.

In the 1980s, various researchers independently derived backpropagation through time, in order to enable training of recurrent neural networks.

In recent years deep neural networks have become ubiquitous and backpropagation is very important for efficient training. Although the algorithm has been modified to be parallelized and run easily on multiple GPUs, Linnainmaa and Rumelhart's original backpropagation algorithm forms the backbone of all deep learning-based AI today.

Reference: 

[1] Paolo Perrotta, Programming Machine Learn: From coding to deep-learning 

[2] arVix:1802.0152, The Matrix Calculus You Need For Deep Learning, Terence Parr and Jeremy Howard 

[3] https://deepai.org/machine-learning-glossary-and-terms/backpropagation

[4]  Softmax, Cross-entropy Loss and Gradient derivation and Implementation

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

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

相关文章

一篇掌握高级交换技术原理与配置(二):mux-vlan

一、概述 MUX VLAN(Multiplex VLAN)提供了一种通过VLAN进行网络资源控制的机制。通过MUX VLAN提供的二层流量隔离的机制可以实现企业内部员工之间互相交流,而企业客户之间是隔离的。 MUX VLAN分为Principal VLAN(主VLAN&#xf…

PANAMA: 共享机器学习集群的网内聚合框架

随着深度学习训练规模的增长,在共享集群内同步训练数据的需求越来越多,怎样高效利用网络资源平衡各种负载的需求,也成了业界关注的课题。MIT的这篇论文提出了一种网内聚合框架,能够大幅降低并行数据作业的流量负载,从而…

外观设计专利注册

专利注册的种类分为好几种,其中一种就是外观设计专利。我国《专利法》二条四款对外观设计的定义是:“外观设计是指对产品的形状、图案或其结合以及色彩与形状、图案的结合所作出的富有美感并适于工业应用的新设计。”并在《专利法》二十三条对其授权条件…

RISC-V(2)——特权级及特权指令集

目录 1. 特权级 2. 控制和状态寄存器(CSR) 2.1 分类 2.2 分析 1. 特权级 一个 RISC-V 硬件线程(hart)是运行在某个特权级上的,这个特权级被编码到一个或者多个 CSR(control and status register&a…

【JavaEE基础学习打卡00】该专栏知识大纲在这里!

目录 前言一、为什么有该教程二、教程内容介绍1.JavaEE2.JDBC3.JSP编程4.JavaBean5.Servlet6.综合案例7.拦截器、过滤器 三、学习前置要求四、课程服务总结 前言 📜 本系列教程适用于 Java Web 初学者、爱好者,小白白。我们的天赋并不高,可贵…

对于论文Semi-Supervised Classification with Graph Convolutional Networks,小白的学习理解

参考笔记:论文笔记:Semi-Supervised Classification with Graph Convolutional Networks_hongbin_xu的博客-CSDN博客 论文笔记:SEMI-SUPERVISED CLASSIFICATION WITH GRAPH CONVOLUTIONAL NETWORKS_semi supervised classification_饮冰l的博…

创建ffmpeg vs2019工程

0 写在前面 本文主要参考链接:https://www.cnblogs.com/suiyek/p/15669562.html 感谢作者的付出; 1 目录结构 2 下载yasm和nasm 如果自己在安装VS2019等IDE的时候已经安装了它们,则不用再单独进行安装,比如我这边已经安装了&a…

VScode 国内下载源 以及 nvm版本控制器下载与使用

VScode 国内下载源 进入官网 https://code.visualstudio.com/ 点击下载 复制下载链接到新的浏览器标签 将地址中的/stable前的az764295.vo.msecnd.net换成vscode.cdn.azure.cn,再回车就会直接在下载列表啦。 参考大神博客 2.使用nvm 对 node 和npm进行版本控制…

【混合时变参数系统参数估计算法】使用范数总和正则化和期望最大化的混合时变参数系统参数估计算法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【洁洁送书第一期】Python高并发与高性能编程: 原理与实践

这里写目录标题 Python高并发、高性能解决问题书本介绍关于作者直播预告 Python高并发、高性能 Python成为时下技术革新的弄潮儿,全民Python的发展趋势让人们不再满足于简单地运行Python程序,逐步探索其更为广泛的日常应用和高性能设计。 以ChatGPT为代…

LeetCode-53-最大子数组和-贪心算法

贪心算法理论基础: 局部最优推全局最优 贪心无套路~ 没有什么规律~ 重点:每个阶段的局部最优是什么? 题目描述: 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素&#…

Running transaction check,yum卡在这个地方不动了

问题:运行yum update卡在这个地方不动 解决办法:运行下面的命令 # /bin/rm /var/lib/rpm/__db.* # cd /var/cache/yum # /bin/rm -rf * # yum clean all # yum update如果运行还不成功,那么重启服务器试试。我的服务器用了各种办法不行&…

金属矿山电子封条系统 yolov5

金属矿山电子封条通过pythonyolov5网络模型框架算法,金属矿山电子封条算法识别到运输设备启动运行或者识别到运输设备运行工作状态下有煤、无煤转换,进行预警分析,金属矿山电子封条算法利用智能化视频识别等技术,实时监测分析矿井出入井人员、…

机器学习技术(六)——有监督学习算法之线性回归算法实操

机器学习技术(五)——有监督学习之线性回归算法实操 引言: 机器学习监督算法是一种基于已有标记数据的学习方法,通过对已知输入和输出数据的学习,建立一个模型来预测新的输入数据的输出。这种算法模仿人类的学习过程&a…

抢跑预制菜,双汇发展转守为攻?

懒,懒出新风口,预制菜竟成了年轻人新时代的“田螺神话”? 《2022年中国预制菜产业发展白皮书》数据显示,2022年全国预制菜的市场规模是4196亿元人民币,到2026年可以突破万亿大关。 预制菜的火爆显而易见,…

ELK日志收集系统集群实验(5.5.0版)

目录 前言 一、概述 二、组件介绍 1、elasticsearch 2、logstash 3、kibana 三、架构类型 四、ELK日志收集集群实验 1、实验拓扑 2、在node1和node2节点安装elasticsearch 3、启动elasticsearch服务 4、在node1安装elasticsearch-head插件 5、测试输入 6、node1服…

【LeetCode题目详解】第八章 贪心算法 part06 738.单调递增的数字 968.监控二叉树 (day37补)

本文章代码以c为例&#xff01; 一、力扣第738题&#xff1a;单调递增的数字 题目&#xff1a; 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数…

嵌入式技术

嵌入式技术 嵌入式微处理器体系结构嵌入式微处理器分类多核处理器嵌入式软件嵌入式系统的组成嵌入式系统的特性 嵌入式技术和计算机网络 超纲的内容很多 这个课件只包含一半的分 其他的分看真题 嵌入式微处理器体系结构 将指令存储器和数据存储器合并在一起的结构 处于同一个存…

搭建一个你的文件共享站

说起文件共享&#xff0c;类似文件站这样的功能。在很久之前我使用过用apache httpd这个方案&#xff0c;这个的话就是太过于简单了。当然是满足需求的&#xff08;又不是不能用&#xff09; 今天来分享一个开源的文件共享平台。Pingvin Share 作者的github地址&#xff1a;ht…

面试了38位Java候选人之后,我总结出了他们关于面试中的16条通病

都说现在Java面试卷&#xff0c;前段时间项目招人的时候&#xff0c;我刚好就作为面试官面试了一些人 在整个面试的过程中&#xff0c;我就发现了一些关于面试的通病 所以呢&#xff0c;趁着这次金&#xff08;铜&#xff09;九银&#xff08;铁&#xff09;十的机会&#xf…