Làm thế nào để giảm độ dốc ngẫu nhiên có thể tiết kiệm thời gian so với độ dốc gốc tiêu chuẩn?


15

Tiêu chuẩn Gradient Descent sẽ tính toán độ dốc cho toàn bộ tập dữ liệu đào tạo.

for i in range(nb_epochs):
  params_grad = evaluate_gradient(loss_function, data, params)
  params = params - learning_rate * params_grad

Đối với số lượng epoch được xác định trước, trước tiên, chúng tôi tính toán vectơ gradient trọng số_grad của hàm mất cho toàn bộ tập dữ liệu ghi thông số vectơ tham số của chúng tôi.

Ngược lại, Stochastic Gradient Descent thực hiện cập nhật tham số cho từng ví dụ đào tạo x (i) và nhãn y (i).

for i in range(nb_epochs):
  np.random.shuffle(data)
  for example in data:
    params_grad = evaluate_gradient(loss_function, example, params)
    params = params - learning_rate * params_grad

SGD được cho là nhanh hơn nhiều. Tuy nhiên, tôi không hiểu làm thế nào nó có thể nhanh hơn nhiều nếu chúng ta vẫn có một vòng lặp trên tất cả các điểm dữ liệu. Có phải tính toán độ dốc trong GD chậm hơn nhiều so với tính toán GD cho từng điểm dữ liệu một cách riêng biệt?

Mã đến từ đây .


1
Trong trường hợp thứ hai, bạn sẽ lấy một lô nhỏ để xấp xỉ toàn bộ tập dữ liệu. Điều này thường hoạt động khá tốt. Vì vậy, phần khó hiểu có lẽ là số lượng epoch giống nhau trong cả hai trường hợp, nhưng bạn sẽ không cần nhiều epoch trong trường hợp 2. "hyperparameter" sẽ khác nhau đối với hai phương thức đó: GD nb_epochs! = SGD nb_epochs. Giả sử mục đích của đối số: GD nb_epochs = ví dụ SGD * nb_epochs, để tổng số vòng lặp là như nhau, nhưng tính toán độ dốc nhanh hơn trong SGD.
Nima Mousavi

Câu trả lời này trên CV là một câu hỏi hay và có liên quan.
Zhubarb

Câu trả lời:


23

Câu trả lời ngắn:

  • Trong nhiều cài đặt dữ liệu lớn (giả sử vài triệu điểm dữ liệu), việc tính toán chi phí hoặc độ dốc mất rất nhiều thời gian, bởi vì chúng ta cần tổng hợp trên tất cả các điểm dữ liệu.
  • Chúng ta KHÔNG cần phải có độ dốc chính xác để giảm chi phí trong một lần lặp nhất định. Một số xấp xỉ của gradient sẽ hoạt động tốt.
  • Độ dốc màu ngẫu nhiên (SGD) xấp xỉ độ dốc chỉ sử dụng một điểm dữ liệu. Vì vậy, việc đánh giá độ dốc giúp tiết kiệm rất nhiều thời gian so với tổng hợp trên tất cả dữ liệu.
  • Với số lần lặp "hợp lý" (con số này có thể là vài nghìn và ít hơn nhiều so với số điểm dữ liệu có thể là hàng triệu), độ dốc ngẫu nhiên có thể có được một giải pháp tốt hợp lý.

Câu trả lời dài:

Ký hiệu của tôi theo khóa học Coursera của Andrew NG. Nếu bạn không quen thuộc với nó, bạn có thể xem lại chuỗi bài giảng ở đây .

Giả sử hồi quy về tổn thất bình phương, hàm chi phí là

J(θ)= =12mΣTôi= =1m(hθ(x(Tôi))-y(Tôi))2

và độ dốc là

dJ(θ)dθ= =1mΣTôi= =1m(hθ(x(Tôi))-y(Tôi))x(Tôi)

đối với độ dốc tốt (GD), chúng tôi cập nhật tham số bằng

θnew= =θotôid-α1mΣTôi= =1m(hθ(x(Tôi))-y(Tôi))x(Tôi)

1/mx(Tôi),y(Tôi)

θnew= =θotôid-α(hθ(x(Tôi))-y(Tôi))x(Tôi)

Đây là lý do tại sao chúng tôi đang tiết kiệm thời gian:

Giả sử chúng ta có 1 tỷ điểm dữ liệu.

  • Trong GD, để cập nhật các tham số một lần, chúng ta cần phải có độ dốc (chính xác). Điều này đòi hỏi phải tổng hợp 1 tỷ điểm dữ liệu này để thực hiện 1 cập nhật.

  • Trong SGD, chúng ta có thể nghĩ về nó như cố gắng để có được một gradient xấp xỉ thay vì gradient chính xác . Phép tính gần đúng đến từ một điểm dữ liệu (hoặc một số điểm dữ liệu được gọi là lô nhỏ). Do đó, trong SGD, chúng tôi có thể cập nhật các thông số rất nhanh. Ngoài ra, nếu chúng tôi "lặp lại" tất cả dữ liệu (được gọi là một epoch), chúng tôi thực sự có 1 tỷ cập nhật.

Mẹo nhỏ là, trong SGD, bạn không cần phải có 1 tỷ lần lặp / cập nhật, nhưng số lần lặp / cập nhật ít hơn nhiều, giả sử là 1 triệu và bạn sẽ có mô hình "đủ tốt" để sử dụng.


Tôi đang viết một mã để demo ý tưởng. Đầu tiên chúng ta giải hệ phương trình tuyến tính bằng phương trình bình thường, sau đó giải nó bằng SGD. Sau đó, chúng tôi so sánh các kết quả về các giá trị tham số và giá trị hàm mục tiêu cuối cùng. Để hình dung nó sau, chúng ta sẽ có 2 tham số để điều chỉnh.

set.seed(0);n_data=1e3;n_feature=2;
A=matrix(runif(n_data*n_feature),ncol=n_feature)
b=runif(n_data)
res1=solve(t(A) %*% A, t(A) %*% b)

sq_loss<-function(A,b,x){
  e=A %*% x -b
  v=crossprod(e)
  return(v[1])
}

sq_loss_gr_approx<-function(A,b,x){
  # note, in GD, we need to sum over all data
  # here i is just one random index sample
  i=sample(1:n_data, 1)
  gr=2*(crossprod(A[i,],x)-b[i])*A[i,]
  return(gr)
}

x=runif(n_feature)
alpha=0.01
N_iter=300
loss=rep(0,N_iter)

for (i in 1:N_iter){
  x=x-alpha*sq_loss_gr_approx(A,b,x)
  loss[i]=sq_loss(A,b,x)
}

Kết quả:

as.vector(res1)
[1] 0.4368427 0.3991028
x
[1] 0.3580121 0.4782659

124.143123.0355

Dưới đây là các giá trị hàm chi phí qua các lần lặp, chúng ta có thể thấy nó có thể giảm tổn thất một cách hiệu quả, điều này minh họa ý tưởng: chúng ta có thể sử dụng một tập hợp con dữ liệu để xấp xỉ độ dốc và nhận được kết quả "đủ tốt".

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

1000sq_loss_gr_approx3001000


Tôi nghĩ rằng đối số về "tốc độ" là nhiều hơn về việc cần bao nhiêu thao tác / lần lặp để hội tụ đến mức tối ưu cục bộ? (Và cũng có thể giảm độ dốc ngẫu nhiên có xu hướng hội tụ để tối ưu hóa tốt hơn .)
GeoMatt22

Theo như tôi hiểu, trong mã python tôi đã cung cấp "dữ liệu" có thể thay đổi giống nhau. Độ dốc hàng loạt nhỏ - mã khác với SDG (và chính xác là anh ta chỉ sử dụng một phần nhỏ dữ liệu). Ngoài ra, trong phần giải thích bạn đã cung cấp, mặc dù chúng tôi đã loại bỏ tổng số trong SDG, chúng tôi vẫn tính toán cập nhật cho từng điểm dữ liệu. Tôi vẫn không hiểu cách cập nhật một tham số trong khi lặp qua từng điểm dữ liệu nhanh hơn là chỉ lấy một tổng số trên tất cả các điểm dữ liệu cùng một lúc.
Alina

@ GeoMatt22 Trong liên kết tôi cung cấp có ghi: "Mặt khác, điều này cuối cùng làm phức tạp sự hội tụ đến mức tối thiểu chính xác, vì SGD sẽ tiếp tục quá mức." Có nghĩa là nó không hội tụ để tối ưu tốt hơn. Hay tôi đã hiểu sai?
Alina

@Tonja Tôi không phải là chuyên gia, nhưng ví dụ, bài viết có ảnh hưởng lớn này trong nghiên cứu sâu đưa ra lập luận "đào tạo nhanh hơn đáng tin cậy hơn" cho việc giảm độ dốc ngẫu nhiên. Lưu ý rằng nó không sử dụng phiên bản "thô", nhưng sử dụng các ước tính độ cong khác nhau để đặt tốc độ học tập (phụ thuộc vào tọa độ).
GeoMatt22

1
@Tonja, vâng. bất kỳ xấp xỉ "yếu" nào của gradient sẽ hoạt động. Bạn có thể kiểm tra "tăng cường độ dốc", đó là ý tưởng tương tự. Mặt khác, tôi đang viết một số mã để demo ý tưởng. Tôi sẽ đăng nó khi nó đã sẵn sàng.
Haitao Du
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.