13 Kasım 2012 Salı

FANN Kütüphanesinin Kullanımı


FANN yani Fast Artificial Neural Network Library Bir Yapay Sinir Ağı (YSA) Kütüphanesi.
YSA nın ne olduğunu bildiğinizi varsayıp. Basitçe kullanımını anlatmak istiyorum.
1) YSA oluşturulur
2) YSA Eğitilir
3) YSA Çalıştırılır.
4) YSA yı Tekrar Kullanama

1) Öncelikle Bir YSA oluşturmamız lazım
Kullanabileceğimiz Fonksiyonlardan biri fann_create_standard

struct fann *FANN_API fann_create_standard( unsigned int num_layers, ... )

YSA nın kaç katmandan oluştuğunu yazıp - num_layers -
Sırayla Giriş, Gizli Katman - yada Katmanlar - Çıkış Katmanlarının kaç birimden oluştuğunu yazıyoruz

Mesela :

5 giriş 2 çıkışlı Tek ve 7 birimlik Gizli Katmanlı bir YSA oluşturmak için

struct fann *ann = fann_create_standard(3, 5, 7, 2);

5 giriş 2 çıkışlı , 7 ve 3 birimlik olmak üzere 2 Gizli Katmanlı bir YSA oluşturmak için

struct fann *ann = fann_create_standard(4, 5, 7,3, 2);

ann işaretçisi artık bizim oluşturduğumuz YSA yı gösteriyor


2) YSA Eğitimi için Kullanabileceğimiz Fonksiyonlardan biri fann_train_on_file

void FANN_API fann_train_on_file(
struct fann * ann, // fann_create_standard ile almıştıkconst char * filename, // Veri Dosyaunsigned int max_epochs,unsigned int epochs_between_reports,
float desired_error
)
ann : fann_create_standard ile aldığımız bizim YSA mızı gösteren işaretçi
filename : Eğitim için kullanacağımız Veri Dosyasının adı
max_epochs : Eğitimin çalışacağı maksimum adım Sayısı
epochs_between_reports : Kaç Adımda bir Rapor verilmesi isteniyor
desired_error : Eğitim sonunda arzulanan hata miktarı

Bu fonksiyonu çağrılınca İsmini belirttiğimiz Dosyadan veriler alınır ve Hata miktarı istenen değere yada maksimum adım sayısına ulaşana kadar YSA eğitime tabi tutulur. Arada belirttiğimiz adımda rapor verilir. Eğer istenen hata değerine ulaşılamazsa eğitim başarısız olmuş olur.

Veri Dosyasının yapısı : Veri Dosyası dediğimiz şey Giriş ve çıkış değerlerinin bulunduğu basit bir text dosyasıdır.
Örnek Sayısı(N) Giriş(K) Çıkış (J)
G11 G12 G13 ...G1K
Ç11 Ç12 Ç13...Ç1J
G21 G22 G23 ...G2K
Ç21 Ç22 Ç23...Ç2J
....
GN1 GN2 GN3 ...GNK
ÇN1 ÇN2 ÇN3...ÇNJ

Mesela 3 Giriş 1 Çıkışlık 2 Örnekli bir veri dosyası

2 3 1
1 1 1
0
1 0 1
1

Eğitim öncesi Aktivasyon Fonksiyonlarını Ayarlamak istiyorsanız

fann_set_activation_function_hidden(
struct fann * ann,
enum fann_activationfunc_enum activation_function
)

fann_set_activation_function_output(
struct fann * ann,
enum fann_activationfunc_enum activation_function
)

Mesela
fann_set_activation_function_hidden(ann, FANN_SIGMOID);
fann_set_activation_function_output(ann, FANN_SIGMOID_SYMMETRIC);
gibi

Kendi rapor Fonksiyonumuzuda tanımlayabiliriz
void fann_set_callback( struct fann * ann, fann_callback_type callback )
Mesela 

int FANN_API my_report(struct fann *ann, struct fann_train_data *train,
unsigned int max_epochs, unsigned int epochs_between_reports,
float desired_error, unsigned int epochs)
{ 
printf("Adım %8d. MSE: %.5f. Desired-MSE: %.5f\n", epochs, fann_get_MSE(ann),desired_error);return 0;
 }

fann_set_callback( ann, my_report );




Eğer Dinamik bir eğitme süreci gerekmiyorsa, Eğitim ve Parametre ayarlarını kolayca FannTool ile yapabilirsiz

3) Artık Eğitimini tamamladığımız YSA yı çalıştırabiliriz. YSA'nın çalışması demek Giriş değerleri verilerek sonuçta elde edilen çıkış değerlerini almak demektir
Bu iş için kullanacağımız fonksiyon fann_run

fann_type * FANN_API fann_run( struct fann * ann, fann_type * input )

Yani YSA'yı giriş değerlerini içeren bir dizinin adresini gönderiyoruz.

Mesela 3 giriş 2 çıkışlı bir YSA için

fann_type *sonuc;
fann_type input[3]={1,1,0}; // giriş değerleri
sonuc = fann_run(ann, input);
printf("Çıkış Değerelri %f %f \n", sonuc[0], sonuc[1] );

4) YSA yı her kullandığımızda yukardekileri tekrar tekrar yapmamıza gerek yok. YSA eğitildikten sonra Kaydedip. Kullanacağımız zaman bu kayıttan yeniden YSA yı oluşturabiliriz.
Kaydetmek için fann_save Kullanımı çok basit

int fann_save( struct fann * ann, const char *FileName )

FileName kısmına bir Dosya ismi girip kaydediyoruz. Kayıt Geri dönüş değerine göre 0 ise başarılı -1 ise başarısız.

Kaydettiğimiz YSA yı tekrar yüklemek için fann_create_from_file fonksiyonu kullanılır.

struct fann * fann_create_from_file(const char *FileName)

Fonksiyon Kaydedilmiş Dosya ismiyle çağrılır.

Eğer YSA ile işimiz bittiyse fann_destroy kullanılarak hafızada YSA için kullandığımız alanlar boşaltılır.

void fann_destroy( struct fann * ann )

Mesela : YSA için İlk üç adımı yaptık kaydediyoruz

fann_save(ann, "YSA.net");
fann_destroy(ann);

Tekrar çağırıyoruz

fann_create_from_file("YSA.net");

 5) Test Etmek : Eğittiğimiz YSA yı test etmek gerekmektedir Eğitim için kullandığımız verinin % 10 - 30 arasındaki bir miktarda veriyle YSA test edilir ve Hata faktörüne bakılır. Öncelikle aynı Eğitim verisi için kullandığımız dosya yapısında bir dosya hazırlanır ve fann_read_train_from_file fonksiyonuyla yüklenir. Bundan sonra tek yapacağınız fann_test_data fonksiyonunu çağırmak. işi bitincede fann_destroy_train ile hafızdaki yerleri boşaltmak

Mesela :
struct fann_train_data *dt;
dt=fann_read_train_from_file("test.dat");
ann=fann_create_from_file("aproje.net");
fann_reset_MSE(ann);
fann_test_data(ann,dt);
printf("\n Test Sonucu MSE : %f \n\n", fann_get_MSE(ann) );
fann_destroy_train(dt);

MSE (Mean Square Error) dediğimiz şey ortalama karesel hata yani bizim YSA mız yaptığı - Eğitim yada Test - işte istenenle hesaplanan değerler arasındaki - Hata - farklarının karelerinin ortalaması gibi birşey

void fann_reset_MSE(struct fann *ann)
MSE değerini sıfırlar

float FANN_API fann_get_MSE(struct fann *ann)
MSE değerini okur


6) Diğer Faydalı Fonksiyonlar

Eğitim Algoritmalarını ayarlayanlar

enum fann_train_enum fann_get_training_algorithm(struct fann *ann)
Kullanılan Eğitim metodunu okur

void fann_set_training_algorithm(struct fann *ann,enum fann_train_enum training_algorithm)
* Eğitim metadunu değiştirir.

Eğitim metodları ise  
FANN_TRAIN_INCREMENTAL, 
FANN_TRAIN_BATCH, 
FANN_TRAIN_RPROP, 
FANN_TRAIN_QUICKPROP 
olarak 4 çeşittir. Metodların detayı için kitaplara yada google müracaat edilsin

* Öğrenme hızını ayarlayanlar


float fann_get_learning_rate(struct fann *ann)
kullanılan öğrenme hızını döndürür.

void fann_set_learning_rate(struct fann *ann, float learning_rate)
Öğrenme hızını ayarlar. Öğrenme hızı için geçerli Normal Değer 0.7
Bu fonkisyonları FANN_TRAIN_RPROP metodu için kullanamıyoruz

* Aktivasyon Fonksiyonlarını Ayarlayanlar
Daha önce geçmişti
Gizli katman için
fann_set_activation_function_hidden(
struct fann * ann,
enum fann_activationfunc_enum activation_function
)
Çıkış katamanı için
fann_set_activation_function_output(
struct fann * ann,
enum fann_activationfunc_enum activation_function
)

kullanılır
Aktivasyon fonksiyonlarıda ;  
FANN_LINEAR,
FANN_THRESHOLD,
FANN_THRESHOLD_SYMMETRIC,
FANN_SIGMOID, 
FANN_SIGMOID_STEPWISE, 
FANN_SIGMOID_SYMMETRIC, 
FANN_GAUSSIAN, 
 FANN_GAUSSIAN_SYMMETRIC, 
FANN_ELLIOT, 
FANN_ELLIOT_SYMMETRIC, 
FANN_LINEAR_PIECE, 
FANN_LINEAR_PIECE_SYMMETRIC 

gibi pek çok çeşit var detayı için bakınız


Uygulama 

 Güneş lekeleri

Güneş lekeleri , Güneş'in yüzeyinde (ışık yuvarda), çevresine oranla daha düşük sıcaklığa sahip olan, ve mıknatıssal etkinliğin gözlemlendiği bölgelerdir. Her ne kadar 4000-4500 K sıcaklık ile son derece parlak olsalar da, çevrelerinin 5778 K'de olması, karanlık bölgeler olarak görüldüklerinden bu ismi alırlar.
Neyse işte insanların işi gücü yok bu lekeleri sayıp kaydını tutmuşlar.Biz de bu verileri kullanacağız.

Öncelikle Neural networks for financial time series prediction isimli dosyaya bir göz atın. O yazıda detaylarıyla anlatıldığı gibi Verileri aldığımız haliyle kullanmayız, ön işlemeden geçirmeliyiz. ( 3.4 Design of ANNs in finance kısmı )

Güneş lekelerinin (2006 - 1980) aralığında aylık ortamalarını raw.dat isimli dosyaya her satır 1 değer olarak kaydedildi. Öncelikle verileri YSA da kullanabilmek için - Kullandığınız aktivasyon fonksiyonuna göre - (0 , 1) yada ( -1 , 1 ) değerleri arasına çekiyoruz Normalizasyon. Bir ay sonraki ortalama güneş lekesi sayısını bulmak için önceki 24 ayın değerleri kullanılıyor. 2 adet gizli katman kullanılıyor yani YSA mızın yapısı girişten çıkışa doğru
24 -> 16 -> 7 -> 1

şeklinde oluyor. Peki Bu değerleri Nasıl belirliyoruz ? derseniz Net bir cevabı yok.* Genellikle Giriş ve çıkış düğüm sayısı bellidir. Saklı katman yada katmanlardaki düğüm sayıları YSA nın eğitim performansına göre seçilir.

Programımız
LoadRawData("raw.dat");
Normalize();
WriteTrainData(24,1,"sunspot.dat");
Train();
Test();
Run();

dan ibaret
Açıklamalarına gelince
  • LoadRawData : Ham verileri ismi verilen - Veri dosyasında Her satır 1 veri içeriyor- text dosyasından okuyup data dizisine aktarıyor
  • Normalize : Diziye atılmış verileri -0.8 ile 0.8 arsına çekerek Normalize ediyor
  • WriteTrainData : Normalize edilmiş verileri alıp FANN kütüphanesinin kullanabileceği veri dosyası olarak kaydediyor
  • Train : YSA yı Eğitiyor.
  • Test : test.dat dosyasındaki verileri kullanarak Eğitilmiş YSA'yı test edip sonuçta ulaşılan Hatadeğerini bildiriyor
  • Run : Verilerimizden Rasgele 10 adedini kullanarak YSA çalıştırılıyor ve YSA nın hesapladığı ve gerçek değeri birlikte gösteriyor
Şimdi gelelim benim yapmadığım fakat aslında yapılması gereken şeylerden bazılarına

1) Veri sayısı yeterince büyük olması lazım
2) Bu veriler Eğitim, Test ve Kontrol için 3 parçaya ayrılıp her işlem için kendine ayrılan veri kulanılması lazım.


Sonuçta yazılan projeyi indirmek için : SunSpot

* bakınız NN_FAQ Bu YSA için yazılmış Sıkça Sorulan Soruları İndirmenizi ve incelemenizde tavsiye ediyorum FAQ.

3 yorum:

  1. Bu yorum bir blog yöneticisi tarafından silindi.

    YanıtlaSil
  2. Hello, Can you please give an example of a working fann_set_callback? I couldn't make it work. Thanks.

    YanıtlaSil