K_b0KBsM · 5月16日 · 广东

创客项目秀 | 基于浊度和TDS传感器的人工舌头

今天小编给大家介绍Thomas Vikstrom的人工舌头项目,该项目使用水质传感器来测量液体的浊度,并通过一个机器学习模型在Seeed Studio WIO终端上对不同种类的液体进行分类。
这个项目的灵感来自本杰明·卡贝令人惊叹的人工鼻子,它可以识别不同的气味。作者认为,找出是否有可能模拟人类舌头的味蕾,来检测各种可饮用的液体,或多或少会很有趣。 在这篇教程中,我们将展示如何使用低成本的水质传感器和WIO终端,以微型机器学习(TinyML)的方式成功检测五种不同的液体。
 title=

说明

这个项目主要是一项基础研究,因此目前没有特别的问题需要解决。然而,关于如何更好地利用这个项目的经验,已经出现了很多有趣的想法。 其中一些想法是用于嗅觉和味觉的训练,例如模拟味蕾来帮助大家更好地感受不同食物和饮料的味道,或者用于那些失去嗅觉和味觉能力的患者。这项技术的应用,能够帮助患者更好地理解食物或饮料的口感,提高他们的生活质量。 另外,这个项目还可以用于品酒,通过识别微小的酸碱度差异,更好地区分和辨别不同类别的酒,提高品酒体验和质量。 此外,这个项目还可以用于水质检测,例如监测废水处理过程中的污染物,这项技术可以更快速、更准确地检测到废水中的有害物质,提高废水的处理效率和安全性。 值得一提的是,一项研究报告显示,大约5%从Covid-19中恢复的患者会持续丧失嗅觉和/或味觉。这项技术可以用于帮助医生更好地评估这些患者的嗅觉和味觉恢复情况,为他们提供更好的医学治疗和保健方案。 总的来说,这项技术有着广泛的应用前景,我们期待能看到更多有创新的想法和应用的实现。
 title=

材料清单

硬件

  • Grove TDS Sensor
  • Grove Turbidity Sensor
  • Wio Terminal及电池模块

软件

  • Edge impulse
  • Arduino IDE

其他

  • 3D打印的外壳

什么是TDS,为什么要关注TDS

简单来说,TDS是衡量水中溶解物质(如盐和矿物质)含量的指标。为什么我们要关心TDS呢?原因是高水平的TDS可能意味着水中含有更多的污染物,这可能对我们的健康造成风险。
 title=

什么是浊度

浊度是测量水中悬浮颗粒数量的指标。Grove浊度传感器可以帮助我们测量水的浊度,即水中悬浮颗粒的数量。该传感器使用光学晶体管和光学二极管,通过测量从光源到光接收器的光量来计算水的浊度。这样我们就可以更好地了解水中悬浮颗粒的数量及其对水质的影响。

硬件配置

  • 先将传感器主板放入3D打印外壳中
  • 将 TDS 传感器的电缆连接到电池机箱上的 Grove 端口 A2,将浊度传感器的电缆连接到 Grove 端口 A4。当然,只要更改代码中的相关定义( #define TDS\_Pin A2 和 #define turbidity\_Pin A4 )。如果不使用 Grove 端口或电池机箱,则可以使用背面的 40 针 GPIO 接头。
  • 仔细检查连接
     title=
  • 3D打印舌头和PCB外壳的 STL 文件可在 GitHub https://github.com/baljo/Tongue/tree/main/3D%20Model/STL-files 存储库中找到:其中包含:

      传感器外壳STL文件
      传感器外壳上盖STL文件
      舌头STL文件
      舌头底盖STL文件
    

 title=

在这个项目中我第一次使用TPU 材质的3D打印丝(来自CCTree),并惊讶地发现它在我使用 Bowden-tube 挤出头的3D打印机上没有问题。我不敢全速(100毫米/秒),而是用了适度的50毫米/秒,温度为220°C。

高质量打印,我选择了 100 微米(0.1 毫米)的最高质量,这使得打印机每个部件都可以工作数小时。

整个打印过程不需要支撑,但还是建议使用底座支撑。与PLA相比TPU加热后粘性更强,所以可能不需要加热床。

“舌头”分为两部分,底部其实可有可无,但在设备不使用时提供一些保护,让它看起来更像真正的舌头!

如果您使用非常柔软的TPU材料进行打印,您可能需要将底部变得更加厚实,比设计文件中设置的更加厚实。这样做可以提高零件的稳定性和耐用性,同时也可以增加底部的保护性。
 title= title=

安装软件

为了能够收集数据,然后在实践中测试设置,您需要为WIO Terminal做一下准备:

  • 训练模型可以参考本教程中的步骤:

https://wiki.seeedstudio.com/Wio-Terminal-TinyML-EI-1/

  • 通过以下方式 Sketch > Include Library > Add .ZIP library 在Arduino IDE 添加以下库:ei-tongue-arduino-1.0.2.zip

https://github.com/baljo/Tongue/tree/main/3D%20Model/STL-files

  • 如果使用Wio Terminal电池拓展板,并且要查看电池状态,可以使用库文件:SparkFun BQ27441-G1A LiPo Fule Gauge Arduino Library

https://github.com/sparkfun/SparkFun\_BQ27441\_Arduino\_Library/tree/master

  • 添加Seeed\_Arduino\_Linechart库文件,将整个存储库下载到本地驱动器。然后添加 .ZIP文件如上

https://github.com/Seeed-Studio/Seeed\_Arduino\_Linechart

数据收集过程

要使用 Edge Impulse 收集数据,只需执行几个步骤:

  • 前期准备:找到至少两种液体,例如自来水和海水。请勿使用任何可能损坏传感器的液体,如油、酸或腐蚀性很强的液体。
  • 将传感器浸入另一种液体之前,使用清水仔细冲洗并擦干,以确保清除任何残留物,以免影响其性能。
  • 编译并上传主程序Tongue.ino到您的 WIO Terminal。

https://github.com/baljo/Tongue/blob/main/Tongue.ino
该程序既用于收集数据,也用于以后的推理。程序将传感器数据写入终端,数据转发器将在下一步中收集这些数据。

  • 使用Edge Impulse的data forwarder,设置 edge-impulse-data-forwarder --frequency 5 频率为 5 Hz
  • 当您看到此消息 2 sensor axes detected (example values: [3,1.79]). What do you want to call them? Separate the names with ',': 时,请键入 TDS, Turbidity ,因为这些是程序中使用的传感器标签。
  • 有关数据转发器工作原理的详细信息,请参阅此处。

https://docs.edgeimpulse.com/docs/tools/edge-impulse-cli/cli-data-forwarder

收集数据

转到 Edge Impulse,创建一个项目(如果尚未创建),然后转到 Data acquisition
 title=

  • 您的设备现在应该在右侧可见。
    使用10000毫秒(= 10秒)的样本长度,频率自动为5 Hz。
    您应该记录数据的第一个标签是 air ,不要将传感器浸入任何液体中,只需将它们保持在空气中即可。
  • 通常需要有一个用作其他或背景的标签。在这种情况下,标签甚至在程序中是“硬编码”的,但即使您不用作 air 标签,该程序在技术上也能正常工作。
  • 点击 Start sampling 收集数据,我为每个标签收集了大约 6 分钟的数据,但我建议每个标签每次的数据采集保持在一分钟左右开始。机器学习通常是一个迭代过程,因此请从小处着手,然后根据需要进行调整。
  • 从液体中收集数据时,请确保传感器浸入足够深的深度。
    对照本教程开头的动画,液体非常靠近玻璃边缘。
    为液体命名,最好用一个简短的标签,因为它们稍后将显示在WIO终端上。
    尝试为每种液体收集大致相同的数据量。

注意

您希望将一些数据样本作为稍后将使用的测试数据放在一边。根据您收集数据的方式,这将自动或不自动发生。如果顶部的饼图将 100%/0% 显示为“训练/测试拆分”,则需要手动干预。
一种方法是单独单击 Test 该 Dataset 部分并在那里收集数据,但尤其是第一次选择“Dashboard , scroll down and then click Perform train/test split”更容易。这将创建一个理想的80%/20%的比例。

训练和构建模型

收集一些数据后,您现在可以构建和训练 ML 模型了:

创建脉冲并生成要素

  • 从菜单中选择 Create impulse ,将窗口大小设置为2000 ms,窗口增加到500 ms,频率设置为5 Hz。
  • 选择 Raw Data 作为 Processing block ,选择 Classification 作为 Learning block
  • 点击 Save impulse
     title=
  • 从菜单中选择“Raw data”
  • 点击 Generate features

一段时间后,您将在右侧的功能资源管理器中看到图形表示。类的分离度越高,模型就越容易分类。

在这种情况下,每个样品使用完全相同的液体浓度,这解释了良好的分离。然而,在大多数实际情况下,浓度会不时发生某种程度的变化,例如,
你可能永远无法每次都以完全相同的强度冲泡茶。
 title=

训练模型

  • 从菜单中选择“Classifier”
  • 如图所示更改设置,最重要的更改是密集层和 Dropout 率,但请随意尝试其他设置。
  • 使用这些设置的未优化 float32 模型将非常小,因此无需分析量化 int8 模型。就我而言,int8 的准确性实际上非常差且无用,但我还没有调查原因,因为 float32 模型工作得很好。
  • 点击 “Start training” ,除非您有大量数据和/或非常庞大的神经网络,否则在这种情况下,训练只需几分钟。
  • 根据您的数据质量/数量和模型设置,您可能会也可能不会达到令人满意的准确性。如果未优化的 float32 模型的精度非常差,您可能需要收集更多数据,但在这种情况下,您还应该检查浊度传感器(较宽的传感器)是否确实足够浸入液体中,否则光学器件将无法正常工作。可能只“看到”空气。
  • 收集新数据后,单击 “Retrain model” 。这样,您就不需要生成新功能。

 title=

测试模型

对于测试(在本例中为干测试!),您将利用 ML 模型以前从未见过的测试数据。这将尽可能接近现实生活中的测试。

选择 Model testing 并单击 Classify all 。
同样,您需要等待一小会儿才能看到模型在看不见的数据上的表现。通常,准确性可能比训练阶段略差,但有时甚至可能更好。不过,最终的真相将在湿测试中首先揭示。

如果准确性比训练阶段差得多,原因通常是模型过度拟合,即它对训练数据建模得太好并且无法泛化。

在这种情况下,它可能有助于使模型不那么复杂(减少神经元的数量),提高丢失率,或者如果你只有几个数据样本,则需要收集更多数据。
 title=

模型部署(湿测试)

当您准备好在现实生活中测试模型时,在这种情况下使用WIO终端,Edge Impulse再次使您变得非常容易:

  • 从菜单中选择“Deployment”
  • 选择 Arduino library
  • 选择 Unoptimized (float32) ,然后单击 Build

 title=

几分钟后,将弹出一个窗口,向您展示如何将Arduino库包含在您自己的代码中。

在这种情况下,您应该再次在Arduino IDE中打开该文件 Tongue.ino ,按照说明包含新库,然后替换为 <Tongue\_inferencing.h> 您自己的库的头文件。如果你命名你的项目,例如 Liquids 在边缘冲动中,你会放 <Liquids.h> 在这里。

/* Includes ---------------------------------------------------------------- */
#include <Tongue_inferencing.h> // <<===============--------------------------- REPLACE this with your own library's header file
#include <SparkFunBQ27441.h> // to read battery info
#include "seeed_line_chart.h" //include the line chart library
#include "TFT_eSPI.h"

最后编译并上传程序到Wio Terminal上。
如果一切正常,您应该在设备本身上看到一个数据略有变化的折线图
传感器数据也显示在Arduino IDE终端窗口中

关于 Tongue.ino 程序的注释

它找到最大分类值并将其作为最终预测

它没有使用任何不确定性阈值,即,它将它感知到的所有内容分类到其中一个类中。
如果需要,请随时将不确定性分类代码添加到Arduino程序中,只需将分类值与给定的不确定性百分比阈值进行比较,例如60%。

结果

在潮湿条件下测试模型时,我得到的第一个结果非常复杂。有时该模型总能正确地对液体进行分类,有时则完全失败。

由于我怀疑我最初没有注意让浊度传感器处于适当且一致的深度,因此我从头开始,在数据收集之前将所有玻璃杯几乎填充到边缘。
这似乎是问题的解决方案,因为该模型现在可以 100% 正确工作。

这再次表明,机器学习作为一种范式通常是一个迭代过程,最好从少量数据开始,构建和测试 ML 模型,然后根据需要进行调整。
如前所述,量化的 int8 模型性能极差且无用。这很有趣,因为未优化的 float32 模型在理论和实践中都具有 100% 的准确度。

我没有进一步调查这个问题,但有兴趣了解为什么会发生这种巨大的差异,以及如何纠正它。
 title=

此外,我还没有测试过不同浓度的模型,并怀疑它可能与非常稀释的液体作斗争。为了克服这个潜在的问题,需要从具有不同稀释度的液体中收集数据并重新训练模型。

还要注意,很可能有完全不同的液体碰巧具有与使用的两个传感器测量的相同特性。

当两个传感器测量相似的值时,即使来自完全不同的液体,从模型的角度来看,液体将是相同的。这个问题可以通过使用“传感器融合”来克服,即添加更多或不同类型的传感器,例如

用于气味的气体传感器。使用WIO终端和Grove组件,这实际上应该很容易做到。
尽管存在上述潜在缺点,但我对这样的模型完美且一致地工作感到非常惊讶。

结论

在这个项目中,你已经学会了如何构建一个有效的 ML 项目,能够以良好或希望完美的准确性对不同的液体进行分类。

建议您对此进行更多探索,并通过添加更多不同类型的传感器来更进一步,尤其是尝试找到此类技术可以发挥作用的用例。
 title=

舌头 3D 设计改编自 Thingiverse  https://www.thingiverse.com/thing:644879 上的这个 3D 文件。我创建的所有 3D 文件的许可方式与原始创建者的许可方式类似(Attribution-ShareAlike 3.0 Unported/CC BY-SA 3.0)。如果你对Wio Terminal有兴趣,欢迎点击链接查看详情:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.731a523csSfurC&id=614341863391&ns=1&abbucket=4#detail

推荐阅读
关注数
8612
内容数
48
深度服务产业的国际化双创平台
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息