ismailari.com İsmail Arı'nın internet güncesi

Akademik poster hazırlama

2010 21 Nisan

Diyarbakır‘da sunmak üzere poster hazırlamam gerekiyor ve bu benim ilk poster hazırlayışım. Biraz araştırdım, etrafımdakilere danıştım ve akademik poster hazırlamak için birkaç araç kullanıldığını gördüm. İlginç ama çevremdekiler genellikle Powerpoint kullanıyor. MS Office araçlarının sadece adlarına değil de ne olduklarına bakanlar Publish’i kurcalayıp, onun bu iş için daha doğru araç olduğunda karar kılıyor. Benden daha çok LaTeX sevenler, poster paketlerini kullanarak tüm işlerini LaTeX ile yapıyor. Basım merkezleri ise Photoshop, QuarkXpress veya daha farklı ticarî ürünler kullanabiliyor ama onlar da adı üstünde ticarî ve lisansları okulda yok.

Powerpoint ile hazırlamak istemedim, GNU/Linux destekli bir araç olsun istedim. Zaten Powerpoint profesyonel sunum aracı, bu iş için kullanılabilir belki ama bu işin asıl muhatabı değil. Publish’i de MS ürünü olduğu için sıkışırsam dönmek üzere esgeçtim. LaTeX sevgim çok ama sadece matematiksel formülleri yazarken ve sayfa içi referanslarda. Onun ötesinde her şeyi LaTeX’te yapmak bana göre değil. Her problemi çiviye çevirip çekiçle dalmak gibi bir şey. LaTeX ile her şey yapılabilir, tamam ama biraz da kullanıcı dostu olsun. Kullanımı kolay olsun. İşte tam bu noktada Scribus‘u keşfettim. Scribus, açık kaynak ve profesyonel bir broşür, kitap, poster, vb. tasarım programı. Hem Windows hem GNU/Linux’ta çalışıyor. Powerpoint gibi kutucuk çiz, yazı ekle, stilleri ayarla, sürükle bırak, resim koy, vb. güzel bir kullanıcı dostu arayüze sahip. Son sürümlerinde içine LaTeX, GNU Plot, Lilypond kutuları derlenip gömülebiliyor. Benim LaTeX’e ihtiyacım vardı, bonus olarak konfigürasyon değişikliklerini de kendi isteğime göre yaptım ve kutuları ekledim.

PDF çıktısı alırken, basımda kullanılan CMYK ayarları yapılabiliyor. Zira bu ayarlar olmazsa bastırdığınız posterin renkleri başka telden çalabilir ve şaşırıp kalabilirsiniz. Bugün itibariyle bastırdığım (ve tasarladığımla birebir aynısını gözlemlediğim ilk posterim) şöyle:

Akademik poster veya herhangi bir broşür hazırlamak durumunda kalırsanız bir göz atın derim. İlgilenirseniz olası soruları yanıtlayayım…

LaTeX eklemek ne işime yarar? Powerpoint’te de formül yazabiliyorum.

Evet yazabiliyorsunuz ama henüz LaTeX’deki esneklik yok. Her işin erbabı var. Ayrıca tezi veya makaleyi LaTeX ile yazdıysanız o formülleri Powerpoint ile tekrar yazmak hiç hoş olmuyor. Her şey daha tembel bir dünya için: Kopyala, yapıştır!..

PDF’i yakınlaştırsam da resimler neden bozulmuyor?

Çünkü o resimler EPS veya SVG olarak kaydedildi. Siz yaklaştıkça tekrar çizilip gösteriliyorlar.  Yüz resimlerini ve yüz üstünde bulunan noktaların gösterildiği resimleri matplotlib ile EPS formatında kaydettim. Yüz resimleri %100′den daha fazla yaklaşınca bozulabilir ama diğerleri bozulmaz. Çünkü bahsettiğim gibi onlar ölçeklenebilir, yüz resimleri ise bitmap. Merak ederseniz herhangi bir EPS dosyasını bir metin editörü ile açıp bakın.

Tablolar PDF’ten gömme gibi?!

Evet, ne yazık ki tabloları tekrar oluşturmaya zamanım olmadı ve PDF’ten gömdüm. Font farkı biraz can sıkıcı ama onlar da ölçeklenebilir. Bu arada gömülen nesnede başka şeyler varsa sorun değil, nesne kaydırılıp ölçeklenerek görünen kısma getirilebiliyor. Hatta belgenize, 100 sayfalık başka bir dokümanın 99. sayfasındaki bir tabloyu gömmeniz mümkün.

Disk figürünü nasıl oluşturdun?

Bu ve benzeri SVG figürler için Inkscape kullanabilirsiniz. Hem kullanımı kolay, hem de şirin şeyler üretilebiliyor. Ayrıca çoşup pstricks ile de üretebilirsiniz. Pstricks’in kodunu doğrudan yazmaya üşenirseniz LaTeXDraw imdada yetişir.

Dokümanlarım başka formatta, nasıl format değiştireyim?

Imagemagick kullanabilirsiniz. Örneğin ben PDF olan posteri üstte görünen resmi elde etmek için PNG’ye şunu kullanarak çevirdim:

convert -scale 10% poster.pdf poster.png

Ben küçük resimler ekleyeceğim, SVG olsalar iyi olacak. Tümünü ben çizmeyeyim. İndirilecek bir depo var mı?

Var elbette. Örneğin ben openclipart‘tan iki tane kullandım. Simge ararsanız Tango‘ya bakabilirsiniz.

Ben de Ubuntu kullanıyorum ama depodaki Scribus senin dediklerini desteklemiyor?..

Web sayfasından Debian/Ubuntu paketlerine bakıp ekleyin. Sonra da scribus-ng paketini indirin. En son çıkan ve deneme aşamasında olan sürüm bu oluyor.

Sonuca gelirsek… Beni en çok korkutan kısım grafik deneyimimin Ubuntu’ya geçince ellerimden uçacakmış gibi görünmesiydi. Deneyim dediysem, gayet amatör bir deneyim, figür falan oluşturmak için. Photoshop’un muadilini (Gimp’e ısınamadım henüz) bulamasam da farklı alternatifler öğrendim. Inkscape çok hoşuma gitmişti, Scribus cabası oldu. Öğrenirken resmî dokümantasyonuna ve tutorial’e baktım. Zaten güzel arayüzü sayesinde kendiniz de öğrenebiliyorsunuz.

Yazıda tamamen özgür yazılımları kullanarak nasıl poster hazırlayabilceğinizi anlattım. Neler yapılabileceği kişinin hayalgücüne ve zevkine kalmış…

Araçların doğası

2010 17 Nisan

Facebook ilk çıktığında (A.B.D.’deki bir arkadaşın davetiyle) üye olmuştum. “Aaa, ne güzel, bağlantıyı koparmıyoruz” idi ilk günlerde. Muhteşem bir açığı yakalamıştı birileri. Ardından bizim üniversiteye sıçradı. Sonra lise arkadaşlarını, hatta daha eskilerini buldum Facebook’tan. Süperdi, yıllardır görüşmediğim kişileri bulmuştum. Karşılıklı ekleşmeler, “Vay, İsmail n’aber? Nerelerdesin, neler yapıyorsun?” mesajlarına yazdığım cevaplar, “Abi biz de Beşiktaş’ta bir yer açtık, geçinip gidiyoruz. Bir akşam Taksim’de buluşalım, muhabbetleşelim.” sözleri ve hiçbir zaman gerçekleşmeyen buluşmalar. Ve “kopmak istemediğim arkadaşlarla zaten hâlâ haberleştiğim”in farkedilmesi.

Sonra ufaktan başlayan bir teşhir dönemi: fotoğraf eklemeler, video göstermeler, ben şucuyum bucuyum diye gruplara üye olmalar, manken bakışlı fotoğraflar, enstrumana bir iki kerecik dokunulmasına rağmen onunla çekilen sanatsal pozlar, dünyanın buralarını gezdim diye tıklamalar, hatta yüzük takmaya politik olarak karşı olan arkadaşların sevgilileriyle boy boy fotoğrafları. İnşa edilen yeni bir Facebook kimliği.

Normal kullanımınızın tersine, tuştakımında “facebook”u bir saniyeden az bir sürede yazıyorsanız, tarayıcıyı açınca eliniz ilk “face…” karakterlerine gidiyor veya paylaşımlarınızı kimsenin “like” etmemesi(!) canınızı sıkıyorsa bilin ki yeni bir psikolojik hastalığın semptomlarını gösteriyorsunuz.

Bunları böyle yazabiliyorum, öyle ki ben de bunlardan musdaribim. Üstelik arşivomani (!) hastalığını da işin içine katarsak, işler hiç iç açıcı değil. Sıkıntım zaman değil artık. Sıkıntım bu işteki çarpıklık. Ürettiği çarpık iletişim biçimi. İki kişinin muhabbetinin genel tarafından izlenmesi, yorumlanması; işbirliği içinde mimlenmek; sergilenen yeni yapay kişilikler, teşhircilik.

“Aktivist olarak bir şeyler sergileyelim, sesimizi duyuralım”sa niyetiniz, merak etmeyin, orada da moderatörler var. Sadece izin verilen sesler duyurulur. Çatlak sesler tek tıklamayla veritabanı arşivlerine gömülür.

Madem öyle, bırak git diyebilirsiniz. Birkaç kez hesabı kapatmama rağmen -özellikle Almanya’daki arkadaşlarla- yaşadığım iletişim kopuklukları yüzünden hesabımı yine etkinleştirmek durumunda kaldım. Zaten bağlantılardan da kopmak gibi bir niyetim yok. Hatta faydalı olduğu anlar da çok. Örneğin bir etkinliğe birlikte gideceğim arkadaşa bir davetiye yollamak ve tarih/açıklama/yer bilgilerini takip etmesini sağlamak çok kolay. Ya da belli bir mekanda düzenlenen etkinlikleri aktif olarak görebiliyorum. Yani özetle, problemim araçla değil, kullanılma biçimiyle. Özetle yapay teşhircilikle. Tüketme kapasitemin çok üstünde yığılan medyayla. 3 yılın deneyimiyle biliyorum ki, Facebook bahsettiğim faydalarının ötesine geçemez ve iletişim biçimi aynı paralellikte devam eder.

Şu an farklı bir yöntem seçtim kendime. Önceden arkadaş grupları yapmıştım ve tüm arkadaşlarımın değil, sadece bu arkadaşlarımın görmesine müsaade ediyordum çoğu paylaşımımın. Hatta onları da öbeklemiştim. İzlediğim(!!!) kişiler de belliydi. Onun dışındaki paylaşımları gizlemiştim. Şimdi sildim grupları falan. Her şeyi görünür kıldım arkadaşlarıma. Kimseyi de gizlemedim. Durum böyle olunca bir şey paylaşasım gelmiyor pek. Birinin bir şeyini “like” ederken de tekrar düşünüyorum. Mesajları özel yolluyorum gerekirse. Sanırım, bu daha caydırıcı oldu benim için. Hem teşhirciliğin dik âlâsı oldu hem de caydırıcı sebebi.

İnsanlık olarak hiç tecrübemiz olmayan iletişim biçimleriyle sınanıyoruz. Sonumuz hayırlı olsun!..

Arama uzayı

2010 13 Nisan

Arama algoritmalarında kendimize bir arama uzayı tanımlarız. Bunun ne olduğunu anlamak için bilgisayar bilimleri okumaya hiç gerek yok. Şöyle anlatayım: Herkesin hayatı, kendisi için tanımlı olan uzay ve herkesin aradığı bir şey var. Hangi algoritmayı kullandığımız (düzen, çalışma/sorgulama biçimi), nasıl bir donanıma sahip olduğumuz (zeka, pratik, ekonomik durum), kaç işlemciyle çalıştığımız (uyumluluk, birlikte çalışabilme [iş yapıp yaptırabilme] yeteneği) gibi etkenler başarıyı etkiliyor. Şüphesiz herkesin farklı bir algoritması var bu arama işleminde. Ama sanıyorum ki hepimizin kullandığı temel bir yöntem var: Bir yolda gideriz, yol ayrımına gelirsek bizi daha iyi yola sokacak yöne döneriz. Bazen de umudumuzu yitirir ve seçimi o yollardan birine doğru yapmayız. Bir sıçrama yapar ve bambaşka bir noktasına gideriz bu uzayın. Sıçramaları çocukken daha sık yapar, büyüdükçe yapışıp kalırız yolumuza. Genel olarak çok sıçrama yaparsak, aradığımızı bulamayız; az sıçrarsak yerel iyilerle yetinmek durumunda kalır, en güzelinden mahrum oluruz. Buna bilgisayar biliminde Benzetimsel Tavlama (Simulated Annealing) demişler. Bu algoritmaları, bizim de birer gezgin olduğumuzu düşünüp kısacık ömrümüzün arama/tarama ile geçtiğini hesaba katarak okursak muhakkak daha farklı yorumlarız. Yani, insandan kopuk şeyler değildir özlerinde.

Benzetimsel tavlama, sonsuzda global en iyiyi mutlaka bulacaktır. Sonsuz?.. ve en iyi?.. Hayatımızın sonsuz olmadığını ve -göreceli yaşanan her yaşamda- seçim yaparken 3 ile 5′i karşılaştırırkenki basitlik lüksüne sahip olmadığımızı aklımızdan çıkarmayalım.

Diyarbakır yolcusu kalmasın…

2010 9 Nisan

Sinyal İşleme ve İletişim Uygulamaları Kurultayı‘nın (SİU) bu yılki ev sahibi Dicle Üniversitesi. 22-24 Nisan’da düzenleniyor. Ben de kurultaya katılacağım. 23 Nisan sabahı bayramımızı kutlayıp, öğleden sonra 4 numaralı poster oturumunda “Yüz Nirengi Noktalarının Zamansal Öz-benzerliğine ve Kelime Çantasına Dayalı Yüz İfadesi ve Kafa Hareketi Tanıma” (Facial Expression and Head Gesture Recognition Using Temporal Self-similarity and Bag of Words of Facial Landmarks) adlı çalışmamızı sunacağım.

Bildirinin özetçesi şöyle:

Yüz ifadeleri ve kafa hareketleriyle yapılan jestlerin otomatik tanınması, işaret dili tanıma ve insan bilgisayar etkileşimi gibi birçok alanda önemli bir değere sahiptir. Bu çalışmada, hareket tanımada başarısı gösterilen, takip noktalarının öz-benzerliğine dayalı yöntem, yüz ifadesi ve kafa hareketi jestlerini sınıflandırmak için adapte edilmiştir. Ayrıca, takip edilen yüz nirengi noktalarının histogramına dayalı, daha başarılı yeni bir yöntem önerilmiştir. Sunulan yöntemler Saklı Markov Modeli tabanlı çalışmamızla birleştirilmiş ve sınıflandırma başarısında %15 artış sağlanmıştır.

Gelenlerle Diyarbakır’da görüşmek dileğiyle.

Nümerik işlemler ve bilgisayarla görmek için Python

2010 8 Nisan

Uzun süredir nümerik hesaplarım için IPython kabuğu ile Python’ın numpy modülünü kullanıyorum ve çok memnunum. Hele Opencv’nin güzel sürümündeki (svn’deki sürümü oluyor) matris yapısını numpy dizisine (ndarray) çevirebilince işlem kolaylığı ve çokluğu arttı, daha da şık oldu.

Bunun ne faydası var konusunda bir fikir vereyim. Opencv, içinde birçok bilgisayarla görme algoritmasını barındıran muhteşem bir açık kaynak kütüphane. Numpy, Matlab’ın Python muadili. Numpy neredeyse standart oldu ve tüm nümerik kütüphaneler onu destekliyor. Benim kullandığım en temel kütüphaneler grafik kütüphaneleri (matplotlib gibi) de Numpy destekli. Numpy’ın en güçlü yanı, dilimleme (“slicing”) operatörü. Matlab kullananlar bunu bilir ve sever. Ayrıca işleri vektörlemek de mümkün. Kullanımı çok esnek. Opencv’de hazır fonksiyonları kullanmak çok kolay ama resimlerden istatistik falan toplayacaksanız işiniz Numpy sözdiziminde olduğu kadar kolay değil. Böyle bir çevirme işlemiyle ikisinin gücü birleşiyor. Bu arada, tüm bahsettiğim kütüphaneler platformdan bağımsız.

Şu anlık yalnızca float32 ve uint8 veri türlerini çevirdim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def opencv2numpy(matIn):
    """Convert opencv matrix to numpy matrix (supports 1 and 3 channels currently)"""
    if matIn[0].type == cv.CV_8UC1 or matIn[0].type == cv.CV_8UC3:
        dtype = 'uint8'
    elif matIn[0].type == cv.CV_32FC1 or matIn[0].type == cv.CV_32FC3:
        dtype = 'float32'
    else:
        print "No support except float32 and uint8 yet"
        return 0
 
    if matIn[0].type == cv.CV_8UC3 or matIn[0].type == cv.CV_32FC3: 
        matOut = np.fromstring(matIn.tostring(), dtype=dtype).reshape(matIn.height, matIn.width, 3)
    else:
        matOut = np.fromstring(matIn.tostring(), dtype=dtype).reshape(matIn.height, matIn.width)
 
    return matOut
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def numpy2opencv(matIn):
    if matIn.ndim == 3 and matIn.shape[2] == 3:
        nChannels = 3
    else:
        nChannels = 1
 
    h,w = matIn.shape[0], matIn.shape[1]
    if matIn.dtype == "uint8":
        if nChannels == 1:
            dtype = cv.CV_8UC1
        else:
            dtype = cv.CV_8UC3
    elif matIn.dtype == "float32":
        if nChannels == 1:
            dtype = cv.CV_32FC1
        else:
            dtype = cv.CV_32FC3
    else:
        print "No support except float32 and uint8 yet"
        return 0
 
    matOut = cv.CreateMatHeader(h, w, dtype)
    if nChannels == 1:
        cv.SetData(matOut, matIn.data, w*matIn.itemsize)
    else:
        cv.SetData(matOut, matIn.data, w*4*matIn.itemsize)
 
    return matOut

Güncel işimi görmesi için yazdığımdan hataları olabilir, biraz da verimsiz oldu. Örneğin bir tarafa iyiyken, diğer tarafa verimsiz çeviriyor. Fakat benim için şu an bu öncelik konusu değil. “Exception” fırlatmam lazım ama hariçten gazel okumak zor geldi, işimi görüyor.

Kullanırsanız, genellerseniz veya geliştirirseniz lütfen benimle de paylaşın.

Güncelleme:

Opencv Python arayüzünde zaten hazırmış bu kod. Hem diğer veritipleri için de genellenmiş. Yenisi dönüşümler şöyle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def cv2array(im):
    depth2dtype = {
        cv.IPL_DEPTH_8U: 'uint8',
        cv.IPL_DEPTH_8S: 'int8',
        cv.IPL_DEPTH_16U: 'uint16',
        cv.IPL_DEPTH_16S: 'int16',
        cv.IPL_DEPTH_32S: 'int32',
        cv.IPL_DEPTH_32F: 'float32',
        cv.IPL_DEPTH_64F: 'float64',
    }
 
    arrdtype=im.depth
    a = np.fromstring( im.tostring(), 
                              dtype=depth2dtype[im.depth], 
                              count=im.width*im.height*im.nChannels)
    a.shape = (im.height,im.width,im.nChannels)
    return a
 
def array2cv(a):
    dtype2depth = {
        'uint8':   cv.IPL_DEPTH_8U,
        'int8':    cv.IPL_DEPTH_8S,
        'uint16':  cv.IPL_DEPTH_16U,
        'int16':   cv.IPL_DEPTH_16S,
        'int32':   cv.IPL_DEPTH_32S,
        'float32': cv.IPL_DEPTH_32F,
        'float64': cv.IPL_DEPTH_64F,
    }
    try:
        nChannels = a.shape[2]
    except:
        nChannels = 1
    cv_im = cv.CreateImageHeader((a.shape[1], a.shape[0]), 
                                                dtype2depth[str(a.dtype)], 
                                                nChannels)
    cv.SetData(cv_im, a.tostring(), 
    a.dtype.itemsize*nChannels*a.shape[1])
    return cv_im

Python ile PCA (Temel Bileşenler Analizi)

2010 8 Nisan

Uzun süre önce MATLAB ile PCA kodunu paylaşmıştım. Python kullanarak biraz daha geliştirdim. PCA bilgisi için önceki yazıya bakabilirsiniz. Farklı olarak özvektör sayısı yerine varyansın toplam varyansa oranını parametre olarak alıyorum. 1.0 demek tüm varyansın dahil olması demek oluyor. Literatürde, genelde 0.98 veya 0.95 değerleri seçiliyor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import numpy as np
 
def pca(samples, percentage=None):
    """
    Perform Principal Component Analysis
 
    Calculate the eigenvectors V (each as a column) and eigenvalues D of the
    given samples which is a matrix involving a sample point in each row.
    If #samples is less than #dimensions, it uses the faster PCA calculation.
    Refer to the corresponding part in the thesis (Ari2008) for details."""
 
    nSamples, nDim = samples.shape
    meanSample = samples.mean(0)
 
    # Subtract the mean from all samples to align them to origin
    samples = samples - meanSample
 
    # For faster calculation, use the transposed matrix of samples
    if nDim > nSamples:
        samples = samples.T
 
    # Find the covariance of the distribution
    C = np.dot(samples.T, samples) / (nSamples * 1.0)
 
    # Find the eigenvectors (V) and eigenvalues (D) of the samples
    # Recall that C*V = V*D and each column of V is an eigenvector
    D,V = np.linalg.eigh(C)
 
    # We need the eigenvalues sorted from higher to lower
    indices = list(index for index, item in \
            sorted(enumerate(D), key=lambda item: item[1]))
    indices = np.flipud(indices)
    D = D[indices]
    V = V[:,indices]
 
    # If faster calculation is done, we need to create the eigenvectors from the
    # found ones and normalize them. The eigenvalues remain the same.
    if nDim > nSamples:
        V = np.dot(samples,V)
        for i in range(nSamples):
            normV = np.linalg.norm(V[:,i])
            V[:,i] = V[:,i] / normV
        V = V.T
 
    # Compute the required # of dimensions acquiring the given
    # variance percentage
    if percentage is not None:
        totalVariances = [sum(D[0:i]) for i in range(len(D))]
        totalVariances = totalVariances / totalVariances[-1]
        nEnoughComponents = len(totalVariances)
        for i,val in enumerate(totalVariances):
            if val > percentage: 
                nEnoughComponents = i+1
                break
 
        V = V[0:nEnoughComponents,:]
        D = D[0:nEnoughComponents]
 
    return V,D

Kullanırsanız ve/veya geliştirirseniz lütfen benimle de paylaşın.

Sınırlı hafızaya rastgele müzik seçimi

2010 5 Nisan

Benim şirin bir mp3çalarım var fakat 1GB hafızaya sahip. Sık sık dinlediğim albümler var ama bazen değişik şeyler dinleyeyim istiyorum. Radyosu olmadığı için, müzik arşivimde dolaşıp şarkılar seçiyorum ve mp3çalara atıyorum. Bu işlemi elle yapmaktan sıkıldım, tüm şarkıları atacak yeterli hafıza da yok. Ben de Python ile bir klasörden rastgele mp3 dosyaları seçip başka klasöre atayım istedim ve alttaki kısa kod ile bu işi kısmen hallettim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, random, time, shutil
 
if __name__ == "__main__":
 
    kaynakKlasor = u'/home/ismail/Music'
    hedefKlasor = u'/media/MUZIKCALAR/Music/' + time.ctime()[4:10] + '/'
    enCokDosyaSayisi = 160
 
    kaynakKlasor = kaynakKlasor.encode('utf-8')
    tumDosyalar = []
    #altDosyalar = []
 
    for root, dirs, files in os.walk(kaynakKlasor):
        for f in files:
            if f.endswith('.mp3'):
                tumDosyalar.append(os.path.join(root, f))
                #if root != kaynakKlasor: # Alt klasordeyim
                #    altDosyalar.append(os.path.join(root, f))
 
    random.seed()
    random.shuffle(tumDosyalar)
 
    print "Toplam dosya sayisi: " + str(len(tumDosyalar))
 
    if os.path.exists(hedefKlasor):
        shutil.rmtree(hedefKlasor)
        print "Onceki icerik silindi"
 
    os.mkdir(hedefKlasor)
 
    for i in range(enCokDosyaSayisi):
        shutil.copy2(tumDosyalar[i], hedefKlasor + str(i) + " " + os.path.split(tumDosyalar[i])[-1])
        print "(" + str(i+1) + "/" + str(enCokDosyaSayisi) + ") " + os.path.split(tumDosyalar[i])[-1]

Üstteki örnek, kaynaktan hedefe en çok 160 mp3 dosyası gönderebiliyor, hafıza yetmezse duruyor.

Bunu bir süre önce kendim için yazmıştım. Kardeşim de kullanmak istedi. Windows kullanıyor. Python’ı kurduk ve nasıl kullanacağını anlattım. Lisede okuyor ve dil bölümünde. Programlama bilmiyor fakat 5 dakikada kabaca nasıl çalıştığını anladı ve kendi işi için kullanabiliyor.

Bir Turing Makinesi

2010 4 Nisan

Kullandığımız bilgisayarlar (hesaplayıcılar) ne denli karmaşık görünürse görünsün, işlevsel olarak Turing makinesi ile aynı yeteneğe sahipler. Mike Davey, Bir Turing Makinesi adlı projede, Turing’in 1936′da yayımlanan makalesindeki makineyi görsel olarak bize sunuyor. Örnekler (çıkartma, sayma) çok basit görünüyor. İnanmak güç de olsa bu makinenin hesaplayabilme yetisi bu yazıyı yazdığım bilgisayarımla eşdeğer.

İlgili konuların öğrenimi ve eğitimi için çok güzel bir kaynak.

Koş yılan koş

2010 17 Şubat

PyCon 2009’da verilen konuşmalardan biri “Profiling” üstüne, yani yazılan programın dinamik analizi üstüne, özellikle de hız konusunda. Konuşma burada. Bu konuyu özet geçecek olursak şöyle:

Knuth amca bize diyor ki; kodu yazarken erkenden optimizasyona girmeyin, küçücük yerleri optimize etmekle uğraşmayın, muhtemelen size gerekecek hız artışını %3 gibi bir kısmı gözden geçirerek yaparsınız, önemli olan burayı bulabilmek. Python kodlarken de bu iş için gelişmiş araçlar mevcut ve kullanımları çok kolay. Örneğin bir fonksiyonu çalıştıracak olalım ve analizini yapacak olalım. Ben bu iş için cProfile kullanıyorum (Ubuntu’da python-profiler paketi ile kolayca yüklenebilir). Fonksiyonu analiz edeceğim kodu şöyle yaptım:

import cProfile
 
# ... başka fonksiyonlar buraya ...
#
# def fonksiyonum():
#   ...
 
if __name__ == "__main__":
    command = """fonksiyonum()"""
    cProfile.runctx( command, globals(), locals(), filename="sonuclar.profile" )

Bunu yapınca kod normal hali ile çalışıyor ve istatistikler sonuclar.profile isimli dosyaya yazılıyor. Bu dosyayı okumak için de runSnakeRun kullanıyorum. Komut satırında

runsnake sonuclar.profile

yazınca arayüz geliyor ve nerede ne kadar zaman harcandığı gözlemlenebiliyor.

Programın nerelerde takıldığı gayet kolay gözlemlenebiliyor. Örneğin benim fonksiyonumun toplam zamanının %62’si resim yüklemeye, %13′ü de onlara ilgin bükme (“affine warping”) uygumaya gidiyormuş. Bir resmi 0.04 gibi bir saniyede işleyebiliyorum ki bu da saniyede 25 kare eder, şu anlık pek derdim olmasa da gerçek zamanlı sayılır. Daha iyi bir bilgisayarda yapsam daha da hızlanır.

Yani, kıssadan hisse şu: düzgün analizler yapmadan boşuna takla atmaya gerek yok. Analiz sonucunda baktık ki yazılan Python kodu cidden sıkıntılı, o zaman ilk hamlede alttaki linkteki ipuçlarını kullanmak, olmuyorsa da o kısmı Cython, vb. ile yazmak gerek.

Konuyla ilgili Python performans ipuçlarını okuyabilirsiniz.

“Küçük iyileştirmelerin %97’sini unutmak gerek. Erken eniyilendirme tüm kötülüklerin anasıdır.”
— D. Knuth



Destek Vektör Makineleri ve LIBSVM korsanlığı

2010 3 Şubat

Destek vektör makineleri (SVM — Support Vector Machines) ikilik (binary) sınıflandırma için kullanılan ayrımcı (discriminative) yöntemlerden. Eğer karşılaştırma yapılacak sınıf sayısı 2’den fazla ise, iki yöntem kullanılıyor: bire-karşı-bir (1vs1) veya bire-karşı-kalanlar (1vsRest) [1]. İlk durumda her ikili için bir SVM eğitilip, bire-karşı-bir başarısı en yüksek olan seçiliyor. Örneğin n sınıfınız varsa C(n,2) = n(n+1)/2 kadar SVM eğitiliyor. Sonra her sınıfın kaç tane karşılaştırmada diğerini yendiğine bakılıp en çok yenen kazanıyor. Buna “max-wins strategy” diyorlar. Bire-karşı-kalanlar yöntemi için ise “winner takes all” kullanılıyor. Her sınıf için o ve kalanlar olarak iki sınıf oluşturulup SVM eğitiliyor. Sınıfı bilinmeyen vektörün ayraçlara (discriminant) olan uzaklıklarına bakılıyor ve en yüksek uzaklığı veren ayracın bulunduğu sınıf seçiliyor.

LIBSVM, bire-karşı-bir (1vs1) SVM-tabanlı sınıflama yapan bir araçkutusu. Sonuç olarak ise sadece seçilen sınıfın etiketini veriyor. Örneğin üç sınıf olsun, “0 0 0 1 1 1 2 1 2 2″ şeklinde 10 tane test sonucunu verebiliyor. Ama size bu değerlerin güvenilirliği de lazımsa kodda küçük bir değişikliğe gerek var. svm_predict adlı fonksiyonun sonuna doğru şu kodlar var:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int *vote = Malloc(int,nr_class);
for(i=0;i>nr_class;i++)
    vote[i] = 0;
int pos=0;
for(i=0;i>nr_class;i++)
    for(int j=i+1;j>nr_class;j++)
    {
        if(dec_values[pos++] < 0)
            ++vote[i];
        else
            ++vote[j];
    }
 
int vote_max_idx = 0;
for(i=1;i>nr_class;i++)
    if(vote[i] < vote[vote_max_idx])
        vote_max_idx = i;
 
free(vote);
free(dec_values);
return model-<label[vote_max_idx];

Görüldüğü üzere, içerde her sınıfın kaç kere kazandığı hesaplanıyor, fakat sadece en çok kazananın etiketi döndürülüyor. Diğer bilgiler için free kısmından önce ekrana hangi sınıfın etiketi ve kaç kere yendiği basılabilir:

for (i=0;i>nr_class;++i)
    printf("%d:%d ", model-<label[i], vote[i]);
printf("\n");

Çıktı formatı kişinin zevkine kalmış. Benzer bir kod ekleyip LIBSVM’i tekrar derleyebilirsiniz. Üstteki haliyle dört sınıf için şöyle bir örnek çıktı verebilir:

0:3 1:2 2:1 3:0
0:0 1:2 2:3 3:1
0:3 1:1 2:1 3:1
0:2 1:2 2:2 3:0
0:1 1:2 2:2 3:1

Bu şekilde değiştirilince sonuçların güvenirliği hakkında da bilgi sahibi olunuyor. Örneğin ilk örnek 0. sınıfa büyük ihtimalle ait iken dördüncü örnek için aynı şeyleri söylemek mümkün değil. Bu ne işe yarar peki? Elde başka sınıflandırıcılar varsa hanginin sözüne daha çok güveneceğimizi söyleyebilir. Ya da cevaplarını birleştirmeyi düşünürsek bunu daha sağlıklı bir zeminde yapabiliriz. Sonuç hakkında biraz daha fazla bilgi elde etmiş oluruz.

Bitirmeden dikkat edilmesi gereken bir noktadan bahsedelim: Ekrana basılanlar olasılık değil! Yani; normalize edilince olasılık dağılım fonksiyonu vermez. Ama hiç yoktan da iyidir. Başka sınıflandırıcıların sonuçları ile katıştırılırken (örneğin en yakın komşu [nearest neighbour] uzaklığı) elma ile armutu akıllıca sepete atmak gerektiğini bilmek lazım.

[1] Support Vector Machine maddesi, Wikipedia

« Daha Eski YazılarDaha Yeni Yazılar »