Dönme açısının parametrelendirilmesi regresyonu


15

Diyelim ki yukarıdan aşağıya bir ok resmim var ve bu okun açısını tahmin etmek istiyorum. Bu arasında olacak ve 360 derece arasında veya 0 ve 2 π . Sorun şu ki, bu hedef daireseldir, 0 ve 360 derece aynıdır, bu da benim hedefime dahil etmek istediğim bir değişmezliktir, bu da genellemeye önemli ölçüde yardımcı olmalıdır (bu benim varsayımım). Sorun şu ki, bunu çözmenin temiz bir yolunu göremiyorum, bu sorunu (veya benzerlerini) çözmeye çalışan kağıtlar var mı? Potansiyel dezavantajları ile ilgili bazı fikirlerim var:036002π0360

  • Bir sigmoid veya tanh aktivasyonu kullanın, ( aralığına ölçeklendirin ve dairesel özelliği kayıp fonksiyonuna dahil edin. Bunun oldukça zor olacağını düşünüyorum, çünkü eğer sınırdaysa (en kötü tahmin) sadece küçük bir gürültü ağırlıkları bir yöne doğru iter. Ayrıca, 0 ve sınırına daha yakın değerlere ulaşmak daha zor olacaktır, çünkü mutlak ön aktivasyon değerinin sonsuza yakın olması gerekecektir.0,2π)02π

  • İki değere, bir ve değerine gerileyin ve bu iki değerin yaptığı açıya göre kaybı hesaplayın. Bunun daha fazla potansiyeli olduğunu düşünüyorum, ancak bu vektörün normu sınırsız, bu da sayısal kararsızlığa yol açabilir ve eğitim sırasında patlamaya veya 0'a yol açabilir. Bu, bu normun 1'den çok uzaklaşmasını önlemek için bazı garip düzenleyiciler kullanılarak çözülebilir.xy

Diğer seçenekler sinüs ve kosinüs fonksiyonları ile bir şeyler yapmak olurdu, ancak çoklu ön aktivasyonların aynı çıktıya eşlenmesinin de optimizasyon ve genellemeleri çok zorlaştıracağını hissediyorum.


Dürüst olmak gerekirse, toplam rotasyonu tahmin etmenin daha kolay olacağını ve daha iyi sonuçlar alacağını düşünüyorum. Şunlar arasından eşleyebilir örneğin için π İstersen aslında sonra. Çarpma işleminden sonra birim çember üzerindeki açıyı tahmin etmeye çalışmak aslında 2 by'ye bölündükten sonra kalanını tahmin etmeye çalışıyor ve bunun toplam büyüklüğü tahmin etmekten ve daha sonra 2 multip katlarını çıkarmaktan daha kolay olacağını göremiyorum . 3ππ2π2π
tom

1
Seçenekler a) yan adım periyodikliktir: sigmoid aktivasyon fonksiyonu kullanarak açının günahını ve cos'ını tahmin edin. b) simetriyi, böyle bir çekirdek vasıtasıyla kayıp fonksiyonuna dahil edin . Rotasyon grupları ve Taco Cohen'in dönüşüm gruplarını öğrenme tezi hakkında bilgi edinin . Ne yazık ki grup teorisi hakkında bilgim yok, bu yüzden daha fazla yardım edemem.
Emre

@tom Bu yaklaşımla ilgili olan şey, ortak hiçbir şeyleri olmadığı halde aynı açıya eşlenen sonsuz ön aktivasyonların olmasıdır. Pozitif x1, her zaman bir açı -1/2 arasında atıfta bulunmakla birlikte 2 \ ve 1 π . Ve Emre, bazı grup teorileriyle çalışacağım, her zaman ilgimi çekti, bu yüzden ML ve grup teorisinin kombinasyonu bana hitap edecekππ
Jan van der Vegt

Yanıtlar:


15

İkinci şekilde, ve y = s i n ( α ) tahminleri tamam.x=cÖs(α)y=sbenn(α)

Evet, tahmin edilen vektörün normunun 1'e yakın olduğu garanti edilmez . Ancak, özellikle sigmoid aktivasyon işlevlerini (doğası gereği sınırlıdır) kullanıyorsanız ve / veya modelinizi iyi düzenlerseniz havaya uçması muhtemel değildir. Tüm eğitim örnekleri [ - 1 , 1 ] ' de ise modeliniz neden büyük bir değer öngörmeli ?(x,y)1[-1,1]

Başka bir yan vektörüdür çok yakın ( 0 , 0 ) . Bu bazen olabilir ve gerçekten de yanlış açıların tahmin edilmesiyle sonuçlanabilir. Ancak modelinizin bir yararı olarak görülebilir - ( x , y ) normunu modelinizin güven ölçüsü olarak düşünebilirsiniz . Gerçekten de, 0'a yakın bir norm, modelinizin doğru yönün nerede olduğundan emin olmadığı anlamına gelir.(x,y)(0,0)(x,y)

Python'da günah ve cos'u tahmin etmenin daha iyi olduğunu, açıyı doğrudan tahmin etmenin daha iyi olduğunu gösteren küçük bir örnek:

# predicting the angle (in radians)
import numpy as np
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import r2_score
# generate toy data
np.random.seed(1)
X = np.random.normal(size=(100, 2))
y = np.arctan2(np.dot(X, [1,2]), np.dot(X, [3,0.4]))
# simple prediction
model = MLPRegressor(random_state=42, activation='tanh', max_iter=10000)
y_simple_pred = cross_val_predict(model, X, y)
# transformed prediction
joint = cross_val_predict(model, X, np.column_stack([np.sin(y), np.cos(y)]))
y_trig_pred = np.arctan2(joint[:,0], joint[:,1])
# compare
def align(y_true, y_pred):
    """ Add or remove 2*pi to predicted angle to minimize difference from GT"""
    y_pred = y_pred.copy()
    y_pred[y_true-y_pred >  np.pi] += np.pi*2
    y_pred[y_true-y_pred < -np.pi] -= np.pi*2
    return y_pred
print(r2_score(y, align(y, y_simple_pred))) # R^2 about 0.57
print(r2_score(y, align(y, y_trig_pred)))   # R^2 about 0.99

Sinüs-kosinüs modelinin öngörülerinin neredeyse doğru olduğunu görmek için devam edebilir ve tahminleri çizebilirsiniz, ancak daha fazla kalibrasyona ihtiyaç duyabilir:

import matplotlib.pyplot as plt
plt.figure(figsize=(12, 3))
plt.subplot(1,4,1)
plt.scatter(X[:,0], X[:,1], c=y)
plt.title('Data (y=color)'); plt.xlabel('x1'); plt.ylabel('x2')
plt.subplot(1,4,2)
plt.scatter(y_simple_pred, y)
plt.title('Direct model'); plt.xlabel('prediction'); plt.ylabel('actual')
plt.subplot(1,4,3)
plt.scatter(y_trig_pred, y)
plt.title('Sine-cosine model'); plt.xlabel('prediction'); plt.ylabel('actual')
plt.subplot(1,4,4)
plt.scatter(joint[:,0], joint[:,1], s=5)
plt.title('Predicted sin and cos'); plt.xlabel('cos'); plt.ylabel('sin')
plt.tight_layout();

resim açıklamasını buraya girin

Güncelleme . Bir navigasyon mühendisi, açı yakın olduğunda böyle bir modelin en doğru olacağını fark etti.πN-2αmarul(α)günah(α)z=günah(α+π4)w=marul(α+π4)

(x,y)(z,w)(x,y)arctan2


Bu mükemmel, çok teşekkürler. Daha fazla inceleyeceğim, daha fazla boyuta genişletmem gerekecek
Jan van der Vegt

2

Kartezyen koordinatlarla çalışmak yukarıda belirtildiği gibi iyi çalışır. Yine de, bence, polar verileri Kartezyen'e dönüştürmek, verilerde orijinal olarak bulunmayan X ve Y koordinatları arasında bağımlılıklar yaratır. Örneğin, bir robotun yol karar modeli kutupsal koordinatlarda Kartezyen'den daha sezgiseldir. Robotun hız vektörünün açı ve büyüklük arasındaki kutupsal koordinatlarda bağımlılığı var olmayabilir veya Kartezyen koordinatlardaki bağımlılıktan farklı olabilir.

Kutupsal koordinatlarla çalışmaya devam ettiğim bir geçici çözüm, MATLAB'daki angdiff () işlevini ve her zamanki gibi büyüklük farkını kullanarak açı farkını hesaplamak için özel bir hata işlevi oluşturmaktır.

Bu işlev -pi ve pi arasındaki fark için '0' değerini döndürür. Mathworks web sitesindeki işlevler destek sayfasına bir bağlantı.

https://www.mathworks.com/help/robotics/ref/angdiff.html

Sigmoid aktivasyonunu kullanıyorsanız ve açı verileriniz [0,1] arasında normalleştirilmişse, angdiff () işlevini kullanmadan önce [-pi, pi] aralığına döndürmeli ve hatayı tekrar [0,1 ] geri yayılım işlemi için aralık.

Ek olarak, Python'daki eşdeğer işlev şöyle olacaktır:

import numpy as np


def angdiff(a, b):
    delta = np.arctan2(np.sin(b-a), np.cos(b-a))
    delta = np.around(delta, 4)  # Since np.sin(pi) result is 1.22e-16
    delta += 0.  # Since np.around return -0.
    return delta


pi = np.pi
a = np.asarray([pi/2, 3*pi/4, 0])
b = np.asarray([pi, pi/2, -pi])

print(angdiff(a, b))
print(angdiff(pi, -pi))
print(angdiff(-pi, pi))

Bu, MATLAB işlevi ile benzer sonuçlar döndürür ve dizilerle de çalışır:

[ 1.5708 -0.7854 -3.1416]
0.0
0.0

Umarım yardımcı olur.

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.