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