Rumah > pembangunan bahagian belakang > Tutorial Python > Mencipta algoritma genetik yang mudah dan cekap untuk rangkaian saraf dengan Python dan NumPy

Mencipta algoritma genetik yang mudah dan cekap untuk rangkaian saraf dengan Python dan NumPy

Susan Sarandon
Lepaskan: 2024-12-13 00:50:10
asal
791 orang telah melayarinya

Creating a simple and efficient genetic algorithm for a neural network with Python and NumPy

Ia adalah artikel pertama dari kursus tentang algoritma evolusi dalam ML.

Algoritma genetik diperlukan apabila anda mengetahui parameter rangkaian saraf anda, tetapi tidak tahu apakah output yang sepatutnya, contohnya, algoritma ini boleh digunakan untuk bermain Google Dinosaur atau Flappy Bird, kerana di sana anda tidak tahu apakah output yang sepatutnya, tetapi anda mempunyai keupayaan untuk mengisih pilihan yang paling berdaya maju, contohnya mengikut masa, ini dipanggil fungsi kecergasan.

Saya tidak pernah dapat mencari algoritma sedemikian yang berfungsi, mudah dan boleh digunakan, jadi saya mula mencipta Algoritma Genetik saya sendiri yang ringan, ringkas dan berfungsi dengan sempurna.

Matlamat saya bukan untuk menyeret keluar penulisan artikel ini, dan untuk menyeksa pembaca dengan panjangnya, jadi mari kita terus ke kod. Seperti yang telah disebutkan, kod itu mudah, jadi kebanyakannya tidak perlu diterangkan dalam keseluruhan esei.

Mula-mula kita perlu mengimport modul:

import numpy as np
import random
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Kemudian kami menambah Set Data dan jawapan kepadanya, tetapi bukan untuk menggunakan algoritma perambatan belakang, tetapi hanya untuk mengira bilangan jawapan yang betul. Kemudian anda boleh mengujinya pada varian lain, yang kini diulas

x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
y = np.array([[0],[1],[1], [0], [0], [0], [0], [1], [1]])

#x = np.array([[0, 1, 1], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [1, 1, 0], [0, 0, 0], [1, 1, 0], [1, 1, 1]])
#y = np.array([[1],[0], [0], [1], [0], [1], [0], [1], [1]])

#x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
#y = np.array([[1],[0],[1], [0], [1], [0], [1], [0], [1]])

Salin selepas log masuk
Salin selepas log masuk

Tambah senarai dan fungsi pengaktifan. Makna senarai akan menjadi jelas kemudian. Fungsi pengaktifan pertama ialah sigmoid, dan yang kedua ialah ambang.

listNet = []
NewNet = []
goodNET = []
GoodNet0 = []
GoodNet1 = []
GoodNet2 = []
GoodNet3 = []
GoodNet4 = []
GoodNet5 = []
GoodNet6 = []
good = 0
epoch = 0

good = 0
epoch = 0

def sigmoid(x):
    return 1/(1 + np.exp(-x)) 
def finfunc(x):
    if x[0] >= 0.5:
        x[0] = 1
        return x[0]

    else:
        x[0] = 0
        return x[0]
Salin selepas log masuk
Salin selepas log masuk

Seterusnya, kita perlu mencipta dua kelas, yang pertama diperlukan untuk mencipta populasi awal, dan yang kedua untuk semua yang berikutnya, sejak kali pertama kita perlu membuat pemberat secara rawak, dan kemudian hanya silang dan mengubah mereka. Fungsi init() digunakan untuk mencipta atau menambah pemberat, predict() diperlukan untuk algoritma itu sendiri dan untuk mengira pilihan terbaik, dan fungsi Fredict() berbeza kerana ia mengembalikan jawapan dan fungsi kecergasan untuk memaparkan nombor pada skrin dan lihat peringkat latihan. Pada lapisan output, fungsi sigmoid mula-mula digunakan untuk mendekatkan jawapan kepada salah satu pilihan, dan hanya kemudian fungsi ambang.

class Network():
    def __init__(self):
        self.H1 = np.random.randn(3, 6)
        self.O1 = np.random.randn(6, 1)

    def predict(self, x, y):
        t1 = x @ self.H1
        t1 = sigmoid(t1)
        t2 = t1 @ self.O1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1

    def Fpredict(self, x, y):
        t1 = x @ self.H1
        t1 = sigmoid(t1)
        t2 = t1 @ self.O1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
        return t2, good
class Network1():
    def __init__(self, H1, O1):
        self.H1 = H1
        self.O1 = O1


    def predict(self, x, y):
        t1 = x @ self.H1
        t1 = sigmoid(t1)
        t2 = t1 @ self.O1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
    def Fpredict(self, x, y):
        t1 = x @ self.H1
        t1 = sigmoid(t1)
        t2 = t1 @ self.O1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
        return t2, good
Salin selepas log masuk

Kami mengeluarkan jawapan pertama dan pembolehubah yang baik, iaitu fungsi kecergasan di sini, kemudian kami menetapkannya semula untuk rangkaian saraf seterusnya, cetakan 'wait0' (anda boleh menulis apa sahaja yang anda mahu di sini) adalah perlu supaya tidak menjadi keliru tentang di mana jawapan rangkaian saraf yang berbeza bermula.

import numpy as np
import random
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Kitaran pertama berlalu, di sini dan dalam semua kitaran berikutnya kami hanya memberikan enam soalan untuk menyemak sejauh mana ia akan menangani tugasan, yang belum dapat dipenuhi, iaitu, kami menyemaknya untuk menjejalkan, dan ini kadang-kadang berlaku. Dan sekarang mari kita pergi ke lebih terperinci: bergantung pada berapa banyak jawapan yang dijawab dengan betul, kami menetapkannya kepada salah satu kelas, jika bilangan besar betul, maka kami mesti menyokong rangkaian saraf sedemikian dan meningkatkan bilangannya, supaya dengan mutasi seterusnya akan ada yang lebih bijak, untuk memahami perkara ini, anda boleh bayangkan bahawa untuk 100 orang terdapat satu genius, tetapi ia tidak mencukupi untuk semua orang, dan ini bermakna geniusnya akan hilang pada masa akan datang generasi, ini bermakna bahawa sama ada rangkaian saraf akan belajar dengan sangat perlahan, atau tidak akan wujud sama sekali, untuk mengelakkan ini, kami meningkatkan bilangan rangkaian saraf dengan sejumlah besar jawapan yang betul dalam kitaran. Pada penghujungnya, kami mengosongkan senarai listNet utama, menetapkan nilai baharu senarai GoodNet mengikut urutan dari yang terbaik kepada yang paling teruk, membuat potongan untuk 100 individu terbaik, untuk mutasi seterusnya.

x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
y = np.array([[0],[1],[1], [0], [0], [0], [0], [1], [1]])

#x = np.array([[0, 1, 1], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [1, 1, 0], [0, 0, 0], [1, 1, 0], [1, 1, 1]])
#y = np.array([[1],[0], [0], [1], [0], [1], [0], [1], [1]])

#x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
#y = np.array([[1],[0],[1], [0], [1], [0], [1], [0], [1]])

Salin selepas log masuk
Salin selepas log masuk

Persilangan dan mutasi itu sendiri: kami mengambil satu bahagian daripada induk pertama, yang kedua dari yang kedua, bermutasi dan kami mendapat anak dalam senarai NewNet, jadi 1000 kali.

listNet = []
NewNet = []
goodNET = []
GoodNet0 = []
GoodNet1 = []
GoodNet2 = []
GoodNet3 = []
GoodNet4 = []
GoodNet5 = []
GoodNet6 = []
good = 0
epoch = 0

good = 0
epoch = 0

def sigmoid(x):
    return 1/(1 + np.exp(-x)) 
def finfunc(x):
    if x[0] >= 0.5:
        x[0] = 1
        return x[0]

    else:
        x[0] = 0
        return x[0]
Salin selepas log masuk
Salin selepas log masuk

Bermula dari bahagian kod sebelumnya, kami menggunakan Network1(), kerana kami kini menyilang dan bermutasi, tetapi tidak mencipta secara rawak. Jadi kita perlu mengulangi 1000 kali (ini adalah hiperparameter, jadi anda boleh memilih sendiri bilangan zaman, 15 sudah cukup untuk saya), kami menunjukkan jawapan pada zaman pertama dan yang ke-1000 adalah versi terakhir (jika anda ada, contohnya, 20, kemudian nyatakan 20). Di sini kod diulang, jadi saya tidak akan menerangkannya, semuanya sangat jelas di sana.

import numpy as np
import random
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Itu sahaja, corak yang perlu dicari oleh rangkaian saraf, ini adalah nombor (pertama, kedua, ketiga) versi akhir bergantung dan mengabaikan yang lain. Anda boleh lakukan, sebagai contoh, operasi logik (XOR, NOT, DAN ...), hanya dalam kes ini dalam kelas rangkaian menukar data input sebanyak dua, saya juga mengikuti peraturan neuron dalam lapisan tersembunyi adalah sama dengan input data didarab dengan dua, ia berfungsi, tetapi anda boleh mencuba pilihan anda, ia juga sangat penting untuk menyediakan rangkaian saraf dengan bilangan yang sama beberapa jawapan dan jawapan lain, supaya bilangan jawapan yang betul, contohnya "a", akan sama dengan "b", jika tidak, rangkaian saraf akan menjawab semua jawapan dengan cara yang sama, iaitu, jika terdapat lebih banyak a, maka ia akan menjawab a kepada segala-galanya dan tiada apa yang akan datang daripadanya, juga memberikan pilihan yang sama sekali berbeza dalam sampel latihan supaya ia memahami corak, sebagai contoh, jika anda membuat blok XOR, maka anda mesti menambah pilihan dengan dua pilihan, tetapi dalam kes operasi logik, anda perlu memberikan semua pilihan, kerana terdapat terlalu sedikit daripada mereka dan ia tidak akan faham apa sahaja.
Itu sahaja!!! Artikel seterusnya (mesti baca!): Tidak lama lagi…
Kod: https://github.com/LanskoyKirill/GenNumPy.git

Tapak saya (ia mungkin sedang menjalani kerja semula): selfrobotics.space

Atas ialah kandungan terperinci Mencipta algoritma genetik yang mudah dan cekap untuk rangkaian saraf dengan Python dan NumPy. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan