当前位置: 首页 > news >正文

用js来做网站/今日桂林头条新闻

用js来做网站,今日桂林头条新闻,网站建设是什么专业,企业网站建设的意义第5章 神经网络基础知识 目录 5.1 由逻辑回归出发 5.2 损失函数 5.3 梯度下降 5.4 计算图 5.5总结 在第1课《深度学习概述》中,我们介绍了神经网络的基本结构,了解了神经网络的基本单元组成是神经元。如何构建神经网络,如何训练、优化神…

第5章 神经网络基础知识

目录

5.1 由逻辑回归出发

5.2 损失函数

5.3 梯度下降

5.4 计算图

5.5总结

在第1课《深度学习概述》中,我们介绍了神经网络的基本结构,了解了神经网络的基本单元组成是神经元。如何构建神经网络,如何训练、优化神经网络,这其中包含了许多数学原理,需要具备一些基本知识。

本课程将重点罗列并详细介绍神经网络必备的基础知识。掌握这些基础知识,就可以为接下来的课程做好准备。

5.1 由逻辑回归出发

逻辑回归(Logistic Regression)是机器学习一个最基本也是最常用的算法模型。与线性回归不同的是,逻辑回归主要用于对样本进行分类。因此,逻辑回归的输出是离散值。对于二分类问题,通常我们令正类输出为1,负类输出为0。例如一个心脏病预测的问题:根据患者的年龄、血压、体重等信息,来预测患者是否会有心脏病,这就是典型的逻辑回归问题。

二元分类,一般使用 y ^ = P ( y ∣ x ) \hat y=P(y|x) y^=P(yx)来表示预测输出为 1 1 1的概率,则 1 − P ( y ∣ x ) 1-P(y|x) 1P(yx)表示预测输出为 0 0 0的概率。概率值取值范围在 [ 0 , 1 ] [0, 1] [0,1]之间。通常, P ( y ∣ x ) ≥ 0.5 P(y|x)\geq0.5 P(yx)0.5,则预测为正类 1 1 1;若 P ( y ∣ x ) < 0.5 P(y|x)\lt0.5 P(yx)<0.5,则预测为负类 0 0 0

  • P ( y ∣ x ) ≥ 0.5 P(y|x)\geq 0.5 P(yx)0.5:正类

  • P ( y ∣ x ) < . 5 P(y|x)\lt .5 P(yx)<.5:负类

根据线性感知机的思想,引入参数 w w w b b b,我们可以写出逻辑回归的线性部分为:

z = w x + b z=wx+b z=wx+b

其中, x x x的维度是 ( n x , m ) (n_x, m) (nx,m) w w w的维度是 ( 1 , n x ) (1, n_x) (1,nx) b b b是一个常量。 n x n_x nx表示输入 x x x的特征个数,例如一张图片所有的像素点, m m m为训练样本个数, z z z是线性输出。

但是,线性输出 z z z可能的取值范围为整个实数区间,而逻辑回归最终输出的概率 y ^ \hat y y^取值范围在 [ 0 , 1 ] [0,1] [0,1]之间。所以,需要对 z z z做进一步处理,常用方法是使用Sigmoid函数,进行非线性映射。

Sigmoid函数是一种激活函数。关于激活函数的概念,我们下一篇再谈。这里,我们只要知道Sigmoid函数是一个非线性函数,它的表达式和图像如下所示:

S ( z ) = 1 1 + e − z S(z)=\frac{1}{1+e^{-z}} S(z)=1+ez1

在这里插入图片描述
从Sigmoid函数曲线可以看出,当自变量 z z z值很大时, S ( z ) ≈ 1 S(z)\approx 1 S(z)1;当 z z z值很小时, S ( z ) ≈ 0 S(z)\approx 0 S(z)0。且当 z = 0 z=0 z=0时, S ( z ) = 0.5 S(z)=0.5 S(z)=0.5。显然,Sigmoid函数实现了 z z z到区间 [ 0 , 1 ] [0,1] [0,1]的非线性映射,根据 S ( z ) S(z) S(z)的值来预测输出类别。

  • S ( z ) ≥ 0.5 S(z)\geq 0.5 S(z)0.5:正类

  • S ( z ) < 0.5 S(z)\lt 0.5 S(z)<0.5:负类

那么,将 z = w x + b z = wx+b z=wx+b代入,逻辑回归整个过程的预测输出即可表示为:

y ^ = S ( z ) = 1 1 + e − z = 1 1 + e − ( w x + b ) \hat y=S(z)=\frac{1}{1+e^{-z}}=\frac{1}{1+e^{-(wx+b)}} y^=S(z)=1+ez1=1+e(wx+b)1

总的来看,逻辑回归模型分成两个部分:线性输出和非线性映射。逻辑回归模型其实就是在前面课程介绍的标准的一类神经元结构。

5.2 损失函数

无论是逻辑回归模型还是其他机器学习模型,优化的目标都是希望预测输出 y ^ \hat y y^与真实输出 y y y越接近越好。因此,我们需要定义一个损失函数,它反映了 y ^ \hat y y^ y y y的差别,即“损失”。损失函数越大,则 y ^ \hat y y^ y y y的差别越大;损失函数越小, y ^ \hat y y^ y y y的差别就越小,这就是我们的优化目标。

逻辑回归模型常用的损失函数定义如下:

L = − [ y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ] L=-[ylog\ \hat y+(1-y)log\ (1-\hat y)] L=[ylog y^+(1y)log (1y^)]

上式又称交叉熵损失函数(Cross Entropy Loss)。为什么损失函数是这种形式?接下来,我们进行简单推导。

我们知道,Sigmoid函数的输出表征了当前样本标签为1的概率:

y ^ = P ( y = 1 ∣ x ) \hat y=P(y=1|x) y^=P(y=1∣x)

那么样本标签为0的概率就可以写成:

1 − y ^ = P ( y = 0 ∣ x ) 1-\hat y=P(y=0|x) 1y^=P(y=0∣x)

从极大似然性的角度出发,把上面两种情况整合到一起:

P ( y ∣ x ) = y ^ y ⋅ ( 1 − y ^ ) 1 − y P(y|x)=\hat y^y\cdot (1-\hat y)^{1-y} P(yx)=y^y(1y^)1y

上面的式子可以这样理解,当真实样本标签 y = 0 y = 0 y=0时, y ^ y = 1 \hat y^y=1 y^y=1 ( 1 − y ^ ) ( 1 − y ) = 1 − y ^ (1-\hat y)^{(1-y)}=1-\hat y (1y^)(1y)=1y^,上式就转化为:

P ( y = 0 ∣ x ) = 1 − y ^ P(y=0|x)=1-\hat y P(y=0∣x)=1y^

当真实样本标签 y = 1 y = 1 y=1时, y ^ y = y ^ \hat y^y=\hat y y^y=y^ ( 1 − y ^ ) ( 1 − y ) = 1 (1-\hat y)^{(1-y)}=1 (1y^)(1y)=1,概率等式转化为:

P ( y = 1 ∣ x ) = y ^ P(y=1|x)=\hat y P(y=1∣x)=y^

两种情况下概率表达式跟之前的完全一致,只不过我们把两种情况整合在一起了。

无论是 y = 0 y = 0 y=0还是 y = 1 y = 1 y=1,哪种情况我们都希望概率 P ( y ∣ x ) P(y|x) P(yx)越大越好。首先,我们对 P ( y ∣ x ) P(y|x) P(yx)引入 l o g log log函数,因为 l o g log log运算并不会影响函数本身的单调性。则有:

l o g P ( y ∣ x ) = l o g ( y ^ y ⋅ ( 1 − y ^ ) 1 − y ) = y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) log\ P(y|x)=log(\hat y^y\cdot (1-\hat y)^{1-y})=ylog\ \hat y+(1-y)log(1-\hat y) log P(yx)=log(y^y(1y^)1y)=ylog y^+(1y)log(1y^)

我们希望 l o g P ( y ∣ x ) log P(y|x) logP(yx)越大越好,反过来,即希望 l o g P ( y ∣ x ) log\ P(y|x) log P(yx)的负值 − l o g P ( y ∣ x ) -log\ P(y|x) log P(yx)越小越好。那我们就可以定义损失函数 L = − l o g P ( y ∣ x ) L = -log P(y|x) L=logP(yx)即可:

L = − [ y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ] L=-[ylog\ \hat y+(1-y)log\ (1-\hat y)] L=[ylog y^+(1y)log (1y^)]

这样,我们就完整地推导了交叉熵损失函数公式的由来。

下面,从图形的角度,我们来分析交叉熵损失函数为什么能够表征 y ^ \hat y y^ y y y的差别。

y = 1 y = 1 y=1时:

L = − l o g y ^ L=-log\ \hat y L=log y^

这时候, L L L与预测输出的关系如下图所示:

在这里插入图片描述

横坐标是预测输出 y ^ \hat y y^,纵坐标是交叉熵损失函数 L L L。显然,预测输出越接近真实样本标签 1 1 1,损失函数L越小;预测输出越接近 0 0 0 L L L越大。因此,函数的变化趋势完全符合实际需要的情况。

y = 0 y = 0 y=0时:

L = − l o g ( 1 − y ^ ) L=-log\ (1-\hat y) L=log (1y^)

这时候, L L L与预测输出的关系如下图所示:

在这里插入图片描述

同样,预测输出越接近真实样本标签 0 0 0,损失函数 L L L越小;预测函数越接近 1 1 1 L L L越大。函数的变化趋势也完全符合实际需要的情况。

从上面两种图,可以帮助我们对交叉熵损失函数有更直观的理解。无论真实样本标签 y y y 0 0 0还是 1 1 1 L L L都表征了预测输出与 y y y的差距。而且, y ^ \hat y y^ y y y差得越多, L L L的值越大,也就是说对当前模型的“惩罚”越大,而且是非线性、类似指数级别的增大,这是由 l o g log log函数本身的特性所决定的。这种对预测不准情形加重惩罚的好处是,模型会倾向于产生更接近 y y y y ^ \hat y y^,即有利于训练出更好的模型。

5.3 梯度下降

损失函数 L L L是关于模型参数的函数,例如逻辑回归中的 w w w b b b。我们的优化目标就是找出最小化 L L L时,对应的 w w w b b b。损失函数 L L L的最小化是一个典型的凸优化问题,最常用的方法就是使用梯度下降(Gradient Descent)算法。深度学习中,许多优化算法都是基于梯度下降原理。

在这里插入图片描述

使用梯度下降来对损失函数进行优化,只要计算当前损失函数对模型参数的一阶导数,即梯度,然后对参数进行更新。经过足够次数迭代之后,一般就能找到全局最优解。每次迭代更新的公式为:

θ = θ 0 − η ⋅ ∇ f ( θ 0 ) \theta=\theta_0-\eta\cdot\nabla f(\theta_0) θ=θ0ηf(θ0)

其中, θ 0 \theta_0 θ0是当前参数, θ \theta θ是更新后的参数, ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)表示损失函数对 θ \theta θ θ 0 \theta_0 θ0处的一阶导数,即梯度。 η \eta η是学习因子,决定了每次数值更新的步长,是可调参数。

梯度下降的公式其实很简单,但是为什么局部下降最快的方向就是梯度的负方向呢?接下来我将以通俗的语言来详细解释梯度下降公式的数学推导过程。

首先,我们需要使用到泰勒展开式。简单来说,泰勒展开式利用的就是函数的局部线性近似这个概念。我们把 f ( θ ) f(\theta) f(θ)进行一阶泰勒展开:

f ( θ ) ≈ f ( θ 0 ) + ( θ − θ 0 ) ∇ f ( θ 0 ) f(\theta)\approx f(\theta_0)+(\theta-\theta_0)\nabla f(\theta_0) f(θ)f(θ0)+(θθ0)f(θ0)

下面用张图来解释上面的公式:

在这里插入图片描述
凸函数 f ( θ ) f(\theta) f(θ)的某一小段 [ θ 0 , θ ] [\theta_0,\theta] θ0,θ由上图黑色曲线表示。如果用一条直线来近似这段黑色曲线,如上图红色直线。该直线的斜率等于 f ( θ ) f(\theta) f(θ) θ 0 \theta_0 θ0处的导数。则根据直线方程,很容易得到 f ( θ ) f(\theta) f(θ)的近似表达式为:

f ( θ ) ≈ f ( θ 0 ) + ( θ − θ 0 ) ⋅ ∇ f ( θ 0 ) f(\theta)\approx f(\theta_0)+(\theta-\theta_0)\cdot\nabla f(\theta_0) f(θ)f(θ0)+(θθ0)f(θ0)

这就是一阶泰勒展开式的推导过程,主要利用的数学思想就是曲线函数的一阶线性近似,是小区域内的一条直线来近似曲线。

知道了一阶泰勒展开式的推导过程后,我们重点来看一下梯度下降算法是如何推导的。其中 , θ − θ 0 ,\theta-\theta_0 θθ0是微小矢量,它的大小就是我们之前讲的学习因子 η \eta η η \eta η为标量。令 θ − θ 0 \theta-\theta_0 θθ0的单位向量用 v v v表示,则 θ − θ 0 \theta-\theta_0 θθ0可表示为:

θ − θ 0 = η v \theta-\theta_0=\eta v θθ0=ηv

需要特别注意的是, θ − θ 0 \theta-\theta_0 θθ0不能太大,因为太大的话,线性近似就不够准确,一阶泰勒近似也就不成立了。替换之后, f ( θ ) f(\theta) f(θ)的表达式为:

f ( θ ) ≈ f ( θ 0 ) + η v ⋅ ∇ f ( θ 0 ) f(\theta)\approx f(\theta_0)+\eta v\cdot\nabla f(\theta_0) f(θ)f(θ0)+ηvf(θ0)

重点来了,局部下降的目的是希望每次 θ \theta θ更新,都能让函数值 f ( θ ) < f ( θ 0 ) f(\theta)<f(\theta_0) f(θ)<f(θ0)。也就是说,上式中,我们希望 f ( θ ) < f ( θ 0 ) f(\theta)<f(\theta_0) f(θ)<f(θ0)。则有:

f ( θ ) − f ( θ 0 ) ≈ η v ⋅ ∇ f ( θ 0 ) < 0 f(\theta)-f(\theta_0)\approx\eta v\cdot\nabla f(\theta_0)<0 f(θ)f(θ0)ηvf(θ0)<0

因为 η \eta η为标量,且一般设定为正值,所以可以忽略,上面的不等式就变成了:

v ⋅ ∇ f ( θ 0 ) < 0 v\cdot\nabla f(\theta_0)<0 vf(θ0)<0

上面这个不等式非常重要! v v v ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)都是向量, ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)是当前位置的梯度方向, v v v表示下一步前进的单位向量, v v v是需要我们求解的,有了它,就能根据 θ − θ 0 = η \theta-\theta_0=\eta θθ0=η确定 θ \theta θ的值了。

想要两个向量的乘积小于零,我们先来看一下两个向量乘积包含哪几种情况:

在这里插入图片描述

上图中, A A A B B B均为向量, α \alpha α为两个向量之间的夹角。 A A A B B B的乘积为:

A ⋅ B = ∣ ∣ A ∣ ∣ ⋅ ∣ ∣ B ∣ ∣ ⋅ c o s ( α ) A\cdot B=||A||\cdot||B||\cdot cos(\alpha) AB=∣∣A∣∣∣∣B∣∣cos(α)

∣ ∣ A ∣ ∣ ||A|| ∣∣A∣∣ ∣ ∣ B ∣ ∣ ||B|| ∣∣B∣∣均为标量,在 ∣ ∣ A ∣ ∣ ||A|| ∣∣A∣∣ ∣ ∣ B ∣ ∣ ||B|| ∣∣B∣∣确定的情况下,只要 c o s ( α ) = − 1 cos(\alpha)=-1 cos(α)=1,即 A A A B B B完全反向,就能让 A A A B B B的向量乘积最小(负最大值)。

也就是说,当 v v v ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)互为反向,即 v v v为当前梯度方向的负方向的时候,就能保证 v ⋅ ∇ f ( θ 0 ) v\cdot\nabla f(\theta_0) vf(θ0)为负最大值,也就证明了 v v v的方向是局部下降最快的方向。知道 v v v ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)的反方向后,可直接得到:

v = − ∇ f ( θ 0 ) ∣ ∣ ∇ f ( θ 0 ) ∣ ∣ v=-\frac{\nabla f(\theta_0)}{||\nabla f(\theta_0)||} v=∣∣∇f(θ0)∣∣f(θ0)

之所以要除以 ∇ f ( θ 0 ) \nabla f(\theta_0) f(θ0)的模 ∣ ∣ ∇ f ( θ 0 ) ∣ ∣ ||\nabla f(\theta_0)|| ∣∣∇f(θ0)∣∣,是因为 v v v是单位向量。求出最优解 v v v之后,带入到 θ − θ 0 = η \theta-\theta_0=\eta θθ0=η中,得:

θ = θ 0 − η ∇ f ( θ 0 ) ∣ ∣ ∇ f ( θ 0 ) ∣ ∣ \theta=\theta_0-\eta\frac{\nabla f(\theta_0)}{||\nabla f(\theta_0)||} θ=θ0η∣∣∇f(θ0)∣∣f(θ0)

一般地,因为 ∣ ∣ ∇ f ( θ 0 ) ∣ ∣ ||\nabla f(\theta_0)|| ∣∣∇f(θ0)∣∣是标量,可以并入到步进因子 η \eta η中,即简化为:

θ = θ 0 − η ∇ f ( θ 0 ) \theta=\theta_0-\eta\nabla f(\theta_0) θ=θ0ηf(θ0)

这样,我们就推导得到了梯度下降算法中 θ \theta θ的更新表达式。那么在逻辑回归模型中, w w w b b b的迭代更新公式即为:

w = w − η ∇ L ( w ) w=w-\eta\nabla L(w) w=wηL(w)

b = b − η ∇ L ( b ) b=b-\eta\nabla L(b) b=bηL(b)

其中, ∇ L ( w ) \nabla L(w) L(w) ∇ L ( b ) \nabla L(b) L(b)分别表示损失函数 L L L w w w b b b的梯度。

5.4 计算图

在下一篇中我们将详细剖析神经网络模型。这里,我们先简单介绍下,每次迭代训练,神经网络模型主要分成两个步骤:正向传播(Forward Propagation)和反向传播(Back Propagation)。正向传播就是计算损失函数过程,反向传播就是计算参数梯度过程。庞大的神经网络,如何有效地进行正向传播和反向传播,如何计算参数梯度?我们将通过介绍计算图(Computation graph)的概念,来帮大家轻松理解整个过程。

举个简单的例子,输入参数有三个,分别是 a a a b b b c c c,损失函数可表示成 J ( a , b , c ) = ( 2 a + b ) c J(a,b,c)=(2a+b)c J(a,b,c)=(2a+b)c。令 a = 3 a = 3 a=3 b = 4 b = 4 b=4 c = 5 c = 5 c=5,对应的 J = ( 2 × 3 + 4 ) × 5 = 50 J = (2\times3+4)\times5=50 J=(2×3+4)×5=50

正向传播过程,我们将 J J J的表达式进行拆分,例如使用 u = 2 a u = 2a u=2a v = u + b v = u + b v=u+b J = u v J = uv J=uv。拆分后的每个单运算都构成一个“节点”,如下图中的矩形方框所示。下面的这张图就是计算图。该计算图中包含了三个节点,分别对应 u = 2 a u = 2a u=2a v = u + b v = u + b v=u+b J = u v J = uv J=uv。这样,我们就把正向传播过程进行了拆分,每个节点对应一个运算。

在这里插入图片描述
反向传播过程,这部分是最重要也是最难的部分。 J J J如何对参数 a a a b b b c c c求导?方法是利用偏导数的思想,分别依次对各个节点 J J J v v v u u u求导,然后再顺序对各参数求导。整个过程如下图红色箭头所示,与黑色箭头方向(正向传播)正好相反。

在这里插入图片描述

首先,对节点 J J J求导,显然为 1 1 1

∂ J ∂ J = 1 \frac{\partial J}{\partial J}=1 JJ=1

对节点 v v v求导:

∂ J ∂ v = c = 5 \frac{\partial J}{\partial v}=c=5 vJ=c=5

对节点 u u u求导:

∂ J ∂ u = ∂ J ∂ v ⋅ ∂ v ∂ u = c ⋅ 1 = 5 \frac{\partial J}{\partial u}=\frac{\partial J}{\partial v}\cdot \frac{\partial v}{\partial u}=c\cdot 1=5 uJ=vJuv=c1=5

然后,就可以对各参数求导:

∂ J ∂ c = v = 10 \frac{\partial J}{\partial c}=v=10 cJ=v=10

∂ J ∂ b = ∂ J ∂ v ⋅ ∂ v ∂ b = 5 \frac{\partial J}{\partial b}=\frac{\partial J}{\partial v}\cdot\frac{\partial v}{\partial b}=5 bJ=vJbv=5

∂ J ∂ a = ∂ J ∂ u ⋅ ∂ u ∂ a = 5 ⋅ 2 = 10 \frac{\partial J}{\partial a}=\frac{\partial J}{\partial u}\cdot\frac{\partial u}{\partial a}=5\cdot2=10 aJ=uJau=52=10

以上就是利用计算图对各参数求导的整个过程。

这个例子非常简单,参数很少,损失函数也不复杂。可能我们没有明显看到计算图在正向传播和反向传播的优势。但是,深度学习模型中,网络结构很深,光是参数就可能有数十万、百万的,损失函数也非常复杂。这时候,利用计算图中的节点技巧,可以大大提高网络的训练速度。值得一提的是现在很多的深度学习框架,例如PyTorch和TensorFlow都是利用计算图对参数进行求导的。

最后,我们来计算一下逻辑回归模型中 w w w b b b的梯度。

正向传播过程:

z = w x + b z=wx+b z=wx+b

y ^ = 1 1 + e − z \hat y=\frac{1}{1+e^{-z}} y^=1+ez1

J = − [ y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ] J=-[ylog\ \hat y+(1-y)log\ (1-\hat y)] J=[ylog y^+(1y)log (1y^)]

反向传播过程:

∂ J ∂ y ^ = 1 − y 1 − y ^ − y y ^ \frac{\partial J}{\partial \hat y}=\frac{1-y}{1-\hat y}-\frac{y}{\hat y} y^J=1y^1yy^y

∂ J ∂ z = ∂ J ∂ y ^ ⋅ ∂ y ^ ∂ z = ( 1 − y 1 − y ^ − y y ^ ) ⋅ y ^ ( 1 − y ^ ) = y ^ − y \frac{\partial J}{\partial z}=\frac{\partial J}{\partial \hat y}\cdot\frac{\partial \hat y}{\partial z}=(\frac{1-y}{1-\hat y}-\frac{y}{\hat y})\cdot\hat y(1-\hat y)=\hat y-y zJ=y^Jzy^=(1y^1yy^y)y^(1y^)=y^y

∂ J ∂ w = ∂ J ∂ z ⋅ ∂ z ∂ w = ( y ^ − y ) x T \frac{\partial J}{\partial w}=\frac{\partial J}{\partial z}\cdot\frac{\partial z}{\partial w}=(\hat y-y)x^T wJ=zJwz=(y^y)xT

∂ J ∂ b = ∂ J ∂ z ⋅ ∂ z ∂ b = y ^ − y \frac{\partial J}{\partial b}=\frac{\partial J}{\partial z}\cdot\frac{\partial z}{\partial b}=\hat y-y bJ=zJbz=y^y

5.5 总结

本文主要介绍了神经网络的基础知识,包括逻辑回归、损失函数、梯度下降和计算图。其实逻辑回归模型就可以看成是神经网络中的单个神经元。掌握逻辑回归模型的正向传播和反向传播细节,对我们熟练了解神经网络模型非常重要。打下这些基础之后,我们将在下一篇开始真正的神经网络学习。

相关文章:

深度学习——第5章 神经网络基础知识

第5章 神经网络基础知识 目录 5.1 由逻辑回归出发 5.2 损失函数 5.3 梯度下降 5.4 计算图 5.5总结 在第1课《深度学习概述》中&#xff0c;我们介绍了神经网络的基本结构&#xff0c;了解了神经网络的基本单元组成是神经元。如何构建神经网络&#xff0c;如何训练、优化神…...

微信网页授权步骤说明

总览 引导用户进入授权页面同意授权&#xff0c;获取code通过code换取网页授权access_token&#xff08;与基础支持中的access_token不同&#xff09;如果需要&#xff0c;开发者可以刷新网页授权access_token&#xff0c;避免过期&#xff08;一般不需要&#xff09;通过网页…...

linux bash shell变量操作符 —— 筑梦之路

1. 变量子串 ${var} 返回变量var的内容&#xff0c;单独使用时有没有{}一样&#xff0c;混合多个变量和常量时&#xff0c;用{}界定变量名 ${#var} 返回变量var内容的长度 ${var:offset} 从变量var中的偏移量offset开始截取到字符串结尾的子字符串&#xff0c;offset从0开始 ${…...

2.61【Python生成器与迭代器】

Python迭代器与生成器 迭代器 什么是迭代器 首先迭代是指python中访问元素的一种方式&#xff0c;迭代器是一个可以记住遍历位置的对象&#xff0c;因此不会像列表那样一次性全部生成&#xff0c;而是可以等到用的时候才生成&#xff0c;因此节省了大量的内存资源 可迭代对…...

devecho stuido npm 失败

使用华为推荐的设置npm 代理方式仍然无效。还是得使用npm 命令去设置代理。地址参考&#xff1a; npm设置和取消代理的方法_npm查看代理-CSDN博客 最后使用自己的代理加载成功&#xff0c;使用华为推荐的代理不成功&#xff0c;不清楚什么原因。 华为推荐的环境配置如下&…...

postgreSql逻辑复制常用语句汇总和说明

简单说明 postgreSql逻辑复制的原理这里不再赘述&#xff0c;度娘一下即可。这里只是对常用的语句做一些汇总和说明&#xff0c;以便日后查找时方便。 逻辑复制的概念 逻辑复制整体上采用的是一个发布订阅的模型&#xff0c;订阅者可以订阅一个或者多个发布者&#xff0c; 发…...

设置Ubuntu或树莓派系统,允许root用户ssh方式连接

Ubuntu 或 Raspbian 系统默认不允许root 用户以ssh方式连接。连接会报如下错误&#xff1a; Permission denied&#xff0c; please try again. 解决步骤&#xff1a; &#xff08;如果是树莓派系统&#xff1a;烧录到内存卡后&#xff0c;拔掉内存卡再重新插到PC机上&#x…...

Ubuntu安装向日葵【远程控制】

文章目录 引言下载向日葵安装向日葵运行向日葵卸载向日葵参考资料 引言 向日葵是一款非常好用的远程控制软件。这一篇博文介绍了如何在 Ubuntu Linux系统 中安装贝瑞向日葵。&#x1f3c3;&#x1f4a5;&#x1f4a5;&#x1f4a5;❗️ 下载向日葵 向日葵官网: https://sunl…...

jquery 实现倒计时60秒

jquery 实现倒计时60秒 <!DOCTYPE html> <html><head><meta http-equiv"content-type" content"text/html; charsetUTF-8"><meta content"widthdevice-width,initial-scale1.0,maximum-scale1.0,user-scalableno" i…...

单例模式:饿汉模式、懒汉模式

目录 一、什么是单例模式 二、饿汉模式 三、懒汉模式 一、什么是单例模式 单例模式是Java中的设计模式之一&#xff0c;能够保证某个类在程序中只存在唯一一份实例&#xff0c;而不会创建出多个实例 单例模式有很多实现方式&#xff0c;最常见的是饿汉和懒汉两种模式 二、…...

提升方法AdaBoost

通过改变训练样本的权重学习多个分类器&#xff0c;并将这些线性分类器进行线性组合&#xff0c;提高分类性能。 AdaBoost 提高前一轮被分类错误的权值&#xff0c;降低前一轮被分类正确的权值&#xff1b;加大分类误差错误率小的弱分类器权重。 算法&#xff1a; 输入&…...

Python自动化测试系列[v1.0.0][多种数据驱动实现附源码]

前情提要 请确保已经熟练掌握元素定位的常用方法及基本支持&#xff0c;请参考Python自动化测试系列[v1.0.0][元素定位] 数据驱动测试是自动化测试中一种重要的设计模式&#xff0c;这种设计模式可以将测试数据和测试代码分开&#xff0c;实现数据与代码解耦&#xff0c;与此同…...

【论文笔记】Gemini: A Family of Highly Capable Multimodal Models——细看Gemini

Gemini 【一句话总结&#xff0c;对标GPT4&#xff0c;模型还是transformer的docoder部分&#xff0c;提出三个不同版本的Gemini模型&#xff0c;Ultra的最牛逼&#xff0c;Nano的可以用在手机上。】 谷歌提出了一个新系列多模态模型——Gemini家族模型&#xff0c;包括Ultra…...

iOS加密CoreML模型

生成模型加密密钥 必须在Xcode的Preferences的Accounts页面登录Apple ID&#xff0c;才能在Xcode中生成模型加密密钥。 在Xcode中打开模型&#xff0c;单击Utilities选项卡&#xff0c;然后单击“Create Encryption Key”按钮。 从下拉菜单中选择当前App的Personal Team&…...

Springboot自定义start首发预告

Springboot自定义start首发预告 基于Springboot的自定义start , 减少项目建设重复工作, 如 依赖 , 出入参包装 , 日志打印 , mybatis基本配置等等等. 优点 模块化 可插拔 易于维护和升级 定制化 社区支持(后期支持) 发布时间 预告: 2023-12-10 预计发布: 2024-1-1 , 元旦首…...

[GWCTF 2019]我有一个数据库1

提示 信息收集phpmyadmin的版本漏洞 这里看起来不像是加密应该是编码错误 这里访问robots.txt 直接把phpinfo.php放出来了 这里能看到它所有的信息 这里并没有能找到可控点 用dirsearch扫了一遍 ####注意扫描buuctf的题需要控制扫描速度&#xff0c;每一秒只能扫10个多一个都…...

【LeetCode每日一题】1904. 你完成的完整对局数

给你两个字符串 startTime 和 finishTime &#xff0c;均符合 "HH:MM" 格式&#xff0c;分别表示你 进入 和 退出 游戏的确切时间&#xff0c;请计算在整个游戏会话期间&#xff0c;你完成的 完整对局的对局数 。 如果 finishTime 早于 startTime &#xff0c;这表示…...

+0和不+0的性能差异

前几日&#xff0c;有群友转发了某位技术大佬的weibo。并在群里询问如下两个函数哪个执行的速度比较快&#xff08;weibo内容&#xff09;。 func g(n int, ch chan<- int) {r : 0for i : 0; i < n; i {r i}ch <- r 0 }func f(n int, ch chan<- int) {r : 0for …...

美颜技术讲解:视频美颜SDK的开发与集成

如今&#xff0c;美颜技术的应用愈发成为吸引用户的一项重要功能。本文将深入探讨视频美颜SDK的开发与集成&#xff0c;揭示其背后的技术原理和实现步骤。 一、美颜技术的背后 美颜技术并非仅仅是简单的滤镜效果&#xff0c;而是一项涉及复杂图像处理和算法的技术。在视频美颜…...

期末数组函数加强练习

前言&#xff1a;由于时间问题&#xff0c;部分题解取自网友&#xff0c;但都是做过的好题。 对于有些用c实现的题目&#xff0c;可以转化成c实现&#xff0c;cin看成c的读入&#xff0c;可以用scanf&#xff0c;输出cout看作printf&#xff0c;endl即换行符 开胃菜&#xff…...

如何下载B站视频?我来教你B站视频下载方法

如何下载B站视频&#xff1f;B站作为一个巨大的宝藏库&#xff0c;日常可以拿它作为娱乐工具&#xff0c;刷一些有趣新奇的短视频。也可以把它作为一款成长学习工具&#xff0c;具有丰富的公开课、纪录片内容。 对于较短的视频来说&#xff0c;花费几分钟时间看一下就结束了&am…...

AcWing 3709:单链表节点交换 ← 四川大学考研机试题

【题目来源】 https://www.acwing.com/problem/content/3712/【题目描述】 输入一个单链表&#xff0c;依次交换前2个数&#xff0c;第3、4个数&#xff0c;第5、6个数&#xff0c;…&#xff0c;以此类推&#xff0c;直到操作完整个链表。 如果链表长度是奇数&#xff0c;则最…...

RocketMQ源码 Broker-ConsumerFilterManager 消费者数据过滤管理组件源码分析

前言 ConsumerFilterManager 继承了ConfigManager配置管理组件&#xff0c;拥有将内存数据持久化到磁盘文件consumerFilter.json的能力。它主要负责&#xff0c;对在消费者拉取消息时&#xff0c;进行消息数据过滤&#xff0c;且只针对使用表达式过滤的消费者有效。 源码版本&…...

数据挖掘-07-航空公司客户价值分析(包括数据和代码)

文章目录 0. 数据代码下载1. 背景与挖掘目标2. 导入相关库&#xff0c;加载数据2.1客户基本信息分布a. 绘制会员性别比例饼图b. 绘制会员各级别人数条形图c. 绘制年龄分布图 2.2 客户乘机信息分布分析a. 绘制客户飞行次数箱线图b. 绘制客户总飞行公里数箱线图 2.3 客户积分信息…...

浏览器 css 默认的字体图表

以下是一些常见的浏览器&#xff08;PC端&#xff09;中网站 CSS 默认字体及其对应的字体系列&#xff08;font family&#xff09;&#xff1a; 浏览器默认字体字体系列&#xff08;font family&#xff09;ChromeArial, sans-serif“Arial”, “Helvetica Neue”, Helvetica…...

JAVA:注册表窗口的实现

目录 题目要求&#xff1a; 思路大意&#xff1a; 窗体的实现&#xff1a; 窗口A&#xff1a; 窗口B&#xff1a; 窗体之间的构思&#xff1a; 关键代码的实现&#xff1a; 窗口A&#xff1a; 封装列表&#xff1a; 窗口B&#xff1a; 题目要求&#xff1a; 使用…...

Liunx Centos 防火墙操作

liunx centos 防火墙 查看防火墙状态 systemctl status firewalld查看已经开放的端口 firewall-cmd --list-ports添加端口3306 firewall-cmd --zonepublic --add-port3306/tcp --permanent重启防火墙 firewall-cmd --reload数据库开放账号可以外网登陆 mysql -u root -p …...

VirtualBox 和 Vagrant 快速安装 Centos7 报错

VirtualBox 和 Vagrant 快速安装 Centos7 报错 今天尝试用 VirtualBox 和 Vagrant 快速安装 Centos7&#xff0c;BUG 多多&#xff01; 1&#xff09;下载 6.1.26 版本 VirtualBox&#xff0c;Windows11 不兼容&#xff1f;&#xff1f;&#xff1f;什么鬼&#xff1f; 解决…...

使用Python进行数学四则运算

当我们讨论到Python中的计算问题时&#xff0c;我们必然涉及到加法运算符&#xff08;&#xff09;、减法运算符&#xff08;-&#xff09;、乘法运算符&#xff08;*&#xff09;以及除法运算符&#xff08;/&#xff09;这四大常见的算术运算。下面&#xff0c;我将为您展示如…...

成都工业学院2021级操作系统专周课程设计FCFS,SSTF,SCAN,LOOK算法的实现

运行环境 操作系统&#xff1a;Windows 11 家庭版 运行软件&#xff1a;CLion 2023.2.2 源代码文件 #include <iostream> #include <vector> #include <algorithm> #include <random> using namespace std;// 生成随机数 int generateRandomNumber…...