Friday, April 28, 2017

Derin Öğrenimle 3D Uzaklık Bilgisi, Görüntü Bölümleri Bulmak

DO ile dış dünyadaki objelerin derinliğini, tek kamera kullanarak ayrıca kameranın hareketini hesaplayabilen bir ağ yapısı surada paylaşılmış. Yazarlardan biri David Lowe: bu araştırmacı DO'dan önce de yapay görüş alanında ünlüydü, görüntülerden özellik çıkartmak (feature extraction) alanında mesela SIFT buluşu vardır... Ilginç bir hikaye: Lowe SIFT'i keşfeder ama bu keşif hakkındaki yazıyı hiçbir bilimsel yayın kabul etmez, o da SIFT'i patentler.

Neyse, genç bir diğer bilimci Zhou'nun başlattığı ve diğerlerinin katıldığı bu en son makalede ilginç bir diğer özellik DO'nun eğitiminin tamamen denetimsiz (unsupervised) olması, yani veri için etiket yok. DO hakkında yapılan eleştirilerden biri çok fazla etiketli veriye ihtiyacı olması, denetimsiz çalışmaması. Bu yaklaşım denetimsiz, ama aslında dolaylı olarak denetimli, çünkü etiketleri eğitim sürecinin kendisi üretiyor. Denetimli eğitim bilindiği gibi, mesela regresyon tekniğinde verili X için bir y'ye bir model uyduruyoruz, y'ler etiket ya da hedef verileri oluyorlar. DO'lar model uydurmayı çok boyutlu ve çok daha esnek şekilde yapabiliyorlar.

Denetimsizlik icin etiket üretimi perspektif geometri kullanarak yapılıyor. Perspektif geometride  bir imajdan diğerine geçerken mesela kamera duruşunun nasıl değiştiğini biliyorsak 1. imajı yamultup (warping) 2. imaja çevirebiliriz, ya da ters yönde ters yamultma ile geriye gidebiliriz. Bunu biliyoruz. Arkadaşlar iki ağ yapısı kurmuşlar, biri derinlik için diğeri duruş için; Bir video'daki tüm kareleri işlerken önceki, sonraki, mevcut imaj kullanıp duruş, sonraki imaj kullanılarak mevcut resimdeki derinlik tahmin edilmeye uğraşılıyor. Sonra her iki ağın çıktısı kullanılarak önceki imaja doğru ters yamultma yapıyorsunuz, eğer yamultma iyi olmadıysa önceki imaja uymayacaktır tabii ki ve bu "hata" bir gradyan inişle her iki ağ üzerinde düzeltme amaçlı kullanılabilir. Geriye doğru yamultma işleminin türevi alınabilir halde olması için özen gösterilmiş ki DO ile eğitim yapılabilsin. Fikir müthiş. Yani perspektif geometri üzerinden verinin kendisi dolaylı denetimli eğitim sağlamış oluyor. 

Egitim KITTI adli bir veri seti üzerinde yapılmış. KITTI saatlerce bir arabanın yolda giderken kamerasından kaydedilmiş görüntülerini içerir.

Kod şurada


DO için Tensorflow kullanılmış, kurmak için

sudo pip install tensorflow==1.1

Eğitilmiş modeli models/download_model.sh ile indirebiliyoruz. Biz modeli modeli test ettik, şu imaj üzerinde, 

from __future__ import division
import os, time
import numpy as np
import scipy.misc
import tensorflow as tf
from SfMLearner import SfMLearner
from utils import *
import matplotlib.pyplot as plt

mode = 'depth'
img_height=240; img_width=320
ckpt_file = 'models/model-145248'
I = scipy.misc.imread('ins.jpg')
I = scipy.misc.imresize(I, (img_height, img_width))

sfm = SfMLearner(batch_size=1,img_height=img_height, img_width=img_width)
sfm.setup_inference_graph(mode=mode)
saver = tf.train.Saver([var for var in tf.trainable_variables()])
with tf.Session() as sess:
    saver.restore(sess, ckpt_file)
    pred = sfm.inference(I[None,:,:,:], sess, mode=mode))
p = pred['depth'][0,:,:,0]
plt.imshow(normalize_depth_for_display(p))
plt.savefig('out2.png')

Sonuç

Daha aydınlık pikseller daha yakın demek. Ortadaki engel açık şekilde görülüyor. Metre olarak biz bazı seçilmiş pikselleri kontrol ettik, 

Çoğu piksel iyi, alt soldaki daha iyi olabilirdi. Muhakkak bu yaklaşımda ilerlemeler olacaktır, ayrıca zaten üstteki türden resimleri kullanarak eğitim yapılsa sonuçlar daha iyi olabilirdi. Yapılan az buz iş değil; tek resme bakılarak tüm piksellerin derinlik bilgisini bulmak! 

Peki birkaç resme bakarak (video mesela) o resimlerdeki tüm objeleri üç boyutta bulmak, takip etmek amacında neredeyiz? Bu bağlamda daha gidecek yol var. Şimdilik en iyi seçenek DO (ya da diger, mesela Felzenswalb) kullanarak iki boyutta görüntü bölmesi (segmentation) yapmak, sonra bu iki boyuttaki görüntü parçalarını 3D takibi yapacak filtrelere geçmek. Filtreler kalman ya da parçacık filtreleri olabilir. Takip etme işlemi de zor bir iş yapıyor, bir zorluk takip edilen objeler görüntüden çıkıyorlar, yeni objeler tekrar giriyorlar. Bir digeri imaj parçalarının doğru filtre ile eşleşmesi lazım, bu eşleşmeyi direk yapan yaklaşım var, olasılıksal yapan yaklaşım var (imaj parçası 'tüm' filtrelere verilir, ama her filtrenin bir hipoteze bağlı olma olasılığı vardır). Filtrelemede iyi bilinen bir diğer  numara aynı ölçümün (bu durumda 2D imaj parçası) iki farklı filtreye verilmesi, mesela bir filtre objenin sola doğru gitmesi, bir diğeri üzerimize doğru gelmesi. Hangi filtre / hipotezin artığı / hatası daha az ise, o baskın haldedir, ve onun hipotezi kabul edilir. Ama arka planda olan filtreye hala ölçüm geçilmeye devam edilir. Tüm bu işlemlerin pür DO yaklaşımı ile yapılması çok zor.

Pür 2D imaj bölmesinden bahsetmişken, bu alanda DO ile bir diğer ilerleme SegNet. 


SegNet anlamsal (semantic) bölme yapıyor, bir görüntüde yol, araba, direk gibi temel bölümleri bulup onları etiketliyor. 

Microsoft'un COCO veri setini kullanarak (denetimli) şekilde resimde DO ile obje bulma çok ilerledi. COCO verisi etiketli, bol veri var, bir imajdaki objenin nerede olduğunu Amazon'un Mekanik Türk servisi üzerinden gerçek insanlara etiket verdirerek kaydetmişler. Bu yer  bir "maske" üzerinden DO'ya veriliyor, ayrıca ham imaj verisi de sağlanıyor. Bu veriyi kullanan ağ yapısı mesela DeepMask var.

Yaklaşımlar

DO etrafında bir "yan sanayi" ya da "paylaşma kültürü" oluşmaya başladı. Zaten makalelerin neredeyse hepsi artık açık bir ortam olan arXiv'de yayınlanıyor (para ile makale servisi yapan şirketler üzerinden değil),  ve DO özelinde ağların kendisi paylaşılıp direk olduğu gibi kullanılıyor. Mesela obje bulma, görüntü işleme yapan DO'lar imajın tamamını sınıflama amaçlı hazırlanmış VGG-16 modelini baz alıyorlar. Ve sadece ağ yapısını değil, eğitilmiş ağın ağırlıklarını bile olduğu gibi kullananlar var. Bu önceden eğitilmiş (pre-trained) model kullanma tekniği. Sonra kendi istediği yeni birkaç katman ekleyebilir, ya da mevcut bir katmanı atıp yerine yenisini koyabilir, vs. Sonra eğitimi mevcut ağırlıkların olduğu yerden "devam ettiriyorlar", böylece mevcut modelden faydalanıyorlar.. Bu mantıklı aslında çünkü VGG-16 imaj sınıflaması için eğitilmiş, o zaman ağırlıklarının içinde imajı anlaması için gerekli bazı ayarlar oluşmuş olmalıdır. Takip eden araştırmacılar bu ayarlardan istifade ediyorlar.

Kapatmadan önce bir noktadan daha bahsedelim; DO'nun sadece denetimli olması bir kısıtlayıcı faktördü fakat bize göre eğer problem alanı hakkında temel matematik bilgisi devreye sokulabilirse denetimli problemler denetimsiz hale çevirilebilir. Mesela paylaşılan ilk makalede bu temel bilgi perspektif geometridir. Arkadaşlar kamera duruşu, yamultma, homografi, vs. gibi pek çok temel bilgi devreye sokarak sonuca ulaşmışlar. DO alaninda bazen bir beklenti "pür pikselleri vereyim her şeyi öğrensin" türünde olabiliyor. Fakat eğer işimizi kolaylaştıracaksa, "hipotez alanını daralatacaksa" eldeki pek çok diğer bilgiyi devreye sokabiliriz. Bilimin temeli modellemedir ne de olsa. Yazının başındaki makalenin yazarlarından Kendall surada benzer vurguyu yapmış.

EK:

Sehir ici etiketlenmis goruntuler icin Cityscapes veri seti ilginc.

Tuesday, March 28, 2017

OpenCV 3.0

OpenCV en son sürüm kurmak için

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev 
sudo apt-get libavformat-dev libswscale-dev python-dev python-numpy libtbb2 
sudo apt-get install libtbb-dev libjpeg-dev libpng-dev libtiff-dev 
sudo apt-get install libjasper-dev libdc1394-22-dev

Sonra

https://github.com/opencv/opencv

adresinden kod indirilir, dizine gidip 

mkdir release
cd release/
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j2
sudo make install

işletilir.

OpenCV ile C++ kodu derlemek icin tipik ornek,

g++ -c -O3 -Wall `pkg-config --cflags opencv` -D LINUX -fPIC videostab.cpp
g++ -o videostab.exe videostab.o `pkg-config --libs opencv`

Bazi yararli olabilecek OpenCV kodlari surada.

Friday, March 24, 2017

Bulut Uzerinde Unix: GCloud

Bilgisayarı almak, taşımak, üzerinde işletim sistemi kurmak, sonra onu İnternet'e açmak için uğraşmak.. Bunlar saç yoldurucu olabilir. Amazon, Google gibi şirketler bu alanda uzun süredir servis sağlıyorlar. İnternet üzerinde isteğe göre, istenen hacimde, istenen işletim sistemini taşıyan bir makinayı yaratmak bulut servisleri ile çok kolay. Amazon EC2 sisteminden önce bahsetmiştik. Eğer Amazon'un servisi memnun etmiyorsa, Google seçilebilir. İlk hesap açımında $300 dolarlık hediye de veriyorlar - rekabet güzel şey! Amazon müşterilerini kendilerine çekmeye uğraşıyorlar.

Bu yazıda komut satırından SSH ile erişilebilecek servis tarzı bir makina yaratmayı işliyoruz.  Google bu servise "hesaplama motoru (compute engine -CE-)" diyor. Makina yaratmak için önce hesap açmak lazım. 

https://cloud.google.com

Kredi kartı, ya da banka bilgileri verildikten sonra (hediye miktarı tüketilmeden para alınmayacak tabii) giriş tamamlanır. Ardından Google servislerine komut satırı erişimi sağlayan SDK lazım,  

https://cloud.google.com/sdk/

Linux icin 

https://cloud.google.com/sdk/docs/quickstart-linux

Indirdikten sonra cd google-cloud-sdk, ve ./install.sh. 

Sonra gcloud init ile kurulum tamamlanır, sorulan sorulara evet deyin, sisteme girme (login) sorusuna evet deyince tarayıcıya aktarılıyorsunuz, google şifresi ile giriş yapınca bağlantı kuruluyor. 

Yeni makina yaratmak gcloud komut satırı ile olabilir, ama en rahatı başta GUI kullanmak. Bir proje yaratılıyor, sonra proje seçiliyor. Ana konsoldan "Go to compute engine dashboard" ile CE'ye gidiliyor. Burada


Benim daha önce başlattığım makina burada görülüyor. Yeni makina için "create instance" tıklanır, seçenekler hangi tür işletim sistemi (bizde Debian), makina donanımı (machine type), belleği, mikroişlemci sayısı, vs., makinanın hangi bölgede başlatılması istendiği (zone) seçiliyor. Bölge mesela makina ABD'de mi, Asya'da mı, Avrupa'da mı başlatılsın? Eğer müşteriye dönük bir uygalama servis edilecekse müşteriye yakın makinalar daha iyi olur, cevap hızının optimal olması için. 


Bu seçimler yapılırken sağ yanda tahmini aylık bedel gösteriliyor. Makina yaratıldıktan sonra iki üstteki resimde SSH seçeneği var, bu seçenekten "view gcloud command" ile bağlanmak için gereken gcloud komut satırı komutu gösteriliyor. Bunu kopyala, yapıştır ile yerel makinamizin Unix konsoluna verip, buluttaki makinamiza ilk girişi yapabiliriz. 

Makinaların ana diski kalıcıdır (persistent), yani makinayı kapatıp açınca disk üzerine yazılmış şeyler hatırlanır. Tabii sanal makina silinirse, dosyalar da silinecektir. 

CE makinalarına statik IP adresi atanması mümkün, yani bu makina üzerinde Web servisi (apache gibi) başlatılınca makina o IP üzerinden erişilebilir hale gelir. DNS ile isim eşlemesi yapılınca, Google bulutu üzerinden tam işlevli Web servisi sunmak mümkün olur. 

Monday, March 13, 2017

Baz Istasyonu ile Yer Bulma, Android

Bu bolume bazi ekler:

Altta baz istasyonlari hakkinda veri tabanindan bahsedildi. Telefonun o anda bagli oldugu baz istasyonun verisini Android'den almak ve kaydetmek icin surada bahsettigimiz olcum toplayici kodlara ekler yaptik. Artik cell.txt adli bir text dosyasinda o anda bagli olunan (servis veren) baz istasyonunun bilgileri yaziliyor. Mesela biraz once bir ornek topladik, bir satirda

262:02:15:13227508:

Bunlar sirasiyla mcc, mnc, lac, cid kodlari. Bu kodlari kullanarak opencellid verisine bakiyoruz, ve

UMTS,262,2,15,13227508,167,13.321302,52.502313,185,9,1,1458941010,1478909517,-101

satirini buluyoruz, yani enlem/boylam 52.502313,13.321302 imis (hakikaten de oradaydik). Bu en yakin baz istasyonunun yeri.

GPS ile algilayici fuzyonu (sensor fusion) yapilarak bu veri oldugumuz yeri daha iyi hesaplamak icin kullanilabilir. GPS bilindigi gibi duvarlardan yansima sonucu bazi sinyallerin yolunun uzamasi sebebiyle (multipath problem) bazen yanlis sonuclar verebiliyor.  GPS baglanti da kuramayabilir bazen, ya da  baglanma uzun surebilir. Tum bu sebeplerden dolayi baz istasyonlari yer bulmak icin takviye amacli kullanilabilir.

Tum dunyadaki baz istasyon kodlari ve yerlerini kayitli tutan bir acik yazilim projesi,

opencellid.org

Baz istasyonu kodu uzerinden bulunur, ve tabanda istasyonun enlem  / boylami da vardir, 3 veya daha fazla istasyon ile ucgenleme yapilabilir. Istasyon tabanini almak icin, once Database | request for API key secilir, email / sifre ile kayit olduktan sonra ile bir arayuz anahtari alinir; Sonra Database | Download Database ile ve API anahtari girilerek taban indirilir.

Tum taban oldukca buyuk, sıkıştırılmış hali bile 600 MB civari - eh normal, tum dunyadaki istasyonlar kayitlanmaya ugrasiliyor. Bu dosyayi kucultmek icin icinde oldugumuz sehir disindakileri filtreleyebiliriz. Mesela sadece istenen enlem / boylam yakininda olanlar icin alttaki kod, diyelim icinde 13 enlem 52 ile baslayan baz istasyonlarini alip ekrana basiyor (komut satirinda > ile cikti dosyarina yonlendirilir)

import re
with open(...) as f:
    for line in f:
        if re.search("13\.\d+,52\.\d+",line): print line.strip()


Not: Kaynaklarda telefonun etrafindaki birden fazla olabilecek baz istasyonunun bilgisini almak icin TelephonyManager.getNeighboringCellInfo cagrisindan bahsediliyor. Bu cagri "kizaga alinmis (deprecated)" bir cagri, artik onun yerine TelephonyManager.getAllCellInfo tavsiye ediliyor, API 17'den itibaren bu cagri Android API kod bazinda var. Fakat tum telefonlar bu cagriyi halen desteklemiyor, biz Android 6.0 (API 23) destekli olan bir telefonda denedik (ucuz bir marka) ve getAllCellInfo bos bir liste geri getirdi. 

Monday, February 13, 2017

Algılayıcı Ölçümleri, Video, Android

Surada bahsettiğimiz uygulamada bazı ekler var. Robotik hedefleri (dış dünyada bağımsız gezinebilen yapay zeka uygulamaları) için ölçüm toplama bağlamında faydalı olabilir.

Kamera resimleri, yön algılayıcısı (orientation sensor), GPS değerleri, ivme algılayıcı (accelerometer) belli aralıklarla biriktirir, ve istendiği anda (Rec düğmesine basılınca) sonuçları telefon dizinine kaydeder. Dosya SDCARD/Bass altında bir numaralı dizindir, her Rec sonrası yeni bir dizin yaratılır. Böylece birkaç ölçümü arka arkaya kaydetmek mümkün olur.


Her ölçüm için ayrı bir txt dosyası var, analiz amaçıyla bu dosyaları USB ile dizüstüne aktarmak yeterli. Her veri dosyasındaki satır sayısı ve kameranın kaydettiği tek resim (frame) sayısı birbiriyle aynı, yani eğer ivme algılayıcından 20 satır kaydedildiyse, yön algılayıcısından da 20 satır kaydedilmiş demektir, ve her satırın zaman indisi birbiriyle eşittir. Yani herhangi bir zaman anında tüm algılayıcılardan alınan veri aynı anda bellege alınır. Böylece sonradan analiz sırasında odaklanan zaman diliminde tüm ölçümlerin hangi seviyede olduğu bilinebilir.

Uygulama içinde ve eğer GPS bağlantısı kurulduysa Map düğmesine basılarak o anda olunan yerin haritası alınabilir. Haritalar bir zip dosyası içinde.

Kamera kalibrasyonu hakkindaki yazi ayni baglantidan bulunabilir.

Thursday, January 26, 2017

Derin Ogrenim, Bazi Video'lar, Baglantilar

Google kurucularindan Brin Davos'ta

https://www.youtube.com/watch?v=XzkUAxtEQXE

Derin Ogrenim mucitlerinden LeCun semineri, goruntu ile araba kullanim hakkinda ilginc bilgiler. 15:35'te gosterilen robot, piksel bazinda, o pikselin uzerinde yurunebilir olup olmadigi bilgisiyle egitiliyor, diger girdi pur imaj. Robot bu bilgiyle etrafta dolasiyor, onune engel cikinca hemen duruyor.

https://www.youtube.com/watch?v=IbjF5VjniVE

UdaCity kurucusu ve surucusuz arabalar arastirmacilarindan Thrun ile LeCun soylesisi


MIT universitesi derin ogrenim ile araba kullanimi hakkinda yeni ders baslatti. Video'lar YouTube'da (baglantilar alttaki sayfada).

http://selfdrivingcars.mit.edu/

YSA egitiminde kullanilan geriye dogru yayilma (backprop) algoritmasini kimin kesfettigi hakkinda ilginc bir tartisma.

Wednesday, January 25, 2017

Araba Kullanan Derin YSA

Keras / Python ile bir model arabayı kullanan ilginç bir proje. YSA eğitilirken girdi olarak arka arkaya alınmış video resimleri kullanılmış, test yol ortamında sağ ve solda beyaz şeritler var, hedef değişkeni direksiyonun kaç derece sağa ya da sola döndüreceğini belirten -90,+90 arasında bir sayı. YSA evrişimsel derin bir ağ, içinde RNN / LSTM kullanılmamış, yine de başarı fena değil. Eğitim için arkadaş video kaydedilirken arabayı kendisi kullanmış, test ortamında araba bu modeli kullanarak şeritler arasında kalarak ilerliyor.

Tek kamera ve yapay öğrenim üzerinden araba kullanmak hala bakir bir alan. Şu anda revaçta olan otomatik araba kullanan teknolojiler radar, lidar, sonar gibi envai türden algılayıcı ile çevre hakkında bilgi topluyorlar, ve filtreleme (parçacık filtreleri) teknikleri ile etraf hakkında konum tahmini yapıp ilerliyorlar. Deep Drive gibi sistemler yeni denenen pür görüntü bazlı yeni yaklaşımlar arasında. Maceracı araştırmacılar buraya atlayabilir. 

Thursday, January 19, 2017

Derin Öğrenim ile Text Üretmek, RNN, LSTM

Derin Öğrenim her yerde; yapay sinir ağları sağlam bir dönüş yaptılar, ve ardı ardına ilerlemeler, ve ilginç kullanımlar haberleri görülebiliyor. Bunlardan biri A. Karpathy'nin Kendini Tekrarlayan Yapay Sinir Ağları (Recurrent Neural Network, -RNN-) hakkında yazdıkları. Arkadaş Shakespeare'in uzun bir oyununu RNN'e okutup sonra bu ağdan Shakespeare ürettirmiş. Sonuçlar fena değil.

Öteki yandan alttaki Y. Goldberg adlı birisi sadece önceki N karakterden sonra her karakterin kaç kere geldiğini "sayarak" ve frekansları kullanarak metin üretmiş. Burada derin öğrenim filan yok, sadece basit sayım var. Sonuçlar onda da iyi. Ama nasıl oldu bu iş? Derin YSA hiçbir iş yapmıyor mu yani? Fakat Goldberg'in dediği gibi aslında RNN, LSTM gibi derin modelleri daha farklı bir şey yapıyorlar. Shakespeare örneğinde her iki yaklaşım da Shakespeare'imsi bir şeyler üretiyor, fakat RNN, LSTM yaklaşımında bazı gramer yapıları öğrenilmeye başlanıyor.

Mesela parantez açıp bir blok sonra parantez kapamak frekans modelleri için zor, fakat DO bunu başarıyor. Goldberg "N sayısını arttırıp 10,20 seviyesine getirsem belki bunları frekans modeli de yapardı ama hafızam yetmezdi" diye bir yorum da yapmış, ve bu nokta DO / YSA'nın önemli bir avantajını yakalamış. Frekans modeli mesela 9 harf geriye bakıp 10. harfi tahmin için, mumkun tum kombinasyonlar icin 20 harflik alfabede 20**10 öğeli bir sözlük / listeye sahip olmalıdır, bu 10240 milyar öğe demektir. O tüm kombinasyonlar tabii ki girdi verisi içinde olmayabilir, fakat az bir kısmı olsa bile bu müthiş büyük bir sayıdır. Halbuki derin öğrenim, her ne kadar modeli derinleştirse de, her seviye sadece bir sonraki seviyeyle iletişimde olduğu için yer israf etmiyor. Üstelik bu katmanlı yaklaşımı ile her katmanın belli alanlara odaklaşmasını teşvik ediyor, böylece model genelleştirebiliyor. Frekans modeli ezberci, derin öğrenim böyle değil.

Su yazıyı baz alarak mevcut olan bir DO'yu (LSTM) yükleyip biz de metin üretme yaptırdık, kurulum için

sudo pip install tensorflow
sudo pip install h5py

Kullanılan DO programı Keras. Kaynak indirilip python setup.py build ve install ile kurulabilir.

Model

http://www.cs.virginia.edu/~vicente/recognition/notebooks/weights-vicente.hdf5

Alttaki kodu arka arkaya isletince

a black cat is drinking into a bowl on the side of a road
a bike sitting next to a stick is taking his lapkay
a person is standing on a restaurant

gibi cümleler üretiliyor. Kelimelerin çoğunun mantıklı olması bir yana, gramer yapısı da fena değil.

Kod

import tensorflow as tf
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation, LSTM
from keras.optimizers import RMSprop
from keras.layers.wrappers import TimeDistributed

# Read captions into a python list.
maxSamples = 10000
captions = []
fopen = open('captions_train.txt', 'r')
iterator = 0
for line in fopen:
    if iterator < maxSamples:
        captions.append(line.lower().strip())
        iterator += 1
fopen.close()
    
# Compute a char2id and id2char vocabulary.
char2id = {}
id2char = {}
charIndex = 0
for caption in captions: 
    for char in caption:
        if char not in char2id:
            char2id[char] = charIndex
            id2char[charIndex] = char
            charIndex += 1

# Add a special starting and ending character to the dictionary.
char2id['S'] = charIndex; id2char[charIndex] = 'S'  # Special sentence start character.
char2id['E'] = charIndex + 1; id2char[charIndex + 1] = 'E'  # Special sentence ending character.
            
# Place captions inside tensors.
maxSequenceLength = 1 + max([len(x) for x in captions])
# inputChars has one-hot encodings for every character, for every caption.
inputChars = np.zeros((len(captions), maxSequenceLength, len(char2id)), dtype=np.bool)
# nextChars has one-hot encodings for every character for every caption (shifted by one).
nextChars = np.zeros((len(captions), maxSequenceLength, len(char2id)), dtype=np.bool)
for i in range(0, len(captions)):
    inputChars[i, 0, char2id['S']] = 1
    nextChars[i, 0, char2id[captions[i][0]]] = 1
    for j in range(1, maxSequenceLength):
        if j < len(captions[i]) + 1:
            inputChars[i, j, char2id[captions[i][j - 1]]] = 1
            if j < len(captions[i]):
                nextChars[i, j, char2id[captions[i][j]]] = 1
            else:
                nextChars[i, j, char2id['E']] = 1
        else:
            inputChars[i, j, char2id['E']] = 1
            nextChars[i, j, char2id['E']] = 1

print("input:")
print(inputChars.shape)  # Print the size of the inputCharacters tensor.
print("output:")
print(nextChars.shape)  # Print the size of the nextCharacters tensor.
print("char2id:")
print(char2id)  # Print the character to ids mapping.

trainCaption = inputChars[25, :, :]  # Pick some caption
labelCaption = nextChars[25, :, :]  # Pick what we are trying to predict.

def printCaption(sampleCaption):
    charIds = np.zeros(sampleCaption.shape[0])
    for (idx, elem) in enumerate(sampleCaption):
        charIds[idx] = np.nonzero(elem)[0].squeeze()
    print(np.array([id2char[x] for x in charIds]))

printCaption(trainCaption)
printCaption(labelCaption)

print('Building training model...')
hiddenStateSize = 128
hiddenLayerSize = 128
model = Sequential()
# The output of the LSTM layer are the hidden states of the LSTM for every time step. 
model.add(LSTM(hiddenStateSize, return_sequences = True, input_shape=(maxSequenceLength, len(char2id))))
# Two things to notice here:
# 1. The Dense Layer is equivalent to nn.Linear(hiddenStateSize, hiddenLayerSize) in Torch.
#    In Keras, we often do not need to specify the input size of the layer because it gets inferred for us.
# 2. TimeDistributed applies the linear transformation from the Dense layer to every time step
#    of the output of the sequence produced by the LSTM.
model.add(TimeDistributed(Dense(hiddenLayerSize)))
model.add(TimeDistributed(Activation('relu'))) 
model.add(TimeDistributed(Dense(len(char2id))))  # Add another dense layer with the desired output size.
model.add(TimeDistributed(Activation('softmax')))
# We also specify here the optimization we will use, in this case we use RMSprop with learning rate 0.001.
# RMSprop is commonly used for RNNs instead of regular SGD.
# See this blog for info on RMSprop (http://sebastianruder.com/optimizing-gradient-descent/index.html#rmsprop)
# categorical_crossentropy is the same loss used for classification problems using softmax. (nn.ClassNLLCriterion)
model.compile(loss='categorical_crossentropy', optimizer = RMSprop(lr=0.001))

print(model.summary()) # Convenient function to see details about the network model.

# Test a simple prediction on a batch for this model.
print("Sample input Batch size:"),
print(inputChars[0:32, :, :].shape)
print("Sample input Batch labels (nextChars):"),
print(nextChars[0:32, :, :].shape)
outputs = model.predict(inputChars[0:32, :, :])
print("Output Sequence size:"),
print(outputs.shape)

inference_model = Sequential()
# Two differences here.
# 1. The inference model only takes one sample in the batch, and it always has sequence length 1.
# 2. The inference model is stateful, meaning it inputs the output hidden state ("its history state")
#    to the next batch input.
inference_model.add(LSTM(hiddenStateSize, batch_input_shape=(1, 1, len(char2id)), stateful = True))
# Since the above LSTM does not output sequences, we don't need TimeDistributed anymore.
inference_model.add(Dense(hiddenLayerSize))
inference_model.add(Activation('relu'))
inference_model.add(Dense(len(char2id)))
inference_model.add(Activation('softmax'))

inference_model.load_weights("weights-vicente.hdf5")

# Given the start Character 'S' (one-hot encoded), predict the next most likely character.
startChar = np.zeros((1, 1, len(char2id)))
startChar[0, 0, char2id['S']] = 1
nextCharProbabilities = inference_model.predict(startChar)

# print the most probable character that goes next.
print(id2char[nextCharProbabilities.argmax()])

inference_model.reset_states()  # This makes sure the initial hidden state is cleared every time.

startChar = np.zeros((1, 1, len(char2id)))
startChar[0, 0, char2id['S']] = 1

res = []
for i in range(0, 100):
    nextCharProbs = inference_model.predict(startChar)
    
    # In theory I should be able to input nextCharProbs to np.random.multinomial.
    nextCharProbs = np.asarray(nextCharProbs).astype('float64') # Weird type cast issues if not doing this.
    nextCharProbs = nextCharProbs / nextCharProbs.sum()  # Re-normalize for float64 to make exactly 1.0.
    
    nextCharId = np.random.multinomial(1, nextCharProbs.squeeze(), 1).argmax()
    res.append(id2char[nextCharId]) # The comma at the end avoids printing a return line character.
    startChar.fill(0)
    startChar[0, 0, nextCharId] = 1
print ''.join(res)

Friday, January 6, 2017

Tıklamaları Örnek Veriye Çevirmek

Bazen belli bir şekilde olan veri noktalarını kabaca tıklayarak üretmek gerekebilir, bu noktaları metin editör içinde yazmak zor olur, görsel yaklaşım tercih edilebilir. Bu işi yapacak basit bir Python programı altta

import pandas as pd
from matplotlib import pyplot as plt

class PointRec:
    def __init__(self, line, ax, fig):
        self.line = line
        self.ax = ax
        self.fig = fig
        self.xs = list(line.get_xdata())
        self.ys = list(line.get_ydata())
        self.cid = line.figure.canvas.mpl_connect('button_press_event', self)

    def __call__(self, event):
        if event.inaxes!=self.line.axes: return
        self.xs.append(event.xdata)
        self.ys.append(event.ydata)
        self.ax.plot(event.xdata, event.ydata,'rd')
        self.fig.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(0, 20);ax.set_ylim(0, 20)
ax.set_title('click to record points, exit to save to out.csv')
line, = ax.plot([0], [0])  
rec = PointRec(line,ax,fig)

plt.show()

df = pd.DataFrame([rec.xs, rec.ys]).T
df.columns = ['x','y']
df.to_csv("out.csv",index=None)

Program tıklamaları hafızada biriktirerek tutar, ve program kapatıldığında veriyi out.csv dosyasına yazar.