Forum: Projekte & Code Neuronales Netzwerke auf dem CH32V003


von Tim  . (cpldcpu)


Lesenswert?

Ich habe mich einmal daran gesetzt, neuronale Netzwerke auf dem CH32V003 
zu implementieren. Besondere Einschränkung: Die MCU nutzt den RV32EC 
Befehlssatz ohne Multiplikation,  sowie hat nur 2kb ram und 16kb flash.

Die Netzwerke müssen demnach mit nur 1-4 Bit (0-3 bit + Vorzeichen) für 
die Parameter auskommen. Die Inferenzengine ist relativ einfach. Die 
Herausforderung lag hier darin, das Netz so zu trainieren, dass es die 
Gewichte mit nur wenigen bits optimal ausnutzt.

Erstaunlicherweise kann man auch auf dieser Plattform >99% MNIST 
Testgenauigkeit erreichen. Es gibt zwar auch viele Beispiele auf Arduino 
u.Ä., aber die legen eher bei <95%

https://cpldcpu.wordpress.com/2024/04/24/implementing-neural-networks-on-the-10-cent-risc-v-mcu-without-multiplier/

https://github.com/cpldcpu/BitNetMCU

Innerloop für 2 Bit weights.
1
        for (uint32_t k = 0; k < n_input; k+=16) {
2
            uint32_t weightChunk = *weightidx++;
3
            for (uint32_t j = 0; j < 16; j++) {
4
                int32_t in=*activations_idx++;
5
                int32_t tmpsum = (weightChunk & 0x80000000) ? -in : in; 
6
                sum += tmpsum;                                  
7
                if (weightChunk & 0x40000000) sum += tmpsum<<1; 
8
                weightChunk <<= 2;
9
            }
10
        }

von Vanye R. (vanye_rijan)


Lesenswert?

Interessant, haette nicht gedacht das sowas auf so einer winzigen
Plattform mit doch sehr beschraenkten Verhaeltnissen moeglich ist!

Jetzt ist das natuerlich eine boese Frage, auch mir ist klar das
man vieles einfach nur aus intellektuellem Spieltrieb macht!
Aber wo genau siehst du eine Anwendung dafuer? .-)

Oder anders gefragt warum genau sollte ich das auf meinem CH32V003
installieren?

Vanye

von Christoph M. (mchris)


Lesenswert?

Jetzt musst du nur noch eine Kamera an die MCU bringen ..

von Tim  . (cpldcpu)


Lesenswert?

Vanye R. schrieb:
> Interessant, haette nicht gedacht das sowas auf so einer winzigen
> Plattform mit doch sehr beschraenkten Verhaeltnissen moeglich ist!
>
> Jetzt ist das natuerlich eine boese Frage, auch mir ist klar das
> man vieles einfach nur aus intellektuellem Spieltrieb macht!
> Aber wo genau siehst du eine Anwendung dafuer? .-)

Für mich ging es eher darum, eine überschaubare Herausforderung zu 
haben, um die Optimierung von quantisierten NN besser zu verstehen :)

Mit QaT bekommt man wesentlich bessere Ergebnisse, als mit den üblichen 
post-quantizations flows, wie sie auch TensorFlow Lite propagiert.

Für einfache Klassifierzungs-Anwendungen sollte sich auch schon ein sehr 
kleines Device eignen.

Hier sind z.B. ein paar aufgelistet: 
https://www.unite.ai/tinyml-applications-limitations-and-its-use-in-iot-edge-devices/

von Tim  . (cpldcpu)


Lesenswert?

Christoph M. schrieb:
> Jetzt musst du nur noch eine Kamera an die MCU bringen ..

Ja, darüber habe ich schon schon nachgedacht. Maussensor oder 
Phototransistor-Matrix waren bisher mögliche optionen :)

von Vanye R. (vanye_rijan)


Lesenswert?

> Für mich ging es eher darum, eine überschaubare Herausforderung zu
> haben, um die Optimierung von quantisierten NN besser zu verstehen :)

Ja, so in der Richtung hatte ich schon vermutet. :-D

Aber die Sache ist halt das der Controller fuer viele der klassischen 
Anwendungen die einen da so einfallen eher eine Nummer zu klein ist
weil die Datenmengen vermutlich schon zu gross. Trotzdem finde ich
das interessant weil es zeigt das man mit den Controllern die etwa
eine Nummer groesser sind da schon ordentlich was machen kann.

BTW: Ich habe gestern Abend durch Zufall einen sehr interessanten Bug in 
der Software gefunden der auch dich betreffen duerfte.

Schau mal: (aus deinem Code)
1
void SystemInit48HSI( void )
2
{
3
  RCC->CTLR  = RCC_HSION | RCC_PLLON;       
4
5
[...]

Du hast das hier in deinem Source auch drin. Damit wird 
unerwuenschterweise die Bitsequence HSICAL im Register CTRL mit 0 
beschrieben obwohl das Datenblatt diesen Teil ausdruecklich als RO 
markiert.

Ich vermute mal das dies ein ganz normales Register ist wo der Bootcode 
im Controller am Anfang einen gemessenen kalibrierungswert fuer den RC 
Oszillator reinschreibt. Bei mir liegt die Frequenz danach 5% daneben.

Meine Loesung sieht so aus:
RCC->CTLR  |= (RCC_HSION | RCC_PLLON);

Damit ist dann der Oszillator sehr genau. koennte von Bedeutung sein 
wenn man den uart verwendet....

Vanye

von Tim  . (cpldcpu)


Lesenswert?

Vanye R. schrieb:

> Schau mal: (aus deinem Code)
>
>
1
> void SystemInit48HSI( void )
2
> {
3
>   RCC->CTLR  = RCC_HSION | RCC_PLLON;
4
> 
5
> [...]
6
> 
7
>
>
> Du hast das hier in deinem Source auch drin. Damit wird
> unerwuenschterweise die Bitsequence HSICAL im Register CTRL mit 0
> beschrieben obwohl das Datenblatt diesen Teil ausdruecklich als RO
> markiert.
>
> Ich vermute mal das dies ein ganz normales Register ist wo der Bootcode
> im Controller am Anfang einen gemessenen kalibrierungswert fuer den RC
> Oszillator reinschreibt. Bei mir liegt die Frequenz danach 5% daneben.
>
> Meine Loesung sieht so aus:
> RCC->CTLR  |= (RCC_HSION | RCC_PLLON);

Interessant. Den Teil habe ich unverändert von ch32v003fun übernommen 
(das repository wird als submodule eingebunden). Bisher habe ich statt 
der UART das Debugging über das one-wire interface genutzt.

Hast Du einen pull-request im ch32v003 fun project gemacht?

von Vanye R. (vanye_rijan)


Lesenswert?

> Hast Du einen pull-request im ch32v003 fun project gemacht?

Ne bestimmt nicht. Ich benutze naemlich eine weitestgehend selbst 
zusammengestellte Umgebung wo ich aber Teile davon kopiert habe. Wuerde 
ich committen wuerde er mich wohl toeten.
Ich hab es ihm aber erzaehlt, aber er meinte wohl das sei nicht relevant 
weil das ja WCH Source sei den er auf dem Dachboden hat. Finde ich aber 
etwas eigenartig, man hat doch keinen source in seinem Projekt den man 
nicht benutzt.

Vanye

von Tim  . (cpldcpu)


Lesenswert?

Vanye R. schrieb:
>> Hast Du einen pull-request im ch32v003 fun project gemacht?
>
> Ne bestimmt nicht. Ich benutze naemlich eine weitestgehend selbst
> zusammengestellte Umgebung wo ich aber Teile davon kopiert habe. Wuerde
> ich committen wuerde er mich wohl toeten.
> Ich hab es ihm aber erzaehlt, aber er meinte wohl das sei nicht relevant
> weil das ja WCH Source sei den er auf dem Dachboden hat. Finde ich aber
> etwas eigenartig, man hat doch keinen source in seinem Projekt den man
> nicht benutzt.

Ja, habe ich auch gesehen. Wäre besser das ch32v003fun Repository zu 
restrukturieren. Ich frage mal.

von Harald K. (kirnbichler)


Lesenswert?

Vanye R. schrieb:
> Ich hab es ihm aber erzaehlt, aber er meinte wohl das sei nicht relevant
> weil das ja WCH Source sei den er auf dem Dachboden hat. Finde ich aber
> etwas eigenartig, man hat doch keinen source in seinem Projekt den man
> nicht benutzt.

Kann das ein Sprachverständnisproblem sein?

von Tim  . (cpldcpu)


Lesenswert?

Harald K. schrieb:
> Vanye R. schrieb:
>> Ich hab es ihm aber erzaehlt, aber er meinte wohl das sei nicht relevant
>> weil das ja WCH Source sei den er auf dem Dachboden hat. Finde ich aber
>> etwas eigenartig, man hat doch keinen source in seinem Projekt den man
>> nicht benutzt.
>
> Kann das ein Sprachverständnisproblem sein?

Das war einfach ein Verzechnis mit Codeschnipseln aus anderen Quellen 
zur Referenz. Er hat es jetzt entfernt und in einem anderen Repository 
untergebracht.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.