精华内容
下载资源
问答
  • 【考前三个月】(江苏专用)2015高考数学程序方法策略篇 专题3 解题策略 第2讲 参数法解题中的应用
  • 【考前三个月】(江苏专用)2015高考数学程序方法策略篇 专题3 解题策略 第6讲 分离参数法解题中的应用
  • 分离参数法【中级和高阶辅导】

    千次阅读 2018-06-28 17:50:00
    在高中数学教学实践中,有一种使用频度比较高的数学方法,叫分离参数法,她和许多数学素材有关联,高三学生大多都耳熟能详,但对其具体的来由和需要注意的问题却不是很清楚,本博文试着对此做个总结,以廓清我们认识...

    前言

    在高中数学教学实践中,有一种使用频度比较高的数学方法,叫分离参数法,她和许多数学素材有关联,高三学生大多都耳熟能详,但对其具体的来由和需要注意的问题却不是很清楚,本博文试着对此做个总结,以廓清我们认识上的误区,帮助我们提高教学,也帮助学生顺利掌握这一方法。

    一、方法定义

    引例:(2018宝鸡市二检理科第10题)关于\(x\)的方程\(\sqrt{3}sin2x+cos2x-k-1=0\)\([0,\cfrac{\pi}{2}]\)内有两个实数根,则\(k\)的取值范围是【\(\hspace{2em}\)】。

    A.\((1,2)\) \(\hspace{2cm}\) B.\([0,2)\) \(\hspace{2cm}\) C.\([0,1)\) \(\hspace{2cm}\) D.\([-2,1)\)

    \(\hspace{2em}\)分析:遇到这样的题目,我们一般是这样做的,先转化为\(k+1=2sin(2x+\frac{\pi}{6}),x\in [0,\cfrac{\pi}{2}]\),然后分别作出函数\(y=k+1\)和函数\(y=2sin(2x+\frac{\pi}{6}),x\in [0,\cfrac{\pi}{2}]\)图像,利用图像就可以知道,要使得两个函数有两个交点,需要满足\(1\leq k+1<2\),解得\(0\leq k<1\),故选C。

    需要注意的是,上述变形中,当将原方程转化为\(k+1=2sin(2x+\frac{\pi}{6})\),就已经将参数和自变量分离开了,这样的方法自然就叫分离参数法。

    二、使用原因

    我们借用上例说事,像这样的方程由于含有\(sin2x\)等,我们就称为超越方程,意思是不能像解\(x^2+3x+2=0\)这样的代数方程一样把她解出来。从数的角度行不通,那就只能考虑从形的角度了,如果我们设函数为\(y=\sqrt{3}sin2x+cos2x-k-1\),那么这个函数就不太好作图,但是如果分离成\(k+1=2sin(2x+\frac{\pi}{6})\),则原方程的实数根的个数问题,就自然转化为两个函数\(y=k+1\)\(y=2sin(2x+\frac{\pi}{6})\)的图像的交点的个数问题了,而且这两个函数的图像都很好作图,一下子就把问题的难度降下来了。可以这样说,分离参数法往往是我们从形的角度思考的前奏。通过这个例子,我们初步体会到分离常数法的优越性。

    三、使用范围

    再看个题目的解答,然后我们回答这个问题。

    案例1【2017西安模拟】已知函数\(f(x)=kx^2-lnx\)有两个零点,求参数\(k\)的取值范围【\(\hspace{2em}\)】。

    A、\(k>\cfrac{e}{2}\) \(\hspace{2cm}\) B、\(0<k<\sqrt{e}\) \(\hspace{2cm}\) C、\(k>\cfrac{\sqrt{2}e}{2}\) \(\hspace{2cm}\) D、 \(0<k<\cfrac{1}{2e}\)

    992978-20171111184856059-1836486122.png

    分析:函数的定义域为\((0,+\infty)\),由函数\(f(x)=kx^2-lnx\)有两个零点,

    转化为方程\(kx^2=lnx\)有两个不同的实数根,

    进而转化为\(k=\cfrac{lnx}{x^2}\)有两个不同的实数根,

    再转化为函数\(y=k\)和函数\(y=g(x)=\cfrac{lnx}{x^2}\)的图像有两个不同的交点,

    用导数研究函数\(g(x)\)的单调性,

    \(g'(x)=\cfrac{\frac{1}{x}\cdot x^2-lnx\cdot 2x}{(x^2)^2}=\cfrac{1-2lnx}{x^3}\)

    \(1-2lnx>0\),得到\(0<x<\sqrt{e}\),令\(1-2lnx<0\),得到\(x>\sqrt{e}\)

    即函数\(g(x)\)在区间\((0,\sqrt{e}]\)上单调递增,在\([\sqrt{e},+\infty)\)上单调递减,

    \(g(x)_{max}=g(\sqrt{e})=\cfrac{1}{2e}\),作出函数\(g(x)\)和函数\(y=k\)的简图,

    由图像可得\(k\)的取值范围是\(k\in(0,\cfrac{1}{2e})\)\(_{\small{\Box}}\)

    从上述的解法中(当然本题还有其他的解法,比如转化为方程\(kx^2=lnx\)有两个不同的实数根,不完全分离参数法),我们体会到,如果一个数学题目从数的角度直接来求解,结果很有可能要么不会求解,要么解不出,更或者没有思路;此时若换个角度思考,从形入手分析,将参数或含有参数的代数式(比如\(k+1\))和自变量分别放置在等号的两端,即\(k=f(x)\)的形式,然后数的问题就转化为形的问题了,从而直观快捷,思路简单明了。

    一句话,从形的角度解题的前提就是施行分离参数的方法。

    四、常见类型

    • ①常规法分离参数:如\(\lambda f(x)=g(x)\Rightarrow \lambda=\cfrac{g(x)}{f(x)}\)

    引例1、已知函数\(f(x)=kx^2-lnx\)有两个零点,求参数\(k\)的取值范围,用常规法分离参数,即得到方程\(k=\cfrac{lnx}{x^2}\)有两个不同实根,具体解法链接

    引例2、已知函数\(f(x)=mlnx+x^2-mx\)\((1,+∞)\)上单调递增,求m的取值范围【】.

    【分析】由函数单调递增,转化为\(f'(x)≥0\)\((1,+∞)\)上恒成立,然后分离参数得到\(m≤g(x)\),用均值不等式求新函数\(g(x)\)的最小值即可。

    【解答】由题目可知,\(f'(x)≥0\)\((1,+∞)\)上恒成立,且\(f'(x)\)不恒为零,

    则有\(f'(x)=\cfrac{m}{x}+2x-m=\cfrac{2x^2-mx+m}{x}≥0\)\((1,+∞)\)上恒成立,

    \(2x^2-mx+m≥0\)\((1,+∞)\)上恒成立,常规法分离参数得到

    m≤\(\cfrac{2x^2}{x-1}=\cfrac{2(x-1)^2+4x-2}{x-1}=\cfrac{2(x-1)^2+4(x-1)+2}{x-1}=2(x-1)+\cfrac{2}{x-1}+4\)

    由于\(x>1\),故\(2(x-1)+\cfrac{2}{x-1}+4≥2\sqrt{4}+4=8\),当且仅当\(x=2\)时取到等号。

    \(m≤8\),当\(m=8\)时,函数不是常函数,也满足题意,故选D。

    【点评】函数\(f(x)\)在区间\(D\) 上单调递增,则\(f'(x)≥0\)\(D\)上恒成立,且\(f'(x)\)不恒为零;

    函数\(f(x)\)在区间\(D\)上单调递减,则\(f'(x)≤0\)\(D\)上恒成立,且\(f'(x)\)不恒为零;

    此处要求\(f'(x)\)不恒为零,意思是要排除函数\(f(x)\)为常函数的情形。

    • ②倒数法分离参数:如\(\lambda f(x)=g(x)\Rightarrow \cfrac{1}{\lambda}=\cfrac{f(x)}{g(x)}\)

    比如,方程\(kx^2=e^x\),若常规法分离参数得到\(k=\cfrac{e^x}{x^2}\),就没有倒数法分离为\(\cfrac{1}{k}=\cfrac{x^2}{e^x}\)优越,

    原因是函数\(y=\cfrac{e^x}{x^2}\)\(x=0\)处有断点,而函数\(y=\cfrac{x^2}{e^x}\)\(x\in R\)上是处处连续的,函数相对简单一些。

    【提炼】已知函数\(f_1(x)=e^x\)\(f_2(x)=ax^2-2ax+b\),设\(a>0\),若对任意的\(m,n∈[0,1](m\neq n)\)\(|f_1(m)-f_1(n)|>|f_2(m)-f_2(n)|\)恒成立,求\(a\)的最大值。

    【分析】利用函数的单调性去掉绝对值符号,构造新函数,可以将问题再次转化为恒成立,然后分离参数求解。

    【解答】不妨设\(m>n\),则函数\(f_1(x)\)在区间\([0,1]\)上单调递增,故\(f_1(m)-f_1(n)>0\)

    \(f_2(x)=a(x-1)^2+b-a\),对称轴是\(x=1\),开口向上,

    故函数\(f_2(x)\)在区间\([0,1]\)上单调递减,故\(f_2(m)-f_2(n)<0\)

    这样对任意的\(m,n\in [0,1](m>n)\)\(|f_1(m)-f_1(n)|>|f_2(m)-f_2(n)|\)恒成立,

    就可以转化为\(f_1(m)-f_1(n)>f_2(m)-f_2(n)\)恒成立,

    \(f_1(m)+f_2(m)>f_1(n)+f_2(n)\)恒成立,

    \(h(x)=f_1(x)+f_2(x)=e^x+ax^2-2ax+b\)

    则到此的题意相当于已知\(m>n\)时,\(h(m)>h(n)\)

    故函数\(h(x)\)在区间\([0,1]\)上单调递增,故\(h'(x)≥0\)在区间\([0,1]\)上恒成立;

    \(h'(x)=e^x+2ax-2a≥0\)在区间\([0,1]\)上恒成立;

    \(2a(1-x)≤e^x\)恒成立,这里我们使用倒数法分离参数得到,

    \(\cfrac{1}{2a}≥\cfrac{1-x}{e^x}\)在区间\([0,1]\)上恒成立;

    再令\(p(x)=\cfrac{1-x}{e^x}\),即需要求\(p(x)_{max}\)

    \(p'(x)=\cfrac{-1×e^x-(1-x)e^x}{(e^x)^2}=\cfrac{x-2}{e^x}\)

    容易看出,当\(x∈[0,1]\)时,\(p'(x)<0\)恒成立,故\(p(x)\)在区间\([0,1]\)上单调递减,

    \(p(x)_{max}=p(0)=1\),故\(\cfrac{1}{2a}≥1\),又\(a>0\)

    故解得\(0<a≤1\)。故\(a_{max}=1\).

    • ③讨论法分离参数:如\(\lambda f(x)\ge g(x)\)

    比如,\(\lambda(x-1)\ge 2lnx\)对任意的\(x\in(0,1]\)恒成立,接下来分\(x=1\)\(0<x<1\)分类讨论分离参数,具体见博文的后半部分的对应例题。

    已知对任意\(x>0\)\(x\neq 1\),不等式\(\cfrac{x-m}{lnx}>\sqrt{x}\)恒成立,求\(m\)的取值范围。

    对任意\(x>0\)\(x\neq 1\),不等式\(\cfrac{x-m}{g(x)}>\sqrt{x}\)恒成立等价于

    \(0<x<1\)时,\(m>x-\sqrt{x}lnx①\)恒成立,或者当\(x>1\)时,\(m<x-\sqrt{x}lnx②\)恒成立,

    \(h(x)=x-\sqrt{x}lnx(x>0,x\neq 1)\)\(h'(x)=\frac{2\sqrt{x}-lnx-2}{2\sqrt{x}}\)

    \(\phi(x)=2\sqrt{x}-lnx-2\),则\(\phi'(x)=\frac{\sqrt{x}-1}{x}\)

    易知\(\phi(x)\)\((0,1)\)上单调递减,在\((1,\infty)\)上单调递增,

    所以\(\phi(x)>\phi(1)=0\),即得到\(h'(x)>0\)

    因此由①式可得,\(m\ge h(1)=1\),由②式得\(m\leq h(1)=1\)

    取两种结果的交集,所以\(m=1\)

    故不等式\(\cfrac{x-m}{g(x)}>\sqrt{x}\)恒成立的充要条件是\(m=1\)

    • ④整体法分离参数:如\(\lambda^2+2\lambda=f(x)\)

    引例1、(2017湖南郴州二模)若命题“\(P:\exists x_0\in R,2^x_0-2+3a\leq a^2\)”是假命题,则实数\(a\)的取值范围是__________。

    分析:由题目可知,命题“\(\neg P:\forall x\in R,2^x-2> a^2-3a\)”是真命题,即\(2^x-2> a^2-3a\)\(\forall x\in R\)恒成立,

    \((2^x-2)_{min}>a^2-3a\),只需求\((2^x-2)_{min}\),而\(2^x-2>-2\),则有\(-2\ge a^2-3a\),即\(a^2-3a+2\leq 0\)

    解得\(1\leq a\leq 2\),故实数\(a\)的取值范围是\([1,2]\)

    引例2、已知函数\(f(x)=-x^2+ax+b^2-b+1(a\in R,b\in R)\),对任意实数\(x\)都有\(f(1-x)=f(1+x)\)成立,若当\(x\in[-1,1]\)时,\(f(x)>0\)恒成立,则\(b\)的取值范围是_____________.

    分析:先由\(f(1-x)=f(1+x)\)得到,二次函数的对称轴\(x=-\cfrac{a}{-2}=1\),解得\(a=2\)

    故题目转化为\(-x^2+2x+b^2-b+1>0\)对任意\(x\in [-1,1]\)恒成立,

    整体法分离参数,得到\(b^2-b>x^2-2x-1\)对任意\(x\in[-1,1]\)恒成立。

    \(g(x)=x^2-2x-1,x\in[-1,1]\),需要求函数\(g(x)_{max}\)

    \(g(x)=x^2-2x-1=(x-1)^2-2,x\in[-1,1]\),故\(g(x)\)在区间\([-1,1]\)上单调递减,则\(g(x)_{max}=g(-1)=2\)

    \(b^2-b>2\),解得\(b<-1\)\(b>2\)

    • ⑤不完全分离参数法:如\(kx^2=lnx\)

    比如,已知函数\(f(x)=kx^2-lnx\)有两个零点,求参数\(k\)的取值范围,用不完全分离参数法,即得到方程\(kx^2=lnx\)有两个不同实根,具体解法链接

    五、局限之处

    并不是所有的含参问题都适合分离参数,比如\(ax^2-a^2x+3<0\)在区间\([1,2]\)上恒成立,求\(a\)的范围,就不能用分离参数的方法,因为你没法将参数和自变量有效的分开,所以此时你可能需要借助二次函数的图像来考虑,而不是一味的使用分离参数法。

    一般来说,以下的一些情形都不适合使用分离参数法:

    • (1)不能将参数和自变量有效的分离开的;

    \(\hspace{2em}\)比如,已知方程\(e^{-x}=ln(x+a)\)\(x>0\)时有解,求参数的取值范围;

    本题目就不能将参数和自变量有效的分离开的,此时我们就可以考虑用数形结合的思路求解。解法

    • (2)如果参数的系数能取到正、负、零三种情形的,

    引例,已知函数\(f(x)=x^2+ax-2a\ge 0\)\(x\in [1,5]\)上恒成立,求参数\(a\)的取值范围。

    如果用分离参数的方法,则先转化为\((x-2)a\ge -x^2,x\in [1,5]\)

    接下来就转化成了三个恒成立的命题了,不管会不会做,从效率上都已经很不划算了。具体的解法已经隐藏。

    • (3)分离参数后,得到的新函数变得复杂无比的;

    \(\hspace{2em}\)比如函数\(f(x)=x^2-2x+a(e^{x-1}+e^{-x+1})\)有唯一的零点,分离参数后,得到\(a=\cfrac{-x^2+2x}{e^{x-1}+e^{-x+1}}=h(x)\)

    你确信你能研究清楚函数\(h(x)\)的性质,并用手工做出函数的图像吗?省省吧,您呐。

    • (4)分离参数后,得到的新函数中有\(sinx\)\(cosx\)的,他们都有无穷阶导数,所以求导会一直做下去,一般不会使得函数式变得简单。

    比如已知\(2a-1+sin2x+a(sinx-cosx)\ge 0\)\(x\in [0,\cfrac{\pi}{2}]\)上恒成立,求参数\(a\)的取值范围。\([1,+\infty)\)

    接下来的思路有:

    思路一:分离参数,当分离为\(a\ge \cfrac{1-sin2x}{2+sinx-cosx}=g(x)\)时,你会发现,求函数\(g(x)_{max}\)很难,所以放弃;

    思路二:链接,转化划归,令\(sinx-cosx=t=\sqrt{2}sin(x-\cfrac{\pi}{4})\),由于\(x\in [0,\cfrac{\pi}{2}]\),故\(t\in [-1,1]\)

    \((sinx-cosx)^2=t^2\),得到\(sin2x=1-t^2\),故不等式转化为\(at+1-t^2+2a-1\ge 0\)

    \(t^2-at-2a\leq 0\)\(t\in [-1,1]\)上恒成立,令\(h(t)=t^2-at-2a,t\in [-1,1]\)

    \(h(t)\leq 0\)等价于\(\begin{cases}h(-1)=1+a-2a\leq 0\\h(1)=1-a-2a\leq 0 \end{cases}\),解得\(a\ge 1\)

    • (5)看题目的选项确定方法

    例12【2019届高三理科数学二轮用题】已知函数\(f(x)=mx-\cfrac{1-m}{x}+lnx\),要使得函数\(f(x)>0\)恒成立,则正实数\(m\)应该满足【】

    $A、\cfrac{m-1}{m}\cdot e^{2m-1}<1$ $B、\cfrac{m-1}{m}\cdot e^{1-2m}<1$ $C、\cfrac{m-1}{m}\cdot e^{2m-1}>1$ $D、\cfrac{m-1}{m}\cdot e^{1-2m}>1$

    法1:先考虑分离参数法,若能成功分离参数,那么得到的形式必然是\(m>g(x)\)\(m<g(x)\)的形式,接下来需要求解函数\(g(x)\)的最值,其必然是数字化的,则结果和给定的选项的形式是不一致的,故这个思路做了大致分析后放弃;

    法2:由函数\(f(x)>0\)恒成立,则需要求在\((0,+\infty)\)上的函数\(f(x)_{min}>0\)即可,故考虑用导数方法;

    \(f'(x)=\cfrac{(x+1)[mx+(1-m)]}{x^2}\), 故函数在\(x=\cfrac{m-1}{m}\)处取到最小值,则要使得函数\(f(x)>0\)恒成立,只需要\(f(\cfrac{m-1}{m})>0\)即可,

    对此化简整理得到,正实数\(m\)应该满足\(\cfrac{m-1}{m}\cdot e^{2m-1}>1\),故选\(C\)

    解后反思:本题目的解法有点漏洞,条件中应该使得\(m>1\),而不仅仅是\(m>0\),否则当\(0<m\leq 1\)时,函数\(f(x)\)\((0,+\infty)\)上单调递增,其最小值的极限为\(f(0)\),题目就有了问题。

    六、使用策略:

    在具体的解题实践中,我们会发现绝大多数的题目可以用分离参数法解决,但是如果简单尝试后发现此法行不通,则需要及时调整解题思路和策略,比如做差构造新函数的思路。

    已知函数\(f(x)=x^2-ax\)\(g(x)=mx+nlnx\),函数\(f(x)\)的图像在点\((1,f(1))\)处的切线的斜率为\(1\),函数\(g(x)\)\(x=2\)处取到极小值\(2-2ln2\)

    (1)求函数\(f(x)\)\(g(x)\)的解析式;

    分析:由题可知\(f'(x)=2x-a\),又\(f'(1)=2-a=1\),解得\(a=1\),即\(f(x)=x^2-x\)

    \(g'(x)=m+\cfrac{n}{x}\),由\(g'(2)=m+\cfrac{n}{2}=0\)\(g(2)=2m+nln2=2-2ln2\),解得\(m=1,n=-2\),即\(g(x)=x-2lnx\)

    (2)已知函数\(f(x)+g(x)\ge x^2-\lambda(x-1)\)对任意的\(x\in(0,1]\)恒成立,求实数\(\lambda\)的取值范围。

    分析:由于\(f(x)+g(x)=x^2-2lnx\),则\(x^2-2lnx\ge x^2-\lambda(x-1)\)对任意的\(x\in(0,1]\)恒成立,可以有以下的思路:

    法1:带参分析法,先令\(h(x)=\lambda(x-1)-2lnx\),则问题转化为\(h(x)\ge 0\)对任意的\(x\in(0,1]\)恒成立,

    \(h'(x)=\lambda-\cfrac{2}{x}=\cfrac{\lambda x-2}{x}\)

    \(\lambda\leq 0\)时,\(h'(x)<0\)\(h(x)\)在区间\((0,1]\)上单调递减,

    \(h(x)_{min}=h(1)=0\),即\(h(x)\ge 0\)恒成立;

    \(0<\lambda \leq 2\)时,\(h'(x)<0\)\(h(x)\)在区间\((0,1]\)上单调递减,

    \(h(x)_{min}=h(1)=0\),即\(h(x)\ge 0\)恒成立;

    \(\lambda>2\)时,\(h'(x)<0\)\((0,\cfrac{2}{\lambda})\)上恒成立,\(h'(x)>0\)\((\cfrac{2}{\lambda},1)\)上恒成立,

    \(h(x)\)\((0,\cfrac{2}{\lambda})\)单调递减,在\((\cfrac{2}{\lambda},1)\)上单调递增,

    所以\(h(\cfrac{2}{\lambda})<h(1)=0\),故不满足题意,注意\(h(1)=0\),即函数\(h(x)\)恒过点\((1,0)\)

    综上所述,实数\(\lambda\)的取值范围为\((-\infty,2]\)

    法2:讨论法分离参数,先转化为\(\lambda(x-1)\ge 2lnx\)对任意的\(x\in(0,1]\)恒成立,

    \(x=1\)时,\(\lambda\cdot 0\ge 2ln1=0\)\(\lambda\in R\)

    \(x\in (0,1)\)时,分离参数得到\(\lambda \leq \cfrac{2lnx}{x-1}\);令\(h(x)= \cfrac{2lnx}{x-1}\)

    \(h'(x)=\cfrac{\cfrac{2}{x}(x-1)-2lnx}{(x-1)^2}=\cfrac{2(1-\cfrac{1}{x}-lnx)}{(x-1)^2}\)

    \(m(x)=1-\cfrac{1}{x}-lnx\),则\(m'(x)=\cfrac{1}{x^2}-\cfrac{1}{x}=\cfrac{1-x}{x^2}\)

    \(m'(x)>0\),则\(m(x)\)\((0,1)\)上单调递增,故\(m(x)<m(1)=0\),故\(h'(x)=\cfrac{2m(x)}{(x-1)^2}<0\)

    \(h(x)\)\((0,1)\)上单调递减,故\(h(x)>h(1)=2\)(由洛必达法则求得),即\(\lambda\leq 2\)

    综上所述求交集得到,\(\lambda \in(-\infty,2]\)

    法3:不完全分离参数法,由\(\lambda(x-1)\ge 2lnx\)对任意的\(x\in(0,1]\)恒成立,

    做函数\(y=\lambda(x-1)\)和函数\(y=2lnx\)的图像,示意图

    设直线\(y=\lambda(x-1)\)与曲线\(y=2lnx\)相切于点\((x_0,y_0)\),则有\(\cfrac{2}{x_0}=\lambda\)\(y_0=2lnx_0\)\(y_0=\lambda(x_0-1)\)

    求得切点坐标\((1,0)\),此时\(\lambda=2\),由\(\lambda\)的几何意义可知,\(\lambda\)的取值范围是\((-\infty,2]\)

    七、注意事项

    • 分离参数法,一般常用于恒成立问题、能成立问题(有解),或无解问题,或已知函数零点个数命题中的参数取值范围问题,又或是从数的角度不好解决需要从形的角度入手的问题。

    • 分离参数时,尽可能的使函数形式简单,这样求导数判断单调性就简单些,而参数形式复杂些或者简单些都无所谓,

    比如方程\((2-a)x-2(1+lnx)+a=0\)\((0,\cfrac{1}{2})\)上无解,求参数的最小值。

    转化一:\(a=\cfrac{2+2lnx-2x}{1-x}=h(x)\)\(\hspace{4em}\) 转化二:\(\cfrac{2-a}{2}=\cfrac{lnx}{x-1}=h(x)\)

    我们看到第二种转化就比第一种转化划归要好的多。

    通过以上七个方面的粗浅探索,相信各位会对分离参数法有更深入的理解,使用会更加得心应手。

    转载于:https://www.cnblogs.com/wanghai0666/p/8617323.html

    展开全文
  • ,而本专题我们将介绍“误差反向传播”,实现损失函数关于权重参数梯度 的高效计算。本主题将从简单的问题开始,逐步深入,最终直达误差反向传播。 理解误差反向传播,一般有基于 数学式 的方法和基于 ...

    目录

    前言

     计算图

    计算图求解示例

    计算图的优点

    反向传播

    思考一个问题

    链式法则

    计算图的反向传播

    链式法则和计算图

    加法节点的反向传播

    乘法节点的反向传播

    “购买水果”问题的反向传播

    激活函数(层)的反向传播

     激活函数ReLU的反向传播

    激活函数Sigmoid的反向传播

    Affine/softmax激活函数的反向传播

    Affine层

    softmax-with-loss层的反向传播

    误差反向传播法的Python实现

    乘法层的Python实现

    加法层的Python实现

    购买水果问题的Python实现

    激活函数层的Python实现

    ReLU层的Python实现

    sigmoid层的Python实现

    Affine层的Python实现

    softmax-with-loss层的Python实现

    误差反向传播法的Python总体实现

    小结


    前言

    计算梯度的传统方法一般采用基于数值微分实现,如下式:

                                                        

    \frac{df\left ( x \right )}{dx}=\lim_{h\rightarrow 0}\frac{f\left ( x+h \right )-f\left ( x \right )}{h}

    虽然数值微分方法比较直观、简单、易于理解,但是计算比较费时间,不适合需频繁计算导数的场合,比如多层神经网络中权重参数的梯度计算。前面我们讲过利用数值微分计算了神经网络中的损失函数关于权重参数的梯度\frac{\partial L}{\partial W},而本专题我们将介绍“误差反向传播法”,实现损失函数关于权重参数梯度\frac{\partial L}{\partial W}的高效计算。本主题将从简单的问题开始,逐步深入,最终直达误差反向传播法。

    理解误差反向传播法,一般有基于数学式的方法和基于计算图的方法。前者比较常见、简洁和严密,但是不直观,因此笔者选择了更加直观、易于理解的计算图来讲解误差反向传播法。

     计算图

     计算图,即将计算过程用图形表示出来,当然,这里的图形指的是具有数据结构(和流程图类似的图形),一般有节点和连接节点的边(线)组成,如图1所示。

    图1 计算图

     图1中圆圈O表示节点,圈内的符号表示计算符号(比如加减乘除),箭头的指向表示节点计算结果的传递方向(图1为从左向右传播,即正向传播),直线上方一般放置中间计算结果(如100)。下面我们基于计算图来分析一个具体的示例。

    计算图求解示例

    问题描述:

    小明在超市买了2个苹果、3个橘子。其中,苹果每个100日元,橘子每个150日元。消费税是10%,请计算支付金额。

    首先,我们采用传统的数学思路来计算支付金额:2个苹果,单价为100日元,因此购买苹果花了200日元;3个橘子,单价150日元,因此,够买橘子花了450日元;因此购买苹果和橘子一共花了650日元,由于消费税是10%,所以支付金额为:650+650·10%=715日元。

    下面我们采用基于计算图来计算支付金额,先直接给出计算图如图2所示,再分析。

    图2  基于计算图计算支付金额

     

    由计算图分析得到的结果和传统方法分析得到的结果一样,均为715日元。现在我们结合图2来分析该计算图,计算图的输入有苹果单价、苹果数量、橘子单价、橘子数量、消费税,中间的计算结果均放置(保存)在直线上面,这里需要强调的是初始输入量的值我们也视为中间结果,比如苹果单价视为输入量(实际等效于一个变量),而100为中间变量(等效于一个实例值)。改图一共有4个节点,其中3节点运算为乘法运算,1个节点运算为加法运算。计算方向为从左至右,这是一种正方向的传播,简称为正向传播。指向节点的箭头可以视为输入,比如上图中输入至加法节点的有两个输入量(苹果总价和橘子总价),当然输入量是没有限制的。图中消费税的中间计算过程为1.1(1+10%),这么做的目的主要是可以直接和水果总价进行乘法运算,当然读者可以自行设计图2中的消费税这一节点。

    我们不难理解,正向传播就是从计算图出发点到结束点的传播,既然有正向传播,那么应该也有反向传播。是的,从右向左的传播就是我们后面将重点关注的反向传播

    计算图的优点

    通过上面给出的计算图求解实际问题的示例可知,计算图的特征是可以通过传递“局部计算”获得最终结果。所谓“局部”,指的是无论全局发生了什么,都能只根据与自己相关的信息输出接下来的结果。假设上面的例子中,购买水果总共花费了650日元,我们不关心650日元是通过什么样的计算得到的,只关心把650日元作为该节点的输出并和其他节点进行运算。换句话说,各个节点处只需进行与自己有关的计算,不用考虑全局。无论全局是多么复杂的计算,都可以通过局部计算使各个节点致力于简单的计算,从而简化问题。

    另一个优点是,利用计算图可以将中间的计算结果全部保存起来(比如200、450、650....),为反向传播的计算提供已知数据。

    反向传播

    思考一个问题

    在上面的问题中,我们计算了购买苹果和橘子时加上消费税最终需要支付的金额。假设我们想知道苹果价格的上涨会在多大程度上影响最终的支付金额,即求“支付金额关于苹果价格的导数”。设苹果的价格为x,支付金额为L,则相当于求\frac{\partial L}{\partial x}。这个导数的值表示当苹果的价格稍微上涨时,支付金额会增加多少。

    首先,我们利用传统的数学解题思路来求解,假设苹果价格上涨了\Delta x日元,支付金额增加了\Delta L日元,则有:

                         \Delta L=\left \{ \left ( 100+\Delta x \right )\cdot 2+150\cdot 3 \right \}\cdot 1.1-\left ( 100\cdot 2+150\cdot 3 \right )\cdot 1.1=2.2\Delta x

    通过数学解题思路,我们得到了支付金额关于苹果的价格的导数为2.2,即苹果价格上涨1日元,则最终的支付金额将会增加2.2日元。现在我们先直接给出利用反向传播法分析得到的结果。图中加粗的箭头表示反向传播,箭头下面的结果表示“局部导数”,也就是说,反向传播传递的是导数。从图中可知,支付金额关于苹果单价的导数的值是2.2,这和数学解题思路得到的答案一样。当然,除了求关于苹果的价格的导数,其他的比如支付金额关于消费税的导数、支付金额关于橘子价格的导数等问题也可以采用同样的方式算出来。

    图3  反向传播求支付金额关于苹果单价的导数

    从图3中还可发现,计算中途求得的导数的结果(比如1.1)可以被共享,从而高效地计算多个导数。因此,计算图可以通过正向传播和反向传播高效地计算各个变量的导数值。反向传播传递导数的原理,是基于链式法则。

    链式法则

    反向传播将局部导数从右到左进行传递的原理是基于链式法则,要理解链式法则,我们还得从复合函数说起。复合函数是由多个函数构成的函数。比如z=\left ( x+y \right )^{2}是由下面的两个式子构成的。

                                                             z=t^{2}

                                                             t=x+y                                                                          (1)

    这里,链式法则是关于符合函数的导数的性质,如下:

    如果某个函数由复合函数表示,则该复合函数的导数可以用构成复合函数的各个函数的导数的乘积表示。

    例如,\frac{\partial z}{\partial x}可以用\frac{\partial z}{\partial t}\frac{\partial t}{\partial x}的乘积表示。即:

                                                                     \frac{\partial z}{\partial x}=\frac{\partial z}{\partial t}\frac{\partial t}{\partial x}

    现在使用链式法则,我们来求式(1)的导数\frac{\partial z}{\partial x}。首先要求它的局部导数:

                                                   \frac{\partial z}{\partial t}=2t

                                                  \frac{\partial t}{\partial x}=1                                                                                     (2)

    所以\frac{\partial z}{\partial x}的导数为:

                                            \frac{\partial z}{\partial x}=\frac{\partial z}{\partial t}\frac{\partial t}{\partial x}=2t\cdot 1=2\left ( x+y \right )

    计算图的反向传播

    假设存在y=f\left ( x \right )的计算,则这个计算的反向传播如图4所示。

    图4  计算图的反向传播

    如图所示,反向传播的计算顺序是:将信号E乘以节点的局部导数\frac{\partial y}{\partial x},然后将结果传递给下一个节点。这里所说的局部导数是指正向传播中y=f\left ( x \right )的导数,也就是\frac{\partial y}{\partial x},比如y=f\left ( x \right )=x^{2},则局部导数为\frac{\partial y}{\partial x}=2x。把这个局部导数乘以上游传过来的值(本例中的E),然后传递给前面的节点。(这里给大家说一下,如果是神经网络,那么最上游应该是损失函数)。

    这就是反向传播的计算程序,结合链式法则可以高效地求出多个导数的值。

    链式法则和计算图

    现在我们用计算图的方法把式(1)的链式法则表示出来。如图5所示,这里我们用“**2”表示平方运算。

    图5  式(2)的计算图:沿着与正方向相反的方向,乘上局部导数后传递

    反向传播时,“**2”节点的输入是\frac{\partial z}{\partial z},将其乘以局部导数\frac{\partial z}{\partial t}(因为正向传播时输入是t,输出是z,所以这个节点的局部导数是\frac{\partial z}{\partial t}),然后传递给下一个节点。这里需要提醒的是,反向传播最开始的信号\frac{\partial z}{\partial z}在前面的数学式中没有出现,因为\frac{\partial z}{\partial z}=1。根据链式法则,最左边的反向传播结果\frac{\partial z}{\partial z}\frac{\partial z}{\partial t}\frac{\partial t}{\partial x}=\frac{\partial z}{\partial t}\frac{\partial t}{\partial x}=\frac{\partial z}{\partial x}成立,对应于“z关于x的导数”。

    现在我们把式(2)的结果代入到图5中,可得\frac{\partial y}{\partial x}=2\left ( x+y \right ),如图6所示。

    图6  反向传播的结果

    到这里,读者也许会生产疑问:反向传播过程中的数字1是怎么得到的,下面的内容将为大家解释这个问题。

    加法节点的反向传播

    加法节点指的是节点运算为加法运算,以 z=x+y为例,则z关于xy的导数为

                                                          \frac{\partial z}{\partial x}=1

                                                         \frac{\partial z}{\partial y}=1

    假设 z=x+y通过某种运算的结果为L,则加法节点的正向传播和反向传播的计算图如下:

    图7 加法节点的反向传播将上游的值原封不动地输出到下游

     我们通过解析性求导,得到z关于xy的导数均为1,因此计算图中,反向传播将上游传过来的导数值(本例中是\frac{\partial L}{\partial z},因为正向传播的输入为z,输出为L)乘以1,然后传向下游。也就是说,加法节点的反向传播只乘以1,所以输入的值会原封不动地流向下一个节点。

    乘法节点的反向传播

    假设有z=xy,则z关于xy的导数为:

                                                                                 \frac{\partial z}{\partial x}=y

                                                                                 \frac{\partial z}{\partial y}=x

    用计算图表示乘法节点的正向传播和反向传播如图8所示。

    图8 乘法节点反向传播将上游的值乘以正向传播时的输入信号的“翻转值”后传递给下游

     乘法的反向传播会将上游的值乘以正向传播时的输入信号的'翻转值"后传递给下游。翻转值表示一种翻转关系,正向传播时信号是x的话,反向传播时则是y;正向传播时信号是y的话,反向传播时则是x。这里需要提醒大家的是,加法的反向传播只是将上游的值传递给下游,并不需要正向传播的输入信号。而乘法的反向传播需要正向传播时的输入信号值,因此要实现乘法节点的反向传播时,需要保存正向传播的输入信号。

    “购买水果”问题的反向传播

    现在我们回到前面给出的问题“购买水果,求支付金额”,因为我们已经介绍了加法和乘法的反向传播,所以我们试着来分析“购买水果”的反向传播,即求包括金额关于苹果单价的导数等其他变量的导数。读者只需记住两点:加法的反向传播将上游传递来的值会原封不动地传递给下游;乘法的反向传播会将输入信号翻转后传递给下游。因此“购买水果”的反向传播的计算图如图9所示。

    图9购买水果的反向传播

    可知,苹果的价格的导数为2.2,橘子的价格的导数为3.3(说明橘子的价格的波动比苹果价格的波动对最终的支付金额的影响更大),消费税的导数是650(消费税的1是100%,水果的价格的1是1日元,所以才形成了这么大的消费税的导数)。

    激活函数(层)的反向传播

     激活函数ReLU的反向传播

    激活函数ReLU的表达式如下式(3):

                                           y=\left\{\begin{matrix} x & \left ( x>0 \right )\\ 0& \left ( x\leq 0 \right ) \end{matrix}\right.                                                 (3)

    y关于x的导数如式(4):

                                          \frac{\partial y}{\partial x}=\left\{\begin{matrix} 1 & \left ( x>0 \right )\\ 0& \left ( x\leq 0 \right ) \end{matrix}\right.                                                 (4)

    由式(4)可知,如果正向传播时的输入x大于0,则反向传播会将上游的值原封不动地传递给下游。如果正向传播时的x小于等于0,则反向传播中传给下游的信号将停止在此处,即反向传播的值为0。用计算图表示如图9所示。

    图9 ReLU层的计算图

    激活函数Sigmoid的反向传播

    sigmoid函数的表达式如式(5)所示。

                                                      y=\frac{\mathrm{1} }{\ 1+exp\left ( -x \right )}                                    (5)

    其计算图如图10所示。

    图10 sigmoid函数的计算图

    说明一下,式(5)的计算由局部计算的传播构成,“exp”节点会进行y=exp\left ( x \right )的计算,“/”会进行y=\frac{\mathrm{1} }{\ x}的计算。下面我们来分析图10的计算图的反向传播。

    第一步:

    节点“/”表示y=\frac{\mathrm{1} }{\ x}的计算,则它的导数如式(6)所示。

                                                                        \frac{\partial y}{\partial x}=-\frac{\mathrm{1} }{\ x^{2}}=-y^{2}                                                        (6)

    可知,“/”节点运算时的反向传播会将上游的值乘以-y^{2}(正向传播的输出的平方乘以-1后的值)后,再传给下游。计算图如图11所示。

    图11 除法节点的反向传播的计算图

    第二步:

    “+”节点将上游的值原封不动地传给下游。计算图如图12所示。

    图 12 加法节点的反向传播的计算图

    第三步:

    “exp”节点表示y=exp\left ( x \right ),则它的导数如式(7)所示。

                                                         \frac{\partial y}{\partial x}=exp(x)=y                                                      (7)

    可知,“exp”节点的反向传播将上游的值乘以正向传播时的输出y(这个例子的输出是exp\left ( -x \right ))后,再传给下游。计算图如图13所示。

    图13 指数运算节点的反向传播的计算图

    第四步:

    “x”节点的反向传播将正向传播时的值翻转后做乘法运算,因此计算图如图14所示。

    图14  sigmoid函数的反向传播的计算图

    综上,sigmoid函数的反向传播的输出为\frac{\partial L}{\partial y}y^{2}exp(-x),这个值会传递给下游的节点。我们发现,\frac{\partial L}{\partial y}y^{2}exp(-x)该值可只根据正向传播时的输入x和输出y就可以计算出来。所以,sigmoid函数的反向传播可以简化为如图15所示的计算图。

    图15  sigmoid函数的反向传播的计算图(简洁版)

    简洁后的反向传播可以忽视中间计算过程,因此大幅度提高了计算效率。其实,我们可以对\frac{\partial L}{\partial y}y^{2}exp(-x)作进一步的处理,如式(8)所示。

    因此,sigmoid函数的反向传播只需根据正向传播的输出就能计算出来,这里我们选择图16所示的计算图作为sigmoid函数的反向传播的最终计算图。

    图 16 sigmoid函数的计算图:只需正向传播的输出y计算反向传播

    Affine/softmax激活函数的反向传播

    Affine层

    在前面的专题讲解中,我们介绍了计算加权信号的总和,即输入信号x与权重w的乘积之和,再加上偏置b。在实现过程中,我们利用了矩阵的乘积运算(Numpy库中的np.dot())来计算了神经元(节点)加权和,即Y=np.dot(X,W)+B,然后将Y经激活函数转换后,传递给下一层。这就是神经网络的正向传播的流程。一般地,神经网络的正向传播涉及矩阵的乘积运算(信号的加权和计算)的过程(变换),我们称为Affine层

    Affine层:

    神经网络的正向传播中进行的矩阵的乘积运算在几何学领域被称为“仿射变换”,它包括一次线性变换和一次平移,分别对应神经网络的加权和运算\sum xw与加偏置预算\left ( \sum xw\right )+b。在这里,我们将进行仿射变换的处理实现为“Affine”层。

    图17为神经网络正向传播的Affine层的计算图,我们需要注意的是,图中的变量均为矩阵形式,所以在进行矩阵运算时,要注意矩阵的形状是否正确。这里我们假设了各变量矩阵的形状,注意这里的计算图中各节点间传递的是矩阵,不是标量。

    图17 Affine层的计算图

    通过Affine层的正向传播,我们如何求它的反向传播呢?在这里我们需要记住两点:第一点是x、w、bwb均为变量,不是常量;第二点是节点中的运算步骤和以标量为对象的计算图相同。因此,我们很容易得到如图18所示的反向传播的计算图。

    图18  Affine层的反向传播

    图18中的反向传播的加法节点将上游传递来的值原封不动地传递给下游。"dot"节点可以看做乘法节点,但又有区别,即它是矩阵乘法,所以在考虑将上游传递来的值乘以正向传播的翻转值的同时,还要注意矩阵的形状。这里我们可以肯定的是:\frac{\partial L}{\partial x}\frac{\partial L}{\partial Y}W的某种乘积关系,而\frac{\partial L}{\partial W}\frac{\partial L}{\partial Y}X的某种乘积关系。因此,仔细分析可知:

    W^{T}W的转置,比如W的形状为(2,3),则W^{T}的形状就是(3,2)。所以图18中Affine层的反向传播的完整的计算图如图19所示:

    图19 Affine层的反向传播的计算图

    当然,这里介绍的Affine层的输入X是以单个数据为对象的,如果我们将N个数据样本(假设数据的特征有2个,则X的形状为(N,2))一起进行正向传播,即批版本的Affine层。那么它的计算图如图20所示。

    图20 批版本的Affine层的计算图

    softmax-with-loss层的反向传播

    神经网络涉及输入信号与权重参数的乘积的加权和(即Affine层)、激活函数、输出层激活函数(softmax)和损失函数(主要使用交叉熵误差)。在这之前,我们已经介绍了Affine层和激活函数的反向传播,下面我们将softmax层和损失函数一起作为对象来分析它们的反向传播的计算图。在这之前,我们以手写数字识别为例,回顾神经网络的推理过程。示意图如图21所示。

    图21 手写数字识别信号传递过程

    图21中,softmax层将输入值正规化(输出值的和调整为1)之后再输出,此外,手写数字识别要进行10类分类,所以向softmax层的输入也有10个。输入图像为“0”,得分为10.1分,经softmax层转换为0.991。

    一般情况下,我们会把softmax层和损失函数一起考虑,由于softmax-with-loss层比较复杂,这里我们直接给出其正向和反向传播的简易计算图如图22所示。具体的分析过程后面我们会专门花一个专题来讲。

    图22 简易版的softmax-with-loss层的计算图

    这里我们重点关注反向传播的结果。softmax层的反向传播得到了(y_{1}-t_{1},y_{2}-t_{2},y_{3}-t_{3})这样漂亮的结果。由于(y_{1},y_{2},y_{3})是softmax层的输出,\left (t_{1},t_{2},t_{3} \right )是监督数据,所以(y_{1}-t_{1},y_{2}-t_{2},y_{3}-t_{3})是softmax层的输出和监督标签的差分。神经网络的反向传播会把这个差分表示的误差传递给前面的层,这是神经网络学习中的重要性质。

    神经网络的学习的目的就是通过调整权重参数,使神经网络的输出(softmax层的输出)接近监督标签。因此,必须将神经网络的输出与监督标签的误差高效地传递给前面的层。前面的(y_{1}-t_{1},y_{2}-t_{2},y_{3}-t_{3})直截了当地表示了当前神经网络的输出与监督标签的误差。比如监督标签(0,1,0),softmax层的输出是(0.3,0.2,0.5)。由于正确解标签处的概率是20%,这时候神经网络未能进行正确的识别。此时,softmax层的反向传播传递的是(0.3,-0.8,0.5)这样一个大的误差。这个大的误差会向前面的层传播,所以softmax层前面的层会从这个大的误差中学习到“大”的内容。

    使用交叉熵误差作为softmax函数的损失函数后,反向传播得到(y_{1}-t_{1},y_{2}-t_{2},y_{3}-t_{3})这样漂亮的结果。实际上,这样的结果并不是偶然的,而是为了得到这样的结果,特意设计了交叉熵误差函数。

    误差反向传播法的Python实现

    乘法层的Python实现

    这里我们把乘法节点的计算图用“乘法层”(MulLayer),在Python中用类表示,类中有两个方法(函数),正向传播forward(),和反向传播backward()。代码如下:

    # coding: utf-8
    
    
    class MulLayer:
        def __init__(self):
            self.x = None
            self.y = None
    
        def forward(self, x, y):
            self.x = x
            self.y = y                
            out = x * y
    
            return out
    
        def backward(self, dout):
            dx = dout * self.y     #翻转x和y
            dy = dout * self.x
    
            return dx, dy

    代码中,__init__()会初始化实例变量x和y,它们主要用来保存正向传播时的输入值。forward()接收x和y两个参数,将它们相乘后输出。backward()将从上游传来的导数dout乘以正向传播的翻转值,然后传给下游。

    加法层的Python实现

    # coding: utf-8
    
    
    
    class AddLayer:
        def __init__(self):
            pass
    
        def forward(self, x, y):
            out = x + y
    
            return out
    
        def backward(self, dout):
            dx = dout * 1
            dy = dout * 1
    
            return dx, dy
    

    由于加法节点的反向传播不需要输入值,所以__init()__中无特意执行语句。forward()接收x和y,将它们相加后输出。backword()将上游传来的导数dout原封不动地传递给下游。

    购买水果问题的Python实现

    # coding: utf-8
    
    apple = 100
    apple_num = 2
    orange = 150
    orange_num = 3
    tax = 1.1
    
    # layer
    mul_apple_layer = MulLayer()
    mul_orange_layer = MulLayer()
    add_apple_orange_layer = AddLayer()
    mul_tax_layer = MulLayer()
    
    # forward
    apple_price = mul_apple_layer.forward(apple, apple_num)  # (1)
    orange_price = mul_orange_layer.forward(orange, orange_num)  # (2)
    all_price = add_apple_orange_layer.forward(apple_price, orange_price)  # (3)
    price = mul_tax_layer.forward(all_price, tax)  # (4)
    
    # backward
    dprice = 1
    dall_price, dtax = mul_tax_layer.backward(dprice)  # (4)
    dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price)  # (3)
    dorange, dorange_num = mul_orange_layer.backward(dorange_price)  # (2)
    dapple, dapple_num = mul_apple_layer.backward(dapple_price)  # (1)
    
    print("price:", int(price))  #715
    print("dApple:", dapple)     #2.2
    print("dApple_num:", int(dapple_num))  #110
    print("dOrange:", dorange)             #3.3
    print("dOrange_num:", int(dorange_num)) #165
    print("dTax:", dtax)                    #650
    

    激活函数层的Python实现

    ReLU层的Python实现

    # coding: utf-8
    
    
    class Relu:
        def __init__(self):
            self.mask = None
    
        def forward(self, x):
            self.mask = (x <= 0)
            out = x.copy()
            out[self.mask] = 0
    
            return out
    
        def backward(self, dout):
            dout[self.mask] = 0
            dx = dout
    
            return dx

    需要提醒大家的是,神经网络的层的实现中,一般假定forward()和backward()的参数是numPy数组。代码中变量mask是由true/false构成的NumPy数组,它会正向传播时的输入x的元素中小于等于0的地方保存为true,大于0的地方保存为false。

    sigmoid层的Python实现

    class Sigmoid:
        def __init__(self):
            self.out = None
    
        def forward(self, x):
            out = sigmoid(x)
            self.out = out
            return out
    
        def backward(self, dout):
            dx = dout * (1.0 - self.out) * self.out
    
            return dx

    正向传播时将输出保存到了变量out中,反向传播时,使用该变量out进行计算。

    Affine层的Python实现

    class Affine:
        def __init__(self, W, b):
            self.W =W
            self.b = b
            
            self.x = None
            self.original_x_shape = None
            # 权重和偏置参数的导数
            self.dW = None
            self.db = None
    
        def forward(self, x):
            # 对应张量
            self.original_x_shape = x.shape
            x = x.reshape(x.shape[0], -1)
            self.x = x
    
            out = np.dot(self.x, self.W) + self.b
    
            return out
    
        def backward(self, dout):
            dx = np.dot(dout, self.W.T)
            self.dW = np.dot(self.x.T, dout)
            self.db = np.sum(dout, axis=0)
            
            dx = dx.reshape(*self.original_x_shape)  # 还原输入数据的形状(对应张量)
            return dx

    需要注意的是,Affine的实现考虑了输入数据为张量(四维数据)的情况。

    softmax-with-loss层的Python实现

    # coding: utf-8
    import numpy as np 
    
    def softmax(x):
        if x.ndim == 2:
            x = x.T
            x = x - np.max(x, axis=0)
            y = np.exp(x) / np.sum(np.exp(x), axis=0)
            return y.T 
    
        x = x - np.max(x) # 溢出对策
        return np.exp(x) / np.sum(np.exp(x))
    
    def cross_entropy_error(y, t):
        if y.ndim == 1:
            t = t.reshape(1, t.size)
            y = y.reshape(1, y.size)
            
        # 监督数据是one-hot-vector的情况下,转换为正确解标签的索引
        if t.size == y.size:
            t = t.argmax(axis=1)
                 
        batch_size = y.shape[0]
        return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size
    
    
    class SoftmaxWithLoss:
        def __init__(self):
            self.loss = None
            self.y = None # softmax的输出
            self.t = None # 监督数据
    
        def forward(self, x, t):
            self.t = t
            self.y = softmax(x)
            self.loss = cross_entropy_error(self.y, self.t)
            
            return self.loss
    
        def backward(self, dout=1):
            batch_size = self.t.shape[0]
            if self.t.size == self.y.size: # 监督数据是one-hot-vector的情况
                dx = (self.y - self.t) / batch_size
            else:
                dx = self.y.copy()
                dx[np.arange(batch_size), self.t] -= 1
                dx = dx / batch_size
            
            return dx
    

    误差反向传播法的Python总体实现

    神经网络中有合适的权重和偏置,调整权重和偏置以便拟合训练数据的过程称为学习。神经网络的学习一般分为以下四个步骤:

    (1)从训练数据中随机选择一部分数据

    (2)计算损失函数关于各个权重参数的梯度(采用误差反向传播法)

    (3)将权重参数沿梯度方向进行微小的更新

    (4) 重复步骤1至步骤3

    下面的代码完成了2层神经网络的实现 

    # coding: utf-8
    import numpy as np
    from collections import OrderedDict
    # coding: utf-8
    import numpy as np
    
    #这里被调用的部分函数可在之前的专题中查找
    
    
    
    
    def numerical_gradient(f, x):
        h = 1e-4 # 0.0001
        grad = np.zeros_like(x)
        
        it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
        while not it.finished:
            idx = it.multi_index
            tmp_val = x[idx]
            x[idx] = float(tmp_val) + h
            fxh1 = f(x) # f(x+h)
            
            x[idx] = tmp_val - h 
            fxh2 = f(x) # f(x-h)
            grad[idx] = (fxh1 - fxh2) / (2*h)
            
            x[idx] = tmp_val # 还原值
            it.iternext()   
            
        return grad
    
    
    class TwoLayerNet:
    
        def __init__(self, input_size, hidden_size, output_size, weight_init_std = 0.01):
            # 初始化权重
            self.params = {}
            self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
            self.params['b1'] = np.zeros(hidden_size)
            self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size) 
            self.params['b2'] = np.zeros(output_size)
    
            # 生成层
            self.layers = OrderedDict()
            self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
            self.layers['Relu1'] = Relu()
            self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
    
            self.lastLayer = SoftmaxWithLoss()
            
        def predict(self, x):
            for layer in self.layers.values():
                x = layer.forward(x)
            
            return x
            
        # x:输入数据, t:监督数据
        def loss(self, x, t):
            y = self.predict(x)
            return self.lastLayer.forward(y, t)
        
        def accuracy(self, x, t):
            y = self.predict(x)
            y = np.argmax(y, axis=1)
            if t.ndim != 1 : t = np.argmax(t, axis=1)
            
            accuracy = np.sum(y == t) / float(x.shape[0])
            return accuracy
            
        # x:输入数据, t:监督数据
        def numerical_gradient(self, x, t):
            loss_W = lambda W: self.loss(x, t)
            
            grads = {}
            grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
            grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
            grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
            grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
            
            return grads
            
        def gradient(self, x, t):
            # forward
            self.loss(x, t)
    
            # backward
            dout = 1
            dout = self.lastLayer.backward(dout)
            
            layers = list(self.layers.values())
            layers.reverse()
            for layer in layers:
                dout = layer.backward(dout)
    
            # 设定
            grads = {}
            grads['W1'], grads['b1'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
            grads['W2'], grads['b2'] = self.layers['Affine2'].dW, self.layers['Affine2'].db
    
            return grads
    

    代码中使用了OrderDict()函数,它是有序字典,即它可以记住向字典里添加元素的顺序。因此,神经网络的正向传播只需按照添加元素的顺序调用各层的forward()方法就可以完成处理,而反向传播只需要按照相反的顺序调用各层即可。

    我们构造了神经网络之后,就可以进行学习了,在前面的专题我们讲过神经网络的学习,其中介绍了用数值微分的方法求梯度,而这里我们则采用误差反向传播法求梯度。除此之外,程序几乎一样。神经网络的学习的Python实现如下:

    # 读入数据
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
    
    network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
    
    iters_num = 10000
    train_size = x_train.shape[0]
    batch_size = 100
    learning_rate = 0.1
    
    train_loss_list = []
    train_acc_list = []
    test_acc_list = []
    
    iter_per_epoch = max(train_size / batch_size, 1)
    
    for i in range(iters_num):
        batch_mask = np.random.choice(train_size, batch_size)
        x_batch = x_train[batch_mask]
        t_batch = t_train[batch_mask]
        
        # 梯度
        #grad = network.numerical_gradient(x_batch, t_batch)  #之前讲过的数值微分求梯度函数
        grad = network.gradient(x_batch, t_batch)            #误差反向传播法求梯度
        
        # 更新
        for key in ('W1', 'b1', 'W2', 'b2'):
            network.params[key] -= learning_rate * grad[key]
        
        loss = network.loss(x_batch, t_batch)
        train_loss_list.append(loss)
        
        if i % iter_per_epoch == 0:
            train_acc = network.accuracy(x_train, t_train)
            test_acc = network.accuracy(x_test, t_test)
            train_acc_list.append(train_acc)
            test_acc_list.append(test_acc)
            print(train_acc, test_acc)
    

    小结

     本章我们介绍了计算图,并使用计算图介绍了神经网络的误差反向传播法,并以层为单位实现了神经网络中的处理。通过将数据正向和反向地传播,可以高效地计算权重参数的梯度。

    欢迎关注微信公众号“Python生态智联”,学知识,享生活!

    展开全文
  • SGD(Stochastic Gradient Descent,随机梯度下降)和New-ton Method(牛顿迭代) 梯度下降,牛顿,高斯-牛顿迭代,附代码实现:https://blog.csdn.net/piaoxuezhong/article/details/60135153 梯度下...

    我一直以为两者是相同的。。。原来SGD是一阶梯度,而牛顿迭代法是二阶梯度。

    SGD(Stochastic Gradient Descent,随机梯度下降法)和New-ton Method(牛顿迭代法) 

    梯度下降法,牛顿法,高斯-牛顿迭代法,附代码实现:https://blog.csdn.net/piaoxuezhong/article/details/60135153

    梯度下降法与牛顿法的解释与对比:https://www.cnblogs.com/happylion/p/4172632.html

    梯度下降法、牛顿迭代法、共轭梯度法:https://wenku.baidu.com/view/81ba70fc915f804d2a16c149.html

    梯度下降和牛顿迭代:https://blog.csdn.net/qjzcy/article/details/51946304

    SGD(Stochastic Gradient Descent,随机梯度下降法)中随机一词是指的样本随机选取,没有特别含义。

    Stochastic gradient descent (often shortened to SGD), also known as incremental gradient descent, is a stochastic approximation of the gradient descent optimization and iterative method for minimizing an objective function that is written as a sum of differentiable functions. In other words, SGD tries to find minima or maxima by iteration.

    SGD,又称为增量梯度递减,是一种随机梯度下降优化逼近以及使目标函数最小的迭代方法,目标函数可写为差分函数之和。换句话说,SGD努力通过迭代寻找最小或最大。

    Both statistical estimation and machine learning consider the problem of minimizing an objective function that has the form of a sum:

    统计估计和机器学习都考虑最小化目标函数的问题:

    where the parameter w which minimizes Q(w) is to be estimated. Each summand function Qi is typically associated with the  i-th observation in the data set (used for training).

    其中使Q(w)最小的参数w是需要估计的。每一个相加的sum函数Qi一般与数据集中的第i个观测(用于训练的数据)相关。

    In classical statistics, sum-minimization problems arise in least squares and in maximum-likelihood estimation (for independent observations). The general class of estimators that arise as minimizers of sums are called M-estimators. However, in statistics, it has been long recognized that requiring even local minimization is too restrictive for some problems of maximum-likelihood estimation.[1] Therefore, contemporary statistical theorists often consider stationary points of the likelihood function (or zeros of its derivative, the score function, and other estimating equations).

    在典型的统计学中,总和最小问题出现在最小二乘和最大似然估计(独立观测)中。通常的一类作为总和最小的估计者叫M-估计者。然而,在统计学中,一直以来认识到哪怕是要求局部最小对于最大似然估计也太严格了。因此,当代统计理论者通常考虑似然函数的平稳点(或导数为零的点,得分函数,和其他的估计等式)。

    The sum-minimization problem also arises for empirical risk minimization. In this case,  Qi(w) is the value of the loss function at i-th example, and Q(w) is the empirical risk.

    这类总和最小问题也出现在最小风险估计中。在这种例子中,Qi(w)是损失函数在第i个例子的值,而Q(w)是最小风险。

    When used to minimize the above function, a standard (or "batch") gradient descent method would perform the following iterations :

    当用于最小化上式时,一个标准的(或“包”)梯度下降方法将如下面的迭代进行:

    (推导方法参加机器学习课程)

    where η is a step size (sometimes called the learning rate in machine learning).

    其中η是步长(有时在机器学习中称为学习率)。

    In many cases, the summand functions have a simple form that enables inexpensive evaluations of the sum-function and the sum gradient. For example, in statistics, one-parameter exponential families allow economical function-evaluations and gradient-evaluations.

    在很多情况下,被加函数有简单的形式,使不费时。

    However, in other cases, evaluating the sum-gradient may require expensive evaluations of the gradients from all summand functions. When the training set is enormous and no simple formulas exist, evaluating the sums of gradients becomes very expensive, because evaluating the gradient requires evaluating all the summand functions' gradients. To economize on the computational cost at every iteration, stochastic gradient descent samples a subset of summand functions at every step. This is very effective in the case of large-scale machine learning problems.

    Newton's method(牛顿迭代法)

    牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要。方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根。牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成超线性收敛。另外该方法广泛用于计算机编程中。

    设r是  的根,选取  作为r的初始近似值,过点  做曲线  的切线L,L的方程为  ,求出L与x轴交点的横坐标  ,称x1为r的一次近似值。过点 做曲线  的切线,并求该切线与x轴交点的横坐标  ,称  为r的二次近似值。重复以上过程,得r的近似值序列,其中,  称为r的  次近似值,上式称为牛顿迭代公式。

    用牛顿迭代法解非线性方程,是把非线性方程   线性化的一种近似方法。把   在点   的某邻域内展开成泰勒级数   ,取其线性部分(即泰勒展开的前两项),并令其等于0,即   ,以此作为非线性方程   的近似方程,若   ,则其解为   , 这样,得到牛顿迭代法的一个迭代关系式:   。
    已经证明,如果是连续的,并且待求的零点是孤立的,那么在零点周围存在一个区域,只要初始值位于这个邻近区域内,那么牛顿法必定收敛。 并且,如果不为0, 那么牛顿法将具有平方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。
    以上是关于求方程的根,那么求方程的参数呢?
    设方程为Q(w)
    那么怎么根据样本求w?Q(w,x)=y
    迭代法求方程参数就两步:(1)找到搜索方向;(2)迭代的步长。应该先采集样本并标上标签y吧。
    对泰勒公式上的导数再用一次泰勒公式则可以得到

    为什么非得用二次泰勒公式而不用第一次的泰勒公式近似法呢(牛顿迭代用于求近似和求最优以及与泰勒公式的关系)?(函数为Loss函数,求Loss最小)Loss=y-Estimate(w,x)

    方向一定要是使Loss最小的方向。也就是梯度方向,那么大小呢?步长。(梯度与导数的关系)

    那么梯度下降法跟牛顿迭代法有什么不同呢?

    梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。

    梯度:对于可微的数量场   ,以   为分量的向量场称为f的梯度或斜量。梯度下降法(gradient descent)是一个最优化算法,常用于机器学习和人工智能当中用来递归性地逼近最小偏差模型。
    顾名思义,梯度下降法的计算过程就是沿梯度下降的方向求解极小值(也可以沿梯度上升方向求解极大值)。
    其迭代公式为   ,其中   代表梯度负方向,   表示梯度方向上的搜索步长。梯度方向我们可以通过对函数求导得到,步长的确定比较麻烦,太大了的话可能会发散,太小收敛速度又太慢。一般确定步长的方法是由线性搜索算法来确定,即把下一个点的坐标看做是ak+1的函数,然后求满足f(ak+1)的最小值的 即可。
    因为一般情况下,梯度向量为0的话说明是到了一个极值点,此时梯度的幅值也为0.而采用梯度下降算法进行最优化求解时,算法迭代的终止条件是梯度向量的幅值接近0即可,可以设置个非常小的常数阈值。
    举一个非常简单的例子,如求函数   的最小值。
    利用梯度下降的方法解题步骤如下:
    1、求梯度, 
    2、向梯度相反的方向移动   ,如下
     ,其中,   为步长。如果步长足够小,则可以保证每一次迭代都在减小,但可能导致收敛太慢,如果步长太大,则不能保证每一次迭代都减少,也不能保证收敛。
    3、循环迭代步骤2,直到   的值变化到使得   在两次迭代之间的差值足够小,比如0.00000001,也就是说,直到两次迭代计算出来的   基本没有变化,则说明此时   已经达到局部最小值了。
    4、此时,输出   ,这个   就是使得函数   最小时的   的取值 。
    Matlab代码:
    %% 最速下降法图示
    % 设置步长为0.1,f_change为改变前后的y值变化,仅设置了一个退出条件。
    syms x;f=x^2;
    step=0.1;x=2;k=0;         %设置步长,初始值,迭代记录数
    f_change=x^2;             %初始化差值
    f_current=x^2;            %计算当前函数值
    ezplot(@(x,f)f-x.^2)       %画出函数图像
    axis([-2,2,-0.2,3])       %固定坐标轴
    hold on
    while f_change>0.000000001                %设置条件,两次计算的值之差小于某个数,跳出循环
        x=x-step*2*x;                         %-2*x为梯度反方向,step为步长,!最速下降法!
        f_change = f_current - x^2;           %计算两次函数值之差
        f_current = x^2 ;                     %重新计算当前的函数值
        plot(x,f_current,'ro','markersize',7) %标记当前的位置
        drawnow;pause(0.2);
        k=k+1;
    end
    hold off
    fprintf('在迭代%d次后找到函数最小值为%e,对应的x值为%e\n',k,x^2,x)
    

      综上所述,梯度下降法与牛顿迭代法都属于迭代法,但是梯度下降法是一阶偏导,而牛顿迭代法是二阶微分而且有Hessian矩阵。两者各有优缺点。

    转载于:https://www.cnblogs.com/2008nmj/p/8857873.html

    展开全文
  • 利用最小二乘法和梯度下降求解多元线性回归的参数,其中X、Y是待拟合的数据,X是自变量,Y是因变量。 2、解题思路 使用梯度下降来求解。损失函数为:1/2(y - f(x))^2,每进行一次迭代,先求出所有...

    1、题目描述

        利用最小二乘法和梯度下降法求解多元线性回归的参数,其中X、Y是待拟合的数据,X是自变量,Y是因变量。

        

        

    2、解题思路

        使用梯度下降法来求解。损失函数为:1/2(y - f(x))^2 ,每进行一次迭代,先求出所有样本点的平均损失,然后损失函数对各个权重求偏导得到关于每个权重的梯度值,接着使用学习率梯度值更新每个权重。这里的权重初始化不能为0,否则梯度不能更新。代码如下:

    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;
    
    void LinearRegression() {
    	/*
    		需要拟合的模型为:y = a + bx0 + cx1,其中(a,b,c)是要求的参数
    	*/
    	vector<vector<float>> X({ {1,1},{2,2},{1,3},{1,6} });
    	vector<float> Y({3.5,6.5,5.5,4.0});
    	float learning_rate = 0.01;                             //学习率
    	float a = 0.1, b = 0.1, c = 0.1;                        //权重初始值
    	unsigned int iterator = 100000;                         //迭代次数
    	for (int i = 0; i < iterator; i++) {
    		float gradient_a = 0;
    		float gradient_b = 0;
    		float gradient_c = 0;   
    		for (int j = 0; j < X.size(); j++) {
    			float x0 = X[j][0];
    			float x1 = X[j][1];
    			float y = Y[j];
    
    			//采用的是梯度下降法,需要对所有样本点的梯度求平均值
    			//这里的损失函数为1/2(y - f(x))^2,损失函数对各个参数分别求偏导得到梯度值			
    			gradient_a = gradient_a - (1.0 / X.size()) * (y - (a + b*x0 + c*x1));     
    			gradient_b = gradient_b - (1.0 / X.size()) * (y - (a + b*x0 + c*x1)) * x0;
    			gradient_c = gradient_c - (1.0 / X.size()) * (y - (a + b*x0 + c*x1)) * x1;
    		}		
                    //权重参数的更新
    		a = a - learning_rate * gradient_a;
    		b = b - learning_rate * gradient_b;
    		c = c - learning_rate * gradient_c;
    	}
            //保留两位小数
    	a = (int)(a * 100) / 100.0;
    	b = (int)(b * 100) / 100.0;
    	c = (int)(c * 100) / 100.0;
    	cout << "a:" << a << endl;
    	cout << "b:" << b << endl;
    	cout << "c:" << c << endl;
    }

        这里只是一个二元一次方程的回归,相当于三维空间中的一条直线,对于其更复杂的回归函数拟合的求解方法是类似的。

    展开全文
  • 左连 翠 济南大学 侯淑 轩 基础 部 摘要 对带参数的 线性方程组的解法进行了系统的研 讨 , 分类给出了具体的解 , 并对一类复 杂 的题目提供了简便的解题 。 关键词 线性方程 组 ; 增广矩 阵 ; 系数矩阵 ...
  • 整理了一些在LeetCode上做的回溯的题目
  • 摘 要:圆锥曲线中求参数范围的问题是一类很常见又很重要的问题,是历年高考中的重点题型.此类问题往往涉及化归转化,数形结合,函数与方程等思想方法.加强此类问题的教学有利于提升学生的综合解题能力,对培养...
  • 本文介绍了三种换元求不定积分的方法及案例,但具体解题时要分析被积函数的具体情况,选取尽可能简捷的代换,不要拘泥于特定的变量代换。
  • 结点电压总结

    千次阅读 2019-09-03 23:20:53
    支路电流、网孔电流、回路电流和结点电压对比 支路电流 网孔电流 回路电流 结点电压 支路电流 网孔电流 回路电流 ...
  • FIR滤波器窗口设计 知识点:各种窗函数的特性;窗口设计基本思路 海宁窗就是正弦窗 二.FIR滤波器频率采样设计 知识点:频率采样设计思路;digiscope设计方法 ...
  • %本程序的功能是用牛顿拉夫逊进行潮流计算n=input('请输入节点数:n=');nl=input('请输入支路数:nl=');isb=input('请输入平衡母线节点号:isb=');pr=input('请输入误差精度:pr=');B1=input('请输入由各支路参数形成...
  • 它的参数量要比 2 月份刚刚推出的、全球最大深度学习模型 Turing NLP 大上十倍,而且不仅可以更好地答题、翻译、写文章,还带有一些数学计算的能力。这样强大的深度学习,不禁让人产生一种错觉:真正的 AI 要来了吗...
  • python实现迭代解方程

    千次阅读 2021-01-12 00:15:47
    一元三次方程x^3-2x+1=0,给定误差0.0001,迭代求解。有3个实数解,其中一个是1。有最大迭代次数判断,以及判断迭代是否收敛的算法。牛顿迭代# -*- coding= utf-8 -*-# 一元三次方程x^3-2x+1=0,给定误差0.0001...
  • 点估计(矩估计和最大似然估计

    万次阅读 多人点赞 2018-07-05 23:23:31
    1、矩估计 做题步骤: 1)、E(x),求总体均值(一般含有未知参数) 2)、命E(x) = 样本均值/样本均量 离散型: 例:设总体X有以下分布律 其实θ为未知参数,从中取样本(X1,X2,...
  • 有限差分以Taylor级数展开等方法,把控制方程中的导数用网格节点上的函数值的差商代替进行离散,从而建立以网格节点上的值为未知数的代数。该方法是一种直接将问题变为代数问题的近似数值解法,数学概念直观,表达...
  • 有限体积及其网格简介

    万次阅读 多人点赞 2018-07-08 11:26:58
    有限体积及其网格简介有限体积使目前CFD领域广泛使用的离散化方法,其特点不仅表现在对控制方程的离散结果上,还表现在所使用的网格上。1.有限体积的基本思想有限体积(Finite Volume Method)又称为控制...
  • 拉格朗日乘数

    2021-07-22 17:24:10
    【百度百科】在数学最优问题中,拉格朗日乘数(以数学家约瑟夫·路易斯·拉格朗日命名)是一种寻找变量受一个或多个条件所限制的多元函数的极值的方法。这种方法将一个有n 个变量与k 个约束条件的最优化问题转换为...
  • 匿名用户1级2010-12-28 回答统计学中把总体的指标统称为参数。而由样本算得的相应的总体指标称为统计量。参数一般是确定但未知的,统计量是变化但可知的。统计量统计量是统计理论中用来对数据进行分析、检验的变量。...
  • 【分支限界】0-1背包问题系列3

    千次阅读 多人点赞 2019-08-05 12:02:28
    分支限界就是广度优先搜索,从活结点表中取出队首的活结点,一次性生成所有符合条件的孩子结点,把孩子结点加入活结点表,然后继续下一个结点的扩展,直至得到最优解或者是活结点表为空。 算法核心 跟...
  • ## 1. 问题描述 ##设有n个物体和一个背包,物体i的重量为wi价值为pi ,背包的载荷为M, 若将物体i(1<= i <=n)装入背包,则有价值为pi .... 队列式分支限界 ##可以通过画分支限界状态空间树的搜索图来理解具...
  • 微信答题红包小程序开发玩解析

    千次阅读 2018-01-24 10:57:55
    微信答题红包小程序是最新上线的,小伙伴们可以给自己的好友进行发红包,发红包的方式只需要小伙伴们使用微信就能发送,不知道怎么发红包的小伙伴们,就让小编给大家详细的讲讲吧。
  • 数值计算——追赶求解三对角方程组(附代码)

    万次阅读 多人点赞 2019-09-22 20:30:30
    追赶基础理论 追赶c++程序代码 程序运行结果 源码文件下载地址 追赶基础理论 在数值计算中,对三次样条曲线插值和用差分方法求解常微分方程边值问题时,通常会遇到Ax=d三对角形式的方程组: ...
  • 梯度下降的原理及例题计算

    千次阅读 2019-09-25 15:00:26
    参数选取的不同会影响到假设函数,在计算机中可以不断的猜测这个参数θ,我们通常会将参数的初始值设为0参数迭代的范围可以称为步长,在机器学习领域中有一个更专业的称呼叫学习率。显而易见,学习率的设置会直接...
  • 1. 这本书对Python的知识点的描述很详细,而且排版看的很舒服. 2. 几个例题:假装自己从零开始学,将一些有代表性、有意思的例题抽取出来. 3. 还有自己对一部分课后复习题,全部课后上机实践题的解题思路
  • 高斯消去是求解线性方程组常用的直接解法 高斯(Gauss)消去解方程组的基本思想是用矩阵的行初等变换将系数矩阵约化为上三角形矩阵,再进行回代求解。 设Ax=b,,若A的所有顺序主子式均不为零,则基本高斯...
  • 梯度下降(Gradient Descent)

    万次阅读 2016-07-06 15:50:12
    梯度下降(通常也称为最速下降)是一个一阶最优化算法。 要使用梯度下降找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正...
  • H20R1353和H20R1203参数

    千次阅读 2020-12-19 06:11:30
    展开全部 英飞凌 印记 : H20R1353 型号: IHW20N135R3 封装 : TO247-3 描述 : Reverse conducting IGBT with monolithic body diode Vce : 1350V Ic : 20A Vcesat : 1.6...同时“参数法 ”也是许许多多解题技巧的源泉。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,899
精华内容 5,159
关键字:

参数法解题