目前我正试图复制这个精彩的项目https://www.youtube.com/watch?v=u8pwmzUVx48,尽管有更多的最小硬件,其中对于分类,我使用嵌入arduino uno中的神经网络进行了训练离线更强大的PC。分类器的代码在这里
#include <math.h>
#include <Wire.h>
double dataMagnitude[100];
double feature[7];
double feat_hid[10];
double output[4];
int classi;
const double w_hid[8][10] =
{
{18.9336670380822,11.9186055569093,-5.40114594311576,-21.1410711100689,-49.7798510124792,-14.8215222433047,-34.7308138535581,118.348601654702,-13.6275407707706,-11.6090487951753},
{-21.4994463865001,72.0672467700052,4.05328299052883,21.4875491464005,51.1604296852446,-15.8459578543758,6.30350750703905,-152.565733734759,12.8648040583067,13.8199895673734},
{8.66214515599865,-200.488705071393,-5.86973559011113,-23.4805286444925,-1.11016147795671,-3.04686605995311,-93.4143749063794,-73.8925691072615,-6.18427236042285,-10.9872535411407},
{-12.317892447947,-37.2154526807162,3.83978412266769,2.12866508710205,-11.9740446238331,10.2198116665101,41.9369083083022,63.2036147993661,1.40768362243561,15.4978881385563},
{7.58319670243546,161.895072542918,-2.3654701067923,1.91708846557259,-2.87224127392426,-16.5850302581614,45.2372430254377,34.255971511768,-2.30234070310014,-7.8952356779332},
{0.603971580989218,128.0244079393,0.628535912033608,-1.25788426737745,-0.204480047424961,-41.3372322514891,3.26860448943873,4.163893213914,0.443532051478394,-0.276136697942473},
{-3.63944154925129,18.3802540188974,0.975095285922393,-0.326187652485656,1.25521855841132,39.4877166809573,-15.3542772116519,-14.9546824078715,0.965532742621277,3.72386985716534},
{5.93321854314305,12.673690719929,-3.36580252980446,-21.2089241183081,-10.8980644878121,-7.29095431091201,-30.2240843969778,-2.48980394834853,-5.4167647620581,-5.68671825319015}
}, w_out[11][4] =
{
{1.07887052819228,-21.9615926704441,105.450147012522,-84.5674248703326},
{0.0344508533215184,0.551350792323934,-0.96380329372866,0.37800164808339},
{-99.251397621058,23.1671754381478,7.53147169676884,68.5527504861813},
{-5.0354869957171,4.36918523413481,0.408725687040089,0.257576074543764},
{-27.4478368365984,7.00659524306471,1.74370945871769,18.6975321348269},
{-0.213736004615516,-0.784795805217531,0.0732416484342244,0.925290161399087},
{8.62052547929066,-45.9408034639393,116.959261953552,-79.6389839689755},
{-8.5317661802465,45.4251911929737,-117.146523754862,80.2530987422069},
{127.053878005091,-29.4397580015468,-9.33919798608733,-88.2749220175082},
{1.11869995358251,-21.5111648695486,105.002356379838,-84.6098914639344},
{-5.81786935588552,3.78305066207264,0.11556429335063,-0.0807455995360207}
};
double S, Sig, Sigma, Sigma1, Sigma2, MAV, RMS, VAR, SDT, WL, ZC, SSC, Xn, accum, accumi;
char analogpin = 0, N=100;
void setup()
{
/* add setup code here */
Serial.begin(9600);
Wire.begin();
}
void loop()
{
do{
//data acqusition
for( int i = 0; i<100;i++)
{
Xn = (analogRead(analogpin))-510;
dataMagnitude[i]=Xn;
delayMicroseconds(830);
// Serial.println(dataMagnitude[i]);
}
S = 0;
for (size_t i = 0; i < N; i++)
{
S = S + dataMagnitude[i];
}
Sig = 0;
Sigma = 0;
Sigma1 = 0;
Sigma2 = 0;
for (size_t i = 0; i < N; i++)
{
Sig = Sig + abs(dataMagnitude[i]);
Sigma = Sigma + pow(dataMagnitude[i], 2);
Sigma1 = Sigma1 + pow((dataMagnitude[i] - S / N), 2);
}
for (size_t i = 0; i < N - 1; i++)
{
Sigma2 = Sigma2 + abs(dataMagnitude[i + 1] - dataMagnitude[i]);
}
//featureextract
MAV = (((1 / (double)N)*Sig-27.67)*2/(272.02-27.67))-1;
RMS = (sqrt((1 / (double)N)*Sigma)-34.91002721)*2/(284.1419012-34.91002721)-1;
VAR = (((1 / (double)(N))*Sigma1)-698.4139)*2/(52178.5691-698.4139)-1;
SDT = (sqrt((1 / (double)(N)) * Sigma1)-26.42752164)*2/(228.4262881-26.42752164)-1;
WL = (Sigma2-1621)*2/(11273-1621)-1;
//ZC = 0;
for (size_t i = 0; i < N - 1; i++)
{
if (dataMagnitude[i] == 0 && dataMagnitude[i] != dataMagnitude[i + 1])
{
ZC++;
}
}
ZC = (ZC-0)*2/(39-0)-1;
//SSC = 0;
for (size_t i = 0; i < N - 2; i++)
{
if (dataMagnitude[i]>dataMagnitude[i + 1] && dataMagnitude[i + 1]<dataMagnitude[i + 2])
{
SSC++;
}
else if (dataMagnitude[i]<dataMagnitude[i + 1] && dataMagnitude[i + 1]>dataMagnitude[i + 2])
{
SSC++;
}
}
SSC = (SSC-48)*2/(78-48)-1;
double feature[] = { MAV, RMS, VAR, SDT, WL, ZC, SSC };
//neural network construction
//first-hidden layer
for (int i = 0; i < 10; i++)
{
accum = w_hid[7][i];
for (int j = 0; j < 7; j++)
{
accum += (feature[j] * w_hid[j][i]);
}
feat_hid[i] = tanh(accum);
}
for (int i = 0; i < 4; i++)
{
accumi = w_out[10][i];
for (int j = 0; j < 10; j++)
{
accumi += (feat_hid[j] * w_out[j][i]);
}
output[i] = round(accumi);
}
//Classify the output
if (output[0] == 1 && output[1] < 1 && output[2] < 1 && output[3] < 1)
{
classi = 1;
}
else if (output[0] < 1 && output[1] == 1 && output[2] < 1 && output[3] < 1)
{
classi = 2;
}
else if (output[0] < 1 && output[1] < 1 && output[2] == 1 && output[3] < 1)
{
classi = 3;
}
else if (output[0] < 1 && output[1] < 1 && output[2] < 1 && output[3] == 1)
{
classi = 4;
}
else
{
classi = 0;
}
Wire.beginTransmission(5);
Wire.write(classi);
//Wire.write(int(output[2]));
Wire.endTransmission();
Serial.println("wew");
Serial.println(output[0]);
Serial.println(output[1]);
Serial.println(output[2]);
Serial.println(output[3]);
//Serial.println(classi);
//Serial.println(feature[1]);
//Serial.println(feature[2]);
//Serial.println(feature[3]);
//Serial.println(feature[4]);
//Serial.println(feature[5]);
//Serial.println(feature[6]);
for (size_t i = 0; i < 10; i++)
{
feat_hid[i] = 0;
}
for (size_t i = 0; i < 4; i++)
{
output[i] = 0;
}
}while(analogRead(analogpin)>0);
}
但实时实现相当不满意,输出总是不匹配,但离线实现要好得多。
我的假设是,在线时的数据捕获相当糟糕,或者是因为其他任何事情?
感谢您的反馈
答案 0 :(得分:0)
您是如何离线培训网络的? 如果您使用Matlab训练网络(即识别权重和偏差值),然后在Arduino上实现相同的网络。 在这种情况下,我们遇到数字精度问题。默认情况下,Matlab工作在64位精度,而Arduino工作在32位。 表示数字的方式不同会产生错误。