基于加速度计的手势识别Conv1D模型训练失败求助
腕带加速度计手势识别神经网络训练问题
背景与数据格式
我正在训练基于腕带加速度计数据的手势识别神经网络,非深度学习与Python专家。
最初使用的训练数据格式:
# 右滑手势训练数据 RightSwipeTrain = { "x": [639, 989, 934, 783, 683, 829, 570,479, 454, 566], "y": [911, 580, 331, 244, -640, -483, 265, 125, 101, 197], "Z": [132, 324, 307, 385, -309, -762, 748, 1035, 742, 622] } df = pd.DataFrame(RightSwipeTrain, index = ["0.00", "0.25", "0.45", "0.65", "0.85", "1.05", "1.25", "1.45", "1.65", "1.85"]) print(df)
之后改用平铺的时序数据格式,想确认该格式是否存在问题:
TimeSeries_RightTrain = [639, 911, 132, 989, 850, 324, 934, 331, 307, 783, 244, 385, 683, -640, -309, 829, -483, -762, 570, 265, 748, 479, 125, 1035, 454, 101, 742, 566, 197, 622] df = pd.DataFrame(TimeSeries_RightTrain) print(df)
模型代码
构建的测试模型如下:
num_vectors = 3 num_features = 3 input = ([[566, 359, 668, 1386, 513, 1086, 1276, 443, 387, 107, 83, 26, 63, 17, 838, 246, 765, 1072, 729, 1407, 1096, 955, 775, 704, 855, 539, 768, -82, -345, 328 ], [1028, 823, 420, 595, 568, 596, 192, 647, 1312, 647, 991, 735, 1573, 449, -131, 1281, -271, -114, 947, -123, 242, 762, -40, 198, 906, 414, 723, 796, 881, 270], [639, 911, 132, 989, 850, 324, 934, 331, 307, 783, 244, 385, 683, -640, -309, 829, -483, -762, 570, 265, 748, 479, 125, 1035, 454, 101, 742, 566, 197, 622]]) output = ( [1,0,0], [0,1,0], [0,0,1] ) # print training vectors for i,c in enumerate(input): print("input: {}, output: {}".format(c, output[i])) from keras.activations import linear from keras.layers.pooling.max_pooling1d import MaxPool1D l0 = tf.keras.layers.Dense(units=3, input_shape=[30,1], activation='relu') l1 = tf.keras.layers.Conv1D(filters=10, kernel_size=3, strides=1, padding='valid', activation='relu', kernel_initializer="glorot_uniform") l2 = tf.keras.layers.Dense(units=4,activation='softmax') model = tf.keras.Sequential([l0, l1, l2]) model.compile(loss='categorical_crossentropy',optimizer=tf.keras.optimizers.Adam(0.1)) history = model.fit(input, output, epochs=100, verbose=True)
报错信息
在Google Colab运行时出现以下错误:
ValueError: in user code: File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1249, in train_function * return step_function(self, iterator) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1233, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1222, in run_step ** outputs = model.train_step(data) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1023, in train_step y_pred = self(x, training=True) File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "/usr/local/lib/python3.8/dist-packages/keras/engine/input_spec.py", line 295, in assert_input_compatibility raise ValueError( ValueError: Input 0 of layer "sequential_5" is incompatible with the layer: expected shape=(None, 30, 1), found shape=(None, 10, 3)
解决方案
报错核心是输入数据形状与模型输入层定义不匹配,具体调整步骤如下:
1. 修正输入数据形状
你的输入数据每个样本是30个数值,对应10个时间步的x/y/z三轴数据(10×3=30),需要将每个样本从一维数组(30,)重塑为时序格式(10,3),让模型识别每个时间步的3个特征。
代码示例:
import numpy as np # 转换为numpy数组方便处理 input_data = np.array(input) # 重塑形状:(样本数, 时间步长, 特征数) input_reshaped = input_data.reshape(3, 10, 3) # 输出也转换为numpy数组 output_data = np.array(output)
2. 调整模型输入层与结构
- 输入层
input_shape改为(10,3),对应每个样本10个时间步、3个特征。 - 调整模型顺序:Conv1D适合先处理时序数据,之后展平再用Dense层分类,原模型把Dense放在Conv1D前不合理。
- 输出层
units改为3,因为是3分类任务,与输出标签维度匹配。 - 降低Adam学习率(从0.1改为0.001),避免训练震荡。
修改后的模型代码:
import tensorflow as tf # 定义模型层 conv_layer = tf.keras.layers.Conv1D( filters=10, kernel_size=3, strides=1, padding='valid', activation='relu', kernel_initializer="glorot_uniform", input_shape=(10,3) # 匹配重塑后的输入形状 ) pool_layer = tf.keras.layers.MaxPool1D(pool_size=2) # 可选,降低特征维度 flatten_layer = tf.keras.layers.Flatten() # 把卷积输出展平为一维 output_layer = tf.keras.layers.Dense(units=3, activation='softmax') # 3分类输出 # 构建模型 model = tf.keras.Sequential([conv_layer, pool_layer, flatten_layer, output_layer]) model.compile( loss='categorical_crossentropy', optimizer=tf.keras.optimizers.Adam(0.001) # 降低学习率 ) # 训练模型 history = model.fit(input_reshaped, output_data, epochs=100, verbose=True)
3. 数据格式说明
你后来改用的平铺时序格式本身没问题,但需要**重塑为(时间步长, 特征数)**的结构,才能让时序模型(如Conv1D)正确理解数据的时间序列关系。
内容的提问来源于stack exchange,提问作者Kevin Birk
相关产品推荐
相关产品推荐

