Сегодня мы расскажем о проекте, нацеленном на распознавание некоторых видов физической активности человека. Делается это с помощью платы Intel Edison, к которой подключён акселерометр ADXL345.
Данные о том, чем именно занят пользователь, способны найти множество применений. Особенно это касается сферы носимой электроники. Например, в среде здравоохранения такие сведения можно использовать для наблюдения за пациентами, в спорте – для анализа особенностей выполнения упражнений и фитнес-трекинга.
В нашем проекте для анализа данных акселерометра используется метод опорных векторов (Support Vector Machine, SVM). Программная часть реализована с применением популярной библиотеки LIBSVM. Код написан в двух вариантах: на Python и Node.js.
Система умеет распознавать следующие виды физической активности: бег, ходьба, подъём и опускание по лестнице. Так же она способна реагировать на состояние покоя. Мы собираем показания акселерометра с некоторыми интервалами, извлекаем интересующие нас значения, в данном случае – значения ускорения по осям X, Y и Z. Затем эти данные используются для создания системы машинного обучения, которая и узнаёт, чем именно занят человек.
Вот, как акселерометр ADXL345 подключён к Intel Edison.
Подключение акселерометра к Edison
Сначала надо загрузить библиотеку LIBSVM и перенести архив LibSVM в корневую папку Intel Edison с использованием WINSCP. Затем архив надо распаковать такой командой:
Теперь надо запустить make в папке libsvm-3.21, далее – make в libsvm-3.21/python.
После этого создадим python-скрипт predict-activity.py в директории libsvm-3.21/python.
Вот, как мы читаем данные акселерометра.
Файл с учебными данными содержит записи для следующих видов физической активности:
Вот фрагмент этого файла:
Файл с данными для обучения системы
Параметр C в реализации метода опорных векторов позволяет управлять соотношением между ошибками SVM на учебных данных и максимизацией ширины границы между классами. Он используется при обучении модели и указывает на учёт выбросов при нахождении опорных векторов. Этот параметры мы подбираем, используя метод поиска по сетке.
Результаты поиска по сетке
Вот код, который занят тем, что определяет, чем же занят человек.
Реализация на Node.js
Данные о том, чем именно занят пользователь, способны найти множество применений. Особенно это касается сферы носимой электроники. Например, в среде здравоохранения такие сведения можно использовать для наблюдения за пациентами, в спорте – для анализа особенностей выполнения упражнений и фитнес-трекинга.
В нашем проекте для анализа данных акселерометра используется метод опорных векторов (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-проектов.
npm install node-svm
npm install <package-name>
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);
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);
Поделиться с друзьями