ข้ามไปยังเนื้อหา
3/30บทที่ 3 จาก 30

ลงเขา: Gradient Descent และสองขั้นตอนที่ทุกคนมักข้าม

คำนวณเพดานที่แน่นอนของอัตราการเรียนรู้ แล้วดูการค้นหา brute-force 3,600 ทิศทางค้นพบ gradient เอง

ในหน้านี้

บทก่อนหน้าจบลงที่หุบเขา

ไม่ใช่หุบเขาเชิงเปรียบเทียบ แต่เป็นเส้นโค้งจริง ๆ: loss ที่พล็อตเทียบกับพารามิเตอร์ตัวเดียว ย่อตัวลงแล้วสูงกลับขึ้นมา และ loss ใต้นั้นไม่ได้ถูกเลือกเพราะมันเรียบร้อยสวยงาม — มันถูกอนุมานมาจากข้อความเกี่ยวกับ noise ในการวัด และ squared error ก็ออกมาอีกด้านหนึ่งในฐานะผลลัพธ์ ไม่ใช่ขนบธรรมเนียม

ดังนั้นเรามี landscape ที่มีจุดต่ำสุด และมีเหตุผลให้เชื่อว่าจุดต่ำสุดคือที่ที่ควรไป สิ่งที่เรายังไม่มีคือวิธีไปให้ถึง

บทนี้จะสร้างวิธีนั้น และมันคืออัลกอริทึมที่ใช้ฝึกทุกโมเดลในส่วนที่เหลือของคอร์สนี้ — ทุกโมเดลโดยไม่มีข้อยกเว้น ไปจนถึงโมเดลที่มีพารามิเตอร์หลายแสนล้านตัว มันเขียนได้ในราวยี่สิบบรรทัด ส่วนที่ยากสองอย่างไม่ได้อยู่ในยี่สิบบรรทัดนั้น และเป็นสองสิ่งที่คำอธิบายแทบทุกแห่งมักข้าม:

  • ทำไมต้องมีเครื่องหมายลบ การอัปเดตลบ gradient ออกไป ทุก tutorial เขียนแบบนี้ แต่มีน้อยมากที่บอกว่าทำไม gradient จึงเป็นทิศทางที่พา ขึ้น ซึ่งเป็นข้อเท็จจริงเดียวที่ทำให้เครื่องหมายลบไม่ใช่แค่การเชื่อตามศรัทธา
  • ก้าวใหญ่แค่ไหน “ใหญ่เกินไปจะ diverge เล็กเกินไปจะช้า” เป็นเรื่องจริงแต่ไร้ประโยชน์ มีตัวเลขที่แน่นอน คำนวณได้จาก loss และบทนี้จะคำนวณมันสองครั้ง — ครั้งหนึ่งสำหรับพาราโบลาของเล่น และอีกครั้งสำหรับข้อมูลจริง

การตั้งโจทย์ และทำไมคุณค้นหาเฉย ๆ ไม่ได้

ลิงก์ไปยังส่วน: การตั้งโจทย์ และทำไมคุณค้นหาเฉย ๆ ไม่ได้

ทบทวนใหม่เพื่อให้บทนี้ยืนได้ด้วยตัวเอง: ชิ้นส่วนทั้งแปดจากสายพานลำเลียงใน บทที่ 1 แต่ถามคำถามคนละแบบ ไม่ใช่ รับหรือปฏิเสธ — เรื่องนั้นจะกลับมาทีหลัง — แต่เป็น ทำนายน้ำหนักของชิ้นส่วนจากความกว้างของมัน

belt.pyPYTHON
import numpy as np

WIDTH  = np.array([18.0, 19.5, 20.2, 21.0, 24.0, 25.5, 23.0, 26.0])
WEIGHT = np.array([47.0, 52.0, 49.0, 55.0, 61.0, 66.0, 70.0, 58.0])

x = WIDTH  - WIDTH.mean()      # 22.15 mm
y = WEIGHT - WEIGHT.mean()     # 57.25 g

ค่าการวัดถูก centered ไว้แล้ว เหมือนในบทที่ 1 และด้วยเหตุผลที่จะกลับมาให้ผลตอบแทนก่อนจบบทนี้ โมเดลคือเส้นตรง y^=ax+b\hat{y} = a x + b และ loss คือ mean squared error ที่บทก่อนหน้าอนุมานไว้:

L(a,b)=1ni=1n(axi+byi)2L(a, b) = \frac{1}{n} \sum_{i=1}^{n} \left(a x_i + b - y_i\right)^2

พารามิเตอร์สองตัว ทำไมไม่ลองค่าจำนวนมากไปเลย? ลองทำจริง ๆ กัน — grid จาก a=0a = 0 ถึง 55 และ b=5b = -5 ถึง 55 โดยก้าวทีละ 0.010.01:

TEXT
grid 501 x 1001 = 501,501 evaluations in 3.67 s
  best found: a = 2.1000, b = -0.0000, L = 24.592450

ประเมินครึ่งล้านครั้งเพื่อปักหมุดตัวเลขสองตัวให้ได้สองตำแหน่งทศนิยม — และวินาทีนั้นเป็นเวลา wall clock บนเครื่องหนึ่ง ดังนั้นรันใหม่อาจอยู่ที่สามถึงหกวินาที; จำนวนการประเมินและค่าต่ำสุดคือส่วนที่ทำซ้ำได้ Gradient descent ตอนท้ายบทนี้ได้สี่ตำแหน่งทศนิยมใน แปดก้าว และได้คำตอบ float64 เต็มในสามสิบหกก้าว

แต่ความเร็วไม่ใช่ข้อโต้แย้ง และนี่คือจุดที่ตัดสินทั้งคอร์ส Grid search ใช้ต้นทุน kPk^P การประเมินสำหรับพารามิเตอร์ PP ตัว ที่แต่ละตัวมี kk ค่า ถ้ามีหนึ่งพันค่าต่อแกน:

โมเดลพารามิเตอร์การประเมินใน grid
เส้นตรงนี้210610^{6}
เครือข่าย XOR ใน บทที่ 59102710^{27}
เครือข่าย multilayer ขนาดเล็ก20,0001060,00010^{60{,}000}

แถวที่สามไม่ใช่จำนวนที่ใหญ่ แต่เป็นจำนวนที่ ไร้ความหมาย — มีอะตอมในเอกภพที่สังเกตได้ประมาณ 108010^{80} อะตอม Search ไม่ได้แค่ช้าลงเมื่อโมเดลโตขึ้น แต่มันหยุดมีตัวตน ทุกอย่างต่อจากนี้มีอยู่เพราะตารางนั้น

ตรึง b=0b = 0 ไว้ชั่วครู่ เพื่อให้เหลือพารามิเตอร์ตัวเดียวและเส้นโค้งเส้นเดียว ซึ่งเป็นภาพที่บทก่อนหน้าทิ้งไว้ให้คุณ หยิบจุดหนึ่งบนเส้นนั้น a=1a = 1 แล้วถามว่า: ถ้าฉันขยับ aa เล็กน้อยเป็นจำนวน hh loss จะขยับเท่าไรต่อหนึ่งหน่วยของการขยับ?

L(a+h)L(a)h\frac{L(a + h) - L(a)}{h}

อัตราส่วนนั้นคือ rise over run — ความชันของเส้นตรงที่ผ่านสองจุดบนเส้นโค้ง เมื่อ hh เล็กลง จุดสองจุดเลื่อนเข้าใกล้กัน และเส้นตรงกลายเป็นเส้นสัมผัส ความชันของมันคือ อนุพันธ์ L(a)L'(a): อัตราที่ loss เปลี่ยนต่อหนึ่งหน่วยการเปลี่ยนของ aa มันไม่ใช่การประมาณอะไรบางอย่าง และไม่ใช่ปริมาณที่เล็กอย่างไม่มีที่สิ้นสุด แต่เป็นลิมิตของอัตราส่วนธรรมดา

ควรรันดู เพราะตัวเลขบอกบางอย่างที่นิยามไม่ได้บอก:

slope.pyPYTHON
def loss1(a):
    return np.mean((a * x - y) ** 2)

for h in [1.0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14]:
    q = (loss1(1.0 + h) - loss1(1.0)) / h
    print(f"h = {h:<8.0e}   slope estimate = {q:.10f}   error = {abs(q + 16.385):.3e}")
TEXT
h = 1e+00      slope estimate = -8.9400000000    error = 7.445e+00
h = 1e-02      slope estimate = -16.3105500000   error = 7.445e-02
h = 1e-04      slope estimate = -16.3842555001   error = 7.445e-04
h = 1e-06      slope estimate = -16.3849925556   error = 7.444e-06
h = 1e-08      slope estimate = -16.3850003787   error = 3.787e-07
h = 1e-10      slope estimate = -16.3850444324   error = 4.443e-05
h = 1e-12      slope estimate = -16.3851154866   error = 1.155e-04
h = 1e-14      slope estimate = -17.0530256582   error = 6.680e-01

มีสองสิ่งเกิดขึ้นตรงนี้ และทั้งสองเป็นเสาหลักของเรื่อง

error ไม่ได้แค่แปรผันคร่าว ๆ กับ hh — แต่มันเท่ากับ 7.445h7.445\,h อย่างพอดี หาร hh ด้วยร้อย error ก็หารด้วยร้อย ทุกครั้งถึงสี่เลขนัยสำคัญ ค่าคงที่นั้นไม่ใช่ของตกแต่ง: มันคือครึ่งหนึ่งของอนุพันธ์ อันดับสอง ของ loss และเป็นการปรากฏครั้งแรกของแนวคิดที่จะมาในอีกสองส่วนข้างหน้า — ว่าเส้นโค้งใกล้จุดหนึ่งดูเหมือนเส้นตรงบวก correction ที่แปรผันกับ h2h^2

แล้ว pattern ก็พัง ต่ำกว่า h=108h = 10^{-8} ค่าประมาณกลับ แย่ลง และที่ 101410^{-14} มันผิดตั้งแต่หลักที่สอง ไม่มีอะไรทางคณิตศาสตร์เกิดขึ้น; กล่อง floating-point จากบทก่อนหน้าต่างหากที่เกิดขึ้น L(a+h)L(a+h) และ L(a)L(a) ตรงกันในสิบหลักแรก การลบมันทำลายหลักเหล่านั้น แล้วการหารซากที่เหลือด้วยจำนวน tiny ก็ขยายสิ่งที่เหลืออยู่ มี hh ที่ดีที่สุด — ที่นี่ราว 10810^{-8} ประมาณรากที่สองของ machine epsilon — และการทำให้เล็กลงไม่ใช่ระมัดระวังขึ้น แต่ระมัดระวังน้อยลง จำเรื่องนี้ไว้; ฟังก์ชันตอนท้ายบทนี้ต้องพึ่งมัน

ความชันที่แน่นอน จากแคลคูลัสแทนการวัด คือ 16.385-16.385 ดังนั้นเราหยุดวัดแล้วเริ่มอนุมานได้

นี่คือแนวคิดที่ส่วนที่เหลือของคอร์สสร้างอยู่บนนั้น กล่าวครั้งเดียวอย่างตรงไปตรงมา

การ ประกอบ ฟังก์ชันสองตัวคือการป้อนตัวหนึ่งเข้าไปในอีกตัวหนึ่ง: (fg)(x)=f(g(x))(f \circ g)(x) = f(g(x)) แค่นั้น

เครือข่าย deep network ไม่ได้ เหมือน การประกอบ แต่มัน คือ การประกอบ layer คือฟังก์ชัน; การวาง layer ซ้อนกันคือการประกอบมัน; “ความลึก” คือจำนวนฟังก์ชันใน chain เมื่อบทที่ 5 สร้างเครือข่าย มันกำลังสร้าง f4f3f2f1f_4 \circ f_3 \circ f_2 \circ f_1 และไม่มีอะไรมากกว่านั้น ซึ่งแปลว่ากฎแคลคูลัสที่สำคัญที่สุดข้อเดียวสำหรับจุดประสงค์ของเรา คือกฎที่หาอนุพันธ์ของการประกอบ:

ddxf(g(x))=f(g(x))g(x)\frac{d}{dx} f(g(x)) = f'(g(x)) \cdot g'(x)

อัตราจะคูณกัน ถ้า gg เปลี่ยนเร็วกว่า xx สามเท่า และ ff เปลี่ยนเร็วกว่า gg สองเท่า แล้ว ff จะเปลี่ยนเร็วกว่า xx หกเท่า นี่คือเนื้อหาทั้งหมด และเป็นเหตุผลว่าทำไมสัญญาณที่ส่งย้อนผ่านสิบ layer จึงถูกคูณด้วยตัวเลขสิบตัว — ซึ่งเป็นเหตุผลที่ บทที่ 6 ใช้หนึ่งส่วนพูดถึงสิ่งที่เกิดขึ้นเมื่อเลขเหล่านั้นทั้งหมดน้อยกว่าหนึ่งเล็กน้อย

ใช้มันกับ loss ของเรา เขียน residual เป็น ri=axi+byir_i = a x_i + b - y_i เพื่อให้ L=1nri2L = \frac{1}{n}\sum r_i^2 แต่ละ rir_i ขึ้นกับ aa ผ่านฟังก์ชันด้านใน axia x_i ซึ่งมีอนุพันธ์ xix_i ใช้ chain rule ทีละเทอม:

La=1ni2rixi,Lb=1ni2ri1\frac{\partial L}{\partial a} = \frac{1}{n}\sum_i 2 r_i \cdot x_i, \qquad \frac{\partial L}{\partial b} = \frac{1}{n}\sum_i 2 r_i \cdot 1

สัญลักษณ์โค้ง \partial เหล่านั้นหมายถึง อนุพันธ์ย่อย: หาอนุพันธ์เทียบกับตัวแปรหนึ่ง และถือว่าตัวอื่นทั้งหมดเป็นค่าคงที่ ไม่มีอะไรใหม่เกิดขึ้น — มันคือลิมิตเดิม เพียงแต่ทำตามแกนหนึ่ง รวบรวมอนุพันธ์ย่อยเป็นเวกเตอร์ แล้วคุณได้ gradient:

L=(La, Lb)\nabla L = \left( \frac{\partial L}{\partial a},\ \frac{\partial L}{\partial b} \right)

ที่จุด (a,b)=(1,4)(a, b) = (1, 4) เวกเตอร์นั้นคือ (16.385, 8.0)(-16.385,\ 8.0) ตัวเลขสองตัว คำถามคือมันหมายความว่าอะไร และนี่คือขั้นตอนแรกที่ทุกคนข้าม

gradient คือเวกเตอร์ของความชัน ตามแกน เท่านั้น นั่นคือทั้งหมดที่เราพิสูจน์ไปแล้ว มันไม่ชัดเจน — และไม่ควรชัดเจน — ว่าการเอามันมาประกอบเป็นเวกเตอร์จะให้สิ่งที่ชี้ไปทางใดทางหนึ่งโดยเฉพาะ

ดังนั้นนิยามสิ่งที่เราต้องการจริง ๆ เลือกเวกเตอร์หน่วย u\mathbf{u} ซึ่งเป็นทิศทางหนึ่ง directional derivative คืออัตราที่ loss เปลี่ยนเมื่อคุณเดินไปทางนั้น:

DuL=limh0L(θ+hu)L(θ)hD_{\mathbf{u}} L = \lim_{h \to 0} \frac{L(\boldsymbol{\theta} + h\mathbf{u}) - L(\boldsymbol{\theta})}{h}

chain rule ทำให้สิ่งนี้คำนวณได้ การเดินตาม u\mathbf{u} เปลี่ยน aa ด้วยอัตรา u1u_1 และเปลี่ยน bb ด้วยอัตรา u2u_2 แล้วผลสนับสนุนเหล่านี้บวกกัน:

DuL=Lau1+Lbu2=LuD_{\mathbf{u}} L = \frac{\partial L}{\partial a} u_1 + \frac{\partial L}{\partial b} u_2 = \nabla L \cdot \mathbf{u}

อัตราการเปลี่ยนใน ทุก ทิศทางคือ dot product ของ gradient กับทิศทางนั้น และตอนนี้คือ punchline ซึ่งเป็นเรขาคณิตเพียงบรรทัดเดียว เขียน dot product ด้วยมุม ϕ\phi ระหว่างเวกเตอร์:

Lu=Lucosϕ=Lcosϕ\nabla L \cdot \mathbf{u} = \lVert \nabla L \rVert \, \lVert \mathbf{u} \rVert \cos\phi = \lVert \nabla L \rVert \cos\phi

เพราะ u\mathbf{u} มีความยาว 1 สิ่งเดียวที่คุณควบคุมคือ cosϕ\cos\phi ซึ่งมากที่สุดที่ ϕ=0\phi = 0 และน้อยที่สุดเมื่อหมุนครึ่งรอบ ϕ=180\phi = 180 องศา ดังนั้น:

  • ขึ้นชันที่สุด คือไปตาม L\nabla L เอง และความชันตรงนั้นคือ L\lVert \nabla L \rVert พอดี
  • ลงชันที่สุด คือไปตาม L-\nabla L และความชันตรงนั้นคือ L-\lVert \nabla L \rVert
  • ตั้งฉากกับ gradient, loss ไม่เปลี่ยนเลย นั่นคือเหตุผลที่เส้นบน contour map ตัดกับ gradient เป็นมุมฉาก

นั่นคือเครื่องหมายลบ ไม่ใช่ขนบ ไม่ใช่การกลับเครื่องหมายที่ใครบางคนเลือก: ทิศทางที่ลดลงเร็วที่สุดคือ negative gradient เพราะ cosϕ\cos\phi มีค่าน้อยที่สุดเมื่อหมุนครึ่งรอบ และไม่มีเหตุผลอื่น

เพราะนี่เป็นข้อกล่าวอ้างเกี่ยวกับทุกทิศทาง จึงทดสอบกับทุกทิศทาง ลองสุ่ม 3,600 ทิศทาง หนึ่งทิศต่อหนึ่งในสิบองศา แล้ววัดแต่ละทิศด้วยการขยับเล็กน้อย:

directions.pyPYTHON
theta = np.array([1.0, 4.0])
g = grad(theta)
print("gradient      ", g)
print("its length    ", np.linalg.norm(g))
print("its angle     ", np.degrees(np.arctan2(g[1], g[0])) % 360, "degrees")

best = max(
    ((loss(theta + 1e-6 * u) - loss(theta - 1e-6 * u)) / 2e-6, np.degrees(ang))
    for ang, u in (
        (a, np.array([np.cos(a), np.sin(a)])) for a in np.arange(3600) * 2 * np.pi / 3600
    )
)
print("steepest slope", best[0], "at", best[1], "degrees")
TEXT
gradient       [-16.385   8.   ]
its length     18.23371122399386
its angle      153.97598928042032 degrees
steepest slope 18.233709624837502 at 154.0 degrees

การค้นหาที่ไม่รู้อะไรเกี่ยวกับ gradient เลย เหนือ 3,600 ทิศทาง พบการไต่ที่ชันที่สุดที่ 154.0 องศา — ซึ่งเป็นทิศของ gradient เอง ภายในความละเอียด 0.1 องศาของการค้นหา และความชันที่มันพบตรงนั้น 18.2337 คือความยาวของ gradient ถึงหกหลัก ทฤษฎีบทนี้ไม่ใช่เรื่องเล่าเกี่ยวกับความหมายของ gradient; มันเป็นข้อเท็จจริงที่วัดได้ และนั่นคือการวัด

ตอนนี้คือขั้นตอนที่สองที่ถูกข้าม เรารู้แล้วว่าทางไหนลง แต่ไม่ได้แปลว่าการเดินไปทางนั้นจะลด loss เพราะ “ลง” เป็นข้อความเกี่ยวกับการขยับเล็กอย่างอนันต์ ส่วนก้าวไม่ใช่อนันต์เล็ก

สะพานเชื่อมคือ linearisation ใกล้จุดหนึ่ง ฟังก์ชันที่ smooth คือเส้นสัมผัสของมันบวก correction:

L(θ+δ)=L(θ)+Lδ+O(δ2)L(\boldsymbol{\theta} + \boldsymbol{\delta}) = L(\boldsymbol{\theta}) + \nabla L \cdot \boldsymbol{\delta} + O(\lVert\boldsymbol{\delta}\rVert^2)

นั่นคือ Taylor expansion อันดับหนึ่ง เทอม O(δ2)O(\lVert\boldsymbol{\delta}\rVert^2) ที่ทิ้งไปคือ curvature — เทอมเดียวกับที่ทำให้ค่าประมาณในตารางความชันผิดไปพอดี 7.445h7.445\,h ใส่ก้าวที่เราตั้งใจจะเดิน δ=ηL\boldsymbol{\delta} = -\eta \nabla L เข้าไป:

L(θηL)L(θ)ηL2L(\boldsymbol{\theta} - \eta \nabla L) \approx L(\boldsymbol{\theta}) - \eta \lVert \nabla L \rVert^2

loss ลดลง ηL2\eta \lVert \nabla L \rVert^2 ทุกส่วนของสิ่งนั้นไม่เป็นลบ ดังนั้นคำสัญญานี้เป็นจริง — สำหรับ η\eta ที่เล็กพอ เพราะเทอมที่ละเลยโตแบบ η2\eta^2 และท้ายที่สุดจะกินมันหมด นั่นคือทฤษฎีทั้งหมด นี่คือคำสัญญาที่ถูกรักษาไว้ แล้วจากนั้นก็ถูกทำลาย:

TEXT
eta = 0.2       promised    66.49364500   delivered   -16.01619240   ratio -0.240868
eta = 0.1       promised    33.24682250   delivered    12.61936315   ratio  0.379566
eta = 0.01      promised     3.32468225   delivered     3.11840766   ratio  0.937957
eta = 0.001     promised     0.33246822   delivered     0.33040548   ratio  0.993796
eta = 0.0001    promised     0.03324682   delivered     0.03322620   ratio  0.999380
eta = 1e-05     promised     0.00332468   delivered     0.00332448   ratio  0.999938

อ่านจากล่างขึ้นบน เมื่อ η\eta เล็กลง drop ที่ได้จริงลู่เข้าหา drop ที่สัญญาไว้ — ratio 0.99938 แล้ว 0.99994 — ซึ่งคือ Taylor theorem ที่ถูกต้อง อ่านจากบนลงล่าง และที่ η=0.2\eta = 0.2 “drop” ที่ได้จริงคือ ติดลบสิบหก ก้าวนั้นเดินลงเขา แต่ loss กลับเพิ่มขึ้น

ดังนั้นกฎการอัปเดตคือ

θθηL(θ)\boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \nabla L(\boldsymbol{\theta})

และมันมาพร้อมเงื่อนไขที่ไม่มีใครบอก คือ η\eta ต้องเล็กพอ เล็กพอเมื่อเทียบกับ อะไร กันแน่ คือส่วนถัดไป

เริ่มจากหุบเขาที่ง่ายที่สุด f(x)=x2f(x) = x^2 โดยที่ f(x)=2xf'(x) = 2x หนึ่งก้าวของ gradient descent คือ

xxη2x=x(12η)x \leftarrow x - \eta \cdot 2x = x\,(1 - 2\eta)

ตำแหน่งถูกคูณด้วย (12η)(1 - 2\eta) ในทุกก้าว นั่นคือ geometric sequence และ geometric sequence มีกฎเดียวอย่างแน่ชัด: มันหดเมื่อตัวคูณมีค่าสัมบูรณ์น้อยกว่า 1 และโตในกรณีอื่น ดังนั้น 12η<1\lvert 1 - 2\eta \rvert < 1 ซึ่งคือ 0<η<10 < \eta < 1

ขอบเขตอยู่ที่ η=1\eta = 1 พอดี ไม่ใช่ “ประมาณ 1” ไม่ใช่ “1 มักใหญ่เกินไป” ที่ η=1\eta = 1 ตัวคูณคือ 1-1 และจุดจะเด้งไปมาระหว่าง xx กับ x-x ตลอดกาล ไม่เข้าใกล้และไม่หนีออกไป ต่ำกว่านั้น converge; สูงกว่านั้น diverge ช่วงยังแยกอีกครั้งที่ η=0.5\eta = 0.5 ซึ่งตัวคูณเปลี่ยนเครื่องหมาย: ต่ำกว่านั้นการเข้าใกล้เป็น monotone สูงกว่านั้นจุดจะ overshoot และสลับข้าง และที่ 0.50.5 พอดี ตัวคูณเป็น 0 และก้าวเดียวก็ลงถึงค่าต่ำสุด

สี่ regime จากพีชคณิตสี่บรรทัด ลองข้ามขอบเขตด้วยตัวเอง:

14 ขั้นตอน สิ้นสุดที่ x = -0.0836.

ดูข้อมูลในรูปแบบตาราง
ขั้นตอนxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨-1.5200⁩⁨2.3104⁩
2⁨-1.2160⁩⁨1.4787⁩
3⁨-0.9728⁩⁨0.9463⁩
4⁨-0.7782⁩⁨0.6057⁩
5⁨-0.6226⁩⁨0.3876⁩
6⁨-0.4981⁩⁨0.2481⁩
7⁨-0.3985⁩⁨0.1588⁩
8⁨-0.3188⁩⁨0.1016⁩
9⁨-0.2550⁩⁨0.0650⁩
10⁨-0.2040⁩⁨0.0416⁩
11⁨-0.1632⁩⁨0.0266⁩
12⁨-0.1306⁩⁨0.0170⁩
13⁨-0.1045⁩⁨0.0109⁩
14⁨-0.0836⁩⁨0.0070⁩
Gradient descent แบบโต้ตอบ

สิบสี่ก้าวที่ rate 0.1 จาก x=1.9x = -1.9 จบที่ 0.0836-0.0836 ดัน rate เป็น 0.5 แล้วก้าวแรกก็ลงถึงก้นหุบเขา ดันเป็น 0.9 แล้วจบที่ 0.0836-0.0836 เดียวกับ 0.1 — ระยะเท่ากัน สไตล์ตรงข้าม เพราะ 12η\lvert 1 - 2\eta \rvert เป็น 0.8 สำหรับทั้งคู่ — แต่มันไปถึงโดย zig-zag ข้ามหุบเขา แทนที่จะเดินลงด้านหนึ่ง

และตอนนี้คือตัวที่น่าสนใจ:

14 ขั้นตอน สิ้นสุดที่ x = -1.9000.

ดูข้อมูลในรูปแบบตาราง
ขั้นตอนxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨1.9000⁩⁨3.6100⁩
2⁨-1.9000⁩⁨3.6100⁩
3⁨1.9000⁩⁨3.6100⁩
4⁨-1.9000⁩⁨3.6100⁩
5⁨1.9000⁩⁨3.6100⁩
6⁨-1.9000⁩⁨3.6100⁩
7⁨1.9000⁩⁨3.6100⁩
8⁨-1.9000⁩⁨3.6100⁩
9⁨1.9000⁩⁨3.6100⁩
10⁨-1.9000⁩⁨3.6100⁩
11⁨1.9000⁩⁨3.6100⁩
12⁨-1.9000⁩⁨3.6100⁩
13⁨1.9000⁩⁨3.6100⁩
14⁨-1.9000⁩⁨3.6100⁩
Gradient descent แบบโต้ตอบ

อยู่บนขอบเขตพอดี สิบสี่ก้าวที่ rate 1 และจบที่ 1.9-1.9: ตรงจุดที่เริ่ม โดยไม่ได้ทำอะไรนอกจากเด้งไปมา ขยับสูงขึ้นนิดเดียว การเด้งจะโตแทนที่จะคงอยู่; ที่ 1.2 มันหลุดกราฟในสี่ก้าว rate ที่ใหญ่เกินไปไม่ได้ converge ช้า ๆ แต่มันไม่ converge เลย

ตอนนี้คือกฎทั่วไป ซึ่งหล่นออกมาจากข้อโต้แย้งเดียวกัน ตัวคูณ 12η1 - 2\eta แท้จริงแล้วคือ 1ηf1 - \eta f'' และใกล้ minimum loss ที่มีหลายพารามิเตอร์มีตัวเลขแบบนี้หนึ่งตัวต่อทิศทาง — eigenvalues ของเมทริกซ์อนุพันธ์อันดับสอง ทุกทิศทางต้อง stable พร้อมกัน ดังนั้นเพดานจึงถูกกำหนดโดยค่าที่ใหญ่ที่สุด:

η<2λmax\eta < \frac{2}{\lambda_{\max}}

สำหรับ f(x)=x2f(x) = x^2, f=2f'' = 2, เพดาน 1 ซึ่งคือสิ่งที่เราเพิ่งอนุมาน สำหรับสายพานของเรา เมทริกซ์อนุพันธ์อันดับสองคือ 2nAA\frac{2}{n} A^{\top} A โดยมี AA เป็นเมทริกซ์ input สองคอลัมน์ และ eigenvalues คือ 2 และ 14.89 ดังนั้นเพดานคือ 2/14.89=0.134322 / 14.89 = 0.13432 นั่นคือการทำนายที่มีห้าเลขนัยสำคัญ ทดสอบมัน:

TEXT
lr=0.1343    -> L =      24.5924
lr=0.13431   -> L =      24.5924
lr=0.13432   -> L =       4707.8       BLEW UP
lr=0.13433   -> L =  4.00452e+16       BLEW UP
lr=0.1344    -> L = 1.18229e+107       BLEW UP

ตรงกันห้าตำแหน่งทศนิยมระหว่าง linear algebra หนึ่งบรรทัดกับการวน for loop หนึ่งแสนครั้ง

และนี่คือจุดที่บทที่ 1 กลับมา ทุกอย่างข้างต้นใช้ค่าการวัดที่ centered รัน code เดียวกันบนมิลลิเมตรและกรัมดิบ แล้ว eigenvalues คือ 0.0298 และ 998.1 แทนที่จะเป็น 2 และ 14.89 เพดานยุบจาก 0.134 เป็น 0.002004 — แน่นอนพอ ๆ กัน converge ที่ lr=0.002003 และ blow up ที่ lr=0.002004

แย่กว่าเพดานคืออัตราส่วนระหว่าง eigenvalues condition number วัดว่าหุบเขาห่างจากความกลมแค่ไหน: ร่องยาวแคบบังคับให้ rate เล็กพอสำหรับผนังชัน แล้วพื้นร่องก็ต้องถูกเดินด้วยความคลานเดียวกัน ของเราเปลี่ยนจาก 7.44 เมื่อ centered เป็น 33,452 เมื่อ raw ด้วย rate ที่ดีที่สุดที่แต่ละเวอร์ชันรับได้:

featurescondition numberrate ที่ดีที่สุดจำนวนก้าวจนอยู่ใน 1% ของ optimum
centered7.440.118410
มิลลิเมตรและกรัมดิบ33,4520.002003779,513

ข้อมูลเดียวกัน code เดียวกัน คำตอบสุดท้ายเดียวกัน — และงานมากกว่าแปดพันเท่า เพราะไม่มีใครลบค่าเฉลี่ย ในบทที่ 1 การละเลยแบบเดียวกันทำให้ perceptron เสีย epoch มากขึ้นหกพันเท่า และการวินิจฉัยตอนนั้นเป็นเชิงเรขาคณิต: ข้อมูลลอยไกลจาก origin นี่คือเรขาคณิตเดียวกันในชุด optimization และเป็นเหตุผลว่าทำไม input normalisation ไม่ใช่คำแนะนำเรื่องความเรียบร้อย แต่เป็นเลขคณิต1

ทั้งหมดข้างต้นไม่ต้องใช้ library นี่คือ optimiser ทั้งหมด

descent.pyPYTHON
def loss(theta):
    a, b = theta
    return np.mean((a * x + b - y) ** 2)


def grad(theta):
    a, b = theta
    residual = a * x + b - y
    return np.array([np.mean(2 * residual * x), np.mean(2 * residual)])


def descend(theta, lr, steps):
    theta = np.array(theta, dtype=float)
    for _ in range(steps):
        theta = theta - lr * grad(theta)   
    return theta


theta = descend([0.0, 0.0], lr=0.05, steps=60)
print(theta, loss(theta))
TEXT
[ 2.10040296e+00 -2.76445533e-15] 24.592448791134984

คำตอบ least-squares แบบ closed-form สำหรับแปดจุดนี้คือ a=2.100403a = 2.100403, b=0b = 0 โดยมี loss 24.59244924.592449 loop พบมันถึงแปดเลขนัยสำคัญโดยไม่รู้ว่ามี closed form อยู่ — ซึ่งสำคัญ เพราะตั้งแต่บทที่ 5 เป็นต้นไปจะไม่มีแบบนั้น

trajectory เพราะประเด็นคือการดูมัน:

TEXT
   0 a=0.000000 b=0.000000 L=57.437500
   1 a=1.563750 b=0.000000 L=26.736582
   2 a=1.963288 b=-0.000000 L=24.732418
   5 a=2.098116 b=-0.000000 L=24.592488
  10 a=2.100400 b=-0.000000 L=24.592449
  60 a=2.100403 b=-0.000000 L=24.592449

ระยะส่วนใหญ่ถูกครอบคลุมในสองก้าวแรก เพราะ gradient ใหญ่ที่สุดเมื่อคุณอยู่ไกลจากก้นหุบเขาที่สุด และหดลงเมื่อคุณเข้าใกล้ Gradient descent ชะลอตัวลงเองใกล้ minimum นั่นเป็น feature และในบทที่ 6 ก็เป็นปัญหาด้วย

ข้อโต้แย้งจนถึงตอนนี้มีช่องโหว่ ก้าวหยุดเมื่อ L=0\nabla L = \mathbf{0} และเราเรียกสิ่งนั้นว่า “minimum” จุดที่ gradient เป็นศูนย์คือ critical point และการเป็น minimum เป็นเพียงหนึ่งในวิธีที่จะเป็นจุดแบบนั้น:

  • local minimum: ขึ้นเขาในทุกทิศทาง แต่อาจไม่ใช่จุดต่ำสุดแบบนั้นในทุกที่;
  • local maximum: ลงเขาในทุกทิศทาง;
  • saddle point: ขึ้นเขาในบางทิศทางและลงเขาในบางทิศทาง พื้นผิว f(x,y)=x2y2f(x,y) = x^2 - y^2 มี f=(2x,2y)\nabla f = (2x, -2y) ซึ่งเป็นศูนย์ที่ origin ที่ซึ่งฟังก์ชันเป็น minimum ตามแกน xx และเป็น maximum ตามแกน yy ในเวลาเดียวกัน

Gradient descent แยกสิ่งเหล่านี้ไม่ออก เพราะมันมองแค่ gradient เท่านั้น และ gradient เป็นศูนย์ในทั้งสามแบบ

เส้นตรงของเรามี critical point หนึ่งจุดและมันคือคำตอบ — squared-error loss บนโมเดล linear เป็น convex เป็นชามใบเดียว และ descent บนมันไม่สามารถพลาด global minimum ได้ คุณสมบัตินั้นไม่รอดเมื่อเจอกับคอร์สนี้ loss ของ neural network ไม่ convex และตั้งแต่บทที่ 5 เป็นต้นไป “minimum” ไม่ใช่สิ่งที่มีอยู่: มีหลายจุด ลึกไม่เท่ากัน และคุณได้จุดไหนขึ้นอยู่กับว่าคุณเริ่มตรงไหน นี่เป็นประโยคเดียวและจะอยู่แค่ประโยคเดียว เพราะทฤษฎีใหญ่มากและผลเชิงปฏิบัติน้อย

คุณเห็นผลลัพธ์ทั้งหมดได้บนเส้นโค้งเดียว ใช้ f(x)=x44x22+x10f(x) = \tfrac{x^4}{4} - \tfrac{x^2}{2} + \tfrac{x}{10} ซึ่งมีหุบเขาสองแห่งที่ลึกไม่เท่ากัน:

TEXT
   x =  -1.046681   f(x) =  -0.352386   minimum
   x =   0.101031   f(x) =   0.005026   maximum
   x =   0.945649   f(x) =  -0.152639   minimum

40 ขั้นตอน สิ้นสุดที่ x = 0.9456.

ดูข้อมูลในรูปแบบตาราง
ขั้นตอนxf(x)
0⁨0.1100⁩⁨0.0050⁩
1⁨0.1122⁩⁨0.0050⁩
2⁨0.1149⁩⁨0.0049⁩
3⁨0.1182⁩⁨0.0049⁩
4⁨0.1223⁩⁨0.0048⁩
5⁨0.1275⁩⁨0.0047⁩
6⁨0.1338⁩⁨0.0045⁩
7⁨0.1416⁩⁨0.0042⁩
8⁨0.1513⁩⁨0.0038⁩
9⁨0.1633⁩⁨0.0032⁩
10⁨0.1781⁩⁨0.0022⁩
11⁨0.1962⁩⁨0.0007⁩
12⁨0.2183⁩⁨-0.0014⁩
13⁨0.2453⁩⁨-0.0046⁩
14⁨0.2779⁩⁨-0.0093⁩
15⁨0.3170⁩⁨-0.0160⁩
16⁨0.3633⁩⁨-0.0253⁩
17⁨0.4172⁩⁨-0.0377⁩
18⁨0.4783⁩⁨-0.0535⁩
19⁨0.5455⁩⁨-0.0721⁩
20⁨0.6163⁩⁨-0.0922⁩
21⁨0.6869⁩⁨-0.1116⁩
22⁨0.7526⁩⁨-0.1277⁩
23⁨0.8092⁩⁨-0.1393⁩
24⁨0.8540⁩⁨-0.1463⁩
25⁨0.8868⁩⁨-0.1499⁩
26⁨0.9091⁩⁨-0.1516⁩
27⁨0.9236⁩⁨-0.1522⁩
28⁨0.9325⁩⁨-0.1525⁩
29⁨0.9379⁩⁨-0.1526⁩
30⁨0.9411⁩⁨-0.1526⁩
31⁨0.9430⁩⁨-0.1526⁩
32⁨0.9441⁩⁨-0.1526⁩
33⁨0.9448⁩⁨-0.1526⁩
34⁨0.9451⁩⁨-0.1526⁩
35⁨0.9454⁩⁨-0.1526⁩
36⁨0.9455⁩⁨-0.1526⁩
37⁨0.9455⁩⁨-0.1526⁩
38⁨0.9456⁩⁨-0.1526⁩
39⁨0.9456⁩⁨-0.1526⁩
40⁨0.9456⁩⁨-0.1526⁩
Gradient descent แบบโต้ตอบ

สี่สิบก้าวจาก x=0.11x = 0.11 ลงตัวที่ 0.94560.9456 — หุบเขาที่ตื้นกว่าในสองแห่ง ตอนนี้ขยับจุดเริ่มหนึ่ง notch ไปทางซ้าย เป็น 0.100.10 rate เดิม สี่สิบก้าวเดิม และมันลงตัวที่ 1.0461-1.0461 แทน ซึ่ง loss ต่ำกว่า 0.199747 สันปันน้ำคือเนินที่ 0.1010310.101031 และความแตกต่างทั้งหมดระหว่างคำตอบสองแบบคือคุณบังเอิญเริ่มอยู่ด้านไหนของมัน

การตกลงในหุบเขาตื้นทำให้ loss แย่ลง 56.7% และอัลกอริทึมไม่มีทางรู้ เพราะจากภายในหุบเขา ทุกทิศทางคือขึ้นเขา ไม่มีการซ่อมสิ่งนี้ใน gradient descent และจะไม่มีมาให้ สิ่งที่มีในทางปฏิบัติคือข้อค้นพบว่ามันสำคัญน้อยกว่าที่ภาพนี้ชวนให้คิดมาก — ในมิติสูงมากของเครือข่ายจริง critical point ส่วนใหญ่กลายเป็น saddle มากกว่า trap,2 และบทที่ 5 จะวัดว่าเครือข่ายเล็ก ๆ ติดจริงบ่อยแค่ไหน

มีสิ่งหนึ่งเกี่ยวกับ grad ข้างต้นที่ควรกวนใจคุณ: มันรวมทั้ง dataset สำหรับทุกก้าว ชิ้นส่วนแปดชิ้นไม่เป็นไร หนึ่งล้านคือการคำนวณ gradient หนึ่งล้านครั้งเพื่อขยับพารามิเตอร์ครั้งเดียว

ทางหนีคือ gradient เป็น ค่าเฉลี่ย และค่าเฉลี่ยประมาณได้จาก sample คำนวณมันบนหยิบมือแบบสุ่ม — minibatch — แล้วก้าวตามนั้น ค่าประมาณมี noise; แต่มันก็ unbiased และก้าว noisy ราคาถูกหลายร้อยก้าวชนะก้าว exact แพง ๆ หนึ่งก้าว บนชิ้นส่วนสังเคราะห์หนึ่งแสนชิ้น นับ per-example gradients แทนจำนวนก้าว:

methodจำนวนก้าวจนอยู่ใน 0.1% ของ optimumper-example gradients
full batch7700,000
minibatch of 321003,200
ทีละตัวอย่าง17,58017,580

ใช้เลขคณิตน้อยลงสองร้อยสิบเก้าเท่าเพื่อไปถึงที่เดียวกัน และสุดขั้ว — ทีละตัวอย่าง การประมาณแบบ stochastic ดั้งเดิมของ Robbins และ Monro3ไม่ใช่ ผู้ชนะ: มันแย่กว่า batch ขนาด 32 ห้าเท่า เพราะ 32 ตัวอย่างแทบไม่แพงกว่า 1 ตัวอย่างบน hardware ที่คูณเมทริกซ์ ขณะที่ noise ลดลงตามรากที่สองของ batch size trade-off นี้คือเหตุผลที่ training script ทุกตัวที่คุณจะได้อ่านมี batch_size อยู่ในนั้น

Momentum คือวิธีแก้ราคาถูกอีกอย่าง และมันเล็งตรงไปที่ร่อง ในหุบเขาที่ condition แย่ ก้าวจะ zig-zag ข้ามทิศทางแคบ ขณะคืบคลานไปตามทิศทางยาว Momentum เก็บ running average ของ gradients ที่ผ่านมา ดังนั้นองค์ประกอบที่แกว่งจะหักล้างกัน และองค์ประกอบที่สม่ำเสมอจะสะสม:4

vβv+L(θ),θθηv\mathbf{v} \leftarrow \beta \mathbf{v} + \nabla L(\boldsymbol{\theta}), \qquad \boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \mathbf{v}

เพิ่มสองบรรทัด บนสายพาน raw ที่ไม่ centered — condition number 33,452 กรณีเลวร้ายที่สุดที่เรามี — ที่ rate ที่ดีที่สุดที่ plain descent รับได้:

TEXT
momentum beta=0.0   ->    79,513 steps to 1%
momentum beta=0.9   ->     1,609 steps to 1%
momentum beta=0.99  ->       461 steps to 1%

ดีขึ้น 172 เท่าจาก code สองบรรทัด บทที่ 6 จะเปลี่ยนสิ่งนี้เป็น Adam; กลไกอยู่ตรงนี้แล้ว

การตรวจสอบที่คุณจะต้องใช้ในบทที่ 5

ลิงก์ไปยังส่วน: การตรวจสอบที่คุณจะต้องใช้ในบทที่ 5

ทุก gradient ในบทนี้ถูกอนุมานด้วยมือ และจึงอาจผิดได้ วิธีแก้คือใช้ตารางความชันจากตอนต้น: วัดอนุพันธ์เชิงตัวเลขแล้วเปรียบเทียบ ใช้ central difference, L(θ+h)L(θh)2h\frac{L(\theta+h) - L(\theta-h)}{2h} ซึ่งหักล้าง error term นำหน้า และแม่นยำกว่ามากสำหรับ hh เดียวกัน

gradcheck.pyPYTHON
def numeric_grad(f, theta, h=1e-5):
    theta = np.asarray(theta, dtype=float)
    out = np.zeros_like(theta)
    for i in range(theta.size):
        bump = np.zeros_like(theta)
        bump[i] = h
        out[i] = (f(theta + bump) - f(theta - bump)) / (2 * h)     
    return out


def gradcheck(f, df, theta, h=1e-5):
    analytic = np.asarray(df(theta), dtype=float)
    numeric = numeric_grad(f, theta, h)
    return np.max(np.abs(analytic - numeric) / np.maximum(1e-8, np.abs(analytic) + np.abs(numeric)))

รูปแบบ relative ของการเปรียบเทียบสำคัญ: absolute difference ขนาด 10410^{-4} คือหายนะบน gradient ขนาด 10310^{-3} และไม่สำคัญบน gradient ขนาด 10610^{6}

TEXT
relative error: 1.8929136036763527e-11
with 2 dropped: 0.33333333331650744

บรรทัดแรกคือ gradient ที่อนุมานด้วยมือข้างต้น บรรทัดที่สองคือฟังก์ชันเดียวกันแต่ลืม factor 2 ใน component หนึ่ง — typo ตัวอักษรเดียว — และการตรวจจับก็จับได้ทันที อะไรที่ต่ำกว่าประมาณ 10710^{-7} คือเห็นพ้องกัน; อะไรที่สูงกว่า 10410^{-4} คือ bug เก็บฟังก์ชันนี้ไว้: บทที่ 5 ใช้มัน debug automatic differentiation engine และมันคือเหตุผลเดียวที่ gradient ผิด ๆ จะถูกหาเจอได้

ทุกอย่างในบทนี้ตั้งอยู่บนสมมติฐานหนึ่งที่ไม่เคยพูดออกมา: ว่าคุณสามารถเขียน L/θ\partial L / \partial \theta ลงมาได้

สำหรับเส้นตรงที่มีสองพารามิเตอร์ นั่นคือพีชคณิตหนึ่งบรรทัด แต่มันหยุดเป็นแบบนั้นแทบจะทันที ลองถาม symbolic algebra system หาอนุพันธ์ของ loss ของเครือข่ายเทียบกับ weight ชั้นแรก หนึ่งตัว สำหรับตัวอย่าง หนึ่งตัว แล้วนับเลขคณิตในคำตอบ:

networkoperations ในอนุพันธ์ย่อยหนึ่งตัว
hidden units สี่ตัว, หนึ่ง layer40
hidden units สี่ตัว, สอง layers301
hidden units สี่ตัว, สาม layers1,717

แถวที่สามคือเครือข่ายที่มี 57 พารามิเตอร์ — เครือข่ายเล็กจนในบทที่ 6 จะเป็นได้แค่เชิงอรรถ — และการเขียน gradient ของมันออกมาด้วยมือหมายถึงประมาณ 97,869 operations สำหรับ training example หนึ่งตัว ไม่มี notation ไหนช่วยชีวิตสิ่งนี้ได้ สิ่งที่ช่วยได้คือข้อสังเกตว่า chain rule เมื่อนำไปใช้กับ composition มีโครงสร้างมหาศาล ว่าปริมาณ intermediate เดิม ๆ ปรากฏซ้ำแล้วซ้ำเล่า และการคำนวณมันตามลำดับที่ถูกต้องจะให้อนุพันธ์ ทั้งหมด ในราคาประมาณเท่ากับ forward pass หนึ่งครั้ง นั่นคือบทที่ 5

แต่มีปัญหาเล็กกว่านั้นก่อน และมันรออยู่ทันที

ตอนนี้เรามีเครื่องจักรที่จะกลิ้งลงเขาบน loss ที่ differentiable ใด ๆ ชี้มันไปที่คำถามดั้งเดิมของสายพาน — รับหรือปฏิเสธ target ที่เป็น 1 หรือ 0 — ใส่ sigmoid บน output เพื่อให้ทำนายความน่าจะเป็น แล้ว minimize squared error มันจะรันได้ แต่มันแทบไม่ขยับเมื่อมันผิดที่สุด และ gradient บอกว่าทำไม:

output zzpredictiontruthgradient with squared errorgradient with cross-entropy
000.500012.5×1012.5 \times 10^{-1}5.0×1015.0 \times 10^{-1}
2-20.119211.850×1011.850 \times 10^{-1}8.808×1018.808 \times 10^{-1}
6-60.002514.921×1034.921 \times 10^{-3}9.975×1019.975 \times 10^{-1}
10-104.54×1054.54 \times 10^{-5}19.079×1059.079 \times 10^{-5}1.0001.000

โมเดลที่ผิดอย่าง มั่นใจและเลวร้ายสุดขีด — ทำนาย 0.0000454 ทั้งที่คำตอบคือ 1 — สร้าง gradient ของ squared-error เท่ากับ 9×1059 \times 10^{-5} มันไม่รู้เลยว่าตัวเองกำลังมีปัญหา อีกคอลัมน์หนึ่ง จาก loss ที่เรายังไม่ได้อนุมาน รายงาน 1.0: ความเร่งด่วนสูงสุด ตรงที่มันสมควรเกิดพอดี

ซึ่งนำไปสู่คำถามที่บทถัดไปจะเปิดด้วย บทก่อนหน้าบอกว่า loss คือสมมติฐานเกี่ยวกับ noise และ squared error สมมติ Gaussian noise แล้วคำตอบแบบใช่หรือไม่ใช่มี noise model แบบไหน — และ loss แบบใดออกมาเมื่อคุณทำการอนุมานเดียวกันกับมัน?


วิธีนี้เก่ากว่าทั้งหมด: Cauchy อธิบายมันในบันทึกถึง Académie des Sciences ในปี 1847 ในฐานะวิธีแก้ระบบสมการด้วยการเดินลงเขาบนผลรวมของ squared residuals ของมัน สิ่งที่ควรอ่านคู่กับบทนี้ด้วย: An overview of gradient descent optimization algorithms ของ Sebastian Ruder (arXiv:1609.04747) ซึ่งครอบคลุม momentum ถึง Adam ในสิบสี่หน้าที่อ่านง่าย; บทที่ 3 ของ Numerical Optimization ของ Nocedal และ Wright (2nd ed., Springer, 2006) ซึ่ง theorem 3.3 ให้ convergence rate ของ steepest descent บน quadratic ในรูป condition number — มันคือทฤษฎีเบื้องหลังว่าทำไม conditioning จึงตัดสินจำนวนก้าว แม้มันจะพิจารณา line search แทนเพดาน fixed-step 2/λmax2/\lambda_{\max} ที่วัดไว้ข้างต้น หรือ §5.8 และ §7.1 ของ Mathematics for Machine Learning โดย Deisenroth, Faisal และ Ong สำหรับพื้นที่เดียวกันแต่ใช้เครื่องมือน้อยกว่า; §6.1 ของ Understanding Deep Learning โดย Prince และ §4.3 ของ Deep Learning โดย Goodfellow, Bengio และ Courville; Dive into Deep Learning §12.1–12.3 ซึ่งมีการวิเคราะห์ minibatch พร้อมการวัดมากกว่าที่มีที่ว่างให้ใส่ที่นี่; และบทที่ 4 ของ Hands-On Machine Learning ของ Géron (3rd ed.) ซึ่งเป็นการอธิบาย learning rate ในฐานะสิ่งที่คุณ tune มากกว่าจะ derive ได้เชิงปฏิบัติที่สุด โน้ต MIT 6.390 วาง gradient descent ไว้ก่อน classification เหมือนคอร์สนี้ และด้วยเหตุผลเดียวกัน

  1. LeCun, Y., Bottou, L., Orr, G. B. and Müller, K.-R. Efficient BackProp, in Neural Networks: Tricks of the Trade (Springer, 1998), pp. 9–50. Section 4.3 ให้คำแนะนำ และ section 5.1 ให้ข้อโต้แย้งที่ใช้ในกล่องรายละเอียดข้างต้น: การ center และ scale input เปลี่ยน eigenvalues ของเมทริกซ์อนุพันธ์อันดับสอง และดังนั้นจึงเปลี่ยนจำนวนก้าว ไม่ใช่เพียงความสบายเชิงตัวเลข

  2. Dauphin, Y. N., Pascanu, R., Gulcehre, C., Cho, K., Ganguli, S. and Bengio, Y. Identifying and attacking the saddle point problem in high-dimensional non-convex optimization, arXiv:1406.2572 (2014). ข้อโต้แย้งว่าในมิติสูง critical points ส่วนใหญ่ท่วมท้นเป็น saddle มากกว่า local minima เพราะ minimum ต้องการให้ทุกหนึ่งในหลายพันทิศทางโค้งขึ้นพร้อมกัน

  3. Robbins, H. and Monro, S. A Stochastic Approximation Method. Annals of Mathematical Statistics 22(3), pp. 400–407 (1951). บทความที่ตั้งหลักว่า estimate ของ gradient ที่มี noise ก็เพียงพอ หากมี step size ที่หดลงในทางที่ถูกต้อง

  4. Polyak, B. T. Some methods of speeding up the convergence of iteration methods. USSR Computational Mathematics and Mathematical Physics 4(5), pp. 1–17 (1964). วิธี heavy-ball ซึ่งคือ momentum update ข้างต้น ยี่สิบสองปีก่อน backpropagation จะมาถึงสาขานี้


สร้างโดย

David Vicente Campos

ผู้ก่อตั้ง NeuraLIA Labs และผู้ร่วมก่อตั้ง MyRealFood

ผมเป็นวิศวกรคอมพิวเตอร์ที่จบจากมหาวิทยาลัยเลออน ผมร่วมก่อตั้ง MyRealFood ที่ที่ผมในฐานะ CTO ได้สร้างแอปซึ่งผู้คนหลายล้านคนใช้เพื่อกินให้ดีขึ้น และผมก่อตั้ง NeuraLIA Labs ที่ที่ผมสร้างผลิตภัณฑ์ AI ที่นี่ผมเขียนถึงสิ่งที่ผมต้องทำความเข้าใจระหว่างทาง ในแบบที่ผมเคยหวังว่าจะมีใครสักคนอธิบายให้ผมฟัง

เพิ่มเติมเกี่ยวกับผู้เขียน

เผยแพร่โดย NeuraLIA Labs

รับโพสต์ใหม่ในกล่องจดหมาย

ข่าว AI คู่มือ และอัปเดตผลิตภัณฑ์ — อีเมลสั้น ๆ เมื่อเรามีสิ่งที่คุ้มเวลาของคุณ

ชอบแบบข้อความมากกว่าไหม รับเนื้อหาเดียวกันได้ที่นี่:คอมมูนิตี้ WhatsApp (เปิดในแท็บใหม่)ช่อง Telegram (เปิดในแท็บใหม่)

ดัชนีคอร์ส

Abstract software decision engine with branching paths, probability nodes, and glowing gates.
jevอ่าน 5 นาที

โมเดล AI Jev สร้างมาเพื่อการตัดสินใจ ไม่ใช่การเขียนความเรียง

Jev ของ TypeSafe AI กำลังได้รับความสนใจ เพราะมองความฉลาดของซอฟต์แวร์เป็นปัญหาความน่าจะเป็น: เลือกกิ่งที่ถูกต้อง แนบความมั่นใจ และหลีกเลี่ยงการจ่ายเงินให้ LLM เขียนข้อความเมื่อโค้ดต้องการการตัดสินใจ

Abstract legal research workspace with documents, search nodes and governance controls.
openaiอ่าน 4 นาที

Astra for Law ของ OpenAI คือระบบ AI ด้านกฎหมาย ไม่ใช่โมเดลใหม่

การเปิดตัวด้านกฎหมายของ OpenAI ไม่ได้เน้นโมเดลฐานรากใหม่เท่ากับระบบที่ล้อมรอบโมเดลนั้น: การค้นคืนเฉพาะโดเมน เครื่องมือที่เชื่อถือได้ สิทธิ์ เบนช์มาร์ก และเส้นทางการตรวจทาน

Abstract agent runtime sorting documents, memory blocks and pointer nodes inside a bounded context frame.
context-engineeringอ่าน 4 นาที

วิศวกรรมบริบทสำหรับเอเจนต์ AI ที่ทำงานระยะยาว

เอเจนต์ที่ทำงานต่อเนื่องไม่ได้ล้มเหลวเพียงเพราะหน้าต่างบริบทเล็กเกินไป แต่ล้มเหลวเมื่อไฟล์ ผลลัพธ์จากเครื่องมือ และประวัติที่ค้างเก่าบดบังงานที่เอเจนต์ควรทำให้เสร็จ

พร้อมให้ LIA เลือกโมเดลให้แล้วหรือยัง?

สร้างงานด้วยโมเดล AI ทุกตัวในที่เดียว เริ่มฟรีวันนี้