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

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
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:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Upprepar: Nej. (Skrev samtidigt.)

På ett operativssystem kan det hända att du får segmenteringsfel. "Programmet har gjort en förbjuden åtgärd". Men det är inte garanterat. Beror på hur många iterationer fel loopen går. Mest sannolikt är att programmet bara börjar läsa/skriva nästa array i minnet.

På en mikrokontroller med minneshanterare kan du också få segmenteringsfel ifall du ställer in minneshanteraren enligt hur du vill ha det.

Du programmerar ju "bare bones". Finns inget som räddar dig. Vad som helst kan hända om programmet skriver till fel minne. Inklusive att din radiostyrda bil fäller käppen för en gammal dam, och kör ut över en kajkant.
Senast redigerad av bearing 4 mars 2020, 17:53:12, redigerad totalt 2 gånger.
Användarvisningsbild
AndLi
Inlägg: 17116
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

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

Inlägg av AndLi »

DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Vad får dig att tro det?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

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

Inlägg av sodjan »

Varför man kan tro det?
Därför att i de flesta programmeringsspråk är det inbyggt.
Det är C som är undantaget i detta fall.
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 »

Sen finns det ju språk där variabeln förstoras automatiskt så att den alltid rymmer det man stoppar i den.
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 »

sodjan skrev:Varför man kan tro det?
Därför att i de flesta programmeringsspråk är det inbyggt.
Det är C som är undantaget i detta fall.
Alltså om jag har en array som rymmer 5 element och sedan initsaliserar jag den med 6 element.

Då varnar min IDE och markerar felet.

Men jag har aldrig fått någon varning om jag kör en funktion som har en for-loop i sig där for loppen skriver ut varje tal + ett extra element som inte finns.

Däremot har jag varit med om att Valgrind har pekat på fel i if-satser. Kanske borde detta göra en enkel simulering med Valgrind igen.
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 »

Vid kompileringen kan vissa fel upptäckas. Men inte under körning. Därför att den enda info som sparas om en array är dess placering i minnet. Längden på arrayen sparas inte.

Och om man ska gå in lite mer tekniskt, fungerar en array bara som en pekare. Den pekar på ett minnesutrymme som allokerats vid länkningen. Och pekaren är bara en variabel som innehåller ett nummer. Numret är adressen till starten på detta minnesutrymme.
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 »

Itererade en 4-array i en for-loop nu där loopen itererade 6 gånger. Inga felmeddelanden från IDE:n eller Valgrind.

Kod: Markera allt

int main() {

	// Matrix A
	float A[4*4] = {0.649587,   0.320520,   0.274275,   0.821053,
				    0.424608,   0.996594,   0.638315,   0.636367,
				    0.719499,   0.017284,   0.321835,   0.060467,
				    0.859543,   0.243554,   0.402577,   0.753847};

	// Vector b
	float b[4] = {0.091799,
				  0.202273,
				  0.269783,
				  0.580578};

	// Do backwardsubstitution
	clock_t start, end;
	float cpu_time_used;
	start = clock();
	backwardsubstitution(A, b, 4); // This ONLY prepare A, b to be solved linsolve
	end = clock();
	cpu_time_used = ((float) (end - start)) / CLOCKS_PER_SEC;
	printf("\nTotal speed  was %f\n", cpu_time_used);

	// Print A and b
	printf("A\n");
	print(A, 4, 4);

	printf("b\n");
	print(b, 4, 1);

	for(int i = 0; i <= 5; i++)
		printf("b[%i] = %f\n", i, b[i]);

	return EXIT_SUCCESS;
}
Skriver ut:

Kod: Markera allt

Total speed  was 0.000003
A
0.649586975574493408 0.320520013570785522 0.274275004863739014 0.821053028106689453 
0.000000029802322388 0.787083387374877930 0.459032863378524780 0.099678814411163330 
0.000000012787971571 0.000000000000000000 0.215008884668350220 -0.806180655956268311 
-0.000000001784709713 0.000000000000000000 0.000000000000000000 0.233807533979415894 

b
0.091798998415470123 
0.142267808318138123 
0.229150220751762390 
0.337253630161285400 

b[0] = 0.091799
b[1] = 0.142268
b[2] = 0.229150
b[3] = 0.337254
b[4] = 0.649587 <- Från A
b[5] = 0.320520 <- Från A
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 »

Testade nu med Valgrind SGCheck och nu kan jag hitta fel i stacken på koden ovan. Den skriver ut exakt vad som händer och räknar fel.
Men alla andra C program som jag har skrivit för numeriska beräkningar:
  • QP-faktorisering
  • Singular Value Decompotision med Golub & Reins algorithm
  • Singular Value Decompotision med Jacobi One-Side rotation
  • LU-faktorisering
  • Tikhonov regularization
  • Choleksy faktorisering
  • Backward subsitution och forward substitution
  • Determinant
  • Lyapunov
0 fel från Valgrind!
Känner att jag redan hör Unreal Tournament 1999 segerlåtar i huvudet mitt. :D Jag har aldrig använt det verktyget förut eller ens kollat om jag har skrivit rätt kod.
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 »

Precis, resultatet blev ju exakt som jag skrev.

Är det inte meningen att man ska skriva in förväntade resultat någonstans i det där programmet Valgrind?
Blir ju inte mycket till verifiering annars. Det blir som att en biltillverkares testförare kör bilen från 0-100 utan att mäta tiden tiden för accelerationen och jämföra med kravet.
Palle500
Inlägg: 4491
Blev medlem: 6 juni 2015, 14:53:06

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

Inlägg av Palle500 »

DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Du löser detta genom att låta en funktion hantera din array och således även felhanteringen. Och det är den funktionen som alla andra funktioner skall anropa istället för att gå rakt på din array.
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 »

bearing skrev:Precis, resultatet blev ju exakt som jag skrev.

Är det inte meningen att man ska skriva in förväntade resultat någonstans i det där programmet Valgrind?
Blir ju inte mycket till verifiering annars. Det blir som att en biltillverkares testförare kör bilen från 0-100 utan att mäta tiden tiden för accelerationen och jämföra med kravet.
Vadå exakt som du skrev?
Jag har skrivit flera hundra rader C kod och Valgrind kunde inte hitta ett enda fel på koden, alltså minnesläcka i stacken.
Däremot om jag medvetet gjorde felet så säger den till.

Här är ett exempel på One-Side SVD med Jacobi rotation. Vad kan man använda denna till då?
Jo, har man mycket mätdata som man samlar i en kvadratisk matris så kan man göra regression, systemidentifiering eller klassificering.

Har man en icke-kvadratisk matris så måste man gå på en QR-metod. Men QR-metoden är dyr och tar mycket tid. Då är det bättre med Golub och Reins algoritm, vilket är de fakto standard. One-Side SVD algorithmen är extremt snabb, men passar bara kvadratisk matriser.

Kod: Markera allt

void svd_jacobi_one_sided(float *A, int row, float *U, float *S, float *V) {
	// i and j are the indices of the point we've chosen to zero out
	float al, b, c, l, t, cs, sn, tmp, sign;
	int i, j, p, k;

	// Create the identity matrix
	memset(U, 0, row*row*sizeof(float));
	memset(V, 0, row*row*sizeof(float));
	memset(S, 0, row*sizeof(float));
	for(i = 0; i < row; i++){
		*(U + row*i + i) = 1;
		*(V + row*i + i) = 1;
	}

	// Apply MAX_ITERATION_COUNT_SVD times. That should be good enough
	for (p = 0; p < MAX_ITERATION_COUNT_SVD; p++) {
		// For all pairs i < j
		for (i = 0; i < row; i++) {
			for (j = i + 1; j < row; j++) {
				al = b = c = l = t = cs = sn = tmp = sign = 0.0;
				// Find the 2x2 submatrix
				for (k = 0; k < row; k++) {
					al += *(A + row*k + i) * *(A + row*k + i);
					b += *(A + row*k + j) * *(A + row*k + j);
					c += *(A + row*k + i) * *(A + row*k + j);
				}

				// Compute Jacobi rotation
				l = (b - al) / (2.0 * c);
				sign = 1.0;
				if (l < 0.0)
					sign = -1.0;
				t = sign / ((sign * l) + sqrtf(1.0 + l * l));
				cs = 1.0 / sqrtf(1.0 + t * t);
				sn = cs * t;

				// Change columns i and j only
				for (k = 0; k < row; k++) {
					tmp = *(A + row*k + i);
					*(A + row*k + i) = cs * tmp - sn * *(A + row*k + j);
					*(A + row*k + j) = sn * tmp + cs * *(A + row*k + j);
				}

				// Update the right singular vectors
				for (k = 0; k < row; k++) {
					tmp = *(V + row*k + i);
					*(V + row*k + i) = cs * tmp - sn * *(V + row*k + j);
					*(V + row*k + j) = sn * tmp + cs * *(V + row*k + j);
				}

			}
		}
	}

	// Find the singular values by adding up squares of each column, then taking square root of each column
	for (j = 0; j < row; j++) {
		for (i = 0; i < row; i++) {
			*(S + j) += *(A + row*i + j) * *(A + row*i + j);
		}
		tmp = *(S + j);
		*(S + j) = sqrtf(tmp);
	}

	// Sort the singular values largest to smallest, and the right matrix accordingly
	for (p = 0; p < (row - 1); p++) {
		for (j = 0; j < row - p - 1; j++) {
			if (*(S + j) < *(S + j + 1)) {
				tmp = *(S + j);
				*(S + j) = *(S + j + 1);
				*(S + j + 1) = tmp;

				// Rearrange columns of u and v accordingly
				for (i = 0; i < row; i++) {
					tmp = *(V + row*i + j);
					*(V + row*i + j) = *(V + row*i + j + 1);
					*(V + row*i + j + 1) = tmp;
					tmp = *(A + row*i + j);
					*(A + row*i + j) = *(A + row*i + j + 1);
					*(A + row*i + j + 1) = tmp;
				}
			}
		}
	}

	// A is A*V, so in order to get U, we divide by S in each column
	for (i = 0; i < row; i++) {
		for (j = 0; j < row; j++) {
			*(A + row*i + j) = *(A + row*i + j) / *(S + j);
		}
	}

	// Set U to A, since we have been making modifications to A
	memcpy(U, A, row*row*sizeof(float));
}

/*
 * GNU Octave code:
 *  >> A
	A =

	   3   4   5
	   2   5   6
	   5   6   7

	>> [u, s, v] = svd(A)
	u =

	  -0.47384   0.10757  -0.87402
	  -0.53340  -0.82478   0.18767
	  -0.70069   0.55512   0.44819

	s =

	Diagonal Matrix

	   14.91526          0          0
			  0    1.58310          0
			  0          0    0.16940

	v =

	  -0.401719   0.915134  -0.033930
	  -0.587752  -0.229240   0.775885
	  -0.702260  -0.331630  -0.629962

	>>
 */
Shimonu
Inlägg: 295
Blev medlem: 21 oktober 2015, 22:44:33

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

Inlägg av Shimonu »

Vad menar du skulle vara en minnesläcka? Du kör ju aldrig dynamisk allokering väl?
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 »

bearing skrev:Precis, resultatet blev ju exakt som jag skrev.
DanielM skrev:Vadå exakt som du skrev?
Jag kan ju inte kräva att du läser mina inlägg, men det hade ju varit roligare att skriva i dina trådar då. Får väl hoppa av den här också då.
DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
bearing skrev: Mest sannolikt är att programmet bara börjar läsa/skriva nästa array i minnet.
DanielM skrev:Itererade en 4-array i en for-loop nu där loopen itererade 6 gånger. Inga felmeddelanden från IDE:n eller Valgrind.

Kod: Markera allt

b[0] = 0.091799
b[1] = 0.142268
b[2] = 0.229150
b[3] = 0.337254
b[4] = 0.649587 <- Från A
b[5] = 0.320520 <- Från A (A är alltså nästa array i minnet /bearing)
DanielM skrev:Alltså om jag har en array som rymmer 5 element och sedan initsaliserar jag den med 6 element.

Då varnar min IDE och markerar felet.

Men jag har aldrig fått någon varning om jag kör en funktion som har en for-loop i sig där for loppen skriver ut varje tal + ett extra element som inte finns.
bearing skrev:Vid kompileringen kan vissa fel upptäckas. Men inte under körning. Därför att den enda info som sparas om en array är dess placering i minnet. Längden på arrayen sparas inte.

Och om man ska gå in lite mer tekniskt, fungerar en array bara som en pekare. Den pekar på ett minnesutrymme som allokerats vid länkningen. Och pekaren är bara en variabel som innehåller ett nummer. Numret är adressen till starten på detta minnesutrymme.
Sen en kommentar angående "Valgrind". Jag har aldrig använt det programmet. Antog att det skulle fungera som liknande program, som går ut på att utföra "code coverage" samt att på andra sätt hitta buggar. Vet faktiskt inte om dessa program brukar identifiera att arrayer läses förbi max index. Men det har jag nog förutsatt när jag använt dem själv.

Med verifiering via Valgrind syftade jag på att du skulle kunna ta reda på ifall det vore möjligt att ställa in ett förväntat resultat. Typ när du kör algoritmen som hittar kortaste vägen. Då kan du hitta kortaste vägen via Octave eller för hand innan, och spara som ett förväntat resultat. Sen kan Valgrind (om det nu är kapabelt till detta) jämföra vad koden producerade, med vad som förväntades.
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 »

bearing skrev: Jag kan ju inte kräva att du läser mina inlägg, men det hade ju varit roligare att skriva i dina trådar då. Får väl hoppa av den här också då.
Bättre om du kunde då förklara vad "det" betyder då.
bearing skrev: Med verifiering via Valgrind syftade jag på att du skulle kunna ta reda på ifall det vore möjligt att ställa in ett förväntat resultat. Typ när du kör algoritmen som hittar kortaste vägen. Då kan du hitta kortaste vägen via Octave eller för hand innan, och spara som ett förväntat resultat. Sen kan Valgrind (om det nu är kapabelt till detta) jämföra vad koden producerade, med vad som förväntades.
Sådant gör jag redan. Skriver koden först i Octave och sedan konverterar jag den till octave. Det tar en tid att skriva från Octave till C.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

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

Inlägg av Mr Andersson »

Valgrind är primärt skapat för att hitta heap-fel. Stackanalyseringen är experimentell.
Om den hittar ett fel, bra då har du identifierat en bugg. Om den inte hittar några fel betyder det inte att koden är felfri.
Skriv svar