训练 NN 以计算 atan2(y, x)
Training NN to calculate atan2(y, x)
我一直在研究Q强化学习实现,其中Q(π,a(是神经网络的近似值。在故障排除过程中,我将问题简化为非常简单的第一步:训练 NN 来计算 atan2(y, x(。
我正在使用 FANN 来解决这个问题,但库在很大程度上无关紧要,因为这个问题更多的是关于要使用的适当技术。
我一直在努力教 NN,给定输入 = {x, y},以计算输出 = atan2(y, x(。
这是我一直在使用的幼稚方法。这非常简单,但我试图保持简单。
#include "fann.h"
#include <cstdio>
#include <random>
#include <cmath>
int main()
{
// creates a 3 layered, densely connected neural network, 2-3-1
fann *ann = fann_create_standard(3, 2, 3, 1);
// set the activation functions for the layers
fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(ann, FANN_SIGMOID_SYMMETRIC);
fann_type input[2];
fann_type expOut[1];
fann_type *calcOut;
std::default_random_engine rng;
std::uniform_real_distribution<double> unif(0.0, 1.0);
for (int i = 0; i < 100000000; ++i) {
input[0] = unif(rng);
input[1] = unif(rng);
expOut[0] = atan2(input[1], input[0]);
// does a single incremental training round
fann_train(ann, input, expOut);
}
input[0] = unif(rng);
input[1] = unif(rng);
expOut[0] = atan2(input[1], input[0]);
calcOut = fann_run(ann, input);
printf("Testing atan2(%f, %f) = %f -> %fn", input[1], input[0], expOut[0], calcOut[0]);
fann_destroy(ann);
return 0;
}
超级简单,对吧?然而,即使经过 100,000,000 次迭代,这个神经网络也会失败:
测试 atan2(0.949040, 0.756997( = 0.897493 -> 0.987712
我还尝试在输出层(FANN_LINEAR
(上使用线性激活函数。没有运气。事实上,结果要糟糕得多。经过 100,000,000 次迭代后,我们得到:
测试 atan2(0.949040, 0.756997( = 0.897493 -> 7.648625
这甚至比随机初始化权重时还要糟糕。NN 在训练后怎么会变得更糟?
我发现FANN_LINEAR
这个问题与其他测试一致。当需要线性输出时(例如,在计算Q值时,对应于任意大或小的奖励(,这种方法会惨败,误差实际上似乎随着训练而增加。
这到底是怎么回事呢?在这种情况下,使用全连接的 2-3-1 NN 是否不合适?隐藏层中的对称 S 形激活函数是否不合适?我看不出还有什么可以解释此错误。
您面临的问题是正常的,并且预测器的质量不会通过增加迭代次数来提高,您应该通过添加一些层或增加隐藏层的大小来增加 NN 的大小。例如,您可以尝试 2-256-128-1,而不是 2-3-1。通常这会更好。如果你想看看我用python编写的这个简单的代码来做同样的任务,它运行良好。
import numpy as np
from numpy import arctan2
from keras.models import Sequential
from keras.layers import Dense, InputLayer
nn_atan2 = Sequential()
nn_atan2.add(Dense(256, activation="sigmoid", input_shape=(2,)))
nn_atan2.add(Dense(128, activation="sigmoid"))
nn_atan2.add(Dense(1, activation='tanh'))
nn_atan2.compile(optimizer="adam", loss="mse")
nn_atan2.summary()
N = 100000
X = np.random.uniform(size=(N,2) )
y = arctan2(X[:,0], X[:,1])/(np.pi*0.5)
nn_atan2.fit(X,y, epochs=10, batch_size=128)
def predict(x, y):
return float(nn_atan2.predict(np.array([[x, y]]))*(np.pi*0.5))
Runnin 这段代码将给出
Epoch 1/10
100000/100000 [==============================] - 3s 26us/step - loss: 0.0289
Epoch 2/10
100000/100000 [==============================] - 2s 24us/step - loss: 0.0104
Epoch 3/10
100000/100000 [==============================] - 2s 24us/step - loss: 0.0102
Epoch 4/10
100000/100000 [==============================] - 2s 24us/step - loss: 0.0096
Epoch 5/10
100000/100000 [==============================] - 2s 24us/step - loss: 0.0082
Epoch 6/10
100000/100000 [==============================] - 2s 23us/step - loss: 0.0051
Epoch 7/10
100000/100000 [==============================] - 2s 23us/step - loss: 0.0027
Epoch 8/10
100000/100000 [==============================] - 2s 23us/step - loss: 0.0019
Epoch 9/10
100000/100000 [==============================] - 2s 23us/step - loss: 0.0014
Epoch 10/10
100000/100000 [==============================] - 2s 23us/step - loss: 0.0010
- OpenCV 3.4.1 error readNetFromTensorflow 无法在 cv::d nn::ReadProtoFromBinaryFile 中打开 .pb
- CMake 用于设定C++标准的设施 "at least C++NN"
- 训练 NN 以计算 atan2(y, x)
- 如何解决 ReLU 不是构建时火炬::nn 错误的成员?
- 使用 atan2 将范围从 - 1 到 1 转换为度
- 支持向量机 (SVM) 与 K-NN 测试效率
- 如何从 k-d 树实现 K-NN 分类
- 开放CV C 人识别K-NN
- 在 c++ 中调用 lua 函数(带有 require 'nn')
- Atan2 table c++
- 使用 aTan2 将对象面向其目标
- 使用 atan2() 函数模拟中的奇怪"yaw"行为
- SFML atan2功能和减速
- 签名的夏亚 ATAN2 和 ATAN 近似值
- 旋转Atan2 CCW CW连续性
- atan2 with CGPoint Iterator
- 如何更新返回值"res"?(ConcativeMat Con NN)