Python Genetik Algoritma ile Resim Oluşturma

Python Genetik Algoritma ile Resim Oluşturma
Yayınlama: 09.11.2022
81
A+
A-

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

Python Genetik Algoritma kullanarak resim oluşturma adımlar:

  1. Üretilecek Hedef Resmi Oku
  2. Uygunluk fonksiyonunu hesapla
  3. Uygun parametrelerle pygad.GA sınıfının bir örneğini oluşturun
  4. PyGAD’ı çalıştırın
  5. Anlık sonuçları yazdırın
  6. Final sonucu yazdırın

1- Üretilecek Hedef Resmi Oku

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)

2- Uygunluk Fonsiyonunu Hesaplayalım

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

3- Uygun parametrelerle pygad.GA sınıfının bir örneğini oluşturun

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)

4-PyGAD’ı çalıştırın

Buraya kadar python genetik algoritmanın tüm adımlarını tamamladık. Aşağıdaki gibi çalıştırmak kaldı:

ga_instance.run()

5- Anlık Sonuçları Yazdırın

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))


6- Final sonucu Yazdırın

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()

Özet:

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.

python genetşk algoritma
Python Genetik Algoritma
image 11
Python genetik algoritma Resim Oluşturma

Python genetik algoritma çalışan kodlar:

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:

derinsurat
Python Genetik Algoritma 2. Örnek

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.

cozum 1000 2
Büyük Popülasyon 1000. Nesil

Burada ise ilk denememizin 1000. denemesini görüyoruz: Ortada nerdeyse hiç bir şey yok.

cozum 1000 1
Ufak Popülasyon 1000. Nesil

1500. nesilde ise fotoğraf daha benzer:

cozum 1500
Büyük Popülasyon 1500. Nesil
cozum 3000
Büyük Popülasyon 30000. Nesil

İ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ı.

cozum 4000
4000. Nesil

Algoritma çalışırken sistem kaynak tüketimi aşağıdaki şekildedir: Genel olarak işlemlerde işlemci kullanılmaktadır.

image 12
Genetik Algoritma Python Sistem Kullanımı

İşlemler uzun sürdüğünden ve ilerleme yavaşladığından program 20.000 nesil beklenmeden durdurulmuştur.

cozum 4500
4500. Nesil

Python genetik algoritma hakkında tüm soru ve görüşlerinizi yorum kısmına yazabilirsiniz.

Ruzgar.com Aklınıza ne eserse!
    Bir Yorum Yazın

    Ziyaretçi Yorumları - 2 Yorum
    1. Avatar of ruzgar ruzgar dedi ki:

      Genetik algoritma nöral ağların en güzel örneği.

    2. Avatar of Veysel Akbaş Veysel Akbaş dedi ki:

      Başarılı bir genetik algoritma örneği. Genetik algoritma nöral ağların en güzel uygulamalarından.