Miért használjunk NumPy-t?
Az előző részekben tiszta Python kóddal építettünk mesterséges neuront és egy egyszerű réteget. Láttuk, hogy a logika nem bonyolult: súlyozott összeadás, eltolás hozzáadása, majd esetleg aktivációs függvény alkalmazása.
De ahogy nő a hálózat mérete – több réteg, több száz vagy ezer neuron –, a tiszta Python megoldás:
- lassú lesz,
- áttekinthetetlenné válik,
- és rengeteg hibalehetőséget hordoz.
Ezért használjuk a NumPy könyvtárat, amely:
- nagyon gyors (C nyelven írták),
- megbízható (alaposan tesztelt),
- és egyszerűvé teszi a vektorokkal, mátrixokkal végzett műveleteket.
Vektorok, tömbök, mátrixok és tenzorok
Mielőtt konkrét példákon keresztül megnéznénk a NumPy használatát, fontos tisztázni néhány fogalmat.
Kezdjük a legegyszerűbb Python adattárolóval, a listával. A Python lista vesszővel elválasztott számokat tartalmaz szögletes zárójelek között. A korábbi részekben a tiszta Python megoldásainkban listákat használtunk az adatok tárolására.
Példa egy listára:
list = [1, 5, 6, 2]Listák listája:
list_of_lists = [[1, 5, 6, 2],
[3, 2, 1, 3]]Listák listáinak listája:
list_of_lists_of_lists = [[[1, 5, 6, 2],
[3, 2, 1, 3]],
[[5, 2, 1, 2],
[6, 4, 8, 4]],
[[2, 8, 5, 3],
[1, 1, 9, 4]]]A fenti példák mindegyike nevezhető tömbnek is. Azonban nem minden lista lehet tömb.
Például:
[[1, 2, 3],
[4, 5],
[6, 7, 8, 9]]Ez a lista nem lehet tömb, mert nem „homológ”. Egy „listák listája” akkor homológ, ha minden sor pontosan ugyanannyi adatot tartalmaz és ez igaz valamennyi dimenzióra. A fenti példa nem homológ, mert az első lista 3 elemből, a második 2-ből, a harmadik pedig 4-ből.
A mátrix definíciója egyszerű: ez egy kétdimenziós tömb. Vannak sorai és oszlopai. Tehát egy mátrix lehet egy tömb. Vajon minden tömb lehet mátrix? Nem. Egy tömb sokkal több lehet, mint sorok és oszlopok. Lehet 3, 5 vagy akár 20 dimenziós is.
Végül mi az a tenzor? A tenzorok és a tömbök pontos definíciójáról oldalak százain keresztül vitáznak szakemberek. Ezt a vitát nagyrészt az okozza, hogy a résztvevők teljesen eltérő területek felől közelítik meg a témát. Ha a mélytanulás és a neurális hálózatok felől akarjuk megközelíteni a tenzor fogalmát, akkor talán a legpontosabb leírás: „A tenzorobjektum olyan objektum, amely tömbként ábrázolható.”
Összefoglalva: A lineáris, vagy 1-dimenziós tömb a legegyszerűbb tömb, Pythonban ennek a lista felel meg. A tömbök többdimenziós adatokat is tartalmazhatnak, ennek legismertebb példája a mátrix, amely egy 2-dimenziós tömb.
Még egy fogalmat fontos tisztázni, ez a vektor. Egyszerűen fogalmazva a matematikában használt vektor megegyezik a Python listával, vagy az 1-dimenziós tömbbel.
Két fontos művelet: dot product és vektorösszeadás
A dot product művelet elvégzésekor két vektort szorzunk össze. Ezt úgy tesszük, hogy sorra vesszük a vektorok elemeit és az azonos indexű elemeket összeszorozzuk, majd ezeket a szorzatokat összeadjuk. Matematikailag leírva ez így néz ki:
\vec{a}\cdot\vec{b} = \sum_{i=1}^n a_ib_i = a_1\cdot b_1+a_2\cdot b_2+...+a_n\cdot b_nFontos, hogy mindkét vektornak azonos méretűnek kell lennie. Ha Python kódban akarjuk ugyanezt leírni, akkor az így nézne ki:
# Első vektor
a = [1, 2, 3]
# Második vektor
b = [2, 3, 4]
# Dot product kiszámítása
dot_product = a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
print(dot_product)
>>> 20Látható, hogy ugyanazt a műveletet végeztük el, mint mikor egy neuron kimeneti értékét számoltuk ki, csak itt nem adtuk hozzá az eltolást. Mivel a Python nyelv alapesetben nem tartalmaz sem utasítást, sem funkciót a dot product kiszámolására, ezért használjuk a NumPy könyvtárat.
Vektorok összeadásánál az egyes vektorok azonos indexű elemeit adjuk össze. Matematikailag leírva ez így néz ki:
\vec{a}+\vec{b} = [a_1+b_1, a_2+b_2,...,a_n+b_n]Itt is fontos, hogy a vektoroknak azonos méretűnek kell lennie. Az eredmény egy ugyanilyen méretű vektor lesz. A NumPy ezt a műveletet is könnyen kezeli.
NumPy használata
Egy neuron
Most kódoljuk le a korábban látott neuront NumPy használatával.
import numpy as np
# Bemenetek és súlyok
inputs = np.array([0.5, 0.8, 0.3, 0.1])
weights = np.array([0.2, 0.7, -0.5, 0.9])
bias = 0.5
# Neuron kimenete (dot product + bias)
output = np.dot(inputs, weights) + bias
print("Neuron kimenete:", output)Itt a np.dot(inputs, weights) kiszámolja a skaláris szorzatot, majd egyszerűen hozzáadjuk a bias-t.
Egy réteg
Most építsünk egy teljes réteget 3 neuronból, amelynek mindegyik neuron 4 bemenetet kap.
import numpy as np
# Példa bemenet (4 elem)
inputs = np.array([1.0, 2.0, 3.0, 2.5])
# 3 neuron súlyai (mátrix: 3 sor, 4 oszlop)
weights = np.array([
[0.2, 0.8, -0.5, 1.0], # Neuron 1
[0.5, -0.91, 0.26, -0.5], # Neuron 2
[-0.26, -0.27, 0.17, 0.87] # Neuron 3
])
# Bias értékek (3 elem)
biases = np.array([2.0, 3.0, 0.5])
# Réteg kimenete (mátrix-szorzás + vektor összeadás)
output = np.dot(weights, inputs) + biases
print("Réteg kimenete:", output)
>>> Réteg kimenete: [4.8 1.21 2.385]Itt a np.dot(weights, inputs) a mátrix (weights) és a vektor (inputs) szorzatát adja vissza, ami pont a neuronok súlyozott összege. Ehhez adjuk hozzá egyszerűen a bias vektort.
Következő rész
A következő cikkben megismerkedünk az aktivációs függvényekkel, és megnézzük, hogyan adnak „nemlineáris erőt” a hálózatnak. Ezek nélkül a hálózatunk csak egyszerűen lineáris összefüggéseket tudna modellezni.

