Python genetik algoritma konusunda oldukça başarılı bir dildir. Güzel bir örnekle sizlere açıklamak isteriz. Genetik algoritmanın nasıl çalıştığını buradaki yazımızda anlatmıştık. Klasik iterasyon yaklaşımıyla çözülmesi yıllar alacak problemlerin Genler, Mutasyonlar ve Crossover’lar ile yani Genetik Algoritma ile daha kısa sürede çözülebilmektedir.
Burda Makine Öğrenmesi Üzerine çalışan Ahmed Fawzy’ Gad’nin oluşturduğu Pygad kütüphanesi üzerinden anlatım yapılacaktır: Kendisine buraya tıklayarak ulaşabilirsiniz: pygad kütüphanesini aşağıdaki kod ile yükleyebilirsiniz: Not Linux ve Mac içinn !pip3 kodunu kullanın.
!pip install pygad
Burada ise Yine aynı kişi tarafından oluşturulan GARI (Genetic Algorithm for Reproducing Images) yani genetik algoritma kullanılarak resimlerin tekrar oluşturulması anlatılacaktır.
Bunun yanında kullanacağımız kütüphaneleri çağıralım:
import numpy
import imageio
import pygad
import matplotlib.pyplot
import functools
import operator
Burada ruzgar.jpg isimli bir fotoğrafı alıp 250piksel genişliğine kadar küçültüyoruz. Aksi halde işlem çok uzun sürecektir. Bu resim dosyasını da python dosyasının çalıştığı yere taşıyoruz.
def fotodan_kromozoma(img_arr):
return numpy.reshape(a=img_arr, newshape=(functools.reduce(operator.mul, img_arr.shape)))
def kromozomdan_fotoya(vector, shape):
if len(vector) != functools.reduce(operator.mul, shape):
raise ValueError("A vector of length {vector_length} into an array of shape {shape}.".format(vector_length=len(vector), shape=shape))
return numpy.reshape(a=vector, newshape=shape)
hedef_foto = imageio.v2.imread('ruzgar.jpg')
hedef_foto = numpy.asarray(hedef_foto/255, dtype=numpy.float64)
hedef_kromozom = fotodan_kromozoma(hedef_foto)
GARI ile birlikte uygunluk fonksiyonunu yazalım ve olutşturulan çözümleri 500 iterasyonda 1 yazdıralım::
def fitness_fun(solution, solution_idx):
fitness = numpy.sum(numpy.abs(hedef_kromozom-solution))
fitness = numpy.sum(hedef_kromozom) - fitness
return fitness
Burada işi python genetik algoitmanın kullanımı için GARI ve Paygad’a emanet edelim ve daha iyi sonuçlar için parametrelerini değiştirebileceğimiz ayar kodlarını aşağıdaki gibi yükleyelim:
ga_instance = pygad.GA(num_generations=20000,
num_parents_mating=10,
fitness_func=fitness_fun,
sol_per_pop=20,
num_genes=hedef_foto.size,
init_range_low=0.0,
init_range_high=1.0,
mutation_percent_genes=0.01,
mutation_type="random",
mutation_by_replacement=True,
random_mutation_min_val=0.0,
random_mutation_max_val=1.0,
on_generation=callback)
Buraya kadar python genetik algoritmanın tüm adımlarını tamamladık. Aşağıdaki gibi çalıştırmak kaldı:
ga_instance.run()
Kodu burada bırakabilirsiniz. Seçtiniz resim boyutuna göre 1dk’da veya çok daha uzun sürede sistem python genetik algoritma kullanarak sonuç üretecektir. Kod satırındaki * işaretinden işlemin devam edip etmediğini görebilirsiniz.
Sistemin çalışıp çalışmadığını görmek için anlık sonuçları yazdıralım.
def callback(ga_instance):
print("Nesil = {gen}".format(gen=ga_instance.generations_completed))
print("Uygunluk = {fitness}".format(fitness=ga_instance.best_solution()[1]))
if ga_instance.generations_completed % 500 == 0:
matplotlib.pyplot.imsave('cozum_'+str(ga_instance.generations_completed)+'.png', kromozomdan_fotoya(ga_instance.best_solution()[0], hedef_foto.shape))
Belirlediğimiz sayıda iterasyon sonucunda pyhon genetik algoritma ile bulunan en iyi sonucu ve uygunluk fonksiyonunun nasıl değiştiğini gösterir:
ga_instance.plot_result()
solution, solution_fitness, solution_idx = ga_instance.best_solution()
print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
print("Index of the best solution : {solution_idx}".format(solution_idx=solution_idx))
if ga_instance.best_solution_generation != -1:
print("Best fitness value reached after {best_solution_generation} generations.".format(best_solution_generation=ga_instance.best_solution_generation))
result = vektoru_resim_yap(solution, hedef_foto.shape)
matplotlib.pyplot.imshow(result)
matplotlib.pyplot.title("PyGAD & GARI Resimleri Tekrar Olustur")
matplotlib.pyplot.show()
Python genetik algoritmada Nesil ile kaçıncı nesil çocukların oluştuğunu gösterilmektedir. Bu belirlediğimiz şekilde, rastgelelik, mutasyon ve gen değişimi içerir. Seçtiğiniz resmin karmaşıklığı ve boyutuna göre iterasyon sayısını, her nesildeki populasyon sayısını toplam kaç iterasyonda bulacağımızı değiştirebiliriz.
Bu örneğimizde pyhton genetik algoritma kullanarak 20.000 nesil oluşturmuş olduk. Her nesil 20 kişiden oluşuyordu. Her bir iterasyonda hedef resme yaklaşmaya çalıştık. Hedef resmin geninden mevcut resmin genini vektörel olarak çıkardığımızdaysa uygunluk fonksiyonunu bulduk.
Python genetik algoritmada uygunluk fonksiyonu pozitif de olabilir nekatif de olabilir. Aşağıdaki örnekte 20 kişilik nesillerden 10’u çiftleşmiştir. Yüzde 1 mutasyon oluşmuştur. 20.000’inci nesilde bulunan en iyi uygunluk değeri 2302’dir. 19997. doğumda görülmüştür.
import numpy
import imageio
import pygad
import matplotlib.pyplot
import functools
import operator
def fotodan_kromozoma(img_arr):
return numpy.reshape(a=img_arr, newshape=(functools.reduce(operator.mul, img_arr.shape)))
def kromozomdan_fotoya(vector, shape):
if len(vector) != functools.reduce(operator.mul, shape):
raise ValueError("A vector of length {vector_length} into an array of shape {shape}.".format(vector_length=len(vector), shape=shape))
return numpy.reshape(a=vector, newshape=shape)
hedef_foto = imageio.v2.imread('fruit.jpg')
hedef_foto = numpy.asarray(hedef_foto/255, dtype=numpy.float64)
hedef_kromozom = fotodan_kromozoma(hedef_foto)
def fitness_fun(solution, solution_idx):
fitness = numpy.sum(numpy.abs(hedef_kromozom-solution))
# Negating the fitness value to make it increasing rather than decreasing.
fitness = numpy.sum(hedef_kromozom) - fitness
return fitness
def callback(ga_instance):
print("Nesil = {gen}".format(gen=ga_instance.generations_completed))
print("Uygunluk = {fitness}".format(fitness=ga_instance.best_solution()[1]))
if ga_instance.generations_completed % 500 == 0:
matplotlib.pyplot.imsave('cozum_'+str(ga_instance.generations_completed)+'.png', kromozomdan_fotoya(ga_instance.best_solution()[0], hedef_foto.shape))
ga_instance = pygad.GA(num_generations=20000,
num_parents_mating=10,
fitness_func=fitness_fun,
sol_per_pop=20,
num_genes=hedef_foto.size,
init_range_low=0.0,
init_range_high=1.0,
mutation_percent_genes=0.01,
mutation_type="random",
mutation_by_replacement=True,
random_mutation_min_val=0.0,
random_mutation_max_val=1.0,
on_generation=callback)
ga_instance.run()
# After the generations complete, some plots are showed that summarize the how the outputs/fitenss values evolve over generations.
ga_instance.plot_result()
# Returning the details of the best solution.
solution, solution_fitness, solution_idx = ga_instance.best_solution()
print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
print("Index of the best solution : {solution_idx}".format(solution_idx=solution_idx))
if ga_instance.best_solution_generation != -1:
print("Best fitness value reached after {best_solution_generation} generations.".format(best_solution_generation=ga_instance.best_solution_generation))
result = kromozomdan_fotoya(solution, hedef_foto.shape)
matplotlib.pyplot.imshow(result)
matplotlib.pyplot.title("PyGAD & GARI Resimleri Tekrar Olustur")
matplotlib.pyplot.show()
Genetik ayarları değiştirilerek yapılan 2. bir örnek:
İşlemin daha hızlı gerçkekleşmesi için resim boyutunu oldukça küçülterek başka bir deneme yapalım:
Bir önceki örnekte; num_parents_mating=60, 1 nesilde eşleşecek ebeveyn sayısını 10’dan 60’a çıkaralım. Aynı şekilde, sol_per_pop=100 ile nesildeki ebeveyn sayısını da 20’dan 100’e çıkaralım. Genlerdeki mutasyon oranını da yüzde 1’den mutation_percent_genes=0.1 ile yüzde 10’a çıkaralım.
Kullandığımız ayar kısmı aşağıdaki gibi olacak:
num_parents_mating=60,
fitness_func=fitness_fun,
sol_per_pop=100,
num_genes=hedef_foto.size,
init_range_low=0.0,
init_range_high=1.0,
mutation_percent_genes=0.1,
mutation_type="random",
mutation_by_replacement=True,
random_mutation_min_val=0.0,
random_mutation_max_val=1.0,
on_generation=callback)
Bu durumda işlem süresi oldukça artmaktadır fakat ilk 500. nesildeki uygunluk bile -1112’den 446’ya çıkmıştır. 1000. denemede ise uygunluk 1285 olmuş ve artık resim belirmiştir.
Bir önceki denemedeki 1000. nesilleri kıyaslarsak: Aşağıdaki fotoğrafta 2. denememizin 1000. neslini görüyoruz. Popülasyon ve mutasyonumuz çok büyük.
Burada ise ilk denememizin 1000. denemesini görüyoruz: Ortada nerdeyse hiç bir şey yok.
1500. nesilde ise fotoğraf daha benzer:
İlerleme 3000. nesilde yavaşlamıştır. 2200’lerde takılı kalmıştır. 4000’lere geldiğimizde ise sonuç 2390’da uzun süre takılı kaldı: 4200’lü nesillerde sürekli 2414 yakınlığında takıldı.
Algoritma çalışırken sistem kaynak tüketimi aşağıdaki şekildedir: Genel olarak işlemlerde işlemci kullanılmaktadır.
İşlemler uzun sürdüğünden ve ilerleme yavaşladığından program 20.000 nesil beklenmeden durdurulmuştur.
Python genetik algoritma hakkında tüm soru ve görüşlerinizi yorum kısmına yazabilirsiniz.
Genetik algoritma nöral ağların en güzel örneği.
Başarılı bir genetik algoritma örneği. Genetik algoritma nöral ağların en güzel uygulamalarından.