seo在中國aso優(yōu)化技術
寫在前面
一直不太理解梯度下降算法是什么意思,今天我們就解開它神秘的面紗
寫在中間
線性回歸方程
如果要求出一條直線,我們只需知道直線上的兩個不重合的點,就可以通過解方程組來求出直線
但是,如果我們選取的這兩個點不在直線上,而是存在誤差(暫且稱作觀測誤差),這樣求出的直線就會和原直線相差很大,我們應該怎樣做呢?首先肯定不能只通過兩個點,就武斷地求出這條直線。
我們通常盡可能多地使用分布在直線周圍的點,也可能不存在一條直線完美的穿過所有采樣點。那么,退而求其次,我們希望能找到一條比較“好”的位于采樣點中間的直線。那么怎么衡量“好”與“不好”呢?一個很自然的想法就是,求出當前模型的所有采樣點上的預測值𝑤𝑥(𝑖) + 𝑏與真實值𝑦(𝑖)之間的差的平方和作為總誤差 L \mathcal{L} L,然后搜索一組參數 w ? , b ? w^{*},b^{*} w?,b?使得 L \mathcal{L} L最小,對應的直線就是我們要尋找的最優(yōu)直線。
w ? , b ? = arg ? min ? w , b 1 n ∑ i = 1 n ( w x ( i ) + b ? y ( i ) ) 2 w^*,b^*=\arg\min_{w,b}\frac{1}{n}\sum_{i=1}^{n}\bigl(wx^{(i)}+b-y^{(i)}\bigr)^2 w?,b?=argminw,b?n1?∑i=1n?(wx(i)+b?y(i))2
最后再通過梯度下降法來不斷優(yōu)化參數 w ? , b ? w^{*},b^{*} w?,b?
有基礎的小伙伴們可能知道求誤差的方法其實就是均方誤差函數,不懂得可以看這篇文章補充養(yǎng)分《誤差函數》 ,我們這篇文章就側重梯度下降。
梯度下降
函數的梯度定義為函數對各個自變量的偏導數組成的向量。不會的話,翻翻高等數學下冊書。
舉個例子,對于曲面函數𝑧 = 𝑓(𝑥, 𝑦),函數對自變量𝑥的偏導數記為 ? z ? x \frac{\partial z}{\partial x} ?x?z?,函數對自變量𝑦的偏導數記為 ? z ? y \frac{\partial z}{\partial y} ?y?z?,則梯度?𝑓為向量 ( ? z ? x , ? z ? y ) ({\frac{\partial z}{\partial x}},{\frac{\partial z}{\partial y}}) (?x?z?,?y?z?),梯度的方向總是指向當前位置函數值增速最大的方向,函數曲面越陡峭,梯度的模也越大。
函數在各處的梯度方向?𝑓總是指向函數值增大的方向,那么梯度的反方向??𝑓應指向函數值減少的方向。利用這一性質,我們只需要按照下式來更新參數,,其中𝜂用來縮放梯度向量,一般設置為某較小的值,如 0.01、0.001 等。
x ′ = x ? η ? d y d x x'=x-\eta\cdot\frac{\mathrmvxwlu0yf4y}{\mathrmvxwlu0yf4x} x′=x?η?dxdy?
結合上面的回歸方程,我們就可對誤差函數求偏導,以循環(huán)的方式更新參數 w , b w,b w,b:
w ′ = w ? η ? L ? w b ′ = b ? η ? L ? b \begin{aligned}w'&=w-\eta\frac{\partial\mathcal{L}}{\partial w}\\\\b'&=b-\eta\frac{\partial\mathcal{L}}{\partial b}\end{aligned} w′b′?=w?η?w?L?=b?η?b?L??
函數實現(xiàn)
計算過程都需要包裹在 with tf.GradientTape() as tape
上下文中,使得前向計算時能夠保存計算圖信息,方便自動求導操作。通過tape.gradient()
函數求得網絡參數到梯度信息,結果保存在 grads 列表變量中。
GradientTape()函數
GradientTape(persistent=False, watch_accessed_variables=True)
-
persistent
: 布爾值,用來指定新創(chuàng)建的gradient
tape是否是可持續(xù)性的。默認是False,意味著只能夠調用一次GradientTape()函數,再次使用會報錯 -
watch_accessed_variables
:布爾值,表明GradientTape()函數是否會自動追蹤任何能被訓練的變量。默認是True。要是為False的話,意味著你需要手動去指定你想追蹤的那些變量。
tape.watch()函數
tape.watch()用于跟蹤指定類型的tensor變量。
- 由于GradientTape()默認只對
tf.Variable
類型的變量進行監(jiān)控。如果需要監(jiān)控的變量是tensor
類型,則需要tape.watch()
來監(jiān)控,否則輸出結果將是None
tape.gradient()函數
tape.gradient(target, source)
-
target
:求導的因變量 -
source
:求導的自變量
import tensorflow as tfw = tf.constant(1.)
x = tf.constant(2.)
y = x * wwith tf.GradientTape() as tape:tape.watch([w])y = x * wgrads = tape.gradient(y, [w])
print(grads)
寫在最后
👍🏻點贊,你的認可是我創(chuàng)作的動力!
?收藏,你的青睞是我努力的方向!
??評論,你的意見是我進步的財富!