上一部分简单介绍了经典的传统机器学习分类模型在人体动作分类领域的基本应用。传统的基于机器学习分类方法主要包括三个步骤,第一对原始输入数据进行预处理,第二对预处理以后的数据进行特征提取,第三是使用分类器进行分类识别。其中的第二步,特征提取非常依赖数据处理人员的先验知识。因此,导致使用机器学习进行的人体动作分类识别性能主要依赖于人工特征的质量,这对人体动作分类的智能化需求是一个巨大的挑战,这也是传统机器学习方法的局限性。
近些年来以卷积神经网络(Convolutional Neural Network,CNN)为代表的深度学习技术发展迅速,深度学习在语音识别、图像和自然语言处理等领域取得了巨大成功,尤其在自学习特征方面的优势被作为一种良好的机器学习方法使用。这一部分讲解如何使用深度学习中的CNN来完成与上一节相同的任务。如果对于CNN理论不熟悉的,目前在网上已有许多的资料可以参阅,这里不再展开叙述。
通常的卷积神经网络是指二维卷积神经网络(2D-CNN),对应的计算过程是将一个特征图在宽和高两个方向进行滑动窗口操作,然后对应位置进行相乘求和,具体如图1所示:
而使用的1D-CNN则只是在宽或高方向上进行滑动窗口并相乘求和,过程如图2所示,是一种退化的二维卷积
而基于IMU的人体动作分类数据是一维数据,较为常用的做法主要包括两种,一种是将一维数据通过时频变换(如短时离散傅里叶变换等)转换为图像,使用2D-CNN;另外一种是直接使用1D-CNN进行特征提取。但通过对原始输入变换为图像再进行的2D-CNN,中间使用了信号变换这个操作,也是一种特征工程,此时的深度学习模型不是一种纯粹上的端到端处理框架,但在实际应用中所构建的深度学习模型通常也会有一定程度使用人工特征工程。为了更接近深度学习提出的初衷,这里介绍的基于IMU的人体动作深度学习分类采用1D-CNN。
下面直接通过代码示例1D-CNN在基于IMU的人体动作分类上的应用,构建CNN结构的代码如下:
class CNN_Model(DNN_Model):
def constructModel(self):
inp_seq = Input((self.width, self.height))
x = Conv1D(kernel_size=3, filters=128, strides=2, padding='same', name='conv-1')(inp_seq)
x = AveragePooling1D(3, strides=2, padding='same', name='pool-1')(x)
x = Conv1D(kernel_size=3, filters=128, strides=2, padding='same', name='conv-2')(x)
x = BatchNormalization(axis=1, name='bn-1')(x)
x = Flatten()(x)
x = Dropout(self.dr, name='dr-1')(x)
x = Dense(128, activation='relu', name='dense-1')(x)
x = Dense(64, activation='relu', name='dense-2')(x)
out = Dense(self.num_class, activation='softmax', name='softmax')(x)
model = Model(inp_seq, out)
self.dnn_Model = model
这里采用的tensorflow2.x的框架,搭建CNN结构有点类似搭积木的形式,设计的1D-CNN结构包括2个卷积层,1个池化层,1个批归一层、一个丢弃层和2个全连接层。用于训练过程的超参数设置如下:
class DNN_Model(object):
def __init__(self, trainData, trainLabel):
self.trainData = trainData
self.trainLabel = trainLabel
self.batch_size = 500 # 批大小
self.epochs = 100
self.verbose = 1
self.num_class = 13 # 分类数目
self.optimizer = tf.keras.optimizers.Adam(learning_rate=0.005)
self.width = 410
self.height = 24
self.dr = 0.5
self.dnn_Model = None
@abc.abstractmethod #测试是否在具体类中提供了相同的名称
def constructModel(self):
pass
使用tensorflow中的plot_model绘制结构图如图3所示:
下面开始训练1D-CNN模型:
训练过程的准确率曲线作为反映使得训练集在分类过程中准确率达到稳定状态的评价指标,可以更加的直观,也更具有可解释性,但是它不可微,无法直接用于网络的训练。而损失函数是可微,可以求梯度,通过反向传播更新参数,损失函数用来估量模型的预测值与目标值的不一致程度。若损失函数很小,表明分类模型与数据真实值很接近,则模型性能良好;若损失函数很大,表明分类模型与数据真实值差别较大,则模型性能不佳。本文中的使用分类模型中常用的交叉熵作为损失函数,在训练过程中的损失函数曲线描述了模型在训练集上收敛到逼近真实值的速度。对应训练过程的模型准确率和损失函数值曲线如图4所示,由于训练超参数采用的Adam优化器,可以不使用验证值。使用训练得到模型进行测试,对应测试集的混淆矩阵如下图5所示:
评价人体活动测试集分类效果的指标精确率(precision)、召回率(recall)和F1-score如图6所示:
t分布随机邻域嵌入(t-SNE)是一种用于探索高维数据的非线性降维算法。它将多维数据映射到适合于人类观察的两个或多个维度。t-SNE算法的目的是将高维度空间中的数据点集合在一个低维度空间中准确地表示出来。对于分类问题,能够通过t-SNE可视化观察出各个类别的空间关联性,可以作为分类结果的可视化工具。t-SNE可视化条件:已知给定特征测试样本和标签,它能够反映出在当前特征下,各类人体活动数据的聚类效果。通过使用测试对1D-CNN模型结构中的第二层卷积层、第一层全连接层和sofmax分类层的二维t-SNE图,分别对图6、图7和图8所示:
可以看出,随着层数加深人体活动测试的聚类效果越好,即提取得到的特征越具有区分性。