Jaringan saraf sebagai basis data aktivasi

Agar AI pada jaringan saraf bersifat universal, Anda perlu memahami apa jaringan saraf tidak cukup untuk keserbagunaan. Untuk melakukan ini, cobalah untuk mengimplementasikan eksekusi penuh dari semua program di jaringan saraf.Ini akan memerlukan transisi bersyarat, kondisi, membaca dan menulis struktur data. Setelah itu, dimungkinkan untuk membuat jaringan saraf berorientasi objek. Artikel harus dibagi menjadi beberapa bagian.



Pertimbangkan berbagai jenis kluster saraf. Gugus sensorik dan efektor telah disebutkan.
Jika Ya Dan , itu diaktifkan hanya jika semua kondisi aktif - yaitu, sinyal telah tiba di semua sinapsis.
Atau- Dipicu jika setidaknya satu fitur telah diaktifkan. Jika kluster ini merupakan bagian dari rantai, maka rantai ke belakang adalah wajib - terhubung dengan kondisi Dan. Dengan kata lain, sebuah cluster diaktifkan hanya jika cluster sebelumnya dari rantai itu aktif dan salah satu kondisinya juga berfungsi. Dalam analogi dengan bahasa pemrograman, komunikasi rantai bertindak sebagai penunjuk instruksi di prosesor pusat - sinyal "Saya mengizinkan eksekusi kondisi yang tersisa dari kluster". Mari kita lihat beberapa kode.

kelas NC; // neurocluster
Tautan kelas {
	publik:
		NC & _dari;
		NC & _to;
		...
};
Links Kelas O; / * wadah untuk tautan keluar. Nyaman dilakukan berdasarkan dorongan :: intrusif
 - untuk menghemat memori dan meningkatkan kinerja * /
kelas LinksI; // juga didasarkan pada boost :: intrusive
struct NeuronA1 {
	qreal _activation = 0;
	static const qreal _threashold = 1;//          ,   .
	bool activated()const {
		return _activation >= _threshold;
	}
};
struct NeuronAT {
	qreal _activation = 0;
	qreal _threashold = 1;//  
	bool activated()const {
		return _activation >= _threshold;
	}
};
class NC {
	public:
		LinksO _next;
		LinksO _down;
		
		LinksI _prev;
		LinksI _up;
		
		NeuronA1 _nrnSumPrev;
		NeuronAT _nrnSumFromBottom;
		...
}
//  ,     _nrnSumPrev:
void NC::sendActivationToNext() {
	for(Link& link: _next) {
		link._to._nrnSumPrev._activation += 1;
	}
}
//      - and/or/not  :
bool NC::allowedToActivateByPrevChain()const {
	if(_prev.isEmpty())//    ,    ,    .
		return true;//    ,     .
	return _nrnSumPrev.activated();
	//         ,         .
	//      0    .
	// -     ,   -     ,    .
}

Perhatikan bahwa dalam _prev biasanya tidak ada tautan, atau satu tautan. Ini membuat pohon awalan dari rantai memori: di _next mungkin ada banyak tautan yang Anda suka, dan di _prev tidak boleh lebih dari satu. Hanya di pohon awalan biasa hanya ada satu huruf di setiap posisi, dan di jaringan saraf ada jumlah karakter yang sewenang-wenang. Berkat ini, bahkan menyimpan kamus Zalizniak tidak akan menghabiskan banyak memori.

Sekarang, demi kenyamanan, kami akan terus maju dan agar nanti kami tidak perlu menulis ulang kode seperti itu, kami akan segera menyingkirkan neuron dan aktivasi.
Jika cluster entah bagaimana menyimpan riwayat aktivasi, dan tidak mengirim aktivasi mereka ke orang lain, kita dapat menulis ulang fungsi ini seperti ini:

bool NC :: allowedToActivateByPrevChain () const {
	untuk (Tautan & tautan: _prev) {
		NC & nc = tautan._dari;
		if (! nc.wasActivated ()) // periksa siklus terakhir
			return false;
	}
	kembali benar;
}


Maka banyak masalah akan segera hilang:
1) Setelah beberapa siklus peramalan, tidak perlu mengembalikan keadaan jaringan saraf - cluster menyimpan dan menyimpan informasi tentang aktivasi mereka untuk siklus yang sesuai. Prediksi dapat dimasukkan lebih sering dan pada interval yang lebih lama ke depan.
2) Jaringan saraf tahan terhadap perubahan: jika koneksi ke sebuah cluster ditambahkan ke cluster dengan penundaan, maka Anda tidak perlu mengirim sinyal lagi untuk meringkas aktivasi pada cluster tujuan - Anda dapat segera memeriksa kondisi. Kode menjadi lebih fungsional-paradigmatik - minimal efek samping.
3) Memungkinkan penundaan sinyal sewenang-wenang: jika cache aktivasi dapat menyimpan data untuk siklus yang berbeda, maka Anda dapat memeriksa apakah gugus siklus N yang lalu aktif.
Untuk melakukan ini, tambahkan parameter variabel ke koneksi - waktu tunda:
Tautan kelas {
	...
	int _delay = 1;
};

dan kemudian fungsinya dimodifikasi seperti ini:
bool NC :: allowedToActivateByPrevChain () const {
	untuk (Tautan & tautan: _prev) {
		NC & nc = tautan._dari;
		if (! nc.wasActivated (tautan._delay)) // // periksa siklus N kembali
			return false;
	}
	kembali benar;
}


4) Kami menghilangkan gagap "rumput di halaman, kayu bakar di rumput, ...": sinyal dari siklus yang lebih baru tidak akan menimpa yang lama, dan sebaliknya.
5) Tidak ada bahaya bahwa aktivasi akan memudar (dengan sendirinya, dari waktu ke waktu) ketika masih diperlukan. Anda dapat memeriksa kondisi jauh di masa lalu.
6) Akhirnya, Anda tidak dapat menulis selusin artikel tentang topik "manajemen jaringan saraf melalui manajemen aktivitas ritmik", "metode visualisasi untuk sinyal kontrol electroencephalograms", "DSL khusus untuk mengelola electroencephalograms" dan membuang semua ini:



Sekarang tentang penerapan cache aktivasi:
1) ENS memberi kita tiga opsi untuk menempatkan cache aktivasi: aktivasi saat ini di neurocluster itu sendiri di neuronnya, aktivasi (dalam bentuk gelombang identifikasi?) Dalam hippocampus (di sini disimpan lebih lama daripada pada cluster itu sendiri), dan memori jangka panjang. Ternyata cache tiga tingkat, sama seperti prosesor modern.
2) Dalam model perangkat lunak, cache aktivasi sekilas berlokasi di setiap cluster.
3) Lebih khusus lagi, kita sudah memiliki ini dan itu: hippocampus dalam model ini menciptakan rantai memori, dan tautan ke semua kluster yang aktif dan tidak dihambat pada saat waktu dimasukkan ke dalam rantai memori. Dan setiap koneksi disimpan dalam satu cluster sebagai keluar dan yang lain sebagai masuk. Ini menunjukkan bahwa "cache" sebenarnya bukan cache, tetapi bahkan memori jangka panjang. Hanya jaringan saraf biologis yang tidak dapat mengekstraksi informasi dari memori jangka panjang secara langsung, hanya melalui aktivasi, dan ANNs dapat melakukannya. Ini adalah keuntungan AI daripada ENS, yang konyol untuk tidak digunakan - mengapa repot dengan aktivasi jika kita membutuhkan informasi semantik?

Jadi, untuk memeriksa apakah cluster aktif N langkah mundur, Anda dapat menggunakan pseudocode berikut (tidak dioptimalkan):

NC * Brain :: _ hippo; // klaster saat ini di mana peristiwa terkini ditambahkan
NC* NC::prevNC(int stepsBack)const {
	//       _prev
	//   link._delay,       .
	// , () 
}
bool NC::wasActivated(int stepsAgo)const {
	NC* timeStamp = _brain._hippo->prevNC(stepsAgo);
	if(!timeStamp)//       
		return false;
	return linkExists(timeStamp, this);
//      ,   boost    intrusive ,
//  ,    node    2  3 
}

Jika alih-alih aktivasi yang telah dilupakan, perlu untuk menjaga tidak hanya keberadaan koneksi, tetapi juga kekuatan aktivasi, maka bidang yang sesuai dapat ditambahkan ke koneksi itu sendiri. Bidang-bidang lain dapat digunakan untuk tujuan ini, tanpa memperkenalkan bidang tambahan: misalnya, "kepentingan", yang menjadi dasar jangka waktu komunikasi.
Tetapi bagaimana dengan cluster di mana aktivasi tidak mencapai ambang, tetapi masih berguna, misalnya, untuk pengenalan fuzzy, atau kesalahan perhitungan probabilitas, dll? Solusi yang tidak dioptimalkan adalah dengan menggunakan semua koneksi yang sama. Untuk melakukan ini, baik membuat wadah tambahan tautan di dalam kluster dan menambahkannya di sana (agar tidak bercampur dengan yang normal yang berfungsi), atau bahkan mengganggu segala sesuatu di tumpukan, dan memisahkannya hanya dengan paksa. Koneksi semacam itu perlu dihilangkan lebih cepat, karena urutannya lebih besar dari yang lain. Solusi yang lebih optimal: setiap cluster menyimpan cache aktivasi normal - misalnya, buffer lingkaran (cincin) dari 16 elemen, di mana setiap elemen menyimpan nomor siklus dan kekuatan aktivasi untuk siklus itu. Ada cache dua tingkat: untuk sinyal lemah, subthreshold, dan yang terbaru - buffer dalam cluster,jika tidak, komunikasi untuk memori jangka panjang. Jangan lupa bahwa dalam artikel ini hanya pseudocode dan algoritma naif yang ditampilkan, dan masalah pengoptimalan dapat mengambil lebih banyak ruang.

Source: https://habr.com/ru/post/id388797/


All Articles