作者:Johannes Wagner, Florian Lingenfelser, Elisabeth André Affiliation: Lab for Human Centered Computing (HCM), University of Augsburg, Germany 介绍 随着直观而自然的人机交互的崛起, 声音, 手势, 模仿(mimics) 等人类行为的自动检测和分析, 将在下一代接口中扮演重要角色. 本文介绍的人类行为分析(SSI), 是一个时实分析人类行为的框架. SSI 支持各种传感器, 过滤器,特色算法. 此外,还支持机器学习和模式识别工具. 鼓励开发者使用 SSI 的 C++ API 添加新组件, 同时也向前端用户提供 XML 接口, 用于创建文本编辑器用的管道(pipelines). SSI 遵守 GPL 协议, 可以到 openssi.net 免费下载. 关键特性人类行为分析(SSI) 框架提供了实时记录,分析和认知人类行为的工具集,诸如手势,模仿(mimic) 点头,和情感对话。让一个基于区块的设计管道(patch-based design pipeline)从自动化组件中获取设置,允许平行,并从多个输入设备中获取同步的传感器数据。尤其是,在它的整个产品线(full length)里,还提供了图形接口,帮助用户收集他们自己训练的语料库,来获得私人化的模型,SSI提供了这些机器学习的管道(pipeline)。 除了大量的内置组件,SSI还一直鼓励用户去提供新的功能(函数)来扩展出有用的工具。 对没有经验的用户,(他们)提供了一个易于使用的XML编辑器用来绘制和运行这些管道(pipelines),并不需要特殊的编程技巧。 SSI是用C++写的,并且充分利用了计算机系统中的多个CPU。 SSI 特点:
此外, SSI 还有各种流行传感器和信号处理用的类库, 如: e-Health Sensor Shield, IOM biofeedback system (Wild Divine), MicrosoftKinect, TheEyeTribe, Wii Remote Control, ARTKplus, FFMpeg, OpenCV, WEKA, Torch, DSPFilters, Fubi, Praat, OpenSmile, LibSox, 和 EmoVoice. 请到我们网站 下载 SSI. 图 1: SSI 个各种功能概要图. 框架概述SSI 是一个时实利用多种传感器作为输入信号, 支持识别系统开发的开源项目[1]. 因此, 他提供各种过滤器和特殊算法处理捕获到的信号. 同时, 也提供各种工具, 用于完成完整的机器学习管道任务(machine learning pipeline). 主要面对两类用户: 给开发者提供 C++-API, 鼓励他们开发自己的组件, 同时前端用户可以用现有的组件, 以 XML 格式定义识别管道(recognition pipelines). 由于社交行为可以通过不同方式表达, 如: 脸部, 声音, 姿势等, 需要多个传感器才能获取一副完整的互动画面. 所以, 要将各种设备的原始信号流同步, 并且统一处理, 才能合成有用的信息. 因此, 不论是波形信号, 心跳信号, 还是视频图像信号, 我们都要一个架构对它们统一处理. 图 2: SSI 支持的各种传感器的示例图. 传感器的原始信号, 需要经过几个处理过程, 把有用的信息分离出来. 因此, SSI 自带了很多过滤器, 特殊算法, 用来处理各种音频, 视频, 生理信号. 把一系列处理模块放在一起, 既能让开发者快速搭建复杂的处理管道, 又不需要过多的关心实现的细节. 像缓存, 同步这些问题, 由框架自动处理. 由于各种处理模块, 分配在不同的线程中, 所以每个处理过程, 都有自己单独设置长度的窗口. 图 3:每个并行处理的信号流都有量身定做长度的窗口.
人与人之间的交流不像机器那么精准, 存在许多差异, 不确定和歧义。所以, 我们需要用概率模型识别和分析这些行为。为此, SSI 集成了各种机器学习管道, 包括: 预处理, 特征提取(feature extraction), 和在线实时分类/结合(fusion)。特色提取的作用是从信号中提取出关键的特征数据 – 只保留分类用到的那部分关键信息. 而分类的作用是将特征向量转换成离散的状态或连续的数值. 至于是用统计分类法,还是用动态分类法, 则取决于提取出来的是单一特征向量, 还是多个长度不一致的特征数据. SSI 框架中包含了这两种方法的例子。 图 4: 支持统计和动态分类法。 为了解决人与人之间交流存在的歧义, 我们需要将各种渠道提取出来的信息合并. SSI 能在不同层进行信息合并. 可以在数据层, 如,通过色彩优化纵深信息. 或在特征层, 将多个渠道提取出来的特征数据合并成单一向量. 也可能是决策层, 合并各种识别器得出的概率. 后几种合并, 都要求合成的信息能及时呈现. 如果是因为临时的偏差, 而无法做到这一点(如: 出现在语音指令后面的手势), 那合并就要在事件层进行. 由信息的类别决定, 他们在哪一层合并. 图 5: 在特征, 决策和事件层的合并. XML 管道(Pipeline)本文主要讲 SSI 的 XML 接口, 该接口允许将管道定义为文本文件. 既不要求使用者会编程, 也不需要特定的开发环境, 就能装配一个任何文本编辑器都能用的管道. 不过, SSI 也自带了一个 XML 编辑器, 该编辑器除了提供了一些特殊的功能外, 还简化了将数据写入管道的步骤, 比如: 列出可选项和解释说明某个选中的组件.
图 6: 在 SSI 的 XML 编辑器中能方便访问现有的组件 (左边的面板). 此外, 组件的选项能直接访问和修改(右边的面板). 让我们用一个简单的例子, 说明下如何在 SSI 中创建 XML 管道. 假设, 我们要写个程序, 将声音信号转换成频谱(spectrogram). 这是音频处理中最常见的功能之一. 因为, 我们可以通过频率分析语音中的诸多属性. 下面例子中的管道, 通过麦克风捕捉音频信号, 然后转换成频谱. 并把原始的信号, 和转换过的信号显示出来.
由于 SSI 支持插件, 组件都是在运行时, 动态加载的. 所以, 我们把需要加载的 DLL 放在 <register> 标志中. 在本例中, 需要加载3个 DLL 文件, ssiaudio.dll, 包含从音频源读取数据的组件, ssisignal.dll, 包含通用的信号处理算法, 和 ssigraphic.dll, 包含各种显示原始信号和处理过的信号的工具. 管道剩下的那一部分用来定义, 要创建哪些组件, 以及用什么方式把它们关联到一起. <sensor> 用来定义管道源. 这里的 ssi_sensor_Audio 是组件的名称, 该组件负责音频输入这部分功能. 通常, 组件都有选项, 允许我们修改组件的行为. 如, 设scale=“true“则让音频传感器,以范围为[-1..1]的浮点数传回波形信号,否则, 我们收到的波形信号是整数流. 而设 option=“audio“, 则是要把配置存到 audio.option 文件中. 接下来,我们要定义哪一个源是我们想监听的.一个传感器至少有一个频道. <provider>用来指定要连接的频道,这个标志包含两个属性: channel 是频道的标识符, pin 则是个可选的标识符, 后面我们会用来引用信号流. SSI 内部有一个缓存, 音频采样数据会持续不断的被写进去. 默认情况下, 缓存会保留最后 10 秒的数据. 所以, 从缓存读取数据的组件能收到一份它需要的采样数据. 连接数据流的组件, 通常会对数据处理, 然后把处理过的数据当作新的数据流输出, 这些组件放在 <transformer>中. 新的数据流跟原来的数据在采样率和类型上会有差别. 比如, 视频图像可能映射成一个表示坐标的值. 又如, 在我们的例子中, 16kHz 的一维音频数据流被映射成多维低频频谱. 频谱用来显示不同频率区的能量分布. SSI中能进行这类数据转换的组件名为 ssi_feature_Spectrogram. 通过选项 minfreq, maxfreq, 和 nbanks, 我们可以设置频率范围 [minfreq...maxfreq](以Hz为单位), 和频率区的数量. 像傅立叶转换的系数(nfft) 和窗口类别 (wintype), 如果没有设置, 则用默认值对其初始化(除非像音频传感器的例子那样, 间接重写由option加载的选项文件的内容). 通过<input> 给转换器指定输入流, 由于我们要读取的是原始的音频采样数据, 所以把 pin 设为 audio. 接下来, 通过属性frame设置输入流的数据块大小. 而读取操作完成后, 窗口平移的数量, 通过属性 delta 来设置. 在本例中, 分别设为0.01s 和0.015s. 也就是说, 每一次循环, 会读取长度为 0.025 秒的数据, 再平移 0.01 秒. 如果采样率为 16kHz(音频流的默认采样率), 就会得到400个采样数据(16kHz*[0.01s+0.015s]) 和一个160个单位的帧平移 (16kHz*0.01s). 换句话说, 每一次从缓存中复制 400 个采样数据后, 当前读指针的位置就会自增 160. 由于输出的数据采样率是 100Hz(1/0.01s), 刚好跟频谱里面的频率区的数量相等. 若要将转换过的新的数据流, 存在 SSI 的另外一个缓存里面, 我们需要将 <output> 的属性 pin 设为spect .
现在, 在命令窗口中输入 xmlpipe <filename> 测试下效果 (如果你用的是SSI的 XML 编辑器, 按 F5 直接运行). 第一次运行的时候, 会弹出一个选择输入源的窗口. 选好后, 选择的内容会存在 audio.option文件中. 运行的结果如下: 图 7: 左上: 原始音频信号图. 左下: 频普图,蓝色表示低频率, 红色表示高能量. 命令窗口显示当前管道的状态. 有的时候, 管道文件内容太长, 需要把重要的选项放到另外一文件中. 我们可以在管道文件里面使用 $(<key>) 代替原来的值, 然后再创建一个新的文件, 在这个文件里面, 使用格式 <key> = <value> 赋值. 比如, 我们可以把频谱转换部分改成:
然后另外建一个文件给这些选项赋值(管道文件以 .pipeline 结尾, 配置文件以 .pipeline-config 文件): minfreq = 100 # 最低频率 为了方便使用, SSI 自带一个图形界面程序 xmlpipeui.exe, 该程序能将某个表中的选项列出来, 并自动分析管道文件中新加的 key: 图 8: 管理选项, 和使用不同配置文件运行管道的图形界面. 在 SSI 中, 跟数据流相对应的是事件. 跟具有持续性的数据流不同, 事件的产生是异步的, 且有明确的开始和结束. 我们修改下前面的例子, 加入一个活动检测器, 让频谱图只在有声音信号的时候才显示, 以此解释下事件的特点. 首先, 我们需要添加两个组件. 一个转换器(AudioActivity), 用来计算音量大小(method=“0“), 和将阈值(threshold=“0.1“)以下的数据置零. 另一个是 consumer (ZeroEventSender), 用来获取信号中非零的数据. 如果检测到这些数据, 而且时长超过 1 秒 (mindur=“1.0“), 事件就会触发. 事件的标识符由事件名称和触发事件的对象名称组成:<event>@<sender>. 在本例中, 选项 ename 和 sname 用来设置事件标识符 activity@audio.
我们现在可以把频谱的显示, 由原来的连续显示, 改成由事件触发. 所以, 要把属性 frame 换成 listen=“activity@audio“. 同时把图形的长度设为 0 (size=“0“), 这样就可以在事件触发的时候自动调整图形的长度.
要把框架里面当前所有的事件都列出来, 我们需要一个 EventMonitor 对象. 由于它只跟事件互动, 与consumer, 或转换器无关, 所以要放在 <object>里面. 通过 <listen> 我们可以指定要接受哪个事件. 设置属性 address=“@“ 和 span=“10000“, 可以显示过去 10 秒内的任意事件.
新管道的输出结果如下. 包含连续的原始音频信号图表和活动信号(左上). 图表的下面是由事件触发的频谱图, 显示的是最新一次活动事件的数据 (18.2s – 19.4s). 也就是监控器中最顶上那一行记录 (右下). 此外还有最新 3 个事件. 由于活动事件不包含其他元数据, 所以占用的空间是 0 字节. 如果是分类事件就会包含类名和概率值. 图 9: 本例中, 通过活动检测驱动频谱显示 (看原始音频信号和频谱中间那张图). 每过一段时间, 就会触发一次事件, 由此驱动频谱的显示. 在命令行窗口中列出的是已经触发过的事件. 多模式喜悦程序检测我们现在将(注意力)转移至更复杂的应用程序 – 多模式喜悦程序检测。 我们要关注的系统是欧洲计划的一部分(FP7) ILHAIRE (把笑合并到人类的虚拟交互中去(Incorporating Laughter into Human Avatar Interactions): 研究和实验, 可以看 http://www.ilhaire.eu/)。它结合了两个传感器的输入,一个麦克风和一个照相机, 来实时检测用户的喜悦水平。 在这篇文章中,我们通过视觉和听觉的暗示来指示出喜悦,并定义喜悦是一个积极的感情场景,例如微笑和狂笑。基于频率和强度的暗示,喜悦的程度就可以被确定下来。 图10:喜悦程度的更多暗示来自用户的展示(输入),这样系统就会有更高的输出。 微调检测模型的训练数据记录在 3~4 个正在聊天的用户的 session 中, 每个 session 的寿命大概是 1.5 小时. 记录期间, 用户的装备有耳麦,Kinect 和 HD 相机. 要同时给 4 个用户记录数据, 就要进行设置, 包括由网络同步 pc 机. 要在分布在网络中的几台机器中保持管道, 就要通过同步创建多个用户的多模式(multi-modal). 在这个例子中, SSI 捕捉到的原始数据每分钟高达 4.78 GB, 包括音频数据, Kinect 对身体, 脸部的跟踪数据, 以及 HD 视频流. 下列管道代码的作用是, 连接到音频和 Kinect 传感器, 并把捕捉到的信号存到磁盘中. 注意, 音频流数据和 Kinect 的 rgb 视频数据混合放在一个文件中. 因此要将音频包含在 <xinput> 中. 还有就是要在文件的顶部配置<framework> , 指定在端口 1234 等待同步信号.
根据音频和视频的内容, 评估者(rater)要标注出音频和视频中有笑声或笑容表的地方. 然后, 从原始数据中把特征信息提取出来, 并根据标注的数据给这些特征打上标签. 而打上标签的特征则作为学习阶段的输入数据, 用来分离特征空间(feature space), 以此给各类标签做出适当的分离. 如, 用来衡量嘴角扩张的特征, 可能跟微笑表情有关. 因此, 可以用来当作喜悦的指标. 由于复杂的识别任务不存在明确的映射关系, 所以解决的办法也不只一个. SSI 自带了几个效果不错的学习算法, 如 K-Nearest Neighbours, Gaussian Mixture Models, 和 Support Vector Machines. 这些算法属于 SSI 机器学习库的一部分, 允许其他工具以最佳的方式模拟管道, 并根据期望的识别精度评估模型. 图 11: 人工标注的喜悦表情用来训练每个模式的检测模型. 下面的C++代码片段给出一个效果,使用SSI的机器学习库是怎样完成学习的。首先,原始音频文件(“user1.wav”)和一个注释文件(“user1.anno”)被加载。下一步,音频流被转换成一个样本列表,提取特征值并应用。最终,使用那些样本的模型被训练。 在训练数据之外,添加一个额外的评价步骤,可以看到模型是如何被执行的。
在经过训练阶段后, 我们就可以将预训练分类模型加入管道中. 要完成管道余下的工作, 还需要训练两个已连接到特征提取组件的模型: 一是检测声音中的笑声, 二是视频中的笑脸. 活动检测则用来判断某个帧包含的信息量是否够用来进行分类处理. 例如, 如果一个帧的图像没有检测到脸部, 或是音频信号的音量太低, 这个帧就会被丢弃. 否则, 就对它进行分类处理, 然后把结果传给 fusion 组件. 管道的头几个步骤基于数据流, 如, 信号持续不断的传给长度固定的窗口处理. 而后面那些负责检测和 fusion 的组件则基于事件, 只有在信号包含相关信息的时候才会触发. 将这两种处理结果结合在一起, 才能得到最终的决策数据. 这个管道是在之前那个记录管道的基础上扩充的, 包含了其他处理步骤. 要处理音频数据流, 需要把下列代码加上:
这部分是视频的代码:
由于加载的组件不同, frame/delta 的值需要调整, 才能适应相同的采样率, 但是这两部分的代码在结构上差不多. 注意, 这回我们把触发器 (voice_activity/face_activity) 放在 <input> 的 trigger 中. 给预训练模型检测声音和面部特征用的数据流, 是通过选项 trainer 从指定的文件加载的. 最后再由向量 fusion 将概率值合并起来 :
在单个或多维事件空间中作为独立向量的 fusion 的核心思想是处理检测到的事件(比如:笑容), 以及根据临时关系汇聚向量推导出最终决策(事件的影响力会随着时间减弱) [2]. 跟标准的基于分段的, 每一步都强制所有的模式做出决策的 fusion 方法对比, 基于向量的 fusion 只在需要的时候为某个模式做出决策. 在下面的动画中, 绿点表示检测到有用的线索, 红点表示什么都没检测到. 注意这里的最终 fusion 决策 – 动画中右边的绿色条形– 检测到有用线索的时候会变高, 随着检测的线索变少, 它会降低: 图 12: 预训练模型用来实时检测喜悦表情(绿色的点). 交叉模式能检测出更多的线索. 最后是 fusion 算法的输出的结果(绿色条形). 下面的视频教我们如何使用检测管道. 输入流显示在左边 (顶部: 包含脸部跟踪信息的视频流, 底部: 原始音频数据流和活动图表). 两种不同模式的笑容检测分别用条形图显示在各自的顶部. 最终的多模式笑容检测结果显示在右边的条形图中. 总结本文介绍的 SSI, 是一个多模式信号处理框架. 除了 SSI 的基本概念之外, 我们还用两个例子讲解如何用 XML 快速搭建管道. 虽然本文的例子用的是现有的组件, 但是, 作为一个支持插件的系统, 当然也允许开发者使用新的组件. 欢迎大家到多媒体社区分享自己的组件, 为扩充 SSI 的功能添砖加瓦. 如果你想查看更多的 SSI 资料或源代码, 请访问 http://openssi.net. 未来的工作目前, SSI 应用主要面对桌面电脑, 或者是分布在某个网络中的几台桌面电脑. 虽然, 现在的无线传感器越来越流行, 具备一定的便携性, 但是, 如果不给它们配上桌面电脑, 那只能在有限的范围内使用. 智能手机, 或类似的移动设备没有这种限制. 有个试点项目, 已经开发出一个能实时将音频, 视频和其他数据, 从 Android 设备通过无线网络传到 SSI 服务的组件. 服务器会即时对这些数据, 并将结果回传给移动设备. 这个例子告诉我们, 新的应用能在更广阔的空间中使用, 因为它能跟着用户到处走. CARE 项目 (一个给老年人用的情景感知推荐系统) 目前正在开发的一个推荐系统, 该系统根据生理, 心理以及社交情况, 给孤寡老人的居家生活提供实时帮助. 他们的目标是帮助老年人重拾生活的信心. 鸣谢本文提及的工作由 European Union under research grant CEEDs (FP7-ICT-2009-5) 和 TARDIS (FP7-ICT-2011-7), 和 ILHAIRE, a Seventh Framework Programme (FP7/2007-2013) under grant agreement n°270780 赞助. 文献[1] Johannes Wagner, Florian Lingenfelser, Tobias Baur, Ionut Damian, Felix Kistler, and Elisabeth André. 2013. 人类行为分析(SSI) 框架: 多模式信号实时处理与识别. 第 21 届 ACM 多媒体国际会议(MM ’13) 报刊. ACM, New York, NY, USA, 831-834. DOI=10.1145/2502081.2502223 http://doi.acm.org/10.1145/2502081.2502223. PDF [2] Florian Lingenfelser, Johannes Wagner, Elisabeth André, Gary McKeown, and Will Curran. 2014. 喜悦心情实时识别, 一个事件驱动 Fusion 方法. 第 22 届 ACM 多媒体国际会议报刊(MM ’14). ACM, Orlando, Florida, USA, to appear. |