Maskinellt lärande i inbyggda system - Vem är på?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

TomasL skrev:
DanielM skrev:Det är bara 1 rad :)
Jag gör så istället för att ha en for-loop. Har man en for-loop så tar det tid. Men gör man exakt allt på en enda rad så går det snabbt.
Har du tittat på den genererade assemblern?
Tyvärr inte. Jag förstår inte assembler heller. Men hur ser man den genererade assemblerkoden som?
rvl skrev:
Jag behöver inte ta abs på alla element. Jag kan summera först och sedan ta abs. Då sparar jag ännu mera tid.
Tänk en gång till.
Gör bättre själv då.
bearing skrev:Det beror på hur man skriver koden i for-loopen.

Jag skrev ett exempel till dig för länge sedan där jag gjorde om din loop från att innehålla typ:

Kod: Markera allt

integral += *(pekare + faktor*i);
Till:

Kod: Markera allt

integral += *pekare;
pekare += faktor;
Det senare brukar gå fortare.

Sen undrar jag varför du ens behöver använda abs() om resultatet blir samma om du summerar utan abs() på varje faktor?
Om det ger samma resultat indikerar det att alla faktorer är positiva (eller alla negativa), och i så fall behövs inte abs() alls, eller?
Brukar? Det är väll det samma?
array[kolumn*rad + kolumn] är exakt samma som array[rad][kolumn] och exakt samma som *(array kolumn*rad + kolumn). Alltså jag kommer åt elementet med samma metod.

Tack. Jag skrev detta ovan att jag behöver bara använda en abs(). Men jag funderar på att jobba lite mera på hur jag ska kunna avgöra om det är ett vist mönster i histogrammet.
Vi säger att du har en bild som ser ut så här i ett histogram. Detta är alltså bilden som är tränad.
Markering_002.png
Men i verkligheten så ser det mer ut så här. Jag jämför histogrammen med varandra. Den som har bäst anpassning väljs ut. Men LBPH är känslig mot brus, dvs om bakgrunden ändras så fungerar inte algoritmen. En lösning på detta är att använda små bilder istället för en stor. Men detta kräver mer beräkningstid då om man ska dela upp 1 bild till 9 bilder :) Då hade jag tänkt om man kunde verifiera ett mönster i histogrammet. Vad tror du?
Markering_003.png
hawkan skrev:Hehe det ÄR 256 rader. Möjligen är det ett statement, nä vad det kallas på svenska slinter från minnet nu.
Men du kommer att få mer kommentarer om din kodningsstil än kring ditt egentliga problem när du gör som du gör.
Och att det är snabbare med 256 rader är inte säkert alls. Men du ser vart det drar iväg så jag stoppar här
och hoppas du kommer framåt med dit egentliga problemlösande.
Inte alls säkert alls?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
bearing
Inlägg: 11250
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av bearing »

Brukar? Det är väll det samma?
Nej, därför att varje multiplikation kostar. I mitt exempel behövs inte en enda.

Sen beror det på processorns arkitektur och hur bra kompilatorn optimerar.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Men jag är behov utav multiplikation då jag kör 1D-arrayer som ska fungera som 2D-arrayer.
Användarvisningsbild
Lennart Aspenryd
Tidigare Lasp
Inlägg: 12607
Blev medlem: 1 juli 2011, 19:09:09
Ort: Helsingborg

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av Lennart Aspenryd »

Att experimentera, testa, lyssna och lära. Testa mera och lära mera. Ja programmering är sannolikt en iterativ process.
Och processorn, den tuggar i sig assemblerkod, inte C eller C++.
Att då skriva en rad med loop eller upprepa flera rader och sedan granska den producerade assemblerkoden! Det är den förståelsen TomasL hintade om.
Man behöver inte kunna asm för det. Lyssna, läs och lär.

https://jigsaw.google.com/assembler/
Senast redigerad av Lennart Aspenryd 9 mars 2020, 12:06:32, redigerad totalt 1 gång.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Jo jag vet att det är assemblerkoden som räknas.
Håller just nu på med att hitta ett bättre sätt att analysera histogrammen.
hummel
Inlägg: 2267
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av hummel »

DanielM skrev: Tyvärr inte. Jag förstår inte assembler heller. Men hur ser man den genererade assemblerkoden som?
Din kompilator generar den filen, möjligen får du aktivera det med en kompilatorflagga eller kryssruta någonstans i ditt IDE. Om ingen listfil skapas får du kolla dokumentationen till din specifika kompilator helt enkelt.
Debuggern kan visa assemblerkoden den med.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Tack. Ska kolla lite på det när jag kommer hem.

Edit:

Vad tror ni om detta förslag?

Istället för att jämföra histogrammen med varandra och kolla vem som har bäst anpassning. Då borde man istället ta hjälp utav minsta kvadratmetoden.
Låt oss säga att \(X\) är våran uint8_t histogram av längd 256 element. Vi gör då om \(X\) till en 16x16 matris som vi kallar för \(A\)

Vi tar \(H = A^TA\) för att få den symmetrisk. Detta är viktigt för vi ska utföra minsta kvadratmetoden. Symmetriska matriser går alltid att lösa, än fast om resultatet inte blir bra.

Träning:
När vi tränar en bild så tar vi och försöker hitta \(x\) som är våran lösning på \(Hx = b\) där \(b\) är själva uint8_t binär array med dimensionen 16 som vi har själva konstruerat. Även \(x\) har dimensionen 16.
Vi börjar för lösa ut \(Hx = b\) och när vi har hittat \(x\) så sparar vi den. Den har ju dimensionen 16.

Verifiering:
När vi ska verifiera så räknar vi fram vårat \(H = A^TA\) av våran bild. Sedan tar vi vårat \(x\) och multiplicerar det med \(H\) så här \(Hx = b\).
Nu ska \(b\) visa ett binärt tal i form av en array, t.ex 1 0 1 0 1 1 1 0....
Vid många försök så kommer vi inte få en array som har enbart bara 1:or och 0:or. Då har vi inte hittat rätt klass.

Varför göra detta omständiga?
  • Vi kan ta hänsyn till brus då vi gör ett medelvärde med hjälp utav att hitta \(x\) från \(Hx = b\) där \(H\) är bilden i matrisform och \(b\) är vårat ID nummer. I detta fall radnummer på arrayen histograms.
  • \(x\) är alltså modellparametrar av dimensionen 16. Det är alltså mindre minne än dimensionen 256 som jag valde ovan.
Detta kräver att man måste göra backward substitution med heltal! Detta är en enkel metod och här skulle jag enkelt kunna tillämpa uint8_t men det blir svårare än med float.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Nu skulle jag behöva lite hjälp.

Vad är det absolut effektivaste sättet att konvertera om uint16_t variabel till en uint8_t array?
Jag vet om att man kan börja med att ta

Kod: Markera allt

uint8_t b0 = var >> 15; // Kan antingen vara 0 eller 1
. Men hur blir det för övriga? Om talet är t.ex 11001000 så blir b7 = 1 samt b6 = 1
.
.
.
.
uint8_t arr[16] = {b0, b1, b2, b3, b4, b5, b6, b7, b8, .. , b15};
Användarvisningsbild
mankan
EF Sponsor
Inlägg: 908
Blev medlem: 18 juli 2015, 11:23:22
Ort: Linköping

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av mankan »

Effektivt eller inte, den gör jobbet.

Kod: Markera allt

for (int = 0; n <= 15; ++n) {
  arr[n] = var & (1 << n) ? 1 : 0;
}
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Aha! Du löste på detta sätt! Låter smart! Tackar :tumupp:

Ska det inte vara n++ ?
Användarvisningsbild
mankan
EF Sponsor
Inlägg: 908
Blev medlem: 18 juli 2015, 11:23:22
Ort: Linköping

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av mankan »

n++ vs ++n, prova och byt och se skillnaden.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

Kod: Markera allt

uint8_t x[16];
		for (uint8_t i = 0; i < 16; i++) {
			x[15-i] = row_h & (1 << i) ? 1 : 0;
		}
		printf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d\n", x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15]);
med i++
0000000000000001
0000000000000010
0000000000000011
0000000000000100
0000000000000101
0000000000000110
0000000000000111
0000000000001000
0000000000001001
0000000000001010
Med ++i
0000000000000001
0000000000000010
0000000000000011
0000000000000100
0000000000000101
0000000000000110
0000000000000111
0000000000001000
0000000000001001
0000000000001010
Användarvisningsbild
mankan
EF Sponsor
Inlägg: 908
Blev medlem: 18 juli 2015, 11:23:22
Ort: Linköping

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av mankan »

Japp, men har du förstått varför det inte gör skillnad i det här fallet? Kanske inte så viktigt i C som i C++.

Varför x[15-i] och inte bara x i din kod ovan?
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av DanielM »

För jag vill ha MSB först :) Eller sist, beror på hur man ska tolka det som.
Lite mer så här har jag tänkt.
https://www.mathsisfun.com/binary-decim ... erter.html

Så nu har jag gjort detta(blev en liten ändring). Där \(A\) är mitt histogram och \(x\) själva den binära vektorn. Här är mitt mål att hitta \(b\), vilket blir ett heltal. \(b\) kan maximalt vara 4080 då 255*16 = 4080. Då kan \(b\) vara en uint16_t array med storleken rad*16. \(b\) ska alltså fylla upp 16 kolumnelement.
\(Ax = b\)

Sedan när jag ska identifiera bilderna så går jag bakvägen. Då vet jag \(A\) som är den nya bilden. Jag plockar fram \(b\) från min uint16_t array och sedan utför jag operationen för att lösa \(x\) som kommer bara ett binärt tal i from av en array.
\(Ax=b\)

Då konveterar jag bara om arrayen \(x\) till ett heltal igen. Notera att det första \(x\) som bildar en array med endast 1:or och 0:or är själva nummret på bilden.

Jag kan göra tvärt om också. Först lösa \(Ax=b\) och vid verifiering så utför jag \(Ax\) och kollar vilket \(Ax\) som motsvarar en binär array.
bearing
Inlägg: 11250
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Maskinellt lärande i inbyggda system - Vem är på?

Inlägg av bearing »

DanielM skrev: Brukar? Det är väll det samma?
array[kolumn*rad + kolumn] är exakt samma som array[rad][kolumn] och exakt samma som *(array kolumn*rad + kolumn). Alltså jag kommer åt elementet med samma metod.
Fast nu tror jag inte du läste mitt inlägg ordentligt, eller så är du bara allmänt arrogant som vanligt, därför att inget av dina exempel hade ju med vad jag skrev att göra. Det är inte alls samma. Du behöver inte alls 256 multiplikationer, utan 0:

Kod: Markera allt

//Equivalent to 256 rows of this type: abs(*(histograms + 256*i + 0) - *(histogram + 0))
sum = 0;
increment = 256;
for (i = 0; i <256; i++)
{
  sum += abs(*histograms - *histogram);
  histograms += increment;
  increment++;
  histogram++;
}
Om jag förstår rätt summerar du absolutvärdena på differensen mellan varje element i en vektor och diagonalelementen i en matris.
DanielM skrev:Nu skulle jag behöva lite hjälp.

Vad är det absolut effektivaste sättet att konvertera om uint16_t variabel till en uint8_t array?
Jag vet om att man kan börja med att ta

Kod: Markera allt

uint8_t b0 = var >> 15; // Kan antingen vara 0 eller 1
. Men hur blir det för övriga? Om talet är t.ex 11001000 så blir b7 = 1 samt b6 = 1
.
.
.
.
uint8_t arr[16] = {b0, b1, b2, b3, b4, b5, b6, b7, b8, .. , b15};
Jag skulle gjort såhär:

Kod: Markera allt

for (int i = 15; i >= 0; i--)
{
  x[i] = row_h & 0x01;
  row_h >>= 1;
}
Då behövs inte någon "barrel shift" varje varv i loopen. Och inte heller något villkor (if-sats). Ifall row_h behöver ha sitt värde kvar efter operationen får du spara row_h i en temporär variabel som sedan används i loopen.
Skriv svar