<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sv">
	<id>http://wiki.sikvall.se/index.php?action=history&amp;feed=atom&amp;title=Racket%2FNeural</id>
	<title>Racket/Neural - Versionshistorik</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.sikvall.se/index.php?action=history&amp;feed=atom&amp;title=Racket%2FNeural"/>
	<link rel="alternate" type="text/html" href="http://wiki.sikvall.se/index.php?title=Racket/Neural&amp;action=history"/>
	<updated>2026-04-06T19:07:00Z</updated>
	<subtitle>Versionshistorik för denna sida på wikin</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>http://wiki.sikvall.se/index.php?title=Racket/Neural&amp;diff=1832&amp;oldid=prev</id>
		<title>Anders: Skapade sidan med &#039;&lt;pre&gt; #lang racket  ;;;;; ;; Neuralt nät implementerad i Racket ;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se ;;;;;    ;;;;; NEURALT NÄT ;;; ;; Detta program implementerar ett litet neuralt nät och tränar det på sannings- ;; tabellen för XOR. Efter några tusen epoker ska prediktionerna ligga extremt nära ;; följande: ;; ;; a,b → a XOR b ;; 0,0 →    0 ;; 0,1 →    1 ;; 1,0 →    1 ;; 1,1 →    0 ;; ;; Implementationen har två input-neuroner för a...&#039;</title>
		<link rel="alternate" type="text/html" href="http://wiki.sikvall.se/index.php?title=Racket/Neural&amp;diff=1832&amp;oldid=prev"/>
		<updated>2026-04-05T13:01:16Z</updated>

		<summary type="html">&lt;p&gt;Skapade sidan med &amp;#039;&amp;lt;pre&amp;gt; #lang racket  ;;;;; ;; Neuralt nät implementerad i Racket ;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se ;;;;;    ;;;;; NEURALT NÄT ;;; ;; Detta program implementerar ett litet neuralt nät och tränar det på sannings- ;; tabellen för XOR. Efter några tusen epoker ska prediktionerna ligga extremt nära ;; följande: ;; ;; a,b → a XOR b ;; 0,0 →    0 ;; 0,1 →    1 ;; 1,0 →    1 ;; 1,1 →    0 ;; ;; Implementationen har två input-neuroner för a...&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ny sida&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#lang racket&lt;br /&gt;
&lt;br /&gt;
;;;;;&lt;br /&gt;
;; Neuralt nät implementerad i Racket&lt;br /&gt;
;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se&lt;br /&gt;
;;;;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;;;;; NEURALT NÄT&lt;br /&gt;
;;;&lt;br /&gt;
;; Detta program implementerar ett litet neuralt nät och tränar det på sannings-&lt;br /&gt;
;; tabellen för XOR. Efter några tusen epoker ska prediktionerna ligga extremt nära&lt;br /&gt;
;; följande:&lt;br /&gt;
;;&lt;br /&gt;
;; a,b → a XOR b&lt;br /&gt;
;; 0,0 →    0&lt;br /&gt;
;; 0,1 →    1&lt;br /&gt;
;; 1,0 →    1&lt;br /&gt;
;; 1,1 →    0&lt;br /&gt;
;;&lt;br /&gt;
;; Implementationen har två input-neuroner för a och b&lt;br /&gt;
;; det finns 5 interna (dolda neuroner) som tränas av indatat&lt;br /&gt;
;; det finns 1 output-neuron som ger svaret&lt;br /&gt;
;;&lt;br /&gt;
;;;;; Kodens uppbyggnad och de olika funktionernas användning&lt;br /&gt;
;;&lt;br /&gt;
;; sigmoid, sigmoid-deriv      Sigmoid-kurva och derivata för backpropagation&lt;br /&gt;
;;&lt;br /&gt;
;; random-matrix, met-vec-mul  Grundläggande linalg&lt;br /&gt;
;; outer-product; vec-add&lt;br /&gt;
;;&lt;br /&gt;
;; struct nn                   Nätverksstruktur, lagrar vikter och bias&lt;br /&gt;
;;&lt;br /&gt;
;; forward                     Beräknar prediktion&lt;br /&gt;
;;&lt;br /&gt;
;; train-step                  En iteration av backpropagation&lt;br /&gt;
;;&lt;br /&gt;
;; train                       Kör många epoker av in och förväntat utdata för&lt;br /&gt;
;;                             att träna modellen&lt;br /&gt;
;;&lt;br /&gt;
;; predict                     Använder nätverket på ny data!&lt;br /&gt;
;;&lt;br /&gt;
;;&lt;br /&gt;
;;;;; Viktiga delar&lt;br /&gt;
;;&lt;br /&gt;
;; * sigmoid mappar alla värden steglöst till intervallet (0,1)&lt;br /&gt;
;; * derivatan används i backpropagation för att räkna ut gradienten&lt;br /&gt;
;;&lt;br /&gt;
;; w1: vikter mellan input och hidden layer (5x2 matris)&lt;br /&gt;
;; b1: bias för hidden layer (5-vektor)&lt;br /&gt;
;; w2: viktar mellan hidden och output (1x5 matris)&lt;br /&gt;
;; b2: bias för output (1-vektor)&lt;br /&gt;
;;&lt;br /&gt;
;; Forward pass&lt;br /&gt;
;;&lt;br /&gt;
;; 1. Beräkna aktivering i hidden layer&lt;br /&gt;
;;    z1 = W1 * input + b1&lt;br /&gt;
;;    h = rho z1&lt;br /&gt;
;; 2. Beräkna output&lt;br /&gt;
;;    z2 = W2 * h +b2&lt;br /&gt;
;;    output = rho(z2)&lt;br /&gt;
;;&lt;br /&gt;
;; Backpropagation (uppdatering av viktningen)&lt;br /&gt;
;;&lt;br /&gt;
;; Hjärtat i träningen av ett neuralt nät. Algorimen är &amp;quot;gradient descent&amp;quot; med batch-&lt;br /&gt;
;; storlek 1.&lt;br /&gt;
;;&lt;br /&gt;
;; 1. Forward pass hidden → output&lt;br /&gt;
;; 2. Output-felet&lt;br /&gt;
;;    delta = (output - target) X rho&amp;#039; (output)&lt;br /&gt;
;; 3. Hidden-felet&lt;br /&gt;
;;    delta hidden = (W2/T * delta out) X rho&amp;#039; (hidden)&lt;br /&gt;
;; 4. Uppdatera vikternas gradienter&lt;br /&gt;
;;    W2 ← W2 - nabla * delta out * h^T&lt;br /&gt;
;;    W1 ← W1 - nabla * delta hidden * input^T&lt;br /&gt;
;; 5. Bias uppdateras på samma sätt (jo det är en genväg)&lt;br /&gt;
;;&lt;br /&gt;
&lt;br /&gt;
(require math/base)&lt;br /&gt;
&lt;br /&gt;
;; ========================================&lt;br /&gt;
;; Aktiveringsfunktioner&lt;br /&gt;
;; ========================================&lt;br /&gt;
(define (sigmoid x)&lt;br /&gt;
  (/ 1.0 (+ 1.0 (exp (- x)))))&lt;br /&gt;
&lt;br /&gt;
(define (sigmoid-deriv y)   ; y måste redan vara sigmoid(x)&lt;br /&gt;
  (* y (- 1.0 y)))&lt;br /&gt;
&lt;br /&gt;
;; ========================================&lt;br /&gt;
;; Matris-/vektorhjälp (enkel version)&lt;br /&gt;
;; ========================================&lt;br /&gt;
(define (random-matrix rows cols)&lt;br /&gt;
  (build-vector rows&lt;br /&gt;
                (λ (_) (build-vector cols (λ (_) (- (* 2.0 (random)) 1.0))))))&lt;br /&gt;
&lt;br /&gt;
(define (vec-add v1 v2)     ; elementvis addition av två vektorer&lt;br /&gt;
  (build-vector (vector-length v1)&lt;br /&gt;
                (λ (i) (+ (vector-ref v1 i) (vector-ref v2 i)))))&lt;br /&gt;
&lt;br /&gt;
(define (scalar-mul s v)&lt;br /&gt;
  (build-vector (vector-length v) (λ (i) (* s (vector-ref v i)))))&lt;br /&gt;
&lt;br /&gt;
(define (outer-product v1 v2)   ; v1 kolumn × v2 rad → matris&lt;br /&gt;
  (build-vector (vector-length v1)&lt;br /&gt;
                (λ (i)&lt;br /&gt;
                  (build-vector (vector-length v2)&lt;br /&gt;
                                (λ (j) (* (vector-ref v1 i) (vector-ref v2 j)))))))&lt;br /&gt;
&lt;br /&gt;
(define (mat-vec-mul M v)       ; M (rows×cols) × v (cols)&lt;br /&gt;
  (build-vector (vector-length M)&lt;br /&gt;
                (λ (i)&lt;br /&gt;
                  (for/sum ([j (in-range (vector-length v))])&lt;br /&gt;
                    (* (vector-ref (vector-ref M i) j)&lt;br /&gt;
                       (vector-ref v j))))))&lt;br /&gt;
&lt;br /&gt;
(define (transpose M)&lt;br /&gt;
  (build-vector (vector-length (vector-ref M 0))&lt;br /&gt;
                (λ (j)&lt;br /&gt;
                  (build-vector (vector-length M)&lt;br /&gt;
                                (λ (i) (vector-ref (vector-ref M i) j))))))&lt;br /&gt;
&lt;br /&gt;
;; ========================================&lt;br /&gt;
;; Neuralt nätverk&lt;br /&gt;
;; ========================================&lt;br /&gt;
(struct nn (w1 b1 w2 b2) #:transparent)&lt;br /&gt;
&lt;br /&gt;
(define (make-nn in-size hidden-size out-size)&lt;br /&gt;
  (nn (random-matrix hidden-size in-size)&lt;br /&gt;
      (make-vector hidden-size 0.0)&lt;br /&gt;
      (random-matrix out-size hidden-size)&lt;br /&gt;
      (make-vector out-size 0.0)))&lt;br /&gt;
&lt;br /&gt;
(define (forward net input)          ; input är en vektor t.ex. #(0 0)&lt;br /&gt;
  (let* ([z1 (vec-add (mat-vec-mul (nn-w1 net) input)&lt;br /&gt;
                      (nn-b1 net))]&lt;br /&gt;
         [h  (build-vector (vector-length z1) (λ (i) (sigmoid (vector-ref z1 i))))]&lt;br /&gt;
         [z2 (vec-add (mat-vec-mul (nn-w2 net) h)&lt;br /&gt;
                      (nn-b2 net))]&lt;br /&gt;
         [o  (build-vector (vector-length z2) (λ (i) (sigmoid (vector-ref z2 i))))])&lt;br /&gt;
    (values o h)))&lt;br /&gt;
&lt;br /&gt;
(define (train-step net input target lr)&lt;br /&gt;
  (let-values ([(output hidden) (forward net input)])&lt;br /&gt;
    (let* ([out-err (build-vector (vector-length output)&lt;br /&gt;
                                  (λ (i) (- (vector-ref output i)&lt;br /&gt;
                                            (vector-ref target i))))]&lt;br /&gt;
           [out-delta (build-vector (vector-length output)&lt;br /&gt;
                                    (λ (i) (* (vector-ref out-err i)&lt;br /&gt;
                                              (sigmoid-deriv (vector-ref output i)))))]&lt;br /&gt;
&lt;br /&gt;
           [hidden-err (mat-vec-mul (transpose (nn-w2 net)) out-delta)]&lt;br /&gt;
           [hidden-delta (build-vector (vector-length hidden)&lt;br /&gt;
                                       (λ (i) (* (vector-ref hidden-err i)&lt;br /&gt;
                                                 (sigmoid-deriv (vector-ref hidden i)))))]&lt;br /&gt;
&lt;br /&gt;
           ;; Uppdateringar&lt;br /&gt;
           [dw2 (outer-product out-delta hidden)]&lt;br /&gt;
           [new-w2 (build-vector (vector-length (nn-w2 net))&lt;br /&gt;
                                 (λ (i)&lt;br /&gt;
                                   (build-vector (vector-length (vector-ref (nn-w2 net) i))&lt;br /&gt;
                                                 (λ (j) (- (vector-ref (vector-ref (nn-w2 net) i) j)&lt;br /&gt;
                                                           (* lr (vector-ref (vector-ref dw2 i) j)))))))]&lt;br /&gt;
           [new-b2 (build-vector (vector-length (nn-b2 net))&lt;br /&gt;
                                 (λ (i) (- (vector-ref (nn-b2 net) i)&lt;br /&gt;
                                           (* lr (vector-ref out-delta i)))))]&lt;br /&gt;
&lt;br /&gt;
           [dw1 (outer-product hidden-delta input)]&lt;br /&gt;
           [new-w1 (build-vector (vector-length (nn-w1 net))&lt;br /&gt;
                                 (λ (i)&lt;br /&gt;
                                   (build-vector (vector-length (vector-ref (nn-w1 net) i))&lt;br /&gt;
                                                 (λ (j) (- (vector-ref (vector-ref (nn-w1 net) i) j)&lt;br /&gt;
                                                           (* lr (vector-ref (vector-ref dw1 i) j)))))))]&lt;br /&gt;
           [new-b1 (build-vector (vector-length (nn-b1 net))&lt;br /&gt;
                                 (λ (i) (- (vector-ref (nn-b1 net) i)&lt;br /&gt;
                                           (* lr (vector-ref hidden-delta i)))))])&lt;br /&gt;
&lt;br /&gt;
      (nn new-w1 new-b1 new-w2 new-b2))))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;; ========================================&lt;br /&gt;
;; Skriv ut vikter och bias – snygg tabell (fixad version)&lt;br /&gt;
;; ========================================&lt;br /&gt;
(define (print-nn net)&lt;br /&gt;
  (printf &amp;quot;\n=== NEURALT NÄTVERK - VIKTER OCH BIAS ===\n\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  ;; Hjälpfunktion för att formatera tal snyggt (med minustecken på rätt plats)&lt;br /&gt;
  (define (fmt x)&lt;br /&gt;
    (~r x &lt;br /&gt;
        #:min-width 10 &lt;br /&gt;
        #:precision &amp;#039;(= 4)&lt;br /&gt;
        #:sign #f))          ; #f = visa minus för negativa, inget tecken för positiva&lt;br /&gt;
&lt;br /&gt;
  ;; W1: Vikter från input till hidden (5×2)&lt;br /&gt;
  (printf &amp;quot;W1 (Hidden × Input):\n&amp;quot;)&lt;br /&gt;
  (printf &amp;quot;          Input0      Input1\n&amp;quot;)&lt;br /&gt;
  (for ([i (in-range (vector-length (nn-w1 net)))])&lt;br /&gt;
    (printf &amp;quot;Hidden~a  &amp;quot; i)&lt;br /&gt;
    (for ([j (in-range 2)])&lt;br /&gt;
      (printf &amp;quot;~a  &amp;quot; (fmt (vector-ref (vector-ref (nn-w1 net) i) j))))&lt;br /&gt;
    (printf &amp;quot;\n&amp;quot;))&lt;br /&gt;
  (printf &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  ;; b1: Bias för hidden layer&lt;br /&gt;
  (printf &amp;quot;b1 (Bias hidden layer):\n&amp;quot;)&lt;br /&gt;
  (for ([i (in-range (vector-length (nn-b1 net)))])&lt;br /&gt;
    (printf &amp;quot;~a  &amp;quot; (fmt (vector-ref (nn-b1 net) i))))&lt;br /&gt;
  (printf &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  ;; W2: Vikter från hidden till output (1×5)&lt;br /&gt;
  (printf &amp;quot;W2 (Output × Hidden):\n&amp;quot;)&lt;br /&gt;
  (printf &amp;quot;         Hidden0     Hidden1     Hidden2     Hidden3     Hidden4\n&amp;quot;)&lt;br /&gt;
  (printf &amp;quot;Output   &amp;quot;)&lt;br /&gt;
  (for ([j (in-range 5)])&lt;br /&gt;
    (printf &amp;quot;~a  &amp;quot; (fmt (vector-ref (vector-ref (nn-w2 net) 0) j))))&lt;br /&gt;
  (printf &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  ;; b2: Bias för output&lt;br /&gt;
  (printf &amp;quot;b2 (Bias output):\n&amp;quot;)&lt;br /&gt;
  (printf &amp;quot;~a\n&amp;quot; (fmt (vector-ref (nn-b2 net) 0)))&lt;br /&gt;
&lt;br /&gt;
  (printf &amp;quot;\n========================================\n&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;; Träna nätverket&lt;br /&gt;
(define (train net data epochs lr)&lt;br /&gt;
  (for ([ep (in-range epochs)])&lt;br /&gt;
    (for ([sample data])&lt;br /&gt;
      (set! net (train-step net (car sample) (cadr sample) lr)))&lt;br /&gt;
    &lt;br /&gt;
    (when (zero? (modulo ep 500))      ; oftare än var 1000:e&lt;br /&gt;
      (let ([loss (for/sum ([sample data])&lt;br /&gt;
                    (let-values ([(output _) (forward net (car sample))])&lt;br /&gt;
                      (let ([target (vector-ref (cadr sample) 0)]&lt;br /&gt;
                            [pred   (vector-ref output 0)])&lt;br /&gt;
                        (sqr (- target pred)))))])&lt;br /&gt;
        (printf &amp;quot;Epoch ~a  Loss: ~a\n&amp;quot; ep (/ loss (length data))))))&lt;br /&gt;
  (print-nn net)&lt;br /&gt;
  net)&lt;br /&gt;
&lt;br /&gt;
;; Prediktera&lt;br /&gt;
(define (predict net input)&lt;br /&gt;
  (let-values ([(output _) (forward net input)])&lt;br /&gt;
    output))&lt;br /&gt;
&lt;br /&gt;
;; ========================================&lt;br /&gt;
;; XOR-exempel&lt;br /&gt;
;; ========================================&lt;br /&gt;
(define xor-data&lt;br /&gt;
  (list (list #(0 0) #(0))&lt;br /&gt;
        (list #(0 1) #(1))&lt;br /&gt;
        (list #(1 0) #(1))&lt;br /&gt;
        (list #(1 1) #(0))))&lt;br /&gt;
&lt;br /&gt;
(define net (make-nn 2 5 1))   ; 2 input, 5 dolda neuroner, 1 output&lt;br /&gt;
(define rounds 8000) ; 2000 är i minsta laget, 5000 eller hellre 8000 är bättre&lt;br /&gt;
(define backpr 0.7)&lt;br /&gt;
(printf &amp;quot;Tränar XOR-problemet i ~a rundor med backprop styrka ~a\n&amp;quot; rounds backpr)&lt;br /&gt;
(set! net (train net xor-data rounds backpr))&lt;br /&gt;
&lt;br /&gt;
(printf &amp;quot;\n=== Testresultat ===\n&amp;quot;)&lt;br /&gt;
(for ([sample xor-data])&lt;br /&gt;
  (let ([pred (vector-ref (predict net (car sample)) 0)])&lt;br /&gt;
    (printf &amp;quot;Input ~a  →  Förväntat: ~a  Predikterat: ~a\n&amp;quot;&lt;br /&gt;
            (car sample)&lt;br /&gt;
            (vector-ref (cadr sample) 0)&lt;br /&gt;
            (if (&amp;gt; pred 0.5) 1.0 0.0))))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anders</name></author>
	</entry>
</feed>