第二种方式,预测x = c o s ( α ) 和 是的= S我n ( α )完全没问题。
是的,预测的范数( x , y)向量不能保证在附近1. 但它不太可能爆发,特别是如果您使用 sigmoid 激活函数(受其性质限制)和/或很好地规范您的模型。如果所有训练样本都在[ - 1 , 1 ]?
另一面是矢量( x , y)太接近( 0 , 0 ). 这有时可能会发生,并且确实可能导致预测错误的角度。但这可能被视为您的模型的一个好处-您可以考虑( x , y)作为模型置信度的衡量标准。实际上,接近 0 的范数意味着您的模型不确定正确的方向在哪里。
这是 Python 中的一个小例子,它表明最好预测 sin 和 cos,直接预测角度:
# 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
您可以继续绘制预测,以查看正弦-余弦模型的预测几乎是正确的,尽管可能需要进一步校准:
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();
更新。一位导航工程师注意到,当角度接近πñ2. 事实上,接近 0° 和 180° 的角度α 几乎是线性的 因( α ),在 90° 和 270° 附近,它几乎是线性的 罪( α ). 因此,增加两个输出可能是有益的,例如z=罪( α +π4) 和 w = cos( α +π4), 使模型分别在 45° 和 135° 附近几乎是线性的。然而,在这种情况下,恢复原始角度并不那么明显。
最好的解决方案可能是提取坐标 ( x , y) 从两种表示中(在第二种表示中,我们需要旋转 ( z, w ) 要得到 ( x , y)),对它们进行平均,然后才计算arctan2
。