实时动物检测与驱赶系统

无论是商业业主还是家庭主人,都可能面临动物如鹿、驼鹿甚至猫对花园、庄稼和财产造成的损害。在本系列文章中,将展示如何在Raspberry Pi上实时(或近实时)检测害虫(例如驼鹿),然后采取措施将其驱赶。由于不想造成伤害,将专注于通过播放响亮的噪音来吓走害虫。

欢迎下载项目的源代码。假设熟悉Python并且对神经网络的工作原理有基本的了解。

在前一篇文章中,为驼鹿检测组装了一个数据集,其中包含驼鹿类和背景类的对象图像。在本文中,将开发一个分类器DNN模型并在数据集上对其进行训练。将使用Caffe来创建和训练DNN。请在PC上安装此框架以继续。

开发DNN

DNN开发始于创建模型结构。由于将在Raspberry Pi上使用神经网络,因此模型应该是轻量级的,以便能够以适当的速度运行。从头开始设计一个优化的DNN模型是一个相当复杂的任务,不会在这里详细描述。建议使用以下网络架构:

这是一个使用免费在线编辑器可视化的CaffeDNN模型。它可能不是绝对最好的模型,但绝对足够满足目的。这是从AlexNet架构衍生而来的,AlexNet是第一个(也是最简单的)成功应用于图像分类的网络。修剪并优化了原始架构,用于对少量对象类别进行分类。生成的模型有四个卷积层,具有64-128-128-64核(卷积滤波器)。

还有两个池化层用于将输入图像的维度减少到128 x 128像素。中间的全连接(FC)层有256个神经元,最后一个FC层有两个神经元(每个对象类别一个:背景和驼鹿)。

还需要的另一个组件是训练模型,这是一个修改后的分类模型,它替换了输入和输出层。训练模型的输入层必须指定用于训练和测试的标记数据源。输出层必须指定在训练期间要最小化的损失函数。

为了提供标记数据源,创建包含所有样本图像路径和标签(图像对象类别的标识符)的文本文件。让将样本图像组织到以下文件夹中:

PI_PEST Learning 0 1 Testing 0 1 如所见,有两个主要文件夹,Learning和Testing,分别用于训练和测试。0子文件夹是背景样本,1子文件夹是驼鹿样本。

首先将每个类别的500个样本图像移动到测试目录,并将所有剩余图像移动到学习目录。现在让编写一些Python代码来生成源文件:

import os import numpy as np import cv2 class TrainFiler: def get_labels(self, folder): subfolders = os.scandir(folder) labels = [] for classfolder in subfolders: class_name = os.path.basename(classfolder) files = FileUtils.get_files(classfolder) for (i, fname) in enumerate(files): label = fname + "\n" + class_name labels.append(label) return labels def save_labels(self, labels, filename): with open(filename, 'w') as f: for label in labels: f.write('%s\n' % label) def gen_train_files(self, learn_folder, test_folder, learn_file, test_file): labels = self.get_labels(learn_folder) self.save_labels(labels, learn_file) labels = self.get_labels(test_folder) self.save_labels(labels, test_file)

可以这样运行它:

learn_folder = r"C:\PI_PEST\Learning" test_folder = r"C:\PI_PEST\Testing" learn_file = r"C:\PI_PEST\classeslearn.txt" test_file = r"C:\PI_PEST\classestest.txt" filer = TrainFiler() filer.gen_train_files(learn_folder, test_folder, learn_file, test_file)

这将产生两个源文件,包含以下数据:

...

C:\PI_PEST\Learning\0\vlcsnap-2020-10-26-16h13m39s332(x253,y219,w342,h342)fliprotate15.png 0

C:\PI_PEST\Learning\0\vlcsnap-2020-10-26-16h13m39s332(x253,y219,w342,h342)fliprotate_15.png 0

C:\PI_PEST\Learning\1\vlcsnap-2020-10-21-13h46m55s365(x106,y28,w633,h633).png 1

C:\PI_PEST\Learning\1\vlcsnap-2020-10-21-13h46m55s365(x106,y28,w633,h633)flip.png 1

...

...

C:\PI_PEST\Testing\0\vlcsnap-2020-10-26-16h16m22s719(x39,y36,w300,h300)smooth5rotate15.png 0

C:\PI_PEST\Testing\0\vlcsnap-2020-10-26-16h16m22s719(x39,y36,w300,h300)smooth5rotate_15.png 0

C:\PI_PEST\Testing\1\vlcsnap-2020-10-26-16h08m31s421(x276,y0,w566,h566)flipsharpen5.png 1

C:\PI_PEST\Testing\1\vlcsnap-2020-10-26-16h08m31s421(x276,y0,w566,h566)flipsharpen5rotate15.png 1

...

在开始训练过程之前,最后一件事是准备所谓的求解器规范。对于Caffe框架,这是一个包含训练过程参数的文本文件。

net: "classes_learn_test.prototxt" test_iter: 1000 max_iter: 100000 base_lr: 0.001 solver_mode: CPU

net参数指定了'训练'模型的路径,test_iter是准确性测试的周期,max_iter是运行的最大迭代次数,base_lr是学习率的起始值,solver_mode参数定义了训练过程是在CPU还是GPU上执行。

要启动Caffe进行模型训练,需要将以下数据文件复制到Caffe可执行文件文件夹:classes_learn_test.prototxt(训练文件),classeslearn.txt和classestest.txt(生成的训练和测试数据文件),以及classes_solver.prototxt(求解器规范文件)。

使用以下命令启动训练过程:

caffe.exe train -solver=classes_solver.prototxt

在打开的控制台窗口中,可以看到训练过程的进度:

I1028 09:10:24.546773 32860 solver.cpp:330] Iteration 3000, Testing net (#0)

I1028 09:13:12.228042 32860 solver.cpp:397] Test net output #0: accuracy = 0.95

I1028 09:13:12.229039 32860 solver.cpp:397] Test net output #1: loss = 0.209061 (* 1 = 0.209061 loss)

I1028 09:13:12.605070 32860 solver.cpp:218] Iteration 3000 (1.83848 iter/s, 543.929s/1000 iters), loss = 0.0429298

I1028 09:13:12.605070 32860 solver.cpp:237] Train net output #0: loss = 0.00469132 (* 1 = 0.00469132 loss)

I1028 09:13:12.608062 32860 sgd_solver.cpp:105] Iteration 3000, lr = 0.000800107

I1028 09:19:11.598755 32860 solver.cpp:447] Snapshotting to binary proto file classes_iter_4000.caffemodel

I1028 09:19:11.641045 32860 sgd_solver.cpp:273] Snapshotting solver state to binary proto file classes_iter_4000.solverstate

I1028 09:19:11.661990 32860 solver.cpp:330] Iteration 4000, Testing net (#0)

I1028 09:21:51.567586 32860 solver.cpp:397] Test net output #0: accuracy = 0.971

I1028 09:21:51.568584 32860 solver.cpp:397] Test net output #1: loss = 0.0755974 (* 1 = 0.0755974 loss)

I1028 09:21:51.942620 32860 solver.cpp:218] Iteration 4000 (1.92553 iter/s, 519.337s/1000 iters), loss = 0.0283988

I1028 09:21:51.942620 32860 solver.cpp:237] Train net output #0: loss = 0.0119124 (* 1 = 0.0119124 loss)

I1028 09:21:51.942620 32860 sgd_solver.cpp:105] Iteration 4000, lr = 0.000751262

I1028 09:29:05.931291 32860 solver.cpp:447] Snapshotting to binary proto file classes_iter_5000.caffemodel

I1028 09:29:06.011082 32860 sgd_solver.cpp:273] Snapshotting solver state to binary proto file classes_iter_5000.solverstate

I1028 09:29:06.042008 32860 solver.cpp:330] Iteration 5000, Testing net (#0)

I1028 09:32:13.374222 32860 solver.cpp:397] Test net output #0: accuracy = 0.877

I1028 09:32:13.374222 32860 solver.cpp:397] Test net output #1: loss = 0.861016 (* 1 = 0.861016 loss)

I1028 09:32:13.743319 32860 solver.cpp:218] Iteration 5000 (1.60823 iter/s, 621.8s/1000 iters), loss = 0.000519958

I1028 09:32:13.743319 32860 solver.cpp:237] Train net output #0: loss = 0.000306881 (* 1 = 0.000306881 loss)

I1028 09:32:13.745313 32860 sgd_solver.cpp:105] Iteration 5000, lr = 0.000708472

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485