机械臂逆运动学LSTM模型精度极低、损失过高问题求助
机械臂逆运动学模型性能优化问题
我正在研究机械臂逆运动学,通过模拟器采集了包含XYZ位置与6个驱动变量的数据集(约31万行),计划以位置为输入、驱动变量为输出构建模型。此前用MLP处理仅3个输出的简单数据集时效果良好,但处理当前6输出的复杂数据集时表现不佳。尝试LSTM模型后,仅能达到0.17的精度与0.06的损失(目标损失值为0.0001),以下是我的代码:
import numpy as np import tensorflow as tf from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler import matplotlib.pyplot as plt # Chargement des données data = np.genfromtxt('/dataprocess.csv', delimiter=',') scaler = MinMaxScaler() data[1:,[7,8,9,10,11,12,13,14,15]] = scaler.fit_transform(data[1:,[7,8,9,10,11,12,13,14,15]]) # Diviser les données en ensembles d'entraînement et de test trainset, testset = train_test_split(data[1:, [7,8,9,10,11,12,13,14,15]], test_size=0.2, random_state=0) # Préparation des données en séquences seq_length = 10 # Longueur de la séquence X_train_seq = [trainset[i:i+seq_length, [6, 7, 8]] for i in range(len(trainset) - seq_length)] Y_train_seq = [trainset[i+seq_length, [0, 1, 2, 3, 4, 5]] for i in range(len(trainset) - seq_length)] X_test_seq = [testset[i:i+seq_length, [6, 7, 8]] for i in range(len(testset) - seq_length)] Y_test_seq = [testset[i+seq_length, [0, 1, 2, 3, 4, 5]] for i in range(len(testset) - seq_length)] X_train_seq = np.array(X_train_seq) Y_train_seq = np.array(Y_train_seq) X_test_seq = np.array(X_test_seq) Y_test_seq = np.array(Y_test_seq) print("X train seq shape : ", np.array(X_train_seq).shape) # Création du modèle RNN avec tf.keras.Model # input_layer = tf.keras.layers.Input(shape=(3,)) # Entrée : x, y, z input_layer = tf.keras.layers.Input(shape=(seq_length, 3)) # Entrée : séquence de x, y, z rnn_layer = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(input_layer) # Couche SimpleRNN hidden_layer2 = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(rnn_layer) # Couche intermédiaire hidden_layer3 = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(hidden_layer2) # Couche intermédiaire hidden_layer4 = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(hidden_layer3) # Couche intermédiaire hidden_layer5 = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(hidden_layer4) # Couche intermédiaire hidden_layer6 = tf.keras.layers.LSTM(256, activation='relu', return_sequences=True)(hidden_layer5) # Couche intermédiaire output_layer = tf.keras.layers.Dense(6)(hidden_layer6) # 6 sorties pour les variables d'actionnement model = tf.keras.Model(inputs=input_layer, outputs=output_layer) # Compilation du modèle model.compile(optimizer='adam', loss='mse', metrics=['accuracy']) # Entraînement du modèle History = model.fit(X_train_seq, Y_train_seq, validation_data=(X_test_seq, Y_test_seq), epochs=100, batch_size=512, verbose=2) # History = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=500, batch_size=1024, verbose=2) # Évaluation du modèle sur les données de test loss, accuracy = model.evaluate(X_test_seq, Y_test_seq, verbose=0) # loss, accuracy = model.evaluate(X_test, Y_test, verbose=0) print("Test accuracy:", accuracy) print("Test loss:", loss)
问题排查与优化方案
1. 核心错误:模型选型与结构不匹配
- 逆运动学本质是静态映射:如果你的需求是「给定单个XYZ位置,输出对应的6个驱动变量」,LSTM完全不适用——LSTM是为时序序列任务设计的,静态映射任务应该用MLP或带残差连接的深度前馈网络。
- LSTM结构错误:即使是时序预测场景,当前所有LSTM层都设置
return_sequences=True,导致输出形状为(batch_size, seq_length, 6),但你的标签Y_train_seq形状是(batch_size, 6),形状完全不匹配,这是模型无法有效训练的关键原因。最后一层LSTM必须设置return_sequences=False,才能输出与标签匹配的维度。
2. 数据处理问题
- 归一化逻辑错误:你将输入(XYZ)和输出(驱动变量)混在一起归一化,应该分别对输入特征和输出标签使用独立的Scaler,且测试集必须用训练集的Scaler做
transform,不能重新fit,避免数据泄露。 - 精度指标无意义:回归任务使用
accuracy指标完全无效,accuracy是分类任务的评价标准,回归任务应使用mae或mse作为监控指标,你看到的0.17精度没有任何参考价值。
3. 模型结构与训练优化
- 简化模型:6层LSTM每层256单元过于庞大,容易过拟合,建议缩减为2-3层,单元数改为128或64,且LSTM默认激活函数是
tanh,比relu更适合循环网络。 - 调整训练配置:Adam默认学习率可能过高,建议降至
1e-4;加入早停机制(EarlyStopping)防止过拟合;增加训练轮次到200+,但需配合早停。
修正后的代码(静态映射场景)
import numpy as np import tensorflow as tf from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler import matplotlib.pyplot as plt # 加载数据并分离输入输出 data = np.genfromtxt('/dataprocess.csv', delimiter=',') X = data[1:, 6:9] # XYZ位置 Y = data[1:, 0:6] # 6个驱动变量 # 分别归一化输入和输出 scaler_X = MinMaxScaler() scaler_Y = MinMaxScaler() X_scaled = scaler_X.fit_transform(X) Y_scaled = scaler_Y.fit_transform(Y) # 划分数据集 X_train, X_test, Y_train, Y_test = train_test_split(X_scaled, Y_scaled, test_size=0.2, random_state=0) # 构建MLP模型 model = tf.keras.Sequential([ tf.keras.layers.Dense(256, activation='relu', input_shape=(3,)), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(64, activation='relu'), tf.keras.layers.Dense(6) ]) # 编译模型,使用合适的回归指标 model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4), loss='mse', metrics=['mae']) # 早停机制防止过拟合 early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True) # 训练模型 history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=200, batch_size=512, verbose=2, callbacks=[early_stop]) # 评估模型 loss, mae = model.evaluate(X_test, Y_test, verbose=0) print("Test MSE loss:", loss) print("Test MAE:", mae) # 反归一化查看真实误差 Y_pred_scaled = model.predict(X_test) Y_pred = scaler_Y.inverse_transform(Y_pred_scaled) Y_true = scaler_Y.inverse_transform(Y_test) print("真实值与预测值的平均误差:", np.mean(np.abs(Y_true - Y_pred)))
时序预测场景修正(若需序列预测)
如果你的任务是根据历史XYZ轨迹预测下一个时刻的驱动变量,修正LSTM结构如下:
# 序列构建部分保持不变 # 修正模型结构 input_layer = tf.keras.layers.Input(shape=(seq_length, 3)) rnn_layer = tf.keras.layers.LSTM(128, activation='tanh', return_sequences=True)(input_layer) rnn_layer = tf.keras.layers.LSTM(64, activation='tanh', return_sequences=False)(rnn_layer) output_layer = tf.keras.layers.Dense(6)(rnn_layer) model = tf.keras.Model(inputs=input_layer, outputs=output_layer) model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4), loss='mse', metrics=['mae'])
内容的提问来源于stack exchange,提问作者Guillaume
相关产品推荐
相关产品推荐

