Neuronales Netzwerke auf dem CH32V003

#7654076
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
        }
#7654281
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

#7654313
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/

#7654331
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

#7654366
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?

#7654542
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

#7654567
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.

#7655085
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren