首页 文章 精选 留言 我的

精选列表

搜索[声音工坊],共7907篇文章
优秀的个人博客,低调大师

唇语识别技术的开源教程,听不见声音我也能知道你说什么!

唇语识别并非最近才出现的技术,早在 2003 年,Intel 就开发了唇语识别软件 Audio Visual Speech Recognition(AVSR),开发者得以能够研发可以进行唇语识别的计算机;2016 年 Google DeepMind 的唇语识别技术就已经可以支持 17500 个词,新闻测试集识别准确率达到了 50% 以上。 大家一定很好奇唇语识别系统要怎么实现。Amirsina Torfi 等人实现了使用 3D 卷积神经网络的交叉视听识别技术进行唇语识别,并将代码托管到 GitHub 上开源: 传送门: https://github.com/astorfi/lip-reading-deeplearning 接下来就为大家介绍如何使用 3D 卷积神经网络的交叉视听识别技术进行唇语识别,完整的论文可参阅: https://ieeexplore.ieee.org/document/8063416 下面是进行唇语识别的简单实现方法。 用户需要按照格式准备输入数据。该项目使用耦合 3D 卷积神经网络实现了视听匹配(audio-visual matching)。唇语识别就是这个项目的具体应用之一。 概况 当音频损坏时,视听语音识别(Audio-visual recognition,AVR)被认为是完成语音识别任务的另一种解决方案,同时,它也是一种在多人场景中用于验证讲话人的视觉识别方法。AVR 系统的方法是利用从某种模态中提取的信息,通过填补缺失的信息来提高另一种模态的识别能力。 问题与方法 这项工作的关键问题是找出音频和视频流之间的对应关系。我们提出了一种耦合 3D 卷积神经网络架构,该架构可以将两种模式映射到一个表示空间中,并使用学到的多模态特征来判断视听流间的对应关系。 如何利用 3D 卷积神经网络 我们提出的该架构将结合时态信息和空间信息,来有效地发现不同模态的时态信息之间的相关性。我们的方法使用相对较小的网络架构和更小的数据集,并在性能上优于现有的视听匹配方法,而现有方法主要使用 CNN 来表示特征。我们还证明了有效的对选择(pair selection)方法可以显著提高性能。 代码实现 输入管道须由用户提供。其余部分的实现包含基于话语的特征提取的数据集。 唇语识别 就唇语识别来讲,必须将视频作为输入。首先,使用 cd 命令进入相应的目录: 运行专用的 python file 如下: 运行上述脚本,通过保存每个帧的嘴部区域来提取唇部动作,并在画框圈出嘴部区域来创建新的视频,以便进行更好的可视化。 所需的 arguments 由以下 Python 脚本定义, VisualizeLip.py 文件中已定义该脚本: 一些已定义的参数有其默认值,它们并不需要进一步的操作。 处理 视觉部分,视频通过后期处理,使其帧率相等,均为 30f/s。然后,使用 dlib 库跟踪视频中的人脸和提取嘴部区域。最后,所有嘴部区域都调整为相同的大小,并拼接起来形成输入特征数据集。数据集并不包含任何音频文件。使用 FFmpeg 框架从视频中提取音频文件。数据处理管道如下图所示: 输入管道 我们所提出的架构使用两个不相同的卷积网络(ConvNet),输入是一对语音和视频流。网络输入是一对特征,表示从 0.3 秒的视频中提取的唇部动作和语音特征。主要任务是确定音频流是否与唇部运动视频在所需的流持续时间内相对应。在接下来的两个小节中,我们将分别讲解语音和视觉流的输入。 语音网络(Speech Net) 在时间轴上,时间特征是非重叠的 20ms 窗口,用来生成局部的频谱特征。语音特征输入以图像数据立方体的形式表示,对应于频谱图,以及 MFEC 特征的一阶导数和二阶导数。这三个通道对应于图像深度。从一个 0.3 秒的视频剪辑中,可以导出 15 个时态特征集(每个都形成 40 个 MFEC 特征),这些特征集形成了语音特征立方体。一个音频流的输入特征维数为 15x40x3。如下图所示: 语音特征使用 SpeechPy 包进行提取。 要了解输入管道是如何工作的,请参阅: code/speech_input/input_feature.py 视觉网络(Visual Net) 在这项工作中使用的每个视频剪辑的帧率是 30 f/s。因此,9 个连续的图像帧形成 0.3 秒的视频流。网络的视频流的输入是大小为 9x60x100 的立方体,其中 9 是表示时态信息的帧数。每个通道是嘴部区域的 60x100 灰度图像。 架构 该架构是一个耦合 3D 卷积神经网络,其中必须训练具有不同权重的两个网络。在视觉网络中,唇部运动的空间信息和时态信息相结合,以此来利用时间相关性。在音频网络中,提取的能量特征作为空间维度,堆叠的音频帧构成了时间维度。在我们提出的 3D 卷积神经网络架构中,卷积运算是在连续的时间帧上对两个视听流执行的。 训练 / 评估 首先,克隆存储库。然后,用 cd 命令进入专用目录: 最后,必须执行 train.py 文件: 对于评估阶段,必须执行类似脚本: 运行结果 下面的结果表明了该方法对收敛准确度和收敛速度的影响。 最好的结果,也就是最右边的结果,属于我们提出的方法。 所提出的在线对选择方法的效果如上图所示。 分析到这,希望大家可以到 Github 上找到源码,开始练起!附上作者给的代码演示。 原文发布时间为:2018-11-6 本文作者:Amirsina Torfi等 本文来自云栖社区合作伙伴“磐创AI”,了解相关信息可以关注“磐创AI”。

优秀的个人博客,低调大师

【曹工杂谈】说说Maven框架和插件的契约

说说Maven框架和插件的契约 前言 Maven框架就像现在公司内的各种平台方,规定一些契约,然后想办法拉动业务方,一起在这个平台上去做生态共建。Maven也是这样,其实它就是一个插件执行的框架,Maven刚开始肯定不知道会有谁去贡献插件,插件如果写得五花八门的话,那对于平台方来说,可能就是一个灾难,所以,平台方就要负责定标准,要在我平台上写插件,必须怎么怎么样。 Maven给插件就定了契约,这个契约,是通过api jar包的方式。每次发布Maven新版本,与之伴随的,都会有一个api jar包。 如果有人要基于这个版本的api jar包来开发插件,就需要把这个插件引入到自己的插件工程中。然后根据api jar包中的契约接口,来实现自己的插件逻辑。 比如,maven clean插件的工程代码中,就依赖了api jar包。如下: api jar包中的契约接口长啥样呢? public interface Mojo { ... void execute() throws MojoExecutionException, MojoFailureException; } 核心方法就是这个,只要你实现这个接口就完事了。 作为框架方,怎么去调用这个插件呢?简而言之,就是: 1、找到插件的实现类jar包,然后构造一个该插件的类加载器,去加载这个jar包,然后找到对应的实现了契约接口的类,比如这里的CleanMojo 2、加载了这个CleanMojo的class之后,当然是反射生成对象,然后强制转换为契约接口,然后调用契约接口就行。比如: Class cleanMojoClass = 插件的类加载器加载插件的jar包; Mojo cleanMojo = (Mojo)cleanMojoClass.newInstance(); cleanMojo.execute(); 到此为止,我们的理论知识已经足够了,我们是不是可以show the code了? 工程实践 我们会模拟上面的过程, 建一个Maven module,用来存放插件api契约接口; 建一个Maven module,引入api,实现插件api,这样,我们的插件就算是实现好了; 接下来,把这两个工程编译一下,把jar包安装到本地仓库; 再新建一个工程,模拟Maven框架去加载插件,并执行插件。 插件api工程 直接用maven的archetype中的quickstart,新建一个module,里面很简单,就一个接口: 然后执行mvn install,安装到本地仓库。 插件实现工程 在pom中,我们会引入api。 <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>my-plugin-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> 代码也很简单,就一个实现类。 然后执行mvn install,安装到本地仓库。 主工程,模拟框架去调用插件 主工程就是模拟我们的Maven框架,由于我们调用插件,肯定是通过api的方式,所以,pom中肯定是要引入api的。 <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>my-plugin-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> 接下来,我们写了个测试类: public static void main( String[] args ) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException { // 1.1处 URL urlForPluginApi = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-api\\1.0-SNAPSHOT\\my-plugin-api-1.0-SNAPSHOT.jar"); URL urlForPluginImpl = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-implementation\\1.0-SNAPSHOT\\my-plugin-implementation-1.0-SNAPSHOT.jar"); URL[] urls = {urlForPluginApi, urlForPluginImpl}; // 1.2 URLClassLoader urlClassLoader = new URLClassLoader(urls,ClassLoader.getSystemClassLoader()){ @Override public Class<?> loadClass(String name) throws ClassNotFoundException { try{ // 保证:寻找类时,优先查找自己的classpath,找不到,再去交给parent classloader Class<?> clazz = findClass(name); return clazz; }catch (ClassNotFoundException exception ){ return super.loadClass(name); } } }; // 1.3 Class<?> implClazzByPluginClassloader = urlClassLoader.loadClass("org.example.MyMojoImplementation"); // 1.4 MojoInterface mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance(); // 1.5 mojoInterface.execute(); System.out.println( "Hello World!" ); } 我先大概讲解一下上述代码: 1.1处,构造了两个url,分别指向我本地仓库的两个文件,也就是api.jar和插件对应的实现的jar 1.2处,使用1.1中的url,构造了一个classloader,这个classloader的parent classloader,我们传的是,系统的AppClassloader。 同时,我们重写了这个classloader的行为,重写后的行为如下:遇到要加载的类时,自己优先加载,也就是会去自己的两个url里面找,看看能不能找到,如果找不到,就会进入异常,异常被我们捕获后,交给parent classloader去加载; 1.3处,我们用新建的classloader,去加载了插件的实现类 1.4处,利用1.3处加载的实现类的class,反射生成对象,强转为MojoInterface接口对象 1.5处,多态方式执行插件逻辑 大家不妨思考下,大家觉得,最终的执行结果是啥?我们的“hello world”能打印出来吗? 这个代码,我们上传了gitee,大家可以拉下来看。 https://gitee.com/ckl111/maven-3.8.1-source-learn 我这边给大家展示下,执行结果: 大家看看,这像话吗,明明我的插件代码里,是实现了接口的,怎么就不能向上转型呢?: public class MyMojoImplementation implements MojoInterface{ @Override public void execute() { System.out.println("implementation execute business logic"); } } 这个。。。怎么说呢。。。这么跟你解释吧,我们加载MyMojoImplementation时,发现这个类吧,还实现了接口MojoInterface,那么,这个接口类也就需要加载,因为我们classloader进行了改写(优先由自己进行加载),因此,最终呢,MojoInterface也就和MyMojoImplementation一样,都是由插件类加载器去加载的。 最终呢,在向上转型时,会出现下边这个情况,两边不匹配,就报错了。 MojoInterface(框架中的这个类,是由框架的类加载器加载的) mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance();(这个实现类实现的接口,是由插件类加载器加载的) 课后题 我们对代码进行了修改,改成了如下的样子,结果,就可以跑通我们的hello world了。这又是为啥呢? 我是逐日, 深圳腾讯打工人,成都深圳两地反复横跳的后端java程序猿一枚. 之前在深圳3年,后来去了成都4年,现在又来了深圳,也开始写写前端,有需要内推的可以找我。对于一线编码实战、网络、数据库、高并发等有浓厚兴趣。 也欢迎加我,拉进技术群一起交流;腾讯内推也可以找我。 本文由博客一文多发平台 OpenWrite 发布!

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册