Chức năng gradient python

Độ dốc của hàm đơn giản có nghĩa là tốc độ thay đổi của hàm. Chúng ta sẽ sử dụng numdifftools để tìm Gradient của một hàm

ví dụ

Input : x^4+x+1
Output :Gradient of x^4+x+1 at x=1 is  4.99

Input :(1-x)^2+(y-x^2)^2
Output :Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.] 

Tiếp cận

  • Đối với hàm một biến. Đối với hàm biến đơn, chúng ta có thể xác định trực tiếp bằng cách sử dụng “lambda” như được nêu bên dưới. -
    g=lambda x:(x**4)+x+1
  • Đối với hàm nhiều biến. Chúng ta sẽ định nghĩa một hàm bằng cách sử dụng “def” và truyền vào một mảng “x” và nó sẽ trả về hàm nhiều biến như được mô tả bên dưới. -
    def rosen(x): 
        return (1-x[0])**2 +(x[1]-x[0]**2)**2

    trong đó 'rosen' là tên của hàm và 'x' được truyền dưới dạng mảng. x[0]x[1] là các phần tử mảng theo thứ tự như được định nghĩa trong mảng. i. e Chức năng được xác định ở trên là (1-x^2)+(y-x^2)^2

Tương tự, Ta có thể định nghĩa hàm nhiều hơn 2 biến theo cách tương tự như đã nêu ở trên

phương pháp được sử dụng. Dốc()
cú pháp

nd.Gradient(func_name)

Thí dụ




import numdifftools as nd

g=lambda x:(x**4)+x+1
0

g=lambda x:(x**4)+x+1
0

g=lambda x:(x**4)+x+1
2
g=lambda x:(x**4)+x+1
3
g=lambda x:(x**4)+x+1
4
g=lambda x:(x**4)+x+1
5
g=lambda x:(x**4)+x+1
6
g=lambda x:(x**4)+x+1
6
g=lambda x:(x**4)+x+1
8
g=lambda x:(x**4)+x+1
9
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
0
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
1
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
0
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
3

def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
4_______1_______3
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
6
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
3
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
8

def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
9
nd.Gradient(func_name)
0_______3_______1
nd.Gradient(func_name)
2

g=lambda x:(x**4)+x+1
0

nd.Gradient(func_name)
4
nd.Gradient(func_name)
5

nd.Gradient(func_name)
6
nd.Gradient(func_name)
7
nd.Gradient(func_name)
0
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
3
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
0
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
1
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
2
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
8
g=lambda x:(x**4)+x+1
6
g=lambda x:(x**4)+x+1
6
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
6
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
0
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
8
def rosen(x): 
    return (1-x[0])**2 +(x[1]-x[0]**2)**2
3x[0]0
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
0
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
1
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
2x[0]0
g=lambda x:(x**4)+x+1
6
g=lambda x:(x**4)+x+1
6
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
6
g=lambda x:(x**4)+x+1
9
g=lambda x:(x**4)+x+1
6
g=lambda x:(x**4)+x+1
6
Gradient of x^4+x+1 at x=1 is  4.999999999999998
Gradient of (1-x^2)+(y-x^2)^2 at (1, 2) is  [-4.  2.]
6


con trăn. Thuật toán Stochastic Gradient Descent with Python and NumPy
Key learning qua video
Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript

Mục lục bài viết

  • Thuật toán Gradient Descent cơ bản
    • Chức năng Chi phí. Mục tiêu của tối ưu hóa
    • Gradient of a function. Trình làm mới tính toán
    • Trực tiếp phía sau sự xuống dốc
    • Triển khai Gradient Descent cơ bản
    • Các tác động đến các tập tin học tập có giá trị
  • Ứng dụng của thuật toán Gradient Descent
    • Ví dụ rút gọn
    • Bình phương nhỏ nhất
    • Bộ quy tắc cải tiến tiến trình
  • Thuật toán đổ dốc Stochastic
    • Minibatches trong Stochastic Gradient Descent
    • Động lượng trong Stochastic Gradient Descent
    • Random value start
  • Gradient Descent trong Keras và TensorFlow
  • Phần kết luận


Giảm dần độ dốc ngẫu nhiên (SGD) là một thuật toán tối ưu hóa thông thường được sử dụng trong các ứng dụng học máy để tìm các tham số mô hình tương ứng với sự phù hợp nhất giữa đầu ra dự kiến ​​và thực tế. Đó là một kỹ thuật không chính xác nhưng mạnh mẽ

SGD được sử dụng rộng rãi trong các ứng dụng máy học. Kết hợp với sự truyền ngược, nó chiếm ưu thế trong ứng dụng đào tạo

Trong hướng dẫn này, bạn sẽ học

  • Cách thức hoạt động của thuật toán giảm độ dốc và giảm độ dốc ngẫu nhiên
  • Cách áp dụng giảm dần độ dốc và giảm dần độ dốc ngẫu nhiên để giảm thiểu hàm mất mát trong máy học
  • Tỷ lệ học là gì, tại sao nó quan trọng, và nó ảnh hưởng đến kết quả như thế nào
  • Cách viết hàm của riêng bạn để giảm độ dốc ngẫu nhiên

Thuật toán Gradient Descent cơ bản

zzzCác thuật toán giảm dần độ dốc là một phương pháp gần đúng và đi lặp lại để tối ưu hóa. Bạn có thể sử dụng nó để tiến gần đến mức tối thiểu của bất kỳ chức năng nào có thể phân biệt nào

Lưu ý. Có nhiều phương pháp tối ưu hóa và các phương pháp. Nếu bạn muốn tìm hiểu cách sử dụng một số trong số chúng với Python, hãy xem Khoa học Python. Sử dụng SciPy để tối ưu hóa và Lập trình thực thi tuyến tính. Tối ưu hóa với Python

Mặc dù sự giảm tốc độ giảm dần khi bị truy vấn ở điểm tối thiểu cục bộ hoặc điểm yên ngựa thay vì tìm ra mức tối thiểu toàn cầu, nhưng nó được sử dụng rộng rãi trong thực tế. Khoa học dữ liệu và phương pháp học máy thường áp dụng nó trong nội bộ để tối ưu hóa các thông số mô hình. Ví dụ, mạng nơ-ron tìm trọng lượng và độ lệch với độ dốc gốc

Chức năng Chi phí. Mục tiêu của tối ưu hóa

Hàm chi phí hoặc hàm tổn thất là hàm được tối thiểu hóa (hoặc tối đa hóa) bằng cách thay đổi các biến quyết định. Nhiều phương pháp học máy giải quyết các vấn đề tối ưu hóa dưới bề mặt. Họ có xu hướng giảm thiểu sự khác biệt giữa đầu ra thực tế và đầu tiên dự đoán bằng cách điều chỉnh các thông số mô hình (như số lượng và mức độ biến đổi cho mạng nơ-ron , quy tắc quyết định cho rừng ngẫu nhiên hoặc . v. )

Trong một  , bạn thường có các góc của các biến đầu vào 𝐱 = (𝑥₁,…, 𝑥ᵣ) và các kết quả đầu ra thực tế 𝑦. Bạn muốn tìm một mô hình ánh xạ 𝐱 hướng tới một phản ứng dự đoán 𝑓 (𝐱) sao cho 𝑓 (𝐱) càng gần với 𝑦 càng tốt. Ví dụ. bạn có thể muốn dự đoán một kết quả đầu ra, chẳng hạn như tiền lương của một người với các yếu tố đầu vào như số năm làm việc tại công ty hoặc trình độ học vấn của người đó

Mục tiêu của bạn là giảm thiểu sự khác biệt giữa dự đoán 𝑓 (𝐱) và dữ liệu thực tế 𝑦. Sự chênh lệch này được gọi là phần dư

Trong định dạng bài toán này, bạn muốn giảm thiểu tổng bình phương phần dư (SSR) , trong đó SSR = Σᵢ (𝑦ᵢ - 𝑓 (𝐱ᵢ)) ² cho tất cả các quan sát 𝑖 = 1,…, 𝑛, trong đó 𝑛 . Ngoài ra, bạn có thể sử dụng lỗi phương pháp trung bình (MSE = SSR / 𝑛) thay vì SSR

Cả SSR và MSE đều sử dụng bình phương của sự khác biệt giữa đầu ra thực tế và đầu ra dự đoán. Kênh lệch càng thấp thì dự đoán càng chính xác. Sự khác biệt bằng 0 cho thấy rằng dự đoán bằng dữ liệu thực tế

SSR hoặc MSE được giảm thiểu bằng cách điều chỉnh các thông số mô hình. Ví dụ, trong hồi quy tuyến tính , bạn muốn tìm hàm 𝑓 (𝐱) = 𝑏₀ + 𝑏₁𝑥₁ + ⋯ + 𝑏ᵣ𝑥ᵣ, vì vậy bạn cần xác định các số quan trọng 𝑏₀, 𝑏₁,…, 𝑏ᵣ để giảm thiểu SSR hoặc MSE

Trong một , đầu ra 𝑦 là phân loại, thường là 0 hoặc 1. Ví dụ: bạn có thể cố gắng dự đoán xem một email có phải là thư rác hay không. Trong trường hợp đầu ra nhị phân, thật thuận tiện để giảm thiểu hàm entropy chéo cũng phụ thuộc vào đầu ra thực tế 𝑦ᵢ và các dự đoán tương ứng 𝑝(𝐱ᵢ)

Loại bỏ các quảng cáo

Trực giác Đằng sau Gradient Descent

Để hiểu thuật toán giảm độ dốc, hãy tưởng tượng một giọt nước trượt xuống thành bát hoặc một quả bóng lăn xuống một ngọn đồi. Viên thả và quả bóng có xu hướng chuyển động theo hướng giảm nhanh nhất cho đến khi chạm đáy. Theo thời gian, họ sẽ đạt được động lực và tăng tốc

Ý tưởng đằng sau việc giảm độ dốc cũng tương tự. bạn bắt đầu với một vị trí được chọn tùy ý của điểm hoặc vectơ 𝐯 = (𝑣₁, …, 𝑣ᵣ) và di chuyển nó lặp đi lặp lại theo hướng giảm nhanh nhất của hàm chi phí. Như đã đề cập, đây là hướng của vectơ gradient âm, −∇𝐶

Sau khi bạn có điểm bắt đầu ngẫu nhiên 𝐯 = (𝑣₁, …, 𝑣ᵣ), bạn cập nhật điểm đó hoặc di chuyển điểm đó đến vị trí mới theo hướng của dải màu âm. 𝐯 → 𝐯 − 𝜂∇𝐶, trong đó 𝜂 (phát âm là “ee-tah”) là một giá trị dương nhỏ được gọi là tỷ lệ học tập

Tốc độ học xác định mức độ lớn của bước cập nhật hoặc di chuyển. Đó là một thông số rất quan trọng. Nếu 𝜂 quá nhỏ thì thuật toán có thể hội tụ rất chậm. Các giá trị 𝜂 lớn cũng có thể gây ra sự cố hội tụ hoặc làm cho thuật toán phân kỳ

Triển khai Gradient Descent cơ bản

Bây giờ bạn đã biết cách hoạt động của tính năng giảm độ dốc cơ bản, bạn có thể triển khai nó trong Python. Bạn sẽ chỉ sử dụng Python và NumPy đơn giản, cho phép bạn viết mã ngắn gọn khi làm việc với mảng (hoặc vectơ) và đạt được hiệu suất tăng

Đây là cách triển khai cơ bản của thuật toán bắt đầu bằng một điểm tùy ý, 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
0, di chuyển lặp đi lặp lại điểm đó về phía giá trị nhỏ nhất và trả về một điểm hy vọng bằng hoặc gần giá trị nhỏ nhất

 1def gradient_descent(gradient, start, learn_rate, n_iter):
 2    vector = start
 3    for _ in range(n_iter):
 4        diff = -learn_rate * gradient(vector)
 5        vector += diff
 6    return vector

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 có bốn đối số

  1. >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    2 là hàm hoặc bất kỳ Python  lấy một vectơ và trả về độ dốc của hàm mà bạn đang cố gắng thu nhỏ
  2. >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    0 là điểm mà thuật toán bắt đầu tìm kiếm, được đưa ra dưới dạng một chuỗi (bộ, danh sách, mảng NumPy, v.v.) hoặc vô hướng (trong trường hợp bài toán một chiều)
  3. >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    4 là tốc độ học kiểm soát cường độ của bản cập nhật vectơ
  4. >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    5 là số lần lặp lại

Chức năng này thực hiện chính xác những gì được mô tả. nó lấy một điểm bắt đầu (dòng 2), lặp lại cập nhật nó theo tốc độ học và giá trị của gradient (dòng 3 đến 5) và cuối cùng trả về vị trí cuối cùng được tìm thấy

Trước khi đăng ký 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1, bạn có thể thêm một tiêu chí chấm dứt hợp đồng khác

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector

Giờ đây, bạn có tham số bổ sung 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
7 (dòng 4), chỉ định chuyển động tối thiểu được phép trong mỗi lần lặp. Bạn cũng đã xác định các giá trị mặc định cho 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
7 và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
5, vì vậy, bạn không cần phải chỉ định các giá trị này mỗi khi gọi cho 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1

Dòng 9 và 10 cho phép 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 ngừng lặp lại và trả về kết quả trước khi đạt được 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
5 nếu cập nhật vectơ trong lần lặp hiện tại nhỏ hơn hoặc bằng 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
7. Điều này thường xảy ra gần mức tối thiểu, trong đó độ dốc thường rất nhỏ. Thật không may, nó cũng có thể xảy ra gần mức tối thiểu cục bộ hoặc điểm yên ngựa

Dòng 9 sử dụng các hàm NumPy thuận tiện 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
4 và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
5 để so sánh các giá trị tuyệt đối của 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6 và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
7 trong một câu lệnh. Đó là lý do bạn 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
8 ở dòng 1

Bây giờ bạn đã có phiên bản đầu tiên của 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1, đã đến lúc kiểm tra chức năng của bạn. Bạn sẽ bắt đầu với một ví dụ nhỏ và tìm giá trị nhỏ nhất của hàm 𝐶 = 𝑣²

Hàm này chỉ có một biến độc lập (𝑣) và gradient của nó là đạo hàm 2𝑣. Đó là một hàm lồi có thể khả vi và cách phân tích để tìm giá trị cực tiểu của nó rất đơn giản. Tuy nhiên, trên thực tế, việc phân tích sự khác biệt có thể khó khăn hoặc thậm chí là không thể và thường được tính gần đúng bằng các phương pháp số

Bạn chỉ cần một câu lệnh để kiểm tra triển khai giảm dần độ dốc của mình

>>>

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06

Bạn sử dụng hàm lambda 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005
.. )
6.050060671375367
0 để cung cấp độ dốc của 𝑣². Bạn bắt đầu từ giá trị 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005
.. )
6.050060671375367
1 và đặt tốc độ học thành 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005
.. )
6.050060671375367
2. Bạn nhận được kết quả rất gần bằng 0, đây là giá trị tối thiểu chính xác

Hình dưới đây cho thấy chuyển động của giải pháp thông qua các lần lặp

Loại bỏ các quảng cáo

Tác động tỷ lệ học tập

Tốc độ học là một tham số rất quan trọng của thuật toán. Các giá trị tốc độ học tập khác nhau có thể ảnh hưởng đáng kể đến hành vi giảm dần độ dốc. Xem xét ví dụ trước, nhưng với tỷ lệ học tập là 0. 8 thay vì 0. 2

>>>

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07

Bạn nhận được một giải pháp khác rất gần bằng 0, nhưng hành vi bên trong của thuật toán thì khác. Đây là điều xảy ra với giá trị của 𝑣 qua các lần lặp

Loại bỏ các quảng cáo

Ứng dụng của thuật toán Gradient Descent

Trong phần này, bạn sẽ thấy hai ví dụ rút ngắn về việc sử dụng giảm dần độ dốc. Bạn cũng sẽ biết rằng nó có thể được sử dụng trong các bài toán máy học ngoài đời thực như hồi quy tuyến tính. Trong trường hợp thứ hai, bạn cần sửa đổi mã 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1vì bạn cần dữ liệu từ các quan sát để tính toán gradient

Ví dụ rút gọn

Đầu tiên, bạn sẽ áp dụng 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1cho một vấn đề khác. Lấy hàm 𝑣 - log (𝑣). Gradient of this function is 1 - 1 / 𝑣. Với thông tin này, bạn có thể tìm thấy mức tối thiểu của nó

>>>

>>> gradient_descent(
..     gradient=lambda v: 1 - 1 / v, start=2.5, learn_rate=0.5
.. )
1.0000011077232125

Với tập hợp các đối số được cung cấp, hãy 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1tính toán chính xác để hàm này có giá trị nhỏ nhất trong 𝑣 = 1. Bạn có thể thử nó với các giá trị khác nhau cho tốc độ học và điểm bắt đầu

Bạn cũng có thể sử dụng 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1với hàm của nhiều hơn một biến. Ứng dụng này cũng giống như vậy, nhưng bạn cần cung cấp độ dốc và điểm bắt đầu dưới dạng nhìn hoặc mảng. Ví dụ. bạn có thể tìm giá trị nhỏ nhất của hàm 𝑣₁² + 𝑣₂⁴ có độ dốc hiển thị (2𝑣₁, 4𝑣₂³)

>>>

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])

Trong trường hợp này, gradient hàm của bạn trả về một mảng và giá trị bắt đầu là một mảng, vì vậy bạn sẽ nhận được một mảng là kết quả. Giá trị kết quả gần nhất là bằng 0, vì vậy bạn có thể nói điều đó 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1một cách chính xác rằng giá trị nhỏ nhất của hàm này là 𝑣₁ = 𝑣₂ = 0

Bình phương nhỏ nhất

Như bạn đã học, hồi quy tuyến tính và phương pháp phương pháp nhỏ nhất thông thường bắt đầu với các giá trị quan sát của đầu vào 𝐱 = (𝑥₁,…, 𝑥ᵣ) và đầu ra 𝑦. Họ định nghĩa một hàm tuyến tính 𝑓 (𝐱) = 𝑏₀ + 𝑏₁𝑥₁ + ⋯ + 𝑏ᵣ𝑥ᵣ, càng gần với 𝑦 càng tốt

Đây là một vấn đề tối ưu hóa. Nó tìm giá trị của các trọng số 𝑏₀, 𝑏₁,…, 𝑏ᵣ để giảm thiểu tổng các phần dư bình phương SSR = Σᵢ (𝑦ᵢ - 𝑓 (𝐱ᵢ)) ² hoặc sai số bình phương trung bình MSE = SSR / 𝑛. Ở đây, 𝑛 là tổng số quan sát và 𝑖 = 1,…, 𝑛

Bạn có thể sử dụng hàm chi phí 𝐶 = SSR / (2𝑛), về mặt toán học thuận tiện hơn với SSR hoặc MSE

Cơ bản lớn nhất của hồi quy tuyến tính là. Nó chỉ có một đầu vào 𝑥 và hai số quan trọng. 𝑏₀ và 𝑏₁. Phương trình của đường hồi quy là 𝑓 (𝑥) = 𝑏₀ + 𝑏₁𝑥. Mặc dù các giá trị tối ưu của 𝑏₀ và 𝑏₁ có thể đạt được, nhưng bạn sẽ sử dụng gradient độ dốc để xác định chúng

Đầu tiên, bạn cần tính toán để tìm gradient của hàm chi phí 𝐶 = Σᵢ (𝑦ᵢ - 𝑏₀ - 𝑏₁𝑥ᵢ) ² / (2𝑛). Vì bạn có hai biến quyết định, 𝑏₀ và 𝑏₁, nên độ dốc ∇𝐶 là một cảnh có hai thành phần

  1. ∂𝐶 / ∂𝑏₀ = (1 / 𝑛) Σᵢ (𝑏₀ + 𝑏₁𝑥ᵢ - 𝑦ᵢ) = nghĩa là (𝑏₀ + 𝑏₁𝑥ᵢ - 𝑦ᵢ)
  2. ∂𝐶 / ∂𝑏₁ = (1 / 𝑛) Σᵢ (𝑏₀ + 𝑏₁𝑥ᵢ - 𝑦ᵢ) 𝑥ᵢ = nghĩa là ((𝑏₀ + 𝑏₁𝑥ᵢ - 𝑦ᵢ) 𝑥ᵢ)

Bạn cần các giá trị của 𝑥 và 𝑦 để tính gradient toán học của hàm chi phí này. Hàm gradient của bạn sẽ bắt đầu không chỉ 𝑏₀ và 𝑏₁ mà còn 𝑥 và 𝑦. Đây là cách nó có thể nhìn

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
0

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
3nhận các mảng 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5chứa các đầu vào và đầu ra quan sát và mảng 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
6chứa các giá trị hiện tại của các biến quyết định 𝑏₀ và 𝑏₁. Trước tiên, hàm này tính toán mảng các phần dư cho mỗi quan sát ( 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
7) và sau đó trả về cặp giá trị của ∂𝐶 / ∂𝑏₀ và ∂𝐶 / ∂𝑏₁

Trong ví dụ này, bạn có thể sử dụng phương thức NumPy thuận tiện 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
8vì bạn chuyển mảng NumPy làm đối số

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 cần hai điều chỉnh nhỏ

  1. Add 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    4và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    5làm các tham số của 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    1dòng 4
  2. Cung cấp 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    4 và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    5 cho hàm gradient và đảm bảo bạn chuyển đổi bộ gradient của mình thành một mảng NumPy trên dòng 8

Đây là cách 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 xử lý những thay đổi này

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
1

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 hiện chấp nhận đầu vào quan sát 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4 và đầu ra 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5 và có thể sử dụng chúng để tính toán độ dốc. Việc chuyển đổi đầu ra của 
>>> gradient_descent(
..     gradient=lambda v: 4 * v**3 - 10 * v - 3, start=0,
..     learn_rate=0.2
.. )
-1.4207567437458342
9 thành một mảng NumPy cho phép nhân các phần tử độ dốc theo từng phần tử với tốc độ học tập, điều này không cần thiết trong trường hợp hàm một biến

Bây giờ hãy áp dụng phiên bản mới của bạn của 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1 để tìm đường hồi quy cho một số giá trị tùy ý của 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4 và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5

>>>

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
2

Kết quả là một mảng có hai giá trị tương ứng với các biến được quyết định. 𝑏₀ = 5,63 và 𝑏₁ = 0,54. Đường hồi quy tốt nhất là 𝑓 (𝑥) = 5,63 + 0,54𝑥. Như trong ví dụ trước, kết quả này phụ thuộc nhiều vào tốc độ học tập. Bạn không thể đạt được kết quả tốt với tỷ lệ học tập quá thấp hoặc quá cao

Ví dụ này không hoàn toàn ngẫu nhiên - nó được lấy từ hướng dẫn. Tin tốt là bạn đã thu được kết quả gần như giống với công cụ hồi quy tuyến tính từ scikit-learning. Dữ liệu và quy định kết quả được hiển thị trong phần

 

Loại bỏ các quảng cáo

Bộ quy tắc cải tiến tiến trình

Bạn có thể làm cho 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1mạnh hơn, toàn diện hơn và đẹp hơn mà không cần sửa đổi chức năng cốt lõi của nó

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
3

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1bây giờ chấp nhận một 
>>> gradient_descent(
..     gradient=lambda v: 4 * v**3 - 10 * v - 3, start=0,
..     learn_rate=0.1
.. )
1.285401330315467
5tham số bổ sung xác định kiểu dữ liệu của mảng NumPy bên trong hàm. Để biết thêm thông tin về các loại NumPy, hãy xem tài liệu chính thức về các loại dữ liệu

Trong hầu hết các ứng dụng, bạn sẽ không nhận thấy sự khác biệt giữa các dấu phẩy động 32 bit và 64 bit, nhưng khi bạn làm việc với bộ dữ liệu lớn, điều này có thể ảnh hưởng đáng kể đến việc sử dụng bộ ứng dụng . Ví dụ. mặc dù NumPy sử dụng phao 64 bit theo mặc định, TensorFlow thường sử dụng thập phân 32 bit

Ngoài việc xem xét các kiểu dữ liệu, đoạn mã trên giới thiệu, một số thay đổi liên quan đến việc kiểm tra kiểu và đảm bảo việc sử dụng các khả năng của NumPy

  • Dòng 8 và 9 kiểm tra xem có phải 

    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    2là một đối tượng có thể gọi là được trong Python hay không và dữ liệu của nó có thể được sử dụng như một hàm hay không. Nếu không, hàm sẽ nâng cấp

  • Dòng 12 đặt một thể hiện của 

    >>> gradient_descent(
    ..     gradient=lambda v: 4 * v**3 - 10 * v - 3, start=0,
    ..     learn_rate=0.1
    .. )
    1.285401330315467
    
    8, sẽ được sử dụng làm kiểu dữ liệu cho tất cả các mảng trong suốt hàm

  • Dòng 15 nhận các đối số 

    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    4và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    5 tạo mảng NumPy với kiểu dữ liệu mong muốn. Các đối số 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    4và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    5có thể là danh sách, bộ giá trị, mảng hoặc các chuỗi khác

  • Dòng 16 và 17 so sánh kích thước của 

    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    4và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=100
    .. )
    3.660323412732294
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=1000
    .. )
    0.0004317124741065828
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
    ..     n_iter=2000
    .. )
    9.952518849647663e-05
    
    5. Điều này hữu ích vì bạn muốn chắc chắn rằng cả hai mảng đều có cùng số lượng quan sát. Nếu không, thì hàm sẽ tăng a

  • Dòng 20 chuyển đổi đối số 

    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    0 thành mảng NumPy. Đây là một thủ thuật thú vị. if 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    0là một Python vô hướng đại lượng, thì nó sẽ được chuyển đổi thành một đối tượng NumPy tương ứng (một mảng có một mục và không có thứ nguyên). Nếu bạn vượt qua một chuỗi, thì nó sẽ trở thành một mảng NumPy thông thường với cùng một số phần tử

  • Dòng 23 làm tương tự với Học tập giá trị. Điều này có thể rất hữu ích vì nó cho phép bạn chỉ định các Tỷ lệ học tập khác nhau cho từng biến được quyết định bằng cách chuyển một danh sách, bộ dữ liệu hoặc mảng NumPy tới _______54_______1

  • Dòng 24 và 25 kiểm tra xem giá trị tốc độ học (hoặc giá trị cho tất cả các biến) có lớn hơn không

  • Dòng 28-35 tương tự thiết lập 

    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    5và 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    7và kiểm tra xem họ lớn hơn không

  • Các dòng từ 38 đến 47 gần giống với dòng trước đây. Sự khác biệt duy nhất là kiểu của mảng gradient trên dòng 40

  • Dòng 49 trả về mảng kết quả thuận lợi nếu bạn có một số biến quyết định hoặc một đại lượng vô hướng Python nếu bạn có một biến duy nhất

Của bạn 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1bây giờ đã hoàn thành. Vui lòng thêm một số khả năng bổ sung hoặc đánh bóng. Bước tiếp theo của hướng dẫn này là sử dụng những gì bạn đã học cho đến nay để phát triển phiên bản ngẫu nhiên của gradient gốc

Thuật toán đổ dốc Stochastic

Thuật toán giảm tốc độ ngẫu nhiên là một sự thay đổi của tốc độ xuống dốc. Trong việc giảm tốc độ dốc ngẫu nhiên, bạn chỉ tính toán độ dốc bằng một phần nhỏ ngẫu nhiên của các quan sát thay vì tất cả chúng. Trong một số trường hợp, cách tiếp cận này có thể giảm thời gian tính toán

Giảm tốc độ ngẫu nhiên trực tuyến là một biến có thể giảm tốc độ ngẫu nhiên trong đó bạn ước tính tốc độ dốc của hàm chi phí cho mỗi lần quan sát và cập nhật các biến quyết định để phù hợp. Điều này có thể giúp bạn tìm ra cực tiểu chung, đặc biệt nếu hàm mục tiêu là hiển thị

Giảm độ dốc ngẫu nhiên hàng loạt nằm ở đâu đó giữa độ dốc thông thường và phương pháp trực tuyến. Các độ dốc được tính toán và các biến quyết định được cập nhật sẽ lặp lại với các tập hợp con của tất cả các quan sát, được gọi là các minibatch. Biến biến này rất phổ biến để tạo mạng nơ-ron

Bạn có thể định hình dung thuật toán trực tuyến là một loại ma thuật toán lô đặc biệt, trong đó mỗi minibatch chỉ có một lần quan sát. Xuống dốc cổ điển là một trường hợp đặc biệt khác trong đó chỉ có một lô chứa tất cả các quan sát

Minibatches trong Stochastic Gradient Descent

Như trong trường hợp giảm tốc độ thông thường, giảm tốc độ dốc ngẫu nhiên bắt đầu với một lệnh cấm đầu của các biến quyết định và cập nhật nó qua một số lần lặp lại. Sự khác biệt giữa cả hai là ở những điều xảy ra bên trong các lần lặp lại

  • Stochastic gradient Desiation ngẫu nhiên các tập hợp các quan sát thành các nhóm nhỏ
  • Đối chiếu với mỗi minibatch, gradient được tính toán và vector được di chuyển
  • Sau khi tất cả các minibatch được sử dụng, bạn nói rằng quá trình lặp lại, hoặc kỷ nguyên , đã kết thúc và bắt đầu cái tiếp theo

Thuật toán này chọn ngẫu nhiên các quan sát cho các minibatch, vì vậy bạn cần phải mô phỏng các hành động ngẫu nhiên (hoặc giả ngẫu nhiên) này. You can doing that do việc tạo ngẫu nhiên số. Python có 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
2mô-đun tích hợp và NumPy có trình tạo ngẫu nhiên của riêng nó. Cái sau thuận tiện hơn khi bạn làm việc với mảng

Bạn sẽ tạo một hàm mới có tên 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
3 rất giống 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1nhưng sử dụng các minibatch được chọn ngẫu nhiên để di chuyển dọc theo không gian tìm kiếm

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
4

You have a new number at here. Với 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
5, bạn chỉ định lượng quan sát trong mỗi lô nhỏ. Đây là một số tham số cần thiết cho sự giảm dần độ dốc ngẫu nhiên có thể ảnh hưởng đáng kể đến hiệu suất. Các dòng từ 34 đến 39 chắc chắn rằng đó 
>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
5là một số nguyên dương không lớn hơn tổng số quan sát

Một tham số mới là 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
7. Nó định nghĩa giống hệt hạt của trình tạo ngẫu nhiên số trên dòng 22. Các hạt giống được sử dụng trên dòng 23 như một đối số để tạo ra một thể hiện của

Nếu bạn chuyển các đối số 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
00cho 
>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
7, thì quá trình tạo số ngẫu nhiên sẽ trả về các số khác nhau mỗi khi nó được khởi động. Nếu bạn muốn từng phiên bản của chương trình tạo hoạt động giống nhau, thì bạn cần chỉ định 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
02. Cách dễ nhất là cung cấp một số tùy chọn nguyên liệu

Dòng 16 suy ra lượng quan sát với 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
03. If 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4là một mảng, thì đây là kích thước của nó. If 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4có hai thứ nguyên, thì đó 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
06là số hàng

Ở dòng 19, bạn sử dụng để chắc chắn rằng cả hai 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5 đảo thành mảng hai chiều với 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
10các hàng và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5có chính xác một cột. thuận tiện nối các cột của 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5thành một mảng duy nhất 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
15,. Đây là một cách để làm cho dữ liệu phù hợp với lựa chọn ngẫu nhiên

Cuối cùng, trên các dòng từ 52 đến 70, bạn thực hiện 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
16 vòng lặp cho đường xuống dốc ngẫu nhiên. Nó khác với 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1. Ở dòng 54, bạn sử dụng trình tạo ngẫu nhiên số và phương pháp của nó để xáo trộn các quan sát. Đây là một trong những cách chọn những chiếc minibatch một cách ngẫu nhiên

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
16Vòng lặp bên trong được lặp lại cho mỗi minibatch. Sự khác biệt chính so với việc giảm độ dốc thông thường là, trên dòng 62, độ dốc được tính cho các quan sát từ một minibatch ( 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
20và 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
21) thay vì tất cả các quan sát ( 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4và 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
5)

Ở dòng 59, 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
20 trở thành một phần của 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
15nó chứa các hàng của minibatch hiện tại (từ 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
0đến 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
27) và các cột tương ứng với 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=100
.. )
3.660323412732294
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=1000
.. )
0.0004317124741065828
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005,
..     n_iter=2000
.. )
9.952518849647663e-05
4.
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
21 giữ các hàng giống nhau từ 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
15nhưng chỉ cột cuối cùng (kết quả đầu ra). Để biết thêm thông tin về cách các số hoạt động duy nhất trong NumPy, hãy xem tài liệu chính thức về lập chỉ mục

Bây giờ, bạn có thể kiểm tra quá trình phát triển của mình về độ dốc ngẫu nhiên

>>>

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
5

Kết quả gần giống như bạn đã nhận được 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
1. Nếu bạn bỏ qua 
>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
7hoặc sử dụng 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
00, thì bạn sẽ nhận được các kết quả hơi khác nhau mỗi khi bạn chạy 
>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
3vì trình tạo số ngẫu nhiên sẽ xáo trộn 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
15 khác nhau

 

Loại bỏ các quảng cáo

Động lượng trong Stochastic Gradient Descent

Như bạn đã thấy, tốc độ học tập có thể có tác động đáng kể đến kết quả giảm độ dốc. Bạn có thể sử dụng một số chiến lược khác nhau để điều chỉnh tốc độ học tập trong quá trình thực thi thuật toán. Bạn cũng có thể áp dụng động lượng cho thuật toán của mình

Bạn có thể sử dụng năng lượng để điều chỉnh ảnh hưởng của tốc độ học. Ý tưởng là ghi nhớ lần cập nhật trước của màn hình và áp dụng nó khi tính toán tiếp theo. Bạn không di chuyển góc nhìn chính xác theo hướng của gradient âm, nhưng bạn cũng có xu hướng giữ nguyên hướng và độ lớn từ lần di chuyển trước đó

Tham số được gọi là tốc độ phân tích hoặc hệ thống số phân tích xác định mức đóng góp của bản cập nhật trước đó. Để bao gồm lượng và tốc độ phân tách, bạn có thể sửa đổi 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
3 bằng cách bổ sung thông số 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
37và sử dụng nó để tính hướng và độ lớn của bản cập nhật véc-tơ ( 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6)

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
6

Trong quá trình khai triển này, bạn thêm 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
37tham số vào dòng 4, chuyển đổi nó thành mảng NumPy có kiểu mong muốn trên dòng 34 và kiểm tra xem nó có nằm trong khoảng từ 0 đến 1 trên dòng 35 và 36. Ở dòng 57, bạn đã khởi tạo 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6 trước khi bắt đầu lặp lại để đảm bảo rằng nó có sẵn trong lần đầu tiên

Change the importantquan trọng nhất xảy ra trên dòng 71. Bạn tính toán lại 

>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6với tốc độ học và độ dốc nhưng cũng bổ sung số lượng của tốc độ phân rã và giá trị cũ của 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6. Bây giờ 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.8
.. )
-4.77519666596786e-07
6có hai thành phần

  1.  1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    44 là động lượng, hoặc tác động của trạng thái trước đó
  2.  1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    45 là tác động của gradient hiện tại

Phân biệt tỷ lệ và Tỷ lệ học tập đóng vai trò trò chơi là một số quan trọng xác định sự đóng góp của cả hai

Random value start

Trái ngược với việc giảm độ dốc thông thường, điểm bắt đầu thường không quá quan trọng đối với việc giảm độ dốc ngẫu nhiên. Nó cũng có thể là một khó khăn không cần thiết cho người dùng, đặc biệt là khi bạn có nhiều biến quyết định. Để có ý tưởng, chỉ cần tưởng tượng nếu bạn cần khởi tạo thủ công các giá trị cho mạng nơ-ron với hàng nghìn thành kiến ​​và trọng số

Trong thực tế, bạn có thể bắt đầu với một số giá trị nhỏ tùy ý. Bạn sẽ sử dụng trình tạo số ngẫu nhiên để lấy chúng

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
7

Bây giờ bạn có tham số mới 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
46 xác định số biến quyết định trong vấn đề của bạn. Tham số 
>>> gradient_descent(
..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
.. )
2.210739197207331e-06
0 là tùy chọn và có giá trị mặc định 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
00. Dòng 27 đến 31 khởi tạo các giá trị bắt đầu của các biến quyết định

  • Nếu bạn cung cấp một giá trị 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    0 khác với 
     1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    00, thì giá trị đó sẽ được sử dụng cho các giá trị ban đầu
  • If 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.2
    .. )
    2.210739197207331e-06
    
    0là 
     1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    00, sau đó bộ tạo số ngẫu nhiên của bạn tạo ra các giá trị bắt đầu bằng cách sử dụng  và phương pháp NumPy 
     1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    53

Bây giờ 

>>> gradient_descent(
..     gradient=lambda v: np.array([2 * v[0], 4 * v[1]**3]),
..     start=np.array([1.0, 1.0]), learn_rate=0.2, tolerance=1e-08
.. )
array([8.08281277e-12, 9.75207120e-02])
3 hãy thử

>>>

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
8

You back got to results

Bạn đã học cách viết các hàm khai triển giảm độ dốc và giảm dần độ dốc ngẫu nhiên. Đoạn mã trên có thể được làm mạnh mẽ và bóng tốt hơn. Bạn cũng có thể tìm thấy các cách phát triển khác nhau của các phương pháp này trong các thư viện học máy nổi tiếng

Gradient Descent trong Keras và TensorFlow

Độ dốc gốc ngẫu nhiên được sử dụng rộng rãi để đào tạo mạng nơ-ron. Các thư viện dành cho mạng nơ-ron thường có các biến thể khác nhau của thuật toán tối ưu hóa dựa trên đường xuống dốc ngẫu nhiên, chẳng hạn như giới hạn

  • Adam
  • Adagrad
  • Adadelta
  • RMSProp

Các thư viện tối ưu hóa này thường được gọi trong bộ nội bộ khi phần mềm mạng nơ-ron được đào tạo. Tuy nhiên, bạn cũng có thể sử dụng chúng một cách độc lập

>>>

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
9

Trong ví dụ này, trước tiên bạn nhập 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
55và sau đó tạo đối tượng cần thiết để tối ưu hóa

  •  1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    56là một ví dụ về trình độ tối ưu hóa dốc nghiêng ngẫu nhiên với tốc độ học tập 
    >>> gradient_descent(
    ..     gradient=lambda v: 2 * v, start=10.0, learn_rate=0.005
    .. )
    6.050060671375367
    
    7và động lượng là 
     1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    58
  •  1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    59là một thể hiện của biến quyết định với giá trị ban đầu là 
     1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    60
  •  1import numpy as np
     2
     3def gradient_descent(
     4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
     5):
     6    vector = start
     7    for _ in range(n_iter):
     8        diff = -learn_rate * gradient(vector)
     9        if np.all(np.abs(diff) <= tolerance):
    10            break
    11        vector += diff
    12    return vector
    
    61 là hàm chi phí, là hàm bình phương trong trường hợp này

Phần chính của mã là một 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
16 vòng lặp đi lặp lại các cuộc gọi 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
63và sửa đổi 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
59và 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
61. Khi hết vòng lặp, bạn có thể nhận giá trị của biến quyết định và hàm chi phí với 
 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
66

Bạn có thể tìm thêm thông tin về các thuật toán này trong tài liệu Keras và TensorFlow. Bài viết Tổng quan về các thuật toán tối ưu hóa độ dốc cung cấp một danh sách đầy đủ với các giải thích về các biến có thể giảm dần độ dốc

 

Loại bỏ các quảng cáo

Phần kết luận

Bây giờ bạn đã biết thuật toán giảm độ dốc và giảm độ dốc ngẫu nhiên là gì và chúng hoạt động như thế nào. Chúng được sử dụng rộng rãi trong các ứng dụng của mạng nơ-ron nhân tạo và được khai thác trong các thư viện phổ biến như Keras và TensorFlow

Trong hướng dẫn này, bạn đã học được

  • Cách viết các chức năng của riêng bạn để giảm độ dốc và giảm độ dốc ngẫu nhiên
  • Cách áp dụng các chức năng của bạn để giải quyết các vấn đề tối ưu hóa
  • Các tính năng và khái niệm chính của việc giảm độ dốc là bất cứ điều gì, chẳng hạn như tốc độ học tập hoặc động lượng, cũng như các hạn chế của nó

Bạn đã sử dụng phương pháp giảm độ dốc và giảm độ dốc ngẫu nhiên để tìm cực tiểu của một hàm số và để phù hợp với đường hồi quy trong một bài toán hồi quy tuyến tính. Bạn đã thấy cách áp dụng lớp 

 1import numpy as np
 2
 3def gradient_descent(
 4    gradient, start, learn_rate, n_iter=50, tolerance=1e-06
 5):
 6    vector = start
 7    for _ in range(n_iter):
 8        diff = -learn_rate * gradient(vector)
 9        if np.all(np.abs(diff) <= tolerance):
10            break
11        vector += diff
12    return vector
67từ TensorFlow được sử dụng để đào tạo mạng thần kinh cũng như