unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Jan Wedekind <jan@wedesoft.de>
To: guile-user@gnu.org
Subject: Re: Tensorflow bindings
Date: Sat, 15 Dec 2018 13:58:46 +0000 (GMT)	[thread overview]
Message-ID: <alpine.DEB.2.20.1812151358050.19603@wedemob.home> (raw)
In-Reply-To: <alpine.DEB.2.20.1812132243270.23803@wedemob.home>

I updated the MNIST example some more and added a bit of documentation:

     (use-modules (oop goops)
                  (ice-9 binary-ports)
                  (ice-9 format)
                  (srfi srfi-1)
                  (rnrs bytevectors)
                  (system foreign)
                  (aiscm core)
                  (aiscm xorg)
                  (aiscm util)
                  (aiscm tensorflow))

     (define (read-images file-name)
       (let* [(f     (open-file file-name "rb"))
              (magic (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))
              (n     (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))
              (h     (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))
              (w     (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))]
         (if (not (eqv? magic 2051)) (error "Images file has wrong magic number"))
         (let [(bv (get-bytevector-n f (* n h w)))]
           (make (multiarray <ubyte> 3) #:memory (bytevector->pointer bv) #:shape (list n h w)))))

     (define (read-labels file-name)
       (let* [(f     (open-file file-name "rb"))
              (magic (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))
              (n     (bytevector-u32-ref (get-bytevector-n f 4) 0 (endianness big)))]
         (if (not (eqv? magic 2049)) (error "Label file has wrong magic number"))
         (let [(bv (get-bytevector-n f n))]
           (make (multiarray <ubyte> 1) #:memory (bytevector->pointer bv) #:shape (list n)))))

     ; Load MNIST data set available at http://yann.lecun.com/exdb/mnist/
     (define images (read-images "train-images-idx3-ubyte"))
     (define labels (read-labels "train-labels-idx1-ubyte"))
     (define n (car (shape images)))

     ; Create Tensorflow session
     (define s (make-session))

     ; Define placeholders for features (images) and labels
     (define x (tf-placeholder #:dtype <ubyte> #:shape '(-1 28 28)))
     (define y (tf-placeholder #:dtype <ubyte> #:shape '(-1)))

     ; Determine parameters for feature scaling
     (define (sqr x) (* x x))
     (define count (apply * (shape images)))
     (define average (exact->inexact (/ (sum images) count)))
     (define stddev (sqrt (/ (sum (sqr (- images average))) count)))

     ; Scale features and reshape to 4D array
     (define (flt x) (tf-cast x #:DstT <float>))
     (define r1 (tf-reshape (tf-mul (flt (/ 1 stddev)) (tf-sub (flt x) (flt average))) (arr <int> -1 28 28 1)))

     ; First convolutional layer with max-pooling and ReLU activation function.
     (define k1 (tf-variable #:dtype <float> #:shape '(3 3 1 4)))
     (define c1 (tf-conv2d r1 k1 #:strides '(1 1 1 1) #:padding 'VALID))
     (define p1 (tf-relu (tf-max-pool c1 #:strides '(1 2 2 1) #:ksize '(1 2 2 1) #:padding 'VALID)))

     ; Second convolutional layer with max-pooling and ReLU activation function.
     (define k2 (tf-variable #:dtype <float> #:shape '(3 3 4 16)))
     (define c2 (tf-conv2d p1 k2 #:strides '(1 1 1 1) #:padding 'VALID))
     (define p2 (tf-relu (tf-max-pool c2 #:strides '(1 2 2 1) #:ksize '(1 2 2 1) #:padding 'VALID)))

     ; Reshape to 2D array
     (define d (* 5 5 16))
     (define r2 (tf-reshape p2 (to-array <int> (list -1 d))))

     ; First fully connected layer with bias units and ReLU activation function.
     (define m1 (tf-variable #:dtype <float> #:shape (list d 40)))
     (define b1 (tf-variable #:dtype <float> #:shape '(40)))
     (define l1 (tf-relu (tf-add (tf-mat-mul r2 m1) b1)))

     ; Second fully connected layer with bias units and softmax activation function.
     (define m2 (tf-variable #:dtype <float> #:shape '(40 10)))
     (define b2 (tf-variable #:dtype <float> #:shape '(10)))
     (define l (tf-softmax (tf-add (tf-mat-mul l1 m2) b2)))

     ; Classification result of neural network.
     (define prediction (tf-arg-max l 1 #:name "prediction"))

     ; Random initialization of network parameters
     (define initializers
       (list (tf-assign k1 (tf-mul (flt (/ 1 9)) (tf-random-uniform (arr <int> 3 3 1 4) #:dtype <float>)))
             (tf-assign k2 (tf-mul (flt (/ 1 9)) (tf-random-uniform (arr <int> 3 3 4 16) #:dtype <float>)))
             (tf-assign m1 (tf-mul (flt (/ 1 n)) (tf-random-uniform (to-array <int> (list d 40)) #:dtype <float>)))
             (tf-assign b1 (fill <float> '(40) 0.0))
             (tf-assign m2 (tf-mul (flt (/ 1 40)) (tf-random-uniform (arr <int> 40 10) #:dtype <float>)))
             (tf-assign b2 (fill <float> '(10) 0.0))))
     (run s '() initializers)

     ; List of all network parameters
     (define vars (list k1 k2 m1 b1 m2 b2))

     ; Logistic loss function
     (define yh (tf-one-hot y 10 (flt 1.0) (flt 0.0)))
     (define (safe-log x) (tf-log (tf-maximum x (flt 1e-10))))
     (define (invert x) (tf-sub (flt 1.0) x))
     (define loss (tf-neg (tf-mean (tf-add (tf-mul yh (safe-log l)) (tf-mul (invert yh) (safe-log (invert l)))) (arr <int> 0 1))))

     ; Regularization term
     (define regularization (tf-add (tf-mean (tf-square (tf-abs m1)) (arr <int> 0 1)) (tf-mean (tf-square (tf-abs m2)) (arr <int> 0 1))))

     ; Overall cost
     (define la 0.02)
     (define cost (tf-add loss (tf-mul (flt la) regularization)))

     ; Implement gradient descent step
     (define gradients (tf-add-gradient cost vars))
     (define alpha 0.4)
     (define step (map (lambda (v g) (tf-assign v (tf-sub v (tf-mul g (flt alpha))))) vars gradients))

     ; Perform gradient descent
     (define j 0.0)
     (for-each
       (lambda (epoch)
         (for-each
           (lambda (i)
             (let* [(range (cons i (+ i 50)))
                    (batch (list (cons x (unroll (get images range))) (cons y (get labels range))))
                    (js    (run s batch cost))]
               (set! j (+ (* 0.99 j) (* 0.01 js)))
               (format #t "\r~2d, ~5d/~5d: ~6,4f" epoch i n j)
               (run s batch step)))
           (iota (/ n 50) 0 50)))
       (iota 3))
     (format #t "~&")

     ; Load MNIST test data.
     (define test-images (read-images "t10k-images-idx3-ubyte"))
     (define test-labels (read-labels "t10k-labels-idx1-ubyte"))
     (define n-test (car (shape test-images)))

     ; Display cost function result for (part of) training and test data
     (define j (run s (list (cons x (unroll (get images '(0 . 10000)))) (cons y (get labels '(0 . 10000)))) loss))
     (define jt (run s (list (cons x test-images) (cons y test-labels)) loss))
     (format #t "train: ~6,4f; test: ~6,4f~&" j jt)

     ; Determine error rate
     (define predicted (run s (list (cons x test-images)) prediction))
     (define n-correct (sum (where (eq predicted test-labels) 1 0)))
     (format #t "error rate: ~6,4f~&" (- 1.0 (/ n-correct n-test)))

     ; Display individual results
     (define time (clock))
     (define i -1)
     (show
       (lambda (dsp)
         (set! i (1+ i))
         (let* [(image (get test-images (modulo i 10000)))
                (pred (get (run s (list (cons x image)) prediction) 0))]
           (synchronise image (- i (elapsed time)) (event-loop dsp))
           (format #t "~a~&" pred)
           image))
       #:width 280)



  reply	other threads:[~2018-12-15 13:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-10 21:27 Tensorflow bindings Jan Wedekind
2018-12-10 22:16 ` Aleix Conchillo Flaqué
2018-12-11 10:17   ` Jérémy Korwin-Zmijowski
2018-12-13 22:46 ` Jan Wedekind
2018-12-15 13:58   ` Jan Wedekind [this message]
2018-12-15 16:31 ` Amirouche Boubekki
2018-12-15 22:55 ` David Pirotte
2018-12-26 12:15   ` Jan Wedekind

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.20.1812151358050.19603@wedemob.home \
    --to=jan@wedesoft.de \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).