Сегодня мы расскажем о проекте, нацеленном на распознавание некоторых видов физической активности человека. Делается это с помощью платы Intel Edison, к которой подключён акселерометр ADXL345.
Данные о том, чем именно занят пользователь, способны найти множество применений. Особенно это касается сферы носимой электроники. Например, в среде здравоохранения такие сведения можно использовать для наблюдения за пациентами, в спорте – для анализа особенностей выполнения упражнений и фитнес-трекинга.
В нашем проекте для анализа данных акселерометра используется метод опорных векторов (Support Vector Machine, SVM). Программная часть реализована с применением популярной библиотеки LIBSVM. Код написан в двух вариантах: на Python и Node.js.
Система умеет распознавать следующие виды физической активности: бег, ходьба, подъём и опускание по лестнице. Так же она способна реагировать на состояние покоя. Мы собираем показания акселерометра с некоторыми интервалами, извлекаем интересующие нас значения, в данном случае – значения ускорения по осям X, Y и Z. Затем эти данные используются для создания системы машинного обучения, которая и узнаёт, чем именно занят человек.
Аппаратная реализация
Вот, как акселерометр ADXL345 подключён к Intel Edison.
Подключение акселерометра к Edison
Реализация на Python
▍Настройка LIBSVM
Сначала надо загрузить библиотеку LIBSVM и перенести архив LibSVM в корневую папку Intel Edison с использованием WINSCP. Затем архив надо распаковать такой командой:
tar –xzf libsvm-3.21.tar.gz
Теперь надо запустить make в папке libsvm-3.21, далее – make в libsvm-3.21/python.
После этого создадим python-скрипт predict-activity.py в директории libsvm-3.21/python.
▍Чтение показателей акселерометра
Вот, как мы читаем данные акселерометра.
import pyupm_adxl345 as adxl345
# Создаём I2C-объект акселерометра
adxl = adxl345.Adxl345(0)
while True:
adxl.update() # Получаем новые данные
raw = adxl.getRawValues() # Считываем необработанные данные
force = adxl.getAcceleration() # Получаем данные ускорения (g)
forceX=format(force[0],'.2f')
forceY=format(force[1],'.2f')
forceZ=format(force[2],'.2f')
sleep(2)
▍Классификация различных видов физической активности
Файл с учебными данными содержит записи для следующих видов физической активности:
0 – ходьба.
1 – бег.
2 – подъём или опускание по лестнице.
3 – отдых.
Вот фрагмент этого файла:
Файл с данными для обучения системы
▍Подбор наилучшего значения параметра C
Параметр C в реализации метода опорных векторов позволяет управлять соотношением между ошибками SVM на учебных данных и максимизацией ширины границы между классами. Он используется при обучении модели и указывает на учёт выбросов при нахождении опорных векторов. Этот параметры мы подбираем, используя метод поиска по сетке.
from svmutil import *
import numpy as nu
param = svm_parameter("-q -h 0")
y, x = svm_read_problem('activity.ds')
problem = svm_problem(y[:100], x[:100])
results = []
for c in range(-10,20):
for g in range(-10,5):
param.C, param.gamma = 2**c, 2**g
m = svm_train(problem,param)
p_lbl, p_acc, p_val = svm_predict(y[100:],x[100:],m)
results.append([param.C, param.gamma, p_acc[0]])
bestIdx = nu.argmax(nu.array(results)[:,2])
print results[bestIdx]
Результаты поиска по сетке
▍Классификация физической активности
Вот код, который занят тем, что определяет, чем же занят человек.
#Загрузка библиотеки LIBSVM:
from svmutil import *
#Создание экземпляра svm_problem, здесь activity.ds содержит набор учебных данных
y, x = svm_read_problem('activity.ds')
#Здесь y – это набор меток, представляющих различные виды физической активности, x – набор записей, представляющих значения ускорения по осям X, Y, Z
m = svm_train(y[0:], x[0:], '-c 0.03125 -h 0 -b 1 -q')
#y[0:] и x[0:] означает, что обучение модели проходит на всём наборе данных
#-h отключить сжатие
#-c : устанавливает параметр стоимости C в C-SVC
#-q: режим работы без вывода данных
values=[[float(forceX),float(forceY), float(forceZ)]]
#forceX,forceY и forceZ данные с акселерометра по соответствующим осям
p_labels,p_acc,p_values = svm_predict([0]*len(values),values,m])
#передаём данные акселерометра для классификации в метод svm_predict(), который возвращает следующее:
#p_labels: список распознанных видов физической активности
# p_acc: набор сведений о точности
#p_values: набор оценок вероятностей (если задан параметр '-b 1')
print p_labels
#вывод распознанных видов активности
Реализация на Node.js
▍Подготовка к работе с пакетом node-svm
Создадим папку для проекта в домашней директории платы и установим node-svm:
npm install node-svm
Скопируем папки build и lib из node-modules/node-svm в папку проекта. Далее – установим пакеты, необходимые для работы node-svm. Для этого нужна команда такого вида:
npm install <package-name>
Нам понадобятся следующие пакеты:
Stringify-object.
- Mout.
- Graceful-fs.
- Optimist.
- Osenv.
- Numeric.
- Q.
- underscore.
▍Работа с акселерометром
Вот как выглядит код для чтения показаний акселерометра.
var adxl345 = require('jsupm_adxl345');
var adxl = new adxl345.Adxl345(0);
setInterval(function()
{
adxl.update(); // Получаем новые данные
var raw = adxl.getRawValues(); // Считываем необработанные данные
var force = adxl.getAcceleration(); // Получаем данные ускорения (g)
var rawvalues = raw.getitem(0) + " " + raw.getitem(1) + " " + raw.getitem(2);
//console.log("Raw Values: " + rawvalues);
var forceX=force.getitem(0).toFixed(2);
var forceY=force.getitem(1).toFixed(2);
var forceZ=force.getitem(2).toFixed(2);
}, 2000);
Теперь можно написать программу для анализа и классификации активности пользователя, используя значение параметра C, полученного после выполнения поиска по сетке с использованием Python.
var so = require('stringify-object');
var svm = require('./lib');
var numeric = require('numeric');
var fs = require('fs');
var fileName = './activity.ds';
//создаём новый объект классификатора
var clf = new svm.CSVC({
c: 0.03125,
normalize: false,
reduce: false,
});
//Строим модель для обучения
svm.read(fileName)
.then(function (dataset) {
return clf.train(dataset)
.progress(function (progress) {
console.log('training progress: %d%', Math.round(progress * 100));
});
})
.spread(function (model, report) {
console.log('SVM trained. nReport:n%s', so(report));
}).done(function () {
console.log('done.');
});
//Анализируем данные в некотором временном интервале
var prediction=clf.predictSync([forceX, forceY, forceZ]);
var probability=clf.predictProbabilitiesSync([forceX, forceY, forceZ]);
console.log(prediction);
Результаты работы программы на Node.js
Итоги
Как видите, на Intel Edison можно создать систему распознавания физической активности человека, которая способна найти применение в сфере носимых устройств. Для этого понадобится лишь подключить к плате акселерометр и написать программу. Вычислительных возможностей Edison и объёма его оперативной памяти вполне хватает для реализации ресурсоёмкого алгоритма SVM.
Вы вполне можете воссоздать нашу систему, воспользовавшись приведённым выше описанием и этим кодом. Однако, и это самое главное, мы надеемся, что наш рассказ вдохновит вас на разработку собственных инновационных IoT-проектов.
Автор: Intel