Vektör işlemlerine dayalı stokastik degrade iniş?


10

Diyelim ki N örneği olan bir veri kümesi kullanarak stokastik bir degrade iniş regresyon algoritması eğitmek istiyorum. Veri kümesinin boyutu sabit olduğundan, veri T zamanlarını yeniden kullanacağım. Her yinelemede veya "dönem" de, tüm eğitim setini rastgele yeniden sıraladıktan sonra her eğitim örneğini tam olarak bir kez kullanıyorum.

Benim uygulama Python ve Numpy dayanmaktadır. Bu nedenle, vektör işlemlerinin kullanılması hesaplama süresini önemli ölçüde azaltabilir. Toplu degrade inişin vektörize bir uygulaması ile gelmek oldukça basittir. Bununla birlikte, stokastik gradyan iniş durumunda, her çağda tüm numuneler boyunca yinelenen dış döngüden nasıl kaçınılacağını anlayamıyorum.

Stokastik gradyan inişin vektörize edilmiş bir uygulamasını bilen var mı?

DÜZENLEME : Veri kümemin boyutu sabitse neden çevrimiçi degrade inişini kullanmak istediğim soruldu.

[1] 'den, çevrimiçi gradyan inişinin, toplu gradyan inişinden ampirik maliyetin minimumuna daha yavaş yakınsadığı görülebilir. Bununla birlikte, genelleme performansını ölçen, beklenen maliyetin en aza indirgenir. Bu teorik sonuçların özel problemimdeki etkilerini çapraz doğrulama yoluyla test etmek istiyorum. Vektörize edilmiş bir uygulama olmadan, çevrimiçi degrade iniş kodum toplu degrade iniş kodundan çok daha yavaştır. Bu, çapraz doğrulama sürecinin tamamlanması için gereken süreyi önemli ölçüde artırır.

EDIT : Ben burada arkadaşım tarafından istendiği gibi, on-line degrade iniş uygulamasının sözde kodu dahil. Bir regresyon problemini çözüyorum.

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] "Büyük Ölçekli Çevrimiçi Öğrenme", L. Bottou, Y. Le Cunn, NIPS 2003.


2
Veri kümesini mini partilere ayırın ve her mini partiye sırayla model takın.
14'te arkadaş

Teşekkürler @ffriend. Ancak, bu tamamen çevrimiçi bir uygulama değildir.
Pablo Suau

1
Veri kümeniz düzeltildiyse "salt çevrimiçi" uygulamayı kullanmanın nedeni nedir? SGD yalnızca tüm veri kümesini bir kerede yinelemenize gerek olmadığını, ancak rastgele sayıda parçaya (mini gruplar) bölüp tek tek işleyebileceğini söylüyor. 1 büyüklüğündeki mini parti yalnızca sürekli ve muhtemelen sonsuz veri kaynağınız varsa (örneğin twitter feed gibi) ve her yeni gözlemden sonra modeli güncellemek istediğinizde anlamlıdır. Ancak bu çok nadir bir durumdur ve kesinlikle sabit veri kümeleri için değildir.
14'te arkadaş

Çok geç cevap verdiğim için özür dilerim. Lütfen, orijinal soruya eklediğim metni kontrol edin.
Pablo Suau

1
Uygulamanızı gösterebilir misiniz? Yanlış anlama görüyorum, ancak kod örneği olmadan bunu açıklamak zor olacak.
arkadaş

Yanıtlar:


10

Her şeyden önce, "örnek" sözcüğü normalde popülasyonun alt kümesini tanımlamak için kullanılır , bu yüzden "örnek" ile aynı şeyi ifade edeceğim.

SGD uygulamanız bu hat nedeniyle yavaş:

for each training example i:

Burada her bir model parametresi güncellemesi için tam olarak bir örnek kullanıyorsunuz. Tanım olarak, vektörleştirme bir eleman üzerindeki işlemleri bu elemanların bir vektörü üzerindeki operasyonlara dönüştürmek için kullanılan bir tekniktir. Böylece, hayır, örnekleri tek tek işleyemez ve yine de vektörleştirmeyi kullanamazsınız.

Bununla birlikte, mini partileri kullanarak gerçek SGD'ye yaklaşabilirsiniz . Mini seri, orijinal veri kümesinin küçük bir alt kümesidir (örneğin, 100 örnek). Mini partilere dayalı hata ve parametre güncellemelerini hesaplarsınız, ancak yine de küresel optimizasyon olmadan çoğunu yineleyerek işlemi stokastik hale getirirsiniz. Bu nedenle, uygulamanızı çok daha hızlı hale getirmek için önceki satırı şu şekilde değiştirmek yeterlidir:

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

ve tek bir örnekten değil, toplu işteki hatayı hesaplayın.

Oldukça açık olmasına rağmen, örnek başına vektörizasyondan da bahsetmeliyim. Yani, böyle bir şey yerine:

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

kesinlikle böyle bir şey yapmalısın:

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

yine, mini partiler için genellemesi kolay:

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
Bence bu yol. İyi seçilmiş bir boyuta sahip mini partiler, toplu işten veya çevrimiçi sürümden daha hızlı bir şekilde birleşebilir (eski, tüm set başına yalnızca bir kez ağırlıkları günceller ve ikincisi vektörleştirilemez, ayrıca ek ağırlık güncelleme adımlarına daha sık sahiptir)
Neil Slater

İkinize de teşekkürler. Mini partileri inatla reddetmek için özür dilerim, ama bu yöntemin yakınsama oranı üzerindeki etkilerinden emin değildim. Neil, olumluluğun kendi deneyiminden mi geliyor, yoksa teorik / ampirik olarak yayınlanan sonuçlar var mı?
Pablo Suau

1
@PabloSuau Andrew Ng'in Machine Learning sınıfını 10. haftada kontrol edebilirsiniz, 10. haftada yakınsamanın neden hem SGD hem de toplu GD'den daha hızlı olabileceğini açıklıyor. Daha kesin olmak gerekirse: her zaman SGD kadar hızlı olmalı, ancak bazen pratikte daha da hızlı olmalıdır.
gaborous

1

Scikit'in SGD sınıflandırıcısının partial_fit yöntemine göz atın . Onunla ne aradığınızı kontrol edebilirsiniz: bir seferde bir örnek ileterek "gerçek" çevrimiçi öğrenmeyi yapabilir veya tüm verileriniz bir dizide mevcutsa örnekleri mini gruplara ayırabilirsiniz. Eğer öyleyse, minibatchları sağlamak için diziyi dilimleyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.