Độ dốc dốc ngẫu nhiên dựa trên các hoạt động vector?


10

giả sử rằng tôi muốn đào tạo một thuật toán hồi quy giảm dần độ dốc ngẫu nhiên bằng cách sử dụng bộ dữ liệu có N mẫu. Vì kích thước của tập dữ liệu là cố định, tôi sẽ sử dụng lại dữ liệu T lần. Ở mỗi lần lặp hoặc "kỷ nguyên", tôi sử dụng mỗi mẫu đào tạo chính xác một lần sau khi sắp xếp lại ngẫu nhiên toàn bộ tập huấn luyện.

Việc triển khai của tôi dựa trên Python và Numpy. Do đó, sử dụng các phép toán vectơ có thể làm giảm đáng kể thời gian tính toán. Việc đưa ra một triển khai véc tơ của việc giảm độ dốc hàng loạt là khá đơn giản. Tuy nhiên, trong trường hợp giảm độ dốc ngẫu nhiên, tôi không thể tìm ra cách tránh vòng lặp bên ngoài lặp lại qua tất cả các mẫu ở mỗi kỷ nguyên.

Có ai biết bất kỳ thực hiện véc tơ của giảm dần độ dốc ngẫu nhiên?

EDIT : Tôi đã được hỏi tại sao tôi muốn sử dụng giảm dần độ dốc trực tuyến nếu kích thước của tập dữ liệu của tôi là cố định.

Từ [1], người ta có thể thấy rằng độ dốc của độ dốc trực tuyến hội tụ chậm hơn độ dốc của độ dốc hàng loạt đến mức tối thiểu của chi phí theo kinh nghiệm. Tuy nhiên, nó hội tụ nhanh hơn đến mức tối thiểu của chi phí dự kiến, đo lường hiệu suất tổng quát hóa. Tôi muốn kiểm tra tác động của các kết quả lý thuyết này trong vấn đề cụ thể của tôi, bằng phương pháp xác nhận chéo. Nếu không có triển khai véc tơ, mã giảm độ dốc trực tuyến của tôi chậm hơn nhiều so với mã giảm dần theo lô. Điều đó làm tăng đáng kể thời gian cần thiết để quá trình xác nhận chéo được hoàn thành.

EDIT : Tôi bao gồm ở đây mã giả của việc thực hiện giảm độ dốc trực tuyến của tôi, theo yêu cầu của ffriend. Tôi đang giải quyết một vấn đề hồi quy.

Method: on-line gradient descent (regression)
Input: X (nxp matrix; each line contains a training sample, represented as a length-p vector), Y (length-n vector; output of the training samples)
Output: A (length-p+1 vector of coefficients)

Initialize coefficients (assign value 0 to all coefficients)
Calculate outputs F
prev_error = inf
error = sum((F-Y)^2)/n
it = 0
while abs(error - prev_error)>ERROR_THRESHOLD and it<=MAX_ITERATIONS:
    Randomly shuffle training samples
    for each training sample i:
        Compute error for training sample i
        Update coefficients based on the error above
    prev_error = error
    Calculate outputs F
    error = sum((F-Y)^2)/n
    it = it + 1

[1] "Học trực tuyến quy mô lớn", L. Bottou, Y. Le Cunn, NIPS 2003.


2
Chia dữ liệu thành các lô nhỏ và mô hình phù hợp với từng lô nhỏ theo tuần tự.
kết bạn

Cảm ơn bạn @ffriend. Tuy nhiên, đó sẽ không phải là một triển khai trực tuyến thuần túy.
Pablo Suau

1
Lý do để sử dụng triển khai "trực tuyến thuần túy" nếu tập dữ liệu của bạn là cố định? SGD chỉ nói rằng bạn không cần phải lặp lại toàn bộ tập dữ liệu cùng một lúc, nhưng có thể chia nó thành một số phần tùy ý (các lô nhỏ) và xử lý từng phần một. Lô nhỏ cỡ 1 chỉ có ý nghĩa khi bạn có nguồn dữ liệu liên tục và có thể là vô tận (ví dụ như nguồn cấp dữ liệu twitter) và muốn cập nhật mô hình sau mỗi lần quan sát mới. Nhưng đó là trường hợp rất hiếm và chắc chắn không phải cho các bộ dữ liệu cố định.

Xin lỗi vì phản ứng rất muộn của tôi. Xin vui lòng, kiểm tra văn bản mà tôi đã thêm vào câu hỏi ban đầu.
Pablo Suau

1
Bạn có thể cho thấy sự thực hiện của bạn? Tôi thấy sự hiểu lầm, nhưng không có mẫu mã sẽ khó giải thích nó.

Câu trả lời:


10

Trước hết, từ "mẫu" thường được sử dụng để mô tả tập hợp con của dân số , vì vậy tôi sẽ đề cập đến điều tương tự như "ví dụ".

Việc triển khai SGD của bạn chậm vì dòng này:

for each training example i:

Ở đây bạn rõ ràng sử dụng chính xác một ví dụ cho mỗi bản cập nhật các tham số mô hình. Theo định nghĩa, vector hóa là một kỹ thuật để chuyển đổi các hoạt động trên một yếu tố thành các hoạt động trên một vector của các yếu tố đó. Do đó, không, bạn không thể xử lý từng ví dụ một mà vẫn sử dụng vector hóa.

Tuy nhiên, bạn có thể ước chừng SGD thực bằng cách sử dụng các lô nhỏ . Mini-batch là một tập hợp con nhỏ của bộ dữ liệu gốc (giả sử, 100 ví dụ). Bạn tính toán các cập nhật lỗi và tham số dựa trên các lô nhỏ, nhưng bạn vẫn lặp đi lặp lại nhiều trong số chúng mà không tối ưu hóa toàn cầu, làm cho quá trình trở nên ngẫu nhiên. Vì vậy, để thực hiện nhanh hơn nhiều, bạn phải thay đổi dòng trước đó thành:

batches = split dataset into mini-batches
for batch in batches: 

và tính toán lỗi từ lô, không phải từ một ví dụ duy nhất.

Mặc dù khá rõ ràng, tôi cũng nên đề cập đến vector hóa ở cấp độ ví dụ. Đó là, thay vì một cái gì đó như thế này:

theta = np.array([...])  # parameter vector
x = np.array([...])      # example
y = 0                    # predicted response
for i in range(len(example)):
    y += x[i] * theta[i]
error = (true_y - y) ** 2  # true_y - true value of response

bạn chắc chắn nên làm một cái gì đó như thế này:

error = (true_y - sum(np.dot(x, theta))) ** 2

một lần nữa, dễ dàng khái quát hóa cho các lô nhỏ:

true_y = np.array([...])     # vector of response values
X = np.array([[...], [...]]) # mini-batch
errors = true_y - sum(np.dot(X, theta), 1)
error = sum(e ** 2 for e in errors)

1
Tôi nghĩ rằng đây là con đường để đi. Các lô nhỏ với kích thước được chọn tốt thực sự có thể hội tụ nhanh hơn cả lô hoặc phiên bản trực tuyến (trước đây chỉ cập nhật trọng số một lần trên toàn bộ và sau đó không thể được vector hóa, cộng với các bước cập nhật trọng lượng bổ sung thường xuyên hơn)
Neil Slater

Cảm ơn cả hai người. Xin lỗi vì đã từ chối các lô nhỏ trước đây, nhưng tôi không chắc về ý nghĩa của phương pháp này đối với tốc độ hội tụ. Neil, là sự khẳng định của bạn đến từ kinh nghiệm của chính bạn, hoặc có bất kỳ kết quả được công bố lý thuyết / thực nghiệm nào không?
Pablo Suau

1
@PabloSuau Bạn có thể kiểm tra lớp Machine Learning của Andrew Ng trên Coursera, tuần 10, anh ấy giải thích lý do tại sao sự hội tụ có thể nhanh hơn cả SGD và GD hàng loạt. Nói chính xác hơn: nó phải luôn nhanh như SGD, nhưng đôi khi nó còn nhanh hơn trong thực tế.
gabious

1

Kiểm tra phương thức part_fit của trình phân loại SGD của scikit . Bạn có quyền kiểm soát những gì bạn gọi với nó: bạn có thể thực hiện việc học trực tuyến "đúng" bằng cách chuyển một cá thể tại một thời điểm hoặc bạn có thể gộp các trường hợp thành các lô nhỏ nếu tất cả dữ liệu của bạn có sẵn trong một mảng. Nếu có, bạn có thể cắt mảng để cung cấp các xe buýt nhỏ.

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.