Micro:bit kao perceptron (umjetna inteligencija)

"Učinkovita umjetna inteligencija najveći je događaj u ljudskoj povijesti. Ili najgori. To još ne znamo."- Stephen Hawking

Nemojte propustiti

E Ink avanture s Inky pHAT-om

E Ink (AKA E Paper, electronic paper) već je neko vrijeme s nama, a mogli ste se sresti s tom tehnologijom ako (još...

Raspberry Pi Story

Raspberry Pi maleni je SBC (single board computer) razvijen od Raspberry Pi Foundation kako bi pomogao u edukaciji osnova računarstva. Međutim, vrlo brzo pokazalo...

Spajanje više tipkala na jedan pin

Mnogi su nas nakon članka o izborniku s LCD shieldom pitali kako spojiti tipkala da rade na takav način. Jedan od načina...

I2C LCD

Sada je vrijeme da se pozabavimo jednim od osnovnih koraka u našim projektima a to je prikazivanje poruka na LCD ekranu. Danas...

Izrada izbornika na LCD štitu

Nakon što smo se upoznali sa shield koji ima LCD ekran i tipkovnicu. Ako još niste možete to učiniti ovdje. Vrijeme je...

Kada sam proučavao specifikaciju micro:bita i vidio da podržava međusobnu radio komunikaciju, neuronska mreža bile mi je prva asocijacija. Uzmete desetak micro:bita, date im ulogu neurona, međusobno ih povežete, zatim ih podučite, uposlite i eto vam zgodne izvedbe za nekomu dočarati što su neuronske mreže i kako funkcioniraju.

Sažeto, neuronske mreže algoritmi su koji moraju naučiti ono što će raditi. Za razliku od klasičnih algoritama, nakon što ih napišete, gotovo sigurno će željeni posao raditi jako loše. Da budu uspješni, morate ih nahraniti s primjerima i željenim rezultatima. Što je broj primjera veći i što su primjeri šarolikiji, kasnije će svoj posao raditi uspješnije. Primjer neuronske mreže prepoznavanje je sadržaja na fotografijama. Taj posao ljudi rasturaju, a klasični programi rade ga katastrofalno. Neuronske mreže oponašaju rad našeg mozga i zato su u tom poslu dosta uspješnije od uobičajenog programiranja.Budući da imam jedan micro:bit, odlučio sam napraviti perceptron, „mrežu“ koja se može izvesti sa samo jednim neuronom. Perceptron je binarni klasifikator. Za skup ulaznih podataka kaže pripada li on nekoj skupini ili ne, odnosno pripada li prvoj ili drugoj skupini. U našem slučaju posao će mu biti da kaže je li neka točka ravnine ispod ili iznad pravca kojeg smo odabrali. Perceptron ne zna koji smo pravac odabrali niti će ikada to izravno saznati. On se sastoji od težina (weight) te pristranosti (bias). Po jedna težina pridružena je svakom ulaznu parametru i ona određuje koliko je taj parametar bitan kod određivanja izlaznog rezultata. Pristranost pomaže ostvariti bolja predviđanja. Također imamo i brzinu učenja (learning rate) koja, pogađate, određuje brzinu učenja. Kod učenja mijenjaju se težine i pristranost. Kako točno, vidjet ćemo kasnije.

- oglas-

Kao što sam već rekao, micro:bit će biti perceptron i napisat ću ga u MakeCodu. Ulogu mentora preuzet će osobno računalo, tj. program napisan u Pythonu. Međusobno će biti povezani serijskom vezom (UART). Na početku će računalo proizvoljno odabrati pravac, a micro:bit će doslovno pogađati položaj zadanih mu točaka. Zatim će računalo podučiti micro:bit tako što će mu poslati određeni broj točaka, skupa s očekivanim rezultatom (položajem u odnosu na pravac). Micro:bit će ihc iskoristiti da fino uštima težine i pristranost. Nakon toga računalo korisniku daje mogućnost testiranja rada perceptrona pomoću grafičkog prikaza ravnine i mogućnosti odabira točaka za testiranje. Ako micro:bit vrati točan položaj, odabrana točka bit će zelena, inače crvena. Kod izrade projekta, prvo što sam napravio je sve skupa testirao na računalu unutar jednog programa. Kod toga programa priložen je na kraju članka.Kada sam utvrdio da sve radi kako je zamišljeno, prešao sam na izradu perceptrona.

A sada slijedi program perceptrona, objašnjen korak po korak cijeli kod nalazi se na kraju.

Na počeku imamo inicijalizaciju glavnih varijabli programa. Budući da MakeCode ne podržava decimalne brojeve, s brojem sto pomnožene su težine i pristranost.

let weight1 = Math.random(201) - 100
let weight2 = Math.random(201) - 100
let bias = Math.random(201) - 100
let learning_rate = 10
let score: string
let delta: number

Slijedi funkcija učenja. Ona prima vrijednosti X i Y zadane točke i željeni rezultat. Prvo se odredi izlazna vrijednost perceptrona. Pomnožimo ulazne parametre s težinama i zbrojimo ih, skupa s pristranošću. Ako je ta suma veća od nule, točka se nalazi iznad pravca (1), inače je ispod (0). Tako dobiveni rezultat usporedi se sa željenim. Ako se razlikuju, perceptron prilagođava vrijednosti težina i pristranosti. Prvo se odredi razlika (delta) željenog i dobivenog rezultata, koja se zbog ranijeg ograničenja množi sa sto. Zatim se težine i pristranost promijene za vrijednost umnoška ulaznog parametra, delte i brzine učenja. I na kraju se vrati dobiveni rezultat.

function learn(x: number, y: number, result: string) {
    if (x * weight1 + y * weight2 + bias > 0) {
        score = 'A'
    } else {
        score = 'B'
    }
    if (score != result) {
        if (result == 'A') {
            delta = 100
        }
        else {
            delta = -100
        }
        weight1 += x * delta * learning_rate
        weight2 += y * delta * learning_rate
        bias += delta * learning_rate
    }
    return score
}

Funkcija testiranja vrati istinu ako je točka iznad pravca, a laž u suprotnom.

function test(x: number, y: number) {
    return x * weight1 + y * weight2 + bias > 0
}

Glavni dio programa serijska je komunikacija s računalom. Kada se pojave ulazni podaci, dohvate se i spreme u varijable. Prvi podatak je vrsta akcije, učenje (L) ili testiranje (T). Iduća dva podatka su vrijednosti X i Y točke čiji položaj se određuje. Ako se radi o učenju, idući podatak je željeni rezultat. Slovo A ako je točka iznad pravca te slovo B ako je ispod. Završni podatak je znak $ koji označava kraj ulaznog skupa podataka. Ako je poslana akcija učenje, poziva se funkcija učenja. Ako se testira rad perceptrona, poziva se funkcija testiranja, pošalje se računalu te prikaže dobiveni rezultat (strelica gore za iznad pravca te strelica dolje za ispod pravca).

  data.shift(2)
    let y = data.getNumber(NumberFormat.Int16BE, 0)
    if (action == 'L') {
        data = serial.readBuffer(2)
        let result = String.fromCharCode(data.getNumber(NumberFormat.Int8BE, 0))
        serial.writeString(learn(x, y, result))
    } else {
        data = serial.readBuffer(1)
        if (test(x, y)) {
            basic.pause(100)
            serial.writeString('A')
            basic.showArrow(ArrowNames.North)
        } else {
            basic.pause(100)
            serial.writeString('B')
            basic.showArrow(ArrowNames.South)
        }
    }
})

Slijedi prikaz koda koji se izvodi na računalu, objašnjen korak po korak cijeli kod nalazi se na kraju.

Rad programa započinje uvozom korištenih modula Pythona. Zatim se uspostavi serijska komunikacija i varijable se inicijaliziraju. Varijable max_NEŠTO služe za određivanje granica kod odabira pravca te kod grafičkog prikaza ravnine. Proizvoljno se odabere naš pravac (varijable a i b, pravac je oblika ax+b).

import matplotlib.pyplot as plt
import random
import serial
import struct
from time import sleep

max_a = 10
max_b = 100
max_x = 100

try:
    s = serial.Serial('COM3', 115200)
       
    a = random.randint(-max_a, max_a)
    b = random.randint(-max_b, max_b)
    max_y = max_a * max_x + max_b
    
    learning_iterations = 1000

Slijedi učenje perceptrona. U ovom našem slučaju varijabla learning_iterations određuje broj točaka (1000) koje ćemo poslati perceptronu, skupa s željenim rezultatom. Perceptron će iskoristiti te podatke da nauči raditi svoj posao.

for i in range(learning_iterations):
        x = random.randint(-max_x, max_x)
        y = random.randint(-max_y, max_y)
        if y > a * x + b:
            result = b'A' # above
        else:
            result = b'B' # below
        data = struct.pack('>chhcc', b'L', x, y, result, b'$')
        s.write(data)
        while s.in_waiting:
            sleep(0.005)
        s.read()

Završni dio programa stvori grafički prikaz ravnine, skupa s pravcem. Korisnik sada može testirati rad perceptrona. Točka se odabere tako što se klikne negdje na ravnini. Podaci o točki pošalju se perceptronu i on vrati rezultat. Program ga usporedi sa željenim rezultatom. Ako je točan, prikaže se zelena oznaka točke, a ako je netočan, prikaže se crvena.

fig, ax = plt.subplots()
    def onclick(event):
        global a
        global b
        global ax
        x = int(round(event.xdata))
        y = int(round(event.ydata))
        data = struct.pack('>chhc', b'T', x, y, b'$')
        s.write(data)
        if y > a * x + b:
            result = b'A'
        else:
            result = b'B'
        while s.in_waiting:
            sleep(0.005)
        score = s.read()
        if score == result:
            ax.plot(x, y, 'gx')
        else:

Ovako sve to skupa uživo izgleda.

Ispričavam se ako sam neki pojam krivo preveo. Moguće je i da množenje sa sto u programu perceptrona nije skroz točno. Budući da perceptron radi podjednako kao i u testiranju, nisam se puno time zamarao.

Preuzimanje:

Možda vas zanima i ovo:

Komentiraj

Unesite svoj komentar!
Ovdje unesite svoje ime

Popularno

Uvjeti korištenja

Uvjeti korištenja seekretors.org stranice (u daljnjem tekstu: ove stranice) u vlasništvu su njenih osnivača Marka Miroslava Bače i Tomislava Preksavca (u daljnjem...

Enderova nova pamet

Enderu 3 teško je naći manu (naročito za cijenu po kojoj se prodaje), i ako bi nešto trebalo izdvojiti, to je sigurno njegov...

PYW – Vijak

Evo nas na prvoj stranici našeg putovanja, a s čime je bolje početi nego s dobrom vezom. Zato krenimo od vijčanog spoja.

Print Your world- uvod

Dobrodošli u novi serijal Print Your world ili kako bi mi rekli ekstrudiraj, ekstrudiraj. U ovom serijalu bavit ćemo...

Korekcija putanje glave 3D printera

Konkretno, u mom slučaju radi se o 3D printeru tipa delta, premda vjerujem da sličnih problema ima i kod modela s klasičnim...