HTML

Programozó Páternoszter

Ez a Programozó Páternoszter (PP) blogja, a programozásról szól. Aktualitása, hogy a Debreceni Egyetem Informatikai Kara Magasszintű programozási nyelvek 1-2, C++ esattanulmányok, Java esettanulmányok című kurzusainak blogja is egyben.

A vadászat

A Debreceni Egyetem Programozói Évkönyve: az UDPROG projekt. A szakmai fórumunk a Facebook-en. Az új előadások a prezin.
A régi előadások:
Prog1:
1. C bevezetés
2. C tárgyalás
3. C befejezés
4. C a gyakorlatban
5. C++ bevezetés
6. C++ tárgyalás
7. C++ befejezés
8. C++ a gyakorlatban
9. Java platform bevezetés
10. Kvantuminformatikai alg. bev.
Prog2:
1. Java bevezetés
2. Java tárgyalás
3. Java befejezés
4. Java a gyakorlatban
5. Software Engineering bev.
6. Java EE bevezetés
7. AspectJ bevezetés
8. BPMN-BPEL SOA programozás
9. C++ haladó
10. Tensorflow

Kövess engem!

Friss topikok

Linkblog

Helló, Samu! a TensorFlow-ból

2016.11.13. 23:07 nb

Az Entrópia Samu projekt célja a mesterséges intelligencia megteremtése... ennyi, nem kell cifrázni :)

Hogyan? Egy új, kifejlesztendő e-sport eredményeképpen... ez lesz az ESAMU, részletek az Entrópia Samu Programozói Kézikönyvben, ami tk. ennek az e-sportnak az előzetes sw követelményeit specifikálja. Az első implementációs gyors protó az Arccsata. Az ESAMU e-sport(ok)nak a játszható felülete a "Gréta, az építő" program, amelynek jelen pillanatban egy And-os implementációja készül. Ennek feladata, hogy a Face Battle ESAMU implementáció TensorFlow (TF, Google DeepMind) alapú arcfelismerő megoldására olyan TF gráfszerkesztőként funkcionáljon, amely a felhasználók felé játékként tud megjelenni.

Ebben a posztban a TF-hez adunk egy kis bevezetést. Nyilván első lépés a TF sikeres telepítése... illetve lásd a kapcsolódó előadást: https://prezi.com/0u8ncvvoabcr/no-programming-programming/

TensorFlow Hello World 1!

Ha megvagy a telepítéssel, találkozzunk a TF repóban, itt: 

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo

ahol a twicetwo könyvtárat már Te hozod létre és kezdjük ennek a kis Python proginak a futtatását. Miért Python? Mert a TF C++ interfésze fejletlen, a számítási gráfokat Python kóddal építjük, majd egy protobuf szerializált gráfot töltönk az arcfelismerő Arccsata C++ Boost-os szerverbe (a "Samu, az agyba"-ba) de még nem ma! Most pár "Helló, Világ!" jellegű példával kezdjük az ismerkedést.

Jöjjön az első Python kód, ezt a nyelv szempontjából magyarázni/tanulni nem kell, hiszen éppen ez az a fícsör, amiért a Python létezik :) Akinek ez lesz az első Python kódja annyit kell tudni, hogy az Algol behozta blokkstruktúra itt nem nyitó és záró tagokkal (begin-end vagy kapcsos zárójelek) hanem a behúzással van megszervezve, azaz az ugyanoda tabulált egymás alatti sorok alkotják a blokkot. Akinek pedig mégis igénye egy kis Python nyelvi bevezetőre, annak a Forstner Bertalan, Ekler Péter, Kelényi Imre: Bevezetés a mobilprogramozásba. Gyors prototípus-fejlesztés Python és Java nyelven c. könyvet ajánlom, amelyben van olyan 10 oldal általános bevezető, ha ezt elolvassa, akkor sok időt megspórolva máris többet tud a Pythonból mint kéne.

twicetwo.py

#
# TensorFlow Hello World 1!
# twicetwo.py
#
import tensorflow

node1 = tensorflow.constant(2)
node2 = tensorflow.constant(2)

node_twicetwo = tensorflow.mul(node1, node2, name="twicetwo")

sess = tensorflow.Session()
print sess.run(node_twicetwo)

writer = tensorflow.train.SummaryWriter("/tmp/twicetwo", sess.graph)
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/tensorboard$ python tensorboard.py --logdir=/tmp/twicetwo

tensorflow.train.write_graph(sess.graph_def, "models/", "twicetwo.pb", as_text=False)
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo$ bazel build :twicetwo
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/twicetwo/models .


Nem túl látványos igaz? Kiszámoljuk, hogy 2*2 az 4:


nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo$ python twicetwo.py
4

és valóban kijött. Lássuk a ezt a számítást elvégző számítási gráfot a Tensorboard-ban:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/tensorboard$ python tensorboard.py --logdir=/tmp/twicetwo

itt megsasolhatjuk, hogy fest a Tensorboard-ba betöltött számítási gráf, amelyet az iménti a Python forráskód felépített:twicetwo.pngVessük össze a Python kóddal: van két konstans csomópontunk, amelyek a twicetwo nevű műveleti csomópont bemeneteire vannak kötve, ami összeszorozza őket. A Python kód a twicetwo.pb protobuf forrásba menti a számítási gráfot, amelyet most a twicetwo.cpp C++ kóddal betöltünk, majd futtatunk:

twicetwo.cpp 

//
// TensorFlow Hello World 1!
// twicetwo.cpp
//
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/tensorboard$ python tensorboard.py --logdir=/tmp/twicetwo
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo$ bazel build :twicetwo
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/twicetwo/models .
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ ./twicetwo4
//
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/public/session.h"

int main(int argc, char **argv)
{
    tensorflow::Session *session;
    tensorflow::Status status = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
    if (!status.ok()) {
        std::cout << "NewSession: " << status.ToString() << std::endl;
        return -1;
    }

    tensorflow::GraphDef graphDef;
    status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), "models/twicetwo.pb", &graphDef);
    if (!status.ok()) {
        std::cout << "ReadBinaryProto: " << status.ToString() << std::endl;
        return -2;
    }
    
    // nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/twicetwo/models .

    status = session->Create(graphDef);
    if (!status.ok()) {
        std::cout << "Create: " << status.ToString() << std::endl;
        return -3;
    }

    std::vector<tensorflow::Tensor> out;

    status = session->Run( {}, {"twicetwo"}, {}, &out);

    if (!status.ok()) {
        std::cout << "Run: " << status.ToString() << std::endl;
        return -4;
    }

    std::cout << out[0].scalar<int>() << std::endl;
    
    // nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ ./twicetwo4
    
    session->Close();
    return 0;
}

Készítsük el a Bazel BUILD fájl:

cc_binary(
    name = "twicetwo",
    srcs = ["twicetwo.cpp"],
    deps = [
        "//tensorflow/core:tensorflow",
    ]
)

majd a Bazellel készítessük el a futtathatót:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo$ bazel build :twicetwo

a Python kód kiírta protobuf gráfot másoljuk oda, ahol a futtatható megtalálja:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/linreg/models .

majd futtathatjuk a progit:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo$ ./twicetwo
4

Feladat

Módosítsuk úgy a példát, hogy a C++ programból jöjjön az egyik tagja a szorzásnak!

twicetwo2.py

#
# TensorFlow Hello World 1!
# Exercise 1
# twicetwo2.py
#
import tensorflow

node1 = tensorflow.Variable(3, name="node1")
node2 = tensorflow.constant(2)

node_twicetwo = tensorflow.mul(node1, node2, name="twicetwo")

sess = tensorflow.Session()
sess.run(tensorflow.initialize_all_variables())
print sess.run(node_twicetwo)

writer = tensorflow.train.SummaryWriter("/tmp/twicetwo2", sess.graph)

tensorflow.train.write_graph(sess.graph_def, "models/", "twicetwo2.pb", as_text=False)

okés:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/twicetwo2$ python twicetwo2.py
6

twicetwo2.png

twicetwo2.cpp

Csak a módosítást mutatva

    tensorflow::Tensor node1(tensorflow::DT_INT32, tensorflow::TensorShape());
    node1.scalar<int>()() = 40;

    std::vector<std::pair<std::string, tensorflow::Tensor>> inputs = {
        { "node1", node1 }
    };

    std::vector<tensorflow::Tensor> out;

    status = session->Run(inputs, {"twicetwo"}, {}, &out);

    if (!status.ok()) {
        std::cout << "Run: " << status.ToString() << std::endl;
        return -4;
    }

    std::cout << out[0].scalar<int>() << std::endl;

fordítsuk, futtassuk és vegyük észre, hogy a bemenet valóban a C++ forrásból jött és a visszavett kimenet ezzel az átvett bemenettel készült:

nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/twicetwo2$ ./twicetwo2
80

TensorFlow Hello World 2!

A következő példában a TF bevezető kis példáját módosítjuk: ugyanúgy regressziós egyenest illesztünk a pontokra, de az egyenes meredekségét és eltolását a számítási gráfból kiszedjük a C++ interfészen keresztül.

#
# TensorFlow Hello World 2!
# linreg.py
#
# This code is based on the introductory tutorial example of TensorFlow 
# that can be found at https://www.tensorflow.org/versions/master/get_started/index.html
#
import tensorflow
import numpy

b = tensorflow.Variable(numpy.random.randn())
W = tensorflow.Variable(.0)

init = tensorflow.initialize_all_variables()
sess = tensorflow.Session()
sess.run(init)

x_data = numpy.random.uniform(-1, 1, 1000)
e_data = numpy.random.normal(0, .1, 1000)
y_data = x_data * .1 + .3 + e_data

y = W * x_data + b

loss = tensorflow.reduce_mean(tensorflow.square(y - y_data))
optimizer = tensorflow.train.GradientDescentOptimizer(.5)
train = optimizer.minimize(loss)

prev = .0
while True:
  sess.run(train)
  print(sess.run(W), sess.run(b))    
  if abs(prev - sess.run(W)) < 0.0001:
    break
  prev = sess.run(W)

tensorflow.assign(W, tensorflow.constant(W.eval(sess)), name="W")
tensorflow.assign(b, tensorflow.constant(b.eval(sess)), name="b")

writer = tensorflow.train.SummaryWriter("/tmp/linreg", sess.graph)
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/tensorboard$ python tensorboard.py --logdir=/tmp/linreg

tensorflow.train.write_graph(sess.graph_def, "models/", "linreg.pb", as_text=False)
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/linreg$ bazel build :linreg
# nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/linreg$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/linreg/models .

  nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/linreg$ python linreg.py
(0.023740066, 0.29856035)
(0.048713982, 0.2989215)
(0.065493196, 0.29930139)
(0.076768726, 0.29955661)
(0.084345818, 0.29972813)
(0.089437582, 0.2998434)
(0.092859216, 0.29992086)
(0.095158532, 0.29997289)
(0.096703663, 0.30000788)
(0.097741976, 0.30003136)
(0.098439716, 0.30004716)
(0.098908596, 0.3000578)
(0.099223681, 0.30006492)
(0.099435419, 0.30006972)
(0.099577703, 0.30007294)
(0.099673316, 0.30007508)

A számítási gráf:

linreg.png

//
// TensorFlow Hello World 2!
// linreg.cpp
//
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/linreg$ python linreg.py 
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/tensorboard$ python tensorboard.py --logdir=/tmp/linreg
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/linreg$ bazel build :linreg
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/linreg$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/linreg/models .
// nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/linreg$ ./linreg
//
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/public/session.h"

int main(int argc, char **argv)
{
    tensorflow::Session *session;
    tensorflow::Status status = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
    if (!status.ok()) {
        std::cout << "NewSession: " << status.ToString() << std::endl;
        return -1;
    }

    tensorflow::GraphDef graphDef;
    status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), "models/linreg.pb", &graphDef);
    if (!status.ok()) {
        std::cout << "ReadBinaryProto: " << status.ToString() << std::endl;
        return -2;
    }
    
    // nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/linreg$ cp -r ~/Robopsychology/repos/tensorflow/tensorflow/linreg/models .

    status = session->Create(graphDef);
    if (!status.ok()) {
        std::cout << "Create: " << status.ToString() << std::endl;
        return -3;
    }

    std::vector<tensorflow::Tensor> out;

    status = session->Run( {}, {"W", "b"}, {}, &out);

    if (!status.ok()) {
        std::cout << "Run: " << status.ToString() << std::endl;
        return -4;
    }

    std::cout << out[0].scalar<float>() << std::endl;
    std::cout << out[1].scalar<float>() << std::endl;
    
    // nbatfai@robopsy:~/Robopsychology/repos/tensorflow/bazel-bin/tensorflow/linreg$ ./linreg
    
    session->Close();
    return 0;
}

 

TensorFlow Hello World 3!

Ebben a példában ugyancsak a tutoriál MNIST példáját próbáljuk ki a C++ interfészen keresztül. Első lépésben a Python kódot az előadásban átvesszük, majd úgy módosítjuk, hogy a tanítás után a MNIST adott képét ismertetjük fel, pl. ezt a MNIST jegyet:

screenshot_20161118_143308.png

amire írja azt ki a módosított Python kód, hogy pl.:


Ez a  42 . indexu tesztkep, ami egy : 4
Ezt a halozat ennek ismeri fel:  4

Majd kézzel rajzolunk egy saját 28x28-as jegyet, mondjuk ezt a 8-ast (a GIMP-el rajzoltam éppen, de fotózhattuk volna is persze)

gimpjegy.jpg

és ezt is ismerjük fel a MNIST jegyekkel trenírozott hálózattal. C++ tekintetében ugyanezt végigcsináljuk. A számítási gráf C++ progiból inicializálása és a felismerés pontosságának visszaadása még itt történik, a custom kép (a 8 :) felismerése már majd ESAMU esattanként az ESMU cs repóban. 

mnist_softmax_UDPROG61.py

# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

# Norbert Batfai, 27 Nov 2016
# Some modifications and additions to the original code:
# https://github.com/tensorflow/tensorflow/blob/r0.11/tensorflow/examples/tutorials/mnist/mnist_softmax.py
# See also http://progpater.blog.hu/2016/11/13/hello_samu_a_tensorflow-bol
# ==============================================================================

"""A very simple MNIST classifier.

See extensive documentation at
http://tensorflow.org/tutorials/mnist/beginners/index.md
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse

# Import data
from tensorflow.examples.tutorials.mnist import input_data

import tensorflow as tf

import matplotlib.pyplot


FLAGS = None


def readimg():
    file = tf.read_file("sajat8a.png")
    img = tf.image.decode_png(file)
    return img

def main(_):
  mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

  # Create the model
  x = tf.placeholder(tf.float32, [None, 784])
  W = tf.Variable(tf.zeros([784, 10]))
  b = tf.Variable(tf.zeros([10]))
  y = tf.matmul(x, W) + b

  # Define loss and optimizer
  y_ = tf.placeholder(tf.float32, [None, 10])

  # The raw formulation of cross-entropy,
  #
  #   tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(tf.nn.softmax(y)),
  #                                 reduction_indices=[1]))
  #
  # can be numerically unstable.
  #
  # So here we use tf.nn.softmax_cross_entropy_with_logits on the raw
  # outputs of 'y', and then average across the batch.
  cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
  train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

  sess = tf.InteractiveSession()
  # Train
  tf.initialize_all_variables().run()
  print("-- A halozat tanitasa")  
  for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
    if i % 100 == 0:
      print(i/10, "%")
  print("----------------------------------------------------------")

  # Test trained model
  print("-- A halozat tesztelese")  
  correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  
  print("-- Pontossag: ", sess.run(accuracy, feed_dict={x: mnist.test.images,
                                      y_: mnist.test.labels}))
  print("----------------------------------------------------------")
  
  print("-- A MNIST 42. tesztkepenek felismerese, mutatom a szamot, a tovabblepeshez csukd be az ablakat")
  
  img = mnist.test.images[42]
  image = img

  matplotlib.pyplot.imshow(image.reshape(28, 28), cmap=matplotlib.pyplot.cm.binary)
  matplotlib.pyplot.savefig("4.png")  
  matplotlib.pyplot.show()

  classification = sess.run(tf.argmax(y, 1), feed_dict={x: [image]})

  print("-- Ezt a halozat ennek ismeri fel: ", classification[0])
  print("----------------------------------------------------------")

  print("-- A sajat kezi 8-asom felismerese, mutatom a szamot, a tovabblepeshez csukd be az ablakat")

  img = readimg()
  image = img.eval()
  image = image.reshape(28*28)

  matplotlib.pyplot.imshow(image.reshape(28, 28), cmap=matplotlib.pyplot.cm.binary)
  matplotlib.pyplot.savefig("8.png")  
  matplotlib.pyplot.show()

  classification = sess.run(tf.argmax(y, 1), feed_dict={x: [image]})

  print("-- Ezt a halozat ennek ismeri fel: ", classification[0])
  print("----------------------------------------------------------")

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data',
                      help='Directory for storing input data')
  FLAGS = parser.parse_args()
  tf.app.run()

Futtassuk:
nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/examples/tutorials/mnist$ python mnist_softmax_UDPROG61.py
Extracting /tmp/tensorflow/mnist/input_data/train-images-idx3-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/train-labels-idx1-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/t10k-images-idx3-ubyte.gz
Extracting /tmp/tensorflow/mnist/input_data/t10k-labels-idx1-ubyte.gz
-- A halozat tanitasa
0.0 %
10.0 %
20.0 %
30.0 %
40.0 %
50.0 %
60.0 %
70.0 %
80.0 %
90.0 %
----------------------------------------------------------
-- A halozat tesztelese
-- Pontossag:  0.9175
----------------------------------------------------------
-- A MNIST 42. tesztkepenek felismerese, mutatom a szamot, a tovabblepeshez csukd be az ablakat

mnist42.png

-- Ezt a halozat ennek ismeri fel:  4
----------------------------------------------------------
-- A sajat kezi 8-asom felismerese, mutatom a szamot, a tovabblepeshez csukd be az ablakat

sajat8.png

-- Ezt a halozat ennek ismeri fel:  8
----------------------------------------------------------
nbatfai@robopsy:~/Robopsychology/repos/tensorflow/tensorflow/examples/tutorials/mnist$
Most nézzük meg a TensorBoard segítségével, hogy alakult a tanítás során a hálózat pontossága:
screenshot_20161128_202630.pngMit szóltok olyan kis bajnoksághoz, hogy minden tizedes javítás a pontosságon lenne x-sok pont!?

Hivatkozások

Szólj hozzá!

A bejegyzés trackback címe:

https://progpater.blog.hu/api/trackback/id/tr3611958293

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása