TFLearn RNN 输出始终不变 - TFLearn 新手

TFLearn RNN output is always constant - New to TFLearn

目标:

我正在尝试开发一个能够学习一些未知的非线性四旋翼无人机动力学的神经网络模型。最终目的是让该模型在我编写的遗传算法工具中使用,该工具将调整无人机的控制系统以实现所需的响应。 GA 需要一个 "black box" 模型,它可以根据一组输入来生成对无人机行为的预测。

神经网络设计:

我创建这样一个模型的想法是利用一个 RNN,它将 ESC 电机控制器命令值的时间历史作为输入(4 个输入,每个电机 1 个),并吐出相应的欧拉角(3 个输出,滚动,俯仰,偏航)。我有一个自定义飞行控制器 designed/wrote,它使我能够将任何必要的数据记录到 SD 卡中,即电机输出和欧拉角。

我目前用来尝试训练这个模型但未成功的代码如下所示。这也是我第一次使用 TFLearn 或任何主要的 NN 编程,因此也将不胜感激。

此外,如果您想自己 运行,您需要的一切(假设您已经拥有 TFLearn 和 TensorFlow)都可以在我的 github 存储库 HERE

# An attempt to use a Recurrent Neural Network to learn and predict drone dynamics. In this version, the
# network inputs are the four motor commands and the outputs are the roll, pitch, and yaw angles.

from __future__ import division, print_function, absolute_import

import tflearn
from tflearn.layers.normalization import batch_normalization
import numpy as np
import pandas as pd
import math
import matplotlib
matplotlib.use('Agg')   # use('Agg') for saving to file and use('TkAgg') for interactive plot
import matplotlib.pyplot as plt

# Configuration Variables
input_dim = 4
output_dim = 3
steps_of_history = 10
batch_len = 128
epoch_len = 3

rawDataPath = 'DroneData/timeSeriesData.csv'

# Generate the data used in training
timeSeries = pd.read_csv(rawDataPath)
x = [timeSeries['m1CMD'], timeSeries['m2CMD'], timeSeries['m3CMD'], timeSeries['m4CMD']]
y = [timeSeries['pitch'], timeSeries['roll'], timeSeries['yaw']]

# Convert row vectors into column vectors
x = np.array(x);     y = np.array(y)
x = np.transpose(x); y = np.transpose(y)

# Generate the input and target training data
input_seq = []
output_seq = []

for i in range(0, len(timeSeries['rtosTick']) - steps_of_history):
    input_seq.append(x[i:i+steps_of_history, :])    # Time history input
    output_seq.append(y[i+steps_of_history, :])     # Single output resulting from ^^^


trainX = np.reshape(input_seq, [-1, input_dim, steps_of_history])
trainY = np.reshape(output_seq, [-1, output_dim])


# Build the network model
input_layer = tflearn.input_data(shape=[None, input_dim, steps_of_history])

layer1 = tflearn.simple_rnn(input_layer, n_units=10, activation='softmax', return_seq=True, name='Layer1')
layer2 = tflearn.simple_rnn(layer1, n_units=10, activation='sigmoid', name='Layer2')
layer3 = tflearn.fully_connected(layer2, output_dim, activation='linear', name='Layer3')

output_layer = tflearn.regression(layer3, optimizer='adam', loss='mean_square', learning_rate=0.1)


# Training
model = tflearn.DNN(output_layer, clip_gradients=0.3, tensorboard_verbose=0)
model.fit(trainX, trainY, n_epoch=epoch_len, validation_set=0.1, batch_size=batch_len)


# Generate a model prediction as a very simple sanity check...
predictY = model.predict(trainX)


# Plot the results
plt.figure(figsize=(20, 4))
plt.suptitle('Pitch Predictions')
plt.plot(trainY[:, 0], 'r-', label='Actual')
plt.plot(predictY[:, 0], 'g-', label='Predicted')
plt.legend()
plt.savefig('pitch.png')

plt.figure(figsize=(20, 4))
plt.suptitle('Roll Predictions')
plt.plot(trainY[:, 1], 'r-', label='Actual')
plt.plot(predictY[:, 1], 'g-', label='Predicted')
plt.legend()
plt.savefig('roll.png')

plt.figure(figsize=(20, 4))
plt.suptitle('Yaw Predictions')
plt.plot(trainY[:, 2], 'r-', label='Actual')
plt.plot(predictY[:, 2], 'g-', label='Predicted')
plt.legend()
plt.savefig('yaw.png')

问题:

如果您查看我的链接存储库根文件夹中的 "pitch.png"、"roll.png"、"yaw.png" 图表,您会看到我的网络的预测值为常数值。我针对包含 7410 个样本的简单飞行日志数据集进行了训练,其中包括俯仰滚转和偏航(+/-20 度左右)的适当变化。查看原始数据 HERE。我知道这对于最终模型来说可能不够好,但它是一个开始。

我觉得我至少应该在输出中得到一些变化,即使它不太合适。有人可以帮我查明这个问题吗?我自己没有任何进步。

我最终解决了这个问题。事实证明,NN 确实 而不是 喜欢输入幅度在 1000+ 范围内的数据。 ESC 数据被记录为 PWM 命令在 uS 中花费 HI 的时间,因此 NN 获取的值介于 1060-1860 之间。

通过在 Matlab 中预处理数据以将其缩小到 0.0-5.0 范围内,系统表现良好并且能够轻松学习动力学。

我会不断更新 github link 上的代码,如果遇到此 post 的任何人都想使用它。