Mala neuronska mreža i scikit-learn
Do sada smo sve pisali sami. Prave neuronske mreže imaju hiljade težina i složeno učenje, pa ih ne pišemo od nule – koristimo biblioteku scikit-learn. U ovoj lekciji mreža uči da prepoznaje rukom pisane cifre i postiže tačnost od skoro 98 %.
Podaci: rukom pisane cifre
Biblioteka scikit-learn ima ugrađen skup od 1797 malih slika rukom pisanih cifara. Svaka slika ima 8 × 8 = 64 piksela, a svaki piksel je broj od 0 (belo) do 16 (crno).
# Pogled na podatke: rukom pisane cifre (8 × 8 piksela) iz biblioteke scikit-learn
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
cifre = load_digits()
print("Broj slika:", len(cifre.images))
print("Veličina jedne slike:", cifre.images[0].shape) # (8, 8)
print("Prva slika kao brojevi (0 = belo, 16 = najtamnije):")
print(cifre.images[0])
# prikaz prvih 10 slika sa oznakama
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(cifre.images[i], cmap="gray_r")
plt.title(f"oznaka: {cifre.target[i]}")
plt.axis("off")
plt.show()
Ispis programa:
Broj slika: 1797
Veličina jedne slike: (8, 8)
Prva slika kao brojevi (0 = belo, 16 = najtamnije):
[[ 0. 0. 5. 13. 9. 1. 0. 0.]
[ 0. 0. 13. 15. 10. 15. 5. 0.]
[ 0. 3. 15. 2. 0. 11. 8. 0.]
[ 0. 4. 12. 0. 0. 8. 8. 0.]
[ 0. 5. 8. 0. 0. 9. 8. 0.]
[ 0. 4. 11. 0. 1. 12. 7. 0.]
[ 0. 2. 14. 5. 10. 12. 0. 0.]
[ 0. 0. 6. 13. 10. 0. 0. 0.]]

Program: mreža uči cifre
# Neuronska mreža prepoznaje rukom pisane cifre (scikit-learn, MLPClassifier)
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
cifre = load_digits()
X = cifre.data / 16.0 # svaka slika je red od 64 broja; delimo sa 16 da budu od 0 do 1
y = cifre.target # tačne oznake: 0..9
# 80 % za učenje, 20 % za proveru
X_ucenje, X_provera, y_ucenje, y_provera = train_test_split(X, y, test_size=0.2, random_state=0)
print("Za učenje:", len(X_ucenje), "slika, za proveru:", len(X_provera))
# mreža sa jednim skrivenim slojem od 64 neurona
mreza = MLPClassifier(hidden_layer_sizes=(64,), max_iter=500, random_state=0)
mreza.fit(X_ucenje, y_ucenje) # TRENING
predvidjeno = mreza.predict(X_provera) # PROVERA
print(f"Tačnost na proveri: {accuracy_score(y_provera, predvidjeno) * 100:.1f} %")
print("Tabela grešaka (red = tačna cifra, kolona = šta je mreža rekla):")
print(confusion_matrix(y_provera, predvidjeno))
# pet slika na kojima je mreža pogrešila
greske = [i for i in range(len(y_provera)) if predvidjeno[i] != y_provera[i]]
for i in greske[:5]:
print(f"slika {i}: tačno {y_provera[i]}, mreža kaže {predvidjeno[i]}")
Ispis programa:
Za učenje: 1437 slika, za proveru: 360
Tačnost na proveri: 97.8 %
Tabela grešaka (red = tačna cifra, kolona = šta je mreža rekla):
[[27 0 0 0 0 0 0 0 0 0]
[ 0 34 0 0 0 0 0 0 1 0]
[ 0 0 36 0 0 0 0 0 0 0]
[ 0 0 0 29 0 0 0 0 0 0]
[ 0 0 0 0 29 0 0 1 0 0]
[ 0 0 0 0 0 39 0 0 0 1]
[ 0 1 0 0 0 0 43 0 0 0]
[ 0 0 0 0 0 0 0 39 0 0]
[ 0 1 1 0 0 0 0 0 37 0]
[ 0 0 0 0 0 1 0 1 0 39]]
slika 118: tačno 6, mreža kaže 1
slika 124: tačno 8, mreža kaže 1
slika 130: tačno 9, mreža kaže 5
slika 143: tačno 9, mreža kaže 7
slika 181: tačno 5, mreža kaže 9
cifre.dataje tabela: svaka slika je jedan red od 64 broja – to su osobine.cifre.targetsu oznake (0–9).train_test_splitdeli podatke na 80 % za učenje i 20 % za proveru – kao u lekciji Kako mašina uči.MLPClassifier(hidden_layer_sizes=(64,))je mreža sa jednim skrivenim slojem od 64 neurona; ulaznih neurona ima 64 (pikseli), izlaznih 10 (cifre).fit= trening,predict= pogađanje.- U tabeli grešaka brojevi na dijagonali su tačni odgovori. Na primer, u drugom redu vidimo da je jedna jedinica proglašena za osmicu.
Poređenje: k-NN i mreža
# Poređenje: k-NN i neuronska mreža na istim podacima
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.neural_network import MLPClassifier
cifre = load_digits()
X, y = cifre.data / 16.0, cifre.target
X_u, X_p, y_u, y_p = train_test_split(X, y, test_size=0.2, random_state=0)
modeli = {
"k-NN (k = 3)": KNeighborsClassifier(n_neighbors=3),
"mreža, 16 neurona": MLPClassifier(hidden_layer_sizes=(16,), max_iter=800, random_state=0),
"mreža, 64 neurona": MLPClassifier(hidden_layer_sizes=(64,), max_iter=500, random_state=0),
}
for ime, model in modeli.items():
model.fit(X_u, y_u)
print(f"{ime:20} tačnost: {model.score(X_p, y_p) * 100:.1f} %")
Ispis programa:
k-NN (k = 3) tačnost: 98.3 %
mreža, 16 neurona tačnost: 97.2 %
mreža, 64 neurona tačnost: 97.8 %
Zanimljivo: na ovim malim slikama jednostavni k-NN je podjednako dobar kao mreža (čak malo bolji). Neuronske mreže pokazuju prednost na velikim slikama i složenim zadacima – tamo gde k-NN postaje prespor i nepouzdan. Pouka: uvek uporedi sa jednostavnim modelom pre nego što posegneš za složenim.
Učenici pokreću program, pa u grupama menjaju broj neurona i broj slika za učenje (zadaci 1 i 3) i upisuju tačnost u zajedničku tabelu na tabli.
Česte zablude
- „98 % znači da mreža skoro nikad ne greši“ – na ovim slikama; na ciframa napisanim drugačije (npr. tvojim rukopisom) može da greši mnogo češće – videćeš u lekciji 18.
- „Više neurona je uvek bolje“ – posle neke granice tačnost raste malo, a učenje traje duže; previše neurona može da dovede i do preprilagođavanja.
Zadaci za vežbu
Pokušaj prvo sam, pa tek onda otvori rešenje.
- Isprobaj mreže sa 4, 8, 32 i 128 neurona u skrivenom sloju. Kako se menja tačnost?
- Prikaži slike na kojima mreža greši, sa tačnom oznakom i odgovorom mreže.
- Koliko je mreža tačna ako uči na samo 50, 100 ili 500 slika?
Rešenje 1: broj neurona
# Zadatak: kako broj neurona u skrivenom sloju utiče na tačnost
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
cifre = load_digits()
X_u, X_p, y_u, y_p = train_test_split(cifre.data / 16.0, cifre.target, test_size=0.2, random_state=0)
for n in [4, 8, 32, 128]:
mreza = MLPClassifier(hidden_layer_sizes=(n,), max_iter=1000, random_state=0)
mreza.fit(X_u, y_u)
print(f"{n:4} neurona: tačnost {mreza.score(X_p, y_p) * 100:.1f} %")
Ispis programa:
4 neurona: tačnost 92.8 %
8 neurona: tačnost 94.4 %
32 neurona: tačnost 97.8 %
128 neurona: tačnost 98.6 %
Sa 4 neurona tačnost je oko 93 %, sa 32 i više oko 98 %. Ako se pojavi upozorenje ConvergenceWarning, mreža nije završila učenje za zadati broj krugova (max_iter) – rezultat i dalje važi, ali možeš da povećaš max_iter.
Rešenje 2: slike grešaka
# Zadatak: prikaži slike na kojima mreža greši
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
cifre = load_digits()
X_u, X_p, y_u, y_p = train_test_split(cifre.data / 16.0, cifre.target, test_size=0.2, random_state=0)
mreza = MLPClassifier(hidden_layer_sizes=(64,), max_iter=500, random_state=0).fit(X_u, y_u)
predvidjeno = mreza.predict(X_p)
greske = [i for i in range(len(y_p)) if predvidjeno[i] != y_p[i]]
for k, i in enumerate(greske[:6]):
plt.subplot(1, 6, k + 1)
plt.imshow(X_p[i].reshape(8, 8), cmap="gray_r") # 64 broja nazad u sliku 8 × 8
plt.title(f"{y_p[i]} → {predvidjeno[i]}")
plt.axis("off")
plt.suptitle("tačno → šta je mreža rekla")
plt.show()

Rešenje 3: malo podataka
# Zadatak: koliko je mreža dobra ako uči na samo 100 slika?
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
cifre = load_digits()
X_u, X_p, y_u, y_p = train_test_split(cifre.data / 16.0, cifre.target, test_size=0.2, random_state=0)
for broj in [50, 100, 500, len(X_u)]:
mreza = MLPClassifier(hidden_layer_sizes=(64,), max_iter=1000, random_state=0)
mreza.fit(X_u[:broj], y_u[:broj])
print(f"uči na {broj:4} slika: tačnost {mreza.score(X_p, y_p) * 100:.1f} %")
Ispis programa:
uči na 50 slika: tačnost 80.8 %
uči na 100 slika: tačnost 90.6 %
uči na 500 slika: tačnost 96.7 %
uči na 1437 slika: tačnost 97.8 %
Što manje primera, to manja tačnost – podaci su zaista „hrana“ za veštačku inteligenciju.
Proveri znanje
Otvori kviz
Kviz: neuronska mreža i scikit-learn
1. Koliko ulaza ima mreža za slike cifara 8 × 8?
2. Šta radi fit?
3. Šta pokazuju brojevi na dijagonali tabele grešaka?
4. Šta se desi kada mreža uči na samo 50 slika?
