啥都吃的豆芽 · 2020年08月18日

使用TensorFlow实现最低功耗新时代农业

使用ML通过音频分析来检测害虫,蚊子和砍伐树木。还可以预测火灾,温室适应和植物生长。
image.png

项目准备

硬件

image.png

软件及服务

image.png

工具

image.png

概述

该项目演示了如何使用TensorFlow和Artemis模块构建设备,以解决任何地方的农村或农业社区所面临的大多数问题。该设备使用机器学习算法检查整个植物的健康状况,进行极端气候预测和保护,自动温室适应并使用音频分析来检测致命的疾病传播媒介或森林的非法砍伐。该项目还演示了如何仅通过收集和利用从传感器获得的数据就能对农场有更多的见解。我从澳大利亚野火,由于错误的农作方法和蝗虫蜂群而造成的印度GDP下降等新闻中获得了灵感,使这个项目变得非常迅速,蝗虫蜂群正在迅速损害东非,巴基斯坦和许多其他国家的作物,蚊子的繁殖速度惊人,

进行此项目时所采取的重要措施是高效,耐心地收集数据,一旦收集了数据,工作就变得更加容易(如果您没有收集正确的数据来养活饥饿的ML框架,则注定会失败)。对于数据收集部分,我使用了过去的项目,该项目仅从传感器收集数据并使用Sigfox协议发送到后端,但是在这里,我将针对这些数据训练设备。这是我过去的项目的链接-https: //www.hackster.io/Vilaksh/sigfy-sigfox-farm-yield-with-crop-and-health-monitoring-3d8116 。首先尝试了解数据收集部分。

该项目的主旨是您需要在每个阶段之后对设备进行调整。因此,让我们开始吧,享受机器学习的乐趣。

技术概述

尽管我们已经搬到了一座现代化城市,但我仍然爱我的村庄。乡村的清新仍然使我从沉思的心情中恢复过来,但是由于周围的污染,我们正处于不良健康的境地,无论我们种植哪种农作物,它们也会对我们的身体产生一些不良影响,因此,重要的是还要照顾这些农作物。植物和人类疾病的早期征兆,也无需使用复杂且耗电的设备,这些设备需要大量维护,远远超出了贫困农民或乡村男人的承受范围。因此,我决定使用能够使用ML功能且延迟低且几乎没有碳足迹的Edge设备。
image.png
image.png

背景

主题:自然

1)农场分析:

随着人口的增加,一种可持续的耕作方法很重要。以前我们只是玩传感器,而现在使用Tensorflow,我们不仅可以感知而且可以分析,预测和采取行动。使用所有收集的数据,我们将 发现作物生长,光合作用速率,极端气候以及对智能温室适应的需求异常。此步骤将停止农民之间使用过量肥料,农药,杀虫剂促进生产的竞争。使用正确的农场分析,该机器将自动建议农民何时在其农场中使用化学品,从而节省了金钱,精力和环境恶化。您可以访问该网站,了解我国农业界面临的更多问题。

https://www.mckinsey.com/indu...

2)使用音频分析检测某些有益和有害生物:

花可以听到嗡嗡的蜂声,这使它们的花蜜更甜

农民正在使用大量化学药品来提高农业产量,但我们往往会忘记,由于过度使用这些农药,杀虫剂和无机肥料,交叉授粉剂,节肢动物(在地球上发现的90%的活生物体是昆虫)不会这样做。不会因过度的化学暴露和污染而被这些植物吸引或死亡。到现在为止,已经有超过2 000种授粉昆虫灭绝,如果没有保护,只有500种灭绝昆虫。

我们还需要尽早发现农作物中的疾病,以阻止其在农场中传播。为了解决这个问题,我想为什么不告诉农民仅在生长方式不良或有害害虫存在的情况下才使用化学药品,即使现在没有病害,农民也无用地喷洒化学药品并杀死蜜蜂等有用的昆虫。它还可以检测某些授粉剂以及它们在田地中的出现频率,基于观察结果,它可以帮助农民种植观赏植物,还可以检测出仅通过声音和频率就破坏农作物的大型动物。现在,我对设备进行了训练,以识别几种蚊子的声音,例如伊蚊,蚊子和按蚊以及蜜蜂。我还将添加,蝗虫和其他一些害虫,因为我的数据集非常小。这里的要点是,在第一次出现任何有害生物迹象时,农民或政府可以采取行动,然后将其传播到各处,而且用户还可以确切地知道从哪个设备接收到了信号。阅读本文https://www.aljazeera.com/new...

如果上述问题没有解决,那么整个世界将陷入粮食危机。“东非蝗虫暴发引发国际援助呼吁”

image.png
image.png

3)停止砍伐森林:

有许多非法砍伐树木的行为,因此我的设备会使用声音分析技术使有关当局意识到砍伐树木的情况,特别是它将检测所用木材切割工具的音调和频率

image.png

4)预测野火并适应极端情况:

如果我们能够分析来自环境传感器和气体传感器的数据,则可以轻松预测野火,还可以使设备学会采取措施,以防工厂无法获得最佳温度和光照,从而可以激活设备温室模式。

image.png

注意:请仔细查看本节中的每个图像,每个图像都包含成功运行模型所需的关键数据

音频分类

步骤1:收集音频分析所需的数据集:

我从kaggle数据集中获得了针对不同种类的蚊子拍子,蜜蜂的音频文件,您也可以从那里下载它,虽然文件很大,但是由于设备内存较小,所以我们不需要那么多数据集,因此我们将限制我们的设备自己只能读取每个类别的200个音频文件,每个音频文件发出一秒钟的声音。同样,您可以通过这种方式获得电锯,蝗虫,板球。如果您的房间里没有昆虫,那么您也可以记录自己的数据,这将更好,更准确,而且非常令人兴奋,但由于考试压力很大,我无法这样做。注意:如果我们直接加载为训练过程下载的音频数据,将无法使用,因为麦克风的架构会有所不同,并且设备无法识别任何内容。因此,一旦文件下载完毕,我们需要通过Artemis麦克风再次记录下来,以便我们可以训练出准确用于运行推理的数据。因此,让我们为Artemis Redboard ATP配置Arduino IDE,请查看下面的链接。

https://learn.sparkfun.com/tu...

选择木板作为Artemis ATP,然后从File-> Examples-> Sparkfun Redboard Artemis Example-> PDM-> Record_to_wav

image.png

除了代码外,还有一个Python脚本,您需要运行该脚本来记录板载麦克风中的音频。这是非常必要的,因为音频文件来自不同的麦克风,因此开发板可能无法准确识别频率并将声音视为噪声。

(Protip:在录制过程中,通过缓慢地前后移动声源来模拟气柱变化,以模拟接近麦克风的真实昆虫,这样我们可以获得更好的结果。我尝试了一下,并提高了准确性。)

#!/usr/bin/python
from __future__ import division
"""
Author: Justice Amoh
Date: 11/01/2019
Description: Python script to stream audio from Artemis Apollo3 PDM microphone
"""
import sys
import serial
import numpy as np
import matplotlib.pyplot as plt
from serial.tools import list_ports
from time import sleep
from scipy.io import wavfile
from datetime import datetime
# Controls
do_plot  = True
do_save  = True
wavname  = 'recording_%s.wav'%(datetime.now().strftime("%m%d_%H%M"))
runtime  = 50#100                      # runtime in frames, sec/10, set it according to your audio duration default is 5 seconds, I set it to 4 minutes as per my audio duration

# Find Artemis Serial Port
ports = list_ports.comports()
try:
sPort = [p[0] for p in ports if 'cu.wchusbserial' in p[0]][0]
except Exception as e:
print 'Cannot find serial port!'
sys.exit(3)
# Serial Config
ser = serial.Serial(sPort,115200)
ser.reset_input_buffer()
ser.reset_output_buffer()
# Audio Format & Datatype
dtype   = np.int16                  # Data type to read data
typelen = np.dtype(dtype).itemsize  # Length of data type
maxval  = 32768. # 2**15            # For 16bit signed
# Plot Parameters
delay   = .00001                    # Use 1us pauses - as in matlab
fsamp   = 16000                     # Sampling rate
nframes = 10                        # No. of frames to read at a time
buflen  = fsamp//10                 # Buffer length
bufsize = buflen*typelen            # Resulting number of bytes to read
window  = fsamp*10                  # window of signal to plot at a time in samples
# Variables
x = [0]*window
t = np.arange(window)/fsamp         # [x/fsamp for x in range(10)]
#---------------
# Plot & Figures
#---------------
plt.ion()
plt.show()
# Configure Figure
with plt.style.context(('dark_background')):
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
lw, = axs.plot(t,x,'r')
axs.set_xlim(0,window/fsamp)
axs.grid(which='major', alpha=0.2)
axs.set_ylim(-1,1)
axs.set_xlabel('Time (s)')
axs.set_ylabel('Amplitude')
axs.set_title('Streaming Audio')
plt.tight_layout()
plt.pause(0.001)
# Start Transmission
ser.write('START')          # Send Start command
sleep(1)
for i in range(runtime):
buf = ser.read(bufsize)                 # Read audio data
buf = np.frombuffer(buf,dtype=dtype)    # Convert to int16
buf = buf/maxval                        # convert to float
x.extend(buf)                           # Append to waveform array
# Update Plot lines
lw.set_ydata(x[-window:])
plt.pause(0.001)
sleep(delay)
# Stop Streaming
ser.write('STOP')
sleep(0.5)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.close()
# Remove initial zeros
x = x[window:]
# Helper Functions
def plotAll():
t   = np.arange(len(x))/fsamp
with plt.style.context(('dark_background')):
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
lw,     = axs.plot(t,x,'r')
axs.grid(which='major', alpha=0.2)
axs.set_xlim(0,t[-1])
plt.tight_layout()
return
# Plot All
if do_plot:
plt.close(fig)
plotAll()
# Save Recorded Audio
if do_save:
wavfile.write(wavname,fsamp,np.array(x))
print "Recording saved to file: %s"%wavname

录制完音频后,您可以使用任何音频分割器将音频文件分割为1秒。我将以下代码段与jupyter notebook一起使用以实现上述步骤。

from pydub import AudioSegment
from pydub.utils import make_chunks

myaudio = AudioSegment.from_file("myAudio.wav" , "wav") 
chunk_length_ms = 1000 # pydub calculates in millisec
chunks = make_chunks(myaudio, chunk_length_ms) #Make chunks of one sec

#Export all of the individual chunks as wav files

for i, chunk in enumerate(chunks):
    chunk_name = "chunk{0}.wav".format(i)
    print "exporting", chunk_name
    chunk.export(chunk_name, format="wav")

在切片之前,我曾使用Audacity清理下载的音频文件,还有非常棒的功能,可以用来了解音频是否纯净(音频频谱图)。

image.png
image.png
image.png

将音频文件切成薄片后,您就可以为Artemis训练这些文件了。但是,您需要进行调整以使其完美工作,因为由于机柜或工作环境而导致数据可能包含大量噪声,因此,我建议您也训练背景数据集,以便即使存在恒定的特殊噪声也可以工作。背景包含Audacity软件中所有修剪的音频片段和一些明显的噪音。

image.png
image.png

为了进行训练训,我使用了Google Colab,以下是完整的培训过程图像,您需要在Colab笔记本中进行培训时上传这些文件并在GPU上运行,对我而言,这花了将近2个小时。我必须训练三次,因为笔记本电脑由于互联网连接缓慢而无法连接,因此我首先训练了一个小数据集,仅蜜蜂,蚊子(无基因或品种分类)和电锯,之后我对整个数据集进行了两次训练,幸运的是,获得成功。

步骤2:训练音频数据

音频培训#1:标签=蚊子,蜜蜂,电锯
image.png
image.png
image.png

训练完成后,我们需要冻结模型并将其转换为精简模型以在Edge设备中使用。我将在代码中附加所有必需的注释。

音频培训#2:标签=埃及伊蚊,古蚊,凤尾鱼,蜜蜂,电锯

image.png
image.png
image.png

下载通过上述步骤生成的所有文件,您还需要为每个类音频文件生成微功能文件,我将在对设备进行编码时对此进行说明。您也可以阅读TensorFlow Lite for Microcontrollers文档以获取更多信息。

资料分类

步骤1:收集期望和不期望行为的传感器数据

1)植株高度:我用过去的项目来发芽后找出水稻植株的高度,但这还不够,因为只要印度没有SigFox连接,我就可以将设备保持打开状态,因此无论得到什么读数,我都使用Excel数学统计函数,回归技术以查找所有其他点并增加了一些噪声。对于为ML提供小的数据集,我感到非常抱歉,但值得庆幸的是,它适合我的应用程序,如果有朝一日将其用作商业产品,那么我将通过生成综合数据来扩展我的数据集。
image.png
image.png

2)火灾预测:我使用了环境组合式传感器来收集正常读数以及火灾情况读数。着火时,我们需要获取温度,温度,tVOC,CO2读数。因此,基本上,我们使用的是使用回归技术建立分类模型来进行预测。我使用了传感器的示例代码来获取所有读数。检测野火是非常重要的功能。

image.png
image.png

3)温室适应:我使用了静态VCNL4040模块来检测环境光水平,并使用环境组合传感器进行温度和CO2感测。基于数据,设备可以预测何时适应温室模式以保存农作物。可以对其进行进一步优化,以保护作物免受冰雹或大雪的影响。

image.png

步骤2:使用深度学习训练数据

如果没有标准化,切勿进行任何训练,因为您将永远不会看到模型提高其准确性。以下是我训练过程中的一些图像,足以让任何人知道训练过程中发生了什么。

训练1:火灾预测

我使用了“ adam” 优化器和“ binary_crossentropy” 损失,它们比任何其他方法都更有效,您可以相应地使用任何方法。其他数据集也遵循相同的训练步骤。此外,Sig 用作输出层的激活函数,因为Sig适用于非线性数据和二进制预测

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

训练2:温室适应预测

神经网络的回归模型配置与火灾预测模型的配置相同。输出预测将帮助用户根据相关的传感器数据来了解植物是否吸收了足够的CO2,光照,温暖,如果没有,则设备可以采取行动适应温室(我将告诉我们何时编码设备)。

image.png
image.png
image.png
image.png

训练3:植物生长追踪

这里使用rmsprop 代替adam 优化器,并将mse 作为损失函数。在此过程中,我训练了基本的神经网络来识别关于天数的生长模式,因此我将使用它来基于天数从模型中计算植物高度,并通过传感器读数检查值是否相差很大,这意味着植物是在那个季节生长不好。

image.png
image.png

准备好我们的代码

在这里,我将描述我们所有项目实现所共有的所有头文件,

#include "xyz_model_data.h"

我们使用xxd训练,转换并转换为C ++的模型

#include "tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h"

一个允许解释器加载模型使用的操作的类

#include "tensorflow/lite/experimental/micro/micro_error_reporter.h"

可以记录错误并输出以帮助调试的类

#include "tensorflow/experimental/lite/micro/micro_interpreter.h"

TensorFlow Lite for Microcontrollers解释器,它将运行我们的模型

#include "tensorflow/lite/schema/schema_generated.h"

定义TensorFlow Lite FlatBuffer数据结构的模式,用于理解sine_model_data.h中的模型数据

#include "tensorflow/lite/version.h"

模式的当前版本号,因此我们可以检查是否使用兼容版本定义了模型。

//You need to install Arduino_Tensorflow_Lite library before proceeding.
#include <TensorFlowLite.h>

在void setup()函数之前定义了一个名称空间,该名称空间用于解决不同程序包之间的名称冲突。另外,您需要为张量和其他相关操作分配内存。

namespace
{
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
// Create an area of memory to use for input, output, and intermediate arrays.
// Finding the minimum value for your model may require some trial and error.
constexpr int kTensorArenaSize = 6 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
}  // namespace

您可以从Arduino IDE示例部分中的Arduino Tensorflow Lite示例开始,然后将转换后的Lite模型数据传输到model_data.h文件,然后根据预测模型的输出采取任何操作。

编程,模型测试和连接Sparkfun Artemis设备

image.png
image.png
image.png
image.png
image.png
image.png

测试1:音频分析-

检查我们的语音模型并在OLED屏幕上显示结果。如果您不确定对整个项目进行编程,则可以选择示例项目并将其作为基础进行修改,您将很容易学习以这种方式进行调试。图片没有详细显示,因此我已经上传了代码,但是您仍然需要根据您的项目进行调整。您还可以轻松地对其进行修改,以根据检测到的声音(例如蚊子)将结果发送到移动站或基站,这样一来,您就可以轻松查看该昆虫在当地的发生率最高,并防止其繁殖或制造自动无人机导航系统,可在农田中喷洒特定的杀虫剂,农药,或在完全精确控制的情况下通知机构有关非法采伐的信息。在下面查看我们的测试结果图像。

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

我们已经完成了对项目的音频分析模型的培训和编程,现在我将继续对其他基于价值的输出模型进行编程。

测试2:火灾预测-

我们将数据模型加载到板上,然后对传感器值进行实时预测,基于该预测,我们将在OLED屏幕上显示通知,从而消除了农场火灾的可能性。这确实花费了我的大部分时间,因为无论我尝试如何,董事会每次都会给我编译错误。但是感谢Hackster社区,他帮助我成功上传了代码。

image.png
image.png
image.png
image.png
image.png

测试3:温室预测

在这里,我们将利用环境光,温度和CO2浓度检测传感器来预测是否有足够的光,温度和CO2可用于植物生长,如果条件不正常,我们将通过以下方式指导伺服电机激活并保护植物:像温室设置一样覆盖农场。
image.png
image.png

测试4:确定植物高度

我们已经训练了模型来通过回归确定植物高度,但是回归有一个缺点,缺点是它只能沿一个线性方向确定值,因此如果一直运行下去,如果没有,它将在某天返回以千米为单位的植物高度设定上限。因此,我们要做的是检测相应天数的植物高度,并用我们的模型检查相应天数,并检查模型预测的高度是否与我们测得的植物高度相差很大,相差很大,这意味着有一定的营养价值不足。
image.png
image.png

我随附了所有注释良好且易于阅读的代码,以实现您自己的算法,不要浪费时间考虑代码,花时间使您的训练数据集尽可能的好。

我没有3D打印机,所以我只是拿了一个塑料盒来构建模型,在提交想法时,我们还需要指定项目的外观,所以这里是安装(不是花园,因为我没有一个),但我尽了最大的努力去尽我所能地进行创新。抱歉,我找不到用于该硬件的起毛部件,但是接线非常简单,因为我使用了非常常见的传感器,并且静态传感器即插即用,所有图像都很清晰,足以详细说明传感器的引脚。

image.png

可持续发展目标

image.png

SDG 3:良好的健康和福祉

使用我们的设备,我们试图让当地人了解所有存在的病媒或正在繁殖的病媒,而且一旦听到任何害虫发出的声音,我们就能够挽救作物,从而节省了农民的大量精力并使它们喷洒仅在需要时使用化学药品,健康饮食。

SDG 13和SDG 15:陆地上的气候行动和生命

联合国目标:到2020年,促进实施所有类型森林的可持续管理,制止毁林,恢复退化的森林并在全球范围内大幅增加造林和重新造林,从各种来源和各级动员大量资源为可持续森林管理提供资金并提供充足的资源。鼓励发展中国家推进这种管理,包括保护和重新造林的管理。通过我们的项目,我们能够识别出非法采伐的树木并将其传达给森林部门以采取行动。因此,我们刻不容缓地停止砍伐森林,我还想到了另一个包括侦察枪声并向政府通报特定地区的偷猎者并采取严厉行动来打击他们的措施。

英文原址[https://www.hackster.io/vilak...]

推荐阅读
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息