如何用Tensorflow.js和React.js进行语音命令识别

866 阅读7分钟

用Tensorflow.js和React.js进行语音命令识别

现在有很多由人工智能驱动的计算机系统,可以使用基于语音的交流方式与人类沟通。这些类型的系统所采用的主要逻辑是能够识别语音并执行相应的任务。

在本教程中,我们将使用TensorFlow在React应用生态系统中提供的语音命令识别器模型,探索语音/命令识别的基本原理。

我们还将演示如何使用系统麦克风进行语音音频输入,并听取音频来进行概率预测。我们将学习如何实时进行语音指令识别,并演示预测的结果。

然后,我们要加载由TensorFlow.org提供的语音命令模型。将音频数据送入模型的神经网络,我们将聆听音频并进行预测。最后,我们还将通过对我们的模型应用argmax函数来提高识别的准确性。

本教程中我们将涉及的内容有

  • 如何从浏览器的麦克风中获取音频数据流。
  • 如何使用来自TensorFlow的预训练的语音命令模型精确地处理语音命令。
  • 如何通过使用argmax函数来提高整体预测/识别概率。

让我们开始吧!

创建一个React项目

首先,我们要创建一个新的React App项目。为此,我们需要在所需的本地目录中运行以下命令。

npx create-react-app speech_command

然后,我们需要在我们的代码编辑器IDE(VSCode)中打开该项目,如下面的屏幕截图所示。

create new react app

现在,我们可以执行yarn startnpm start 命令,在我们本地主机的3000端口上运行该项目。

preview react app

安装Tensorflow.js和语音命令识别

现在,我们要安装主要的TensorFlow.js包,以及TensorFlow.org提供的语音命令识别包。

为了安装该包,我们需要在我们的项目命令行或终端执行以下命令。

yarn add @tensorflow/tfjs @tensorflow-models/speech-commands
  • @tensorflow/tfjs:这是基于JavaScript的核心Tensorflow包。
  • @tensorflow-models/speech-commands。这是一个Tensorflow模型,使我们能够对口语命令进行识别。

导入依赖项

在成功安装了所需的包之后。我们需要在我们的React项目的App.js文件中导入它们,如下面的代码片段所示。

import * as tf from "@tensorflow/tfjs"
import * as speech from "@tensorflow-models/speech-commands"

设置应用程序的状态

然后,我们需要使用useState 钩子为模型、行动和标签定义状态变量,如下面的代码片断所示。

export default () => {
const [model, setModel] = useState(null)
const [action, setAction] = useState(null)
const [labels, setLabels] = useState(null)

它们在开始时都被初始化为空值。

useState 钩子使我们能够定义状态变量,这是一种在函数调用之间保存数值的方法。钩子方法接收任何数据类型的初始化参数并返回两对值。

一个值是当前的状态,在上面的代码片段中是model,action, 和labels 。另一个是用于更新状态的函数,在上面的代码中是setModel,setAction,setLabels

现在作为一个例子,你可以简单地使用更新函数来更新状态,如下面的代码片段所示。

加载语音识别器模型

在这里,我们将创建一个名为loadModel 的函数,将语音识别器模型加载到我们的应用程序中。首先,使用speech 模块提供的create 方法初始化一个recognizer

这将在应用程序中加载语音模型。然后,我们确保使用recognizer 中的ensureModelLoaded 方法加载该模型。

然后我们可以将recognizer 设置为models 状态,将识别器中的wordLabels 设置为labels 状态。接下来我们将在useEffect 钩子里面调用loadModel 函数,以便在应用程序启动时触发它。

实现方式见下面的代码片断。

const loadModel = async () =>{
  // start loading model
  const recognizer = await speech.create("BROWSER_FFT") 
 // check if model is loaded
  await recognizer.ensureModelLoaded();
  // store model instance to state
  setModel(recognizer)
 // store command word list to state
  setLabels(recognizer.wordLabels())
}
useEffect(()=>{loadModel()}, []);

useEffect钩子使我们能够在React组件中执行操作。这个钩子在组件加载到DOM上时运行。因此,任何需要在模板挂载时自动触发的功能调用都要放在useEffect钩子里。

第一个参数是一个功能回调,我们可以在其中应用任何代码表达式。第二个参数允许我们跟踪状态的变化,进而触发回调。

在上面的代码片段中,我们在useEffect钩子中调用了loadModel方法,其第二个参数中没有跟踪状态。因此,一旦组件安装完毕,loadModel方法就会被触发。

现在,当我们可以重新加载我们的应用程序时,我们会看到模型已经加载,并且在控制台中记录了标签,如下图所示。

list of command

激活语音识别器

在这一步,我们将激活我们的语音识别器,即开始听音频语音。为此,我们将实现一个名为recognizeCommands 的函数。在这个函数中,我们将使用listen 方法从model 状态听音频,然后记录语音的spectrogram 结果。

应用probabilityThreshold 的附加选项来提高识别率。最后,我们应用setTimeout 回调来触发stopListening 方法,以便停止语音识别器。

下面的代码片段中提供了整体的实现。

const recognizeCommands = async () => {
    console.log("Listening for commands");
    // start model and listen for command
    model.listen(
      (result) => {
        // print result
        console.log(result.spectrogram);
      },
      { includeSpectrogram: true, probabilityThreshold: 0.9 }
    );
    // set timeout after which the stops listening 
    setTimeout(() => model.stopListening(), 10e3);
  };

接下来,我们添加一个按钮来激活浏览器的麦克风,其onClick 事件将触发recognizeCommands 函数,如下面的代码片段所示。

<button onClick={recognizeCommands}>Press to Speak</button>

现在,一旦我们点击该按钮,应用程序中的模型将开始聆听语音,如下面的截图所示。

listening for command

这就完成了React应用程序中的语音识别功能的实现。我们现在可以运行应用程序并检测语音音频。

但为什么不改善语音检测结果呢。为了改善检测结果,我们将使用argmax函数。

添加argmax以获得最高概率的检测

现在,我们要在我们的语音识别器模型中添加argmax 函数,以提高其检测结果的最高可能性。

这个函数的实际源代码可以在这里找到。

function argMax(arr){
  return arr.map((x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r))[1];
}

该函数使用map 逻辑以及reduce 方法来提高整体的检测概率。因此,它是一个Map-Reduce算法。

map 函数接收输入,将输入转换为键值对,并对数据进行排序。map函数的输出被输入到reduce函数。

reduce 函数接收来自map 函数的排序后的键值数据。然后,它搜索和比较匹配的数据对并减少它们。它可以防止冗余并消除重复的数据对。

现在,我们要将argMax 函数应用于我们的模型,并将labels 设置为action 状态,如下面的代码片断所示。

const recognizeCommands = async () =>{
  console.log('Listening for commands')
   // start model to listening command
  model.listen(result=>{
    // add argMax function
    setAction(labels[argMax(Object.values(result.scores))])
  }, {includeSpectrogram:true, probabilityThreshold:0.7})
      // set timeout for stop working 
  setTimeout(()=>model.stopListening(), 10e3)
}

将命令显示在屏幕上

最后,我们将使用条件渲染将动作或命令的结果显示在屏幕上,如下面的代码片断所示。

{action ? <div>{action}</div>:<div>No Action Detected</div> }

总结

在本教程中,我们已经学会了如何使用语音命令识别器TensorFlow模型来检测我们React应用程序中的语音。

由于有了语音命令识别器COCO TensorFlow模型,在React应用中的语音识别的整体实现被简化了,变得简单了。

本教程的主要目的是探索语音命令识别器模型的使用案例,并使用它来创建一个简单的语音识别器React应用程序。

这样的语音识别器功能对许多基于音频文本的应用程序非常有用。这样的命令识别器可以用来建立一个机器人或任何基于人工智能的应用程序,将音频输入作为一个命令来触发行动。