Thursday, May 21, 2020

AI pentru oameni - retele neuronale

Bun, sa incercam ceva impreuna. Probabil ati auzit de Inteligenta Artificiala (AI - Artificial Intelligence). Asta e un domeniu mare dar in ultimii ani vedem tot felul de nebunii: masini care se conduc singure, algoritmi care bat experti in Go, etc.
Majoritatea chestiilor care apar pe la televizor se folosesc de asa numitele retele neuronale: niste algoritmi care sunt inspirati de neuronii din creierul nostru. Uuuuuuu, interesant, Terminator (Sky net) ne va manca pe toti! Vreau sa va arat ca nu e chiar asa, si ca algoritmii astia pot fi intelesi si nu fac mare lucru.
Daca vrei sa-i intelegi complet e suficient sa stii ceva matematica de liceu (derivata), cam cum spunea Ada Milea: “Minunea tehnicii moderne e mecanica / de clasa a 9-a”. Ai putea spune ca minunea e acum matematica de clasa a 11-a. Dar pentru ce va explic eu nu e nevoie nici de asta.
Ce fac retelele neuronale? Clasifica. Iti spun atunci cand le arati o poza daca e catel sau masina (2 clase: caini si masini). Atat! Le dai ceva si ele iti spun in ce clasa se afla. Sper ca m-ati putut urmari pana aici. Ca sa poata face asta ele trebuie sa invete (magie!!!). Invata vazand exemple. Le arati o poza cu un catel si le ceri sa iti spuna ce e. Reteaua zice masina, ii dai peste degete si o iei de la capat pana zice bine si ii arati milioane de catei si milioane de masini si ii tot dai peste mana pana reuseste sa zica cum trebuie (in majoritatea cazurilor). Si i le tot arati asa pana te plictisesti. Bun.
Dupa ce a invatat, ii poti arata noi poze (pe care nu le-a mai vazut pana atunci) si reteaua neuronala raspunde daca e caine sau masina. Atat. Retineti asta!
O poza e ceva complicat, de exemplu o poza de 3 mega pixeli (stiti ca era nebunia cati mega pixeli are aparatul tau foto sau telefonul) are 3 milioane de pixeli. Imi este mai greu sa explic mai departe pornind de la exemplu cu poza pentru ca ce urmeaza sa va explic tine de coordonate. Stiti, chestia aia Ox, Oy, alea doua sageti perpendiculare una pe alta (vezi imaginea de mai jos).

Sper ca nu ati renuntat. Problema cu o imagine de 3 mega pixeli e ca ar trebui sa va explic ceva in 3 milioane de dimensiuni si mintea mea se opreste la 3 dimensiuni. Norocul nostru e ca matematica functioneaza exact la fel, fie ca sunt 2, 3 sau 3 milioane de dimensiuni. Asa ca ramanem in 2 dimensiuni si va las tema pentru acasa sa va ganditi la mai multe :).
Schimbam problema:
Avem puncte in 2 dimensiuni, unele sunt albastre si altele rosii si le-am desenat mai jos (sunt alese asa intentionat)




















Punctele albastre sunt cateii si cele rosii sunt masinile. Un punct de-al nostru are doua chestii care il caracterizeaza: pozitia (pixelii din imagine) si culoarea (e catel sau masina). Deci punctele au niste chestii care le caracterizeaza (pozitia lor in spatiu sau in cazul pozelor cu caini si masini multe puncte colorate) si inca o proprietate care e ceea ce sunt (culoarea rosu sau albastru sau in cazul unei poze daca e imaginea unui caine sau a unei masini).
Noi avem initial un set de puncte rosii si albastre si pozitia lor (coordonatele x si y, pentru cei care isi mai amintesc ceva din scoala generala). Vrem ca pe viitor, dupa ce reteaua neuronala invata, sa ii zicem doar coordonate si reteaua neuronala sa ne spuna daca sunt puncte rosii sau albastre (exact ca in exemplul cu caini si masini). Repet, dupa ce invata reteaua ne va spune despre niste coordonate (o imagine) daca reprezinta un punct rosu sau albastru (caine sau masina) fara sa ii spunem ce e, cat timp invata ii si spunem ce e.


Cum ar putea invata algoritmul nostru? Ideea e sa gasim o linie care separa punctele in puncte rosii si in puncte albastre. Daca gasim linia asta, am putea zice mai tarziu cand vine un punct, pe care nu l-am mai vazut vreodata, ca daca punctul e situat deasupra liniei banuim ca e albastru iar daca e sub linie banuim ca e rosu.
Pentru noi e usor sa gasim linia asta:   



Calculatorul e mai tantalau. El o ia cam pe incercatelea si incepe sa deseneze linii (nu le chiar deseneaza, se foloseaste de ecuatia dreptei: clasa a 7-a).
Sa zicem ca face o linie ca in poza de mai jos, cu o panta mica. Linia asta o va da in bara, punctele de deasupra ei sunt multe rosii si nu toate albastre cum am vrea sa fie. Deci are o eroare mare.



Dupa aceea incearca una ca cea de mai jos, cu o panta mare. Si iarasi ii da prost. Acum sunt toate sub linie si ar zice ca si cele albastre sunt rosii, daca ar trebui sa ghiceasca mai tarziu.



Daca am calcula cumva eroarea (sa zicem cate puncte am nimerit si cate am gresit) am avea ceva ca mai jos.



Noi vrem eroare mica, adica unde panta e numa’ buna. In cazul in care calculatorul tot incearca pante ar obtine cam asa ceva:


 Pe masura ce te apropii de panta ideala eroarea scade iar cand te indepartezi de ea eroarea creste iarasi. Daca ai face asta la infinit ai obtine o functie din aia de gradul doi (he, he, vremuri bune). Daca vrei sa afli minimul functiei trebuie sa afli unde tangenta (derivata) are panta zero - clasa a 11-a, dar nu intru in detalii.
 Ideea e urmatoarea: calculatorul, calculand derivate pana ii iasa pe ochi, gaseste acel minim care ii spune panta, ii spune cum arata dreapta care il ajuta sa spuna daca punctele sunt albastre sau rosii. Asta e tot. Asta e toata magia. Restul sunt doar trucuri inventate ca sa ajute algoritmul sa distinga mai usor in spatii cu milioane de dimensiuni. Un truc ar fi sa ai zeci de mii de astfel de linii care fiecare clasifica ceva (e ochi? e roata?). Si daca ai uni zeci de mii de astfel de clasificatoare intr-o retea ar semana cu neuronii din creier uniti de sinapse (retea neuronala). Ai avea multe clasificatoare care atunci cand primesc o imagine iti zic: in imagine sunt doua urechi, doi ochi, mustati … daca are urechi, ochi si mustati e catel.
Toate chestiile astea sunt cunoscute de mult timp (au aparut niste shmecherii noi mai recent, dar ideea de baza asta e). Ce s-a schimbat e ca avem calculatoare puternice si o multime de oameni care isi incarca pozele pe Facebook. Adica avem calculatoare sa calculeze derivate si multe poze pe care sa le folosim sa antrenam aceste programe.
Care e problema cu ele? Pai nu stiu sa faca mare lucru. Stiu sa faca doar ce le antrenezi sa faca: sa recunoasca caini si masini in poze, sa joace Go, etc., dar noi nu stim sa construim retele neuronale care sa rezolve probleme generale cum le poate rezolva omul. In domeniul asta suntem foarte la inceput si nimeni nu stie cand vom ajunge sa reusim ceva. Da, retelele astea fac niste trucuri interesante dar nu vor fi in stare sa ne conduca curand.


Va puteti opri aici!

Vreti un pic mai mult (va promit ca nu devine mai complicat)? Atunci continuati.

Ne intoarcem la problema cu masini si catei. Sa zicem ca am o poza cu semnul de la Volkswagen in ea. E foarte probabil sa fie o masina in poza. Dar, dupa cum ziceam, clasificatoarele mele sunt cam nataflete. Sigla Volkswagen e ceva complicat pentru ele. Dar din ce e formata sigla? Un cerc, un V si un W. W-ul e format din doi de V. Fiecare V e format din doua linii oblice. La fel si cercul e format din patru sferturi de cerc. Daca as putea cumva sa am ceva care sa imi spuna ca am patru sferturi de cerc care formeaza un cerc si o groaza de linii oblice, in interiorul cercului, care formeaza un V si un W as putea zice ca am gasit sigla de la Volkswagen. 

Acum plecam invers. 

Avem aceste clasificatoare care imi spun ca un punct e rosu sau albastru. In cazul unei imagini ele pot relativ usor sa-mi spuna daca am o liniuta verticala ( | ) sau o liniuta oblica (\  /) sau am un sfert de cerc, etc. Va rog sa ma credeti pe cuvant pentru ca matematica e putin mai complicata ca sa explic cum face. Daca desenez clasificatoarele astea ca niste cercuri si le fac sa isi trimita rezultatul mai departe la alte clasificatoare (ca in maginea de mai jos, nu am desenat toate sagetile), pot ajunge in urmatoarea situatie:

 


Sa zicem ca am 4 cerculete (clasificatoare) care fiecare identifica daca in poza am sau nu am un sfert de cerc. Daca cele 4 trimit toate un DA la alt cerculet acesta poate decide ca in poza am un cerc si el va trimite rezultatul mai departe (ca in poza e un cerc). Cele care identifica liniute oblice imi zic ca au gasit un V in poza si inca 2 de V. Alt cerc care primeste informatia asta zice ca atatea V-uri pot insemna V si W (dublu V) si ca se afla intr-un cerc deci am semnul de Volkswagen, si tot asa, deci e o masina. Asa ajunge sa identifice roti, faruri, eleroane, ochi, urechi, labute si tot asa pana poate decide daca in poza e o masina sau un catel.

Va puteti gandi la furnici. O furnica singura pare cam prostuta, dar multe furnici impreuna fac lucruri uimitoare. Cam asa si aici. Un clasificator (neuron) de unu singur nu face multe, dar multe clasificatoare care comunica ne uimesc prin ceea ce pot realiza.

Friday, October 15, 2010

Installing SCoPE and M3P plugin (XML I/O plug-in) for M3Explorer on Ubuntu 10.10

You can download everything you need (except systemc 2.20) from http://www.teisa.unican.es/gim/en/scope/scope_web/scope_download.php download SCoPE 1.1.5 and XML I/O plug-in(Compatible with SCoPE 1.1.5) 1.0.5

You can obtain SystemC 2.2.0 from http://www.systemc.org/downloads/standards/
Extract everything in your home folder. You should have the following directories:

systemc-2.2.0
SCoPE-v1.1.5
m3p-v1.0.5
Installing the required libraries
* GNU C/C++ toolchain: gcc/g++ (v4.x), make
* Bison and flex tools (as riquired by SCoPE)
* zlib-devel library

Installing SystemC

create a file called systemc.patch and add the following code:
diff -Nurd systemc-2.2.0/Makefile.am systemc-2.2.0-ubuntu9.04/Makefile.am
--- systemc-2.2.0/Makefile.am 2006-12-15 21:31:28.000000000 +0100
+++ systemc-2.2.0-ubuntu9.04/Makefile.am 2009-10-17 15:25:42.000000000 +0200
@@ -32,8 +32,8 @@
SUBDIRS = \
src \
- examples \
.
+# examples
INST_FILES = \
AUTHORS \
diff -Nurd systemc-2.2.0/src/sysc/utils/sc_utils_ids.cpp systemc-2.2.0-ubuntu9.04/src/sysc/utils/sc_utils_ids.cpp
--- systemc-2.2.0/src/sysc/utils/sc_utils_ids.cpp 2006-12-15 21:31:39.000000000 +0100
+++ systemc-2.2.0-ubuntu9.04/src/sysc/utils/sc_utils_ids.cpp 2009-10-17 15:26:54.000000000 +0200
@@ -58,6 +58,8 @@
// the source.
//
+#include
+#include
#include "sysc/utils/sc_report.h"

Save this file in the systemc-2.2.0 folder
Run this command from a terminal:

cd systemc-2.2.0
patch -p1 < ../systemc.patch

Then compile SystemC:

aclocal
automake
autoconf
./configure
make
make install

Installing SCoPE 1.15
Set the environment variables:
gedit ~/.bashrc

add at the end (replace horicul with your username):

export CXX=g++
export SYSTEMC=/home/horicul/systemc-2.2.0
export SCOPE_HOME=/home/horicul/SCoPE-v1.1.5
export PATH=$PATH:/home/horicul/SCoPE-v1.1.5/bin
export SCOPE_XML_PLUGIN=/home/horicul/m3p-v1.0.5
export LD_LIBRARY_PATH=/home/horicul/m3p-v1.0.5/build

Open a terminal and go to your SCoPE directory then run:
make all
If it crashes do the following (and then rerun make all):
copy from:
/home/horicul/SCoPE-v1.1.5/utils/Compiler
the file:
scope-g++
to:
/home/horicul/SCoPE-v1.1.5/bin

copy from:
/home/horicul/SCoPE-v1.1.5/utils/OpCost
the file:
opcost
to:
/home/horicul/SCoPE-v1.1.5/bin

Even if it does not crash do the steps above

Installing M3P
Navigate to your m3p folder and in src/arp_lib/Makefile add
ARP_HOME = /home/horicul/sim/m3p-v1.0.5/src/arp_lib/
on the first line (repalce accordingly with your path)
Open a terminal and navigate to the m3p folder then run:

make

Go to Synaptic and install gcc-4.1 and cpp-4.1
Open a terminal:

cd /usr/bin
sudo rm cpp gcc
sudo ln -s gcc-4.1 gcc
sudo ln -s cpp-4.1 cpp

Now you have replaced your gcc.
Open a terminal and navigate to the m3p folder then run:

make examples
make run

If you wish to return to your previous gcc version run:

cd /usr/bin
sudo rm cpp gcc g++
sudo ln -s g++-4.4 g++
sudo ln -s gcc-4.4 gcc
sudo ln -s cpp-4.4 cpp

How to change your gcc compiler in Ubuntu 10.10 32Bit to another gcc version

Ubuntu 10.10 comes by default with gcc 4.4 (at least when this post was written)
You might need to change the gcc to an older version for whatever reasons (installing SCoPE simulator for example)
Go to Synaptic and install the desired gcc version ( gcc-4.3, gcc-4.5, etc.) also install cpp and g++ for the same version. If you need gcc-4.1 skip the g++ (I did not find it)
After installing these packages open a terminal and run the following commands (replace 4.4 to your desired version of gcc - with the code below you go back to the original settings):

cd /usr/bin
sudo rm cpp gcc g++
sudo ln -s g++-4.4 g++
sudo ln -s gcc-4.4 gcc
sudo ln -s cpp-4.4 cpp

If you want to install gcc-4.1 do this:

cd /usr/bin
sudo rm cpp gcc
sudo ln -s gcc-4.1 gcc
sudo ln -s cpp-4.1 cpp

This works for Ubuntu 10.10 on 32 bits. You might have to do other steps on 64 bits. See this post about this