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 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
A tanítást érdemes otthon végezni, mert órákig tart, amit persze kis paraméterezgetéssel lehet csökkenteni, ezt a fészen megbeszélhetjük. Maga a feladat egy saját kép felismerése. Konkrétan lefényképeztem a gyerekek egy Prius matchboxát és azt szeretnénk, ha ezt a hálózat felismerné mint CIFAR-10 kategáriát és azt mondaná rá, hogy: "automobil".
Oké-zsoké, lássuk mit kell ehhez forrás szinten módosítani a tutoriál példájában.
Először is a két tesztelendő képet olyan bináris állománnyá kell alakítani, amit a tutoriál tud értelmezni. Ehhez a legegyszerűbb egy olyan kis progit írni, ami páldául a http://stackoverflow.com/questions/35032675/how-to-create-dataset-similar-to-cifar-10 kis progija mintájára ezt a konverziót elvégzi (itt mi a bemenő képek címkéjét 0-ra állítottuk, mert a pontossággal nem akarunk foglalkozni, csak azzal, hogy az egyedi bemenő képeket felismeri-e a háló).
Aztán a cifar10_input.py-ban módosítsuk az input() fgv.-t, hogy a mi input.bin állományunkat olvassa be: else: #filenames = [os.path.join(data_dir, 'test_batch.bin')] filenames = [os.path.join(data_dir, 'input.bin')]
Majd a cifar10_eval.py forrást butítsuk le, hogy ne számoljon pontosságot, hanem csak nézze meg, hogy minek ismerte fel leginkább a hálózat a bemenő képet, az eval_once() fgv.-ben: #while step < num_iter and not coord.should_stop(): # predictions = sess.run([top_k_op]) predictions = sess.run([top_k_op]) print(sess.run(logits[0])) classification = sess.run(tf.argmax(logits[0], 0)) cifar10classes = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"] print(cifar10classes[classification])
Van még pár apróság, mint páldául a cifar10.py-ban a batch_size 1-re állítása, de ha minden eszünkbe jutna most, akkor nem lenne olyan izgalmas a labor :)
Nyelvi bevezetés
Az előző MNIST és az iménti CIFAR-10 példa azt domborítja ki, hogy a TF egy ML (Machine Learning) nyelv. Most lássuk a "klasszikus" megközelítést. Láttuk, hogy a hivatalos tutoriál szerint a TF "Helló, Világ!" program az a MNIST-es példa, de lássuk egy szokásos Helló Világot: a részleteket majd az előadáson megbeszéljük. A mi (UDPROG) "klasszikus" példánk a Mandelbrot halmaz (számoltuk C-ben, C++-ban, Qt-vel, P-szálakkal, Open MP-vel, CUDA-val és elosztva, ja és még Javából is megismételtük a számolást, nagyítást, utazást) s lássunk csodát a hivatalos TF tutoriálnak is van Mandelbrotos példája: https://www.tensorflow.org/versions/r0.12/tutorials/mandelbrot/index.html Csináljuk meg ugyanazt az első példát, mint C++-ban és Javában: csak zöld árnyalatokkal rajzolja a halmazt. Magam a TF példájából forkolva csinátam egy csak vöröset:
és meg is jeleníti valóban (vegyük észre, hogy ez az ablak egy jupyter-console)
De a kis nyelvi bemelegítő után máris térjünk vissza a ML témához. Végezetül próbáljuk ki a hivatalos TF tutoriál képfelismerés példáját, futtatva egy saját képre (itt ehhez nem kell programozni szemben az eddigiekkel)
nbatfai@robopsy:~/Robopsychology/repos/gpu/tensorflow$ bazel-bin/tensorflow/examples/label_image/label_image --image=palyan.png W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization(). I tensorflow/examples/label_image/main.cc:206] bathing cap (785): 0.415266 I tensorflow/examples/label_image/main.cc:206] rule (519): 0.163412 I tensorflow/examples/label_image/main.cc:206] swimming trunks (945): 0.0780062 I tensorflow/examples/label_image/main.cc:206] snorkel (507): 0.0300284 I tensorflow/examples/label_image/main.cc:206] maillot (977): 0.017797 nbatfai@robopsy:~/Robopsychology/repos/gpu/tensorflow$
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.
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.
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:Vessü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:
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 =.0whileTrue:
sess.run(train)
print(sess.run(W), sess.run(b))
ifabs(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 .
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:
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)
é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 athttp://tensorflow.org/tutorials/mnist/beginners/index.md"""from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
# Import datafrom tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import matplotlib.pyplot
FLAGS =Nonedef 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 inrange(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 modelprint("-- 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
-- Ezt a halozat ennek ismeri fel: 4 ---------------------------------------------------------- -- A sajat kezi 8-asom felismerese, mutatom a szamot, a tovabblepeshez csukd be az ablakat
-- 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: Mit szóltok olyan kis bajnoksághoz, hogy minden tizedes javítás a pontosságon lenne x-sok pont!?
Hivatkozások
Abadi, M., Agarwal, A., Barham, P., Brevdo, E., Chen, Z., Citro, C., Corrado, G.~S., Davis, A., Dean, J., Devin, M., Ghemawat, S., Goodfellow, I., Harp, A., Irving, G., Isard, M., Jia, Y., Jozefowicz, R., Kaiser, L., Kudlur, M., Levenberg, J., Mane, D., Monga, R., Moore, S., Murray, D., Olah, C., Schuster, M., Shlens, J., Steiner, B., Sutskever, I., Talwar, K., Tucker, P., Vanhoucke, V., Vasudevan, V., Viegas, F., Vinyals, O., Warden, P., Wattenberg, M., Wicke, M., Yu, Y., Zheng, X. (2016) TensorFlow: Large-Scale Machine Learning on Heterogeneous Distributed Systems, ArXiv e-prints, https://arxiv.org/abs/1603.04467