Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Neyron nima
- 2.2. Bias nima uchun kerak
- 2.3. Perseptron o'rgatish qoidasi
- 2.4. Chiziqli ajralish va XOR
- 2.5. Qatlam — XOR yechimi
- 2.6. Perseptron va logistik regressiya
- 2.7. Tuzoqlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Bitta neyronni qo'lda hisoblash
- Misol 2 — Perseptron o'rgatish qoidasi
- Misol 3 — XOR ni ikki qatlam bilan yechish
- Misol 4 — Perseptron va logistik regressiya
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
20.1-dars: Neyron va perseptron
20-QISM — NEYRON TARMOQLAR · 1-dars
1. Kirish va motivatsiya
Shu paytgacha modellarni tayyor oldik: LogisticRegression, RandomForest, HistGradientBoosting. Ular ichida nima bo'layotganini bilardik, lekin o'zimiz qurmadik.
Neyron tarmoqlar boshqacha: ular juda oddiy bloklardan yig'iladi. Bitta blok — neyron — atigi ikki amal bajaradi: kirishlarni og'irliklar bilan ko'paytirib qo'shadi, so'ng natijani aktivatsiya funksiyasidan o'tkazadi. Hammasi shu.
Sehr bloklarda emas, ularning soni va joylashuvida. Bitta neyron faqat to'g'ri chiziq chiza oladi. Ikki qatlam neyron esa — 1989-yilda isbotlangan universal approksimatsiya teoremasi bo'yicha — istalgan uzluksiz funksiyani xohlagancha aniq taqlid qila oladi.
Bu darsda eng boshidan boshlaymiz: bitta neyron, uni qo'lda hisoblash, perseptron o'rgatish qoidasi va perseptronning mashhur cheklovi — XOR muammosi.
Real vaziyat. 1958-yilda Frank Rosenblatt perseptronni e'lon qilganda, gazetalar "o'zini anglaydigan mashina" deb yozdi. 1969-yilda Minsky va Papert bitta perseptron XOR ni yecha olmasligini isbotladi va soha 15 yilga to'xtadi. Cheklov haqiqiy edi — lekin u faqat bitta qatlam uchun.
Bu darsda neyronning ichini ochamiz.
Bu darsda:
- Neyron: og'irlik, bias, aktivatsiya
- Perseptron o'rgatish qoidasi
- Chiziqli ajralish
- XOR muammosi
- Qatlam tushunchasi
- Tuzoqlar
- Amaliy: qo'lda neyron
ℹ Misollar real numpy/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Neyron nima
KIRISH OG'IRLIK YIG'INDI AKTIVATSIYA CHIQISH
x1 ---- w1 ----\
x2 ---- w2 -----> z = w·x + b --> f(z) -------> a
x3 ---- w3 ----/
IKKI QADAM:
1. CHIZIQLI: z = w1*x1 + w2*x2 + ... + wn*xn + b
2. NOCHIZIQLI: a = f(z)
w — og'irliklar (weights): har kirishning MUHIMLIGI
b — siljish (bias): chegarani surish
f — aktivatsiya: nochiziqlilik manbai
MUHIM: f BO'LMASA, neyron chiziqli regressiyadan farq qilmaydiNeyron = chiziqli kombinatsiya + nochiziqli funksiya. Ikkinchisisiz qancha qatlam qo'ysangiz ham natija baribir chiziqli bo'ladi.
2.2. Bias nima uchun kerak
b SIZ: z = w1*x1 + w2*x2
chegara (z = 0) HAR DOIM koordinata boshidan o'tadi
b BILAN: z = w1*x1 + w2*x2 + b
chegarani istalgan joyga surish mumkin
MISOL: "harorat 37 dan yuqorimi" degan neyron
b siz: w*harorat > 0 -> faqat harorat > 0 ni aniqlaydi
b bilan: w*harorat - 37w > 0 -> to'g'ri chegaraBias — chegarani surish imkoni; usiz model koordinata boshiga bog'lanib qoladi.
2.3. Perseptron o'rgatish qoidasi
AKTIVATSIYA: step(z) = 1 agar z > 0, aks holda 0
HAR NAMUNA UCHUN:
bashorat = step(w·x + b)
xato = haqiqiy - bashorat # -1, 0 yoki +1
w <- w + eta * xato * x
b <- b + eta * xato
MANTIQ:
xato = 0 -> hech narsa o'zgarmaydi
xato = +1 -> bashorat past edi, w ni x YO'NALISHIDA suramiz
xato = -1 -> bashorat baland edi, w ni x ga QARSHI suramiz
KAFOLAT (Novikoff, 1962):
ma'lumot chiziqli ajraladigan bo'lsa - CHEKLI qadamda to'xtaydi
ajralmasa - ABADIY aylanadiPerseptron faqat chiziqli ajraladigan ma'lumotda yaqinlashadi — bu teorema, taxmin emas.
2.4. Chiziqli ajralish va XOR
AND OR XOR
x1 x2 | y x1 x2 | y x1 x2 | y
0 0 | 0 0 0 | 0 0 0 | 0
0 1 | 0 0 1 | 1 0 1 | 1
1 0 | 0 1 0 | 1 1 0 | 1
1 1 | 1 1 1 | 1 1 1 | 0
AND, OR: bitta to'g'ri chiziq 0 larni 1 lardan ajratadi -> YECHILADI
XOR: 1 lar DIAGONAL joylashgan -> YECHILMAYDI
1 | 1 0 bitta chiziq bilan
| diagonalni ajratib bo'lmaydi
0 | 0 1
+-----------
0 1XOR — bitta neyronning chegarasi, chunki bitta neyron faqat bitta gipertekislik chiza oladi.
2.5. Qatlam — XOR yechimi
IKKI QATLAM XOR ni yechadi:
h1 = step(x1 + x2 - 0.5) # OR
h2 = step(x1 + x2 - 1.5) # AND
y = step(h1 - h2 - 0.5) # OR VA AND EMAS
x1 x2 | h1 h2 | y
0 0 | 0 0 | 0
0 1 | 1 0 | 1
1 0 | 1 0 | 1
1 1 | 1 1 | 0
YASHIRIN QATLAM ma'lumotni YANGI FAZOGA ko'chiradi,
u yerda sinflar chiziqli ajraladigan bo'lib qoladiYashirin qatlamning vazifasi — koordinatani almashtirish, shundan keyin oxirgi qatlam oddiy chiziq chizadi.
2.6. Perseptron va logistik regressiya
perseptron logistik regressiya
aktivatsiya step (0/1) sigmoid (0..1)
chiqish sinf EHTIMOLLIK
loss yo'q (qoida) log-loss
gradient yo'q (step uzilgan) bor
ajralmasa aylanaveradi yaqinlashadi
marja e'tibor bermaydi maksimallashtiradi
XULOSA: perseptron - tarixiy asos, amalda sigmoid/softmax ishlatiladiStep funksiyaning hosilasi hamma joyda nol — shuning uchun perseptronni gradient bilan o'rgatib bo'lmaydi va shuning uchun zamonaviy tarmoqlarda u ishlatilmaydi.
2.7. Tuzoqlar
Asosiy tuzoqlar: aktivatsiyasiz qatlamlarni ko'paytirish (natija baribir chiziqli); bias ni unutish; perseptronni ajralmaydigan ma'lumotda cheksiz aylantirish; step bilan gradient izlash; XOR ni bitta neyron bilan yechishga urinish; og'irliklarni nol bilan boshlash (ko'p neyronli qatlamda hammasi bir xil qoladi).
3. Tez ma'lumotnoma
import numpy as np
# bitta neyron
def neyron(x, w, b, f=lambda z: (z > 0).astype(float)):
return f(x @ w + b)
# perseptron o'rgatish
for _ in range(davrlar):
for xi, yi in zip(X, y):
xato = yi - neyron(xi, w, b)
w += eta * xato * xi
b += eta * xato
# XOR ni ikki qatlam bilan
W1 = np.array([[1.0, 1.0], [1.0, 1.0]]) # (kirish, yashirin)
b1 = np.array([-0.5, -1.5])
W2 = np.array([[1.0], [-1.0]])
b2 = np.array([-0.5])Neyron xulosasi
z = w·x + b chiziqli qism
a = f(z) nochiziqli qism
perseptron: step + xato*x qoidasi
chiziqli ajralish -> yaqinlashadi
XOR -> ikki qatlam kerak4. Batafsil misollar
Misollar real numpy/sklearn bilan (Python 3.14).
Misol 1 — Bitta neyronni qo'lda hisoblash
"""Neyronning ichi: og'irlik, bias, aktivatsiya (real numpy)."""
import numpy as np
def step(z):
return (np.asarray(z) > 0).astype(float)
def neyron(X, w, b, f=step):
return f(X @ w + b)
def main() -> None:
X = np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
print("=== 1. Qo'lda qo'yilgan og'irliklar: AND ===")
w_and, b_and = np.array([1.0, 1.0]), -1.5
print(f" w = {w_and}, b = {b_and}")
print(f" {'x1':>4} {'x2':>4} {'z = w·x + b':>13} {'step(z)':>9}")
for x in X:
z = float(x @ w_and + b_and)
print(f" {x[0]:>4.0f} {x[1]:>4.0f} {z:>13.1f} {step(z):>9.0f}")
print("\n=== 2. Bir xil tuzilma, boshqa bias: OR ===")
w_or, b_or = np.array([1.0, 1.0]), -0.5
print(f" w = {w_or}, b = {b_or} (faqat b o'zgardi)")
print(f" {'x1':>4} {'x2':>4} {'z':>7} {'step(z)':>9}")
for x in X:
z = float(x @ w_or + b_or)
print(f" {x[0]:>4.0f} {x[1]:>4.0f} {z:>7.1f} {step(z):>9.0f}")
print(" BIAS chegarani suradi - og'irliklar o'zgarmadi")
print("\n=== 3. Bias nima uchun kerak ===")
print(f" {'holat':<22} {'z(0,0)':>8} {'natija':>8}")
for nom, b in [("b = 0 (bias yo'q)", 0.0), ("b = -0.5", -0.5),
("b = +0.5", 0.5)]:
z = float(np.zeros(2) @ w_or + b)
print(f" {nom:<22} {z:>8.1f} {step(z):>8.0f}")
print(" b = 0 bo'lsa chegara HAR DOIM (0,0) dan o'tadi")
print("\n=== 4. Chegara chizig'i ===")
print(" w·x + b = 0 => x2 = -(w1/w2)*x1 - b/w2")
for nom, w, b in [("AND", w_and, b_and), ("OR", w_or, b_or)]:
qiya = -w[0] / w[1]
kesim = -b / w[1]
print(f" {nom:<4} x2 = {qiya:+.1f}*x1 {kesim:+.1f}")
print("\n=== 5. Aktivatsiyasiz nima bo'ladi ===")
W1 = np.array([[0.5, -1.0], [2.0, 0.3]])
W2 = np.array([[1.5], [-0.7]])
ikki_qatlam = (X @ W1) @ W2 # aktivatsiya YO'Q
birlashgan = X @ (W1 @ W2) # bitta matritsa
print(f" ikki qatlam (f yo'q): {ikki_qatlam.ravel().round(4)}")
print(f" bitta matritsa: {birlashgan.ravel().round(4)}")
print(f" bir xilmi: {np.allclose(ikki_qatlam, birlashgan)}")
print(" ⭐ Aktivatsiyasiz N qatlam = 1 qatlam")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Qo'lda qo'yilgan og'irliklar: AND ===
w = [1. 1.], b = -1.5
x1 x2 z = w·x + b step(z)
0 0 -1.5 0
0 1 -0.5 0
1 0 -0.5 0
1 1 0.5 1
=== 2. Bir xil tuzilma, boshqa bias: OR ===
w = [1. 1.], b = -0.5 (faqat b o'zgardi)
x1 x2 z step(z)
0 0 -0.5 0
0 1 0.5 1
1 0 0.5 1
1 1 1.5 1
BIAS chegarani suradi - og'irliklar o'zgarmadi
=== 3. Bias nima uchun kerak ===
holat z(0,0) natija
b = 0 (bias yo'q) 0.0 0
b = -0.5 -0.5 0
b = +0.5 0.5 1
b = 0 bo'lsa chegara HAR DOIM (0,0) dan o'tadi
=== 4. Chegara chizig'i ===
w·x + b = 0 => x2 = -(w1/w2)*x1 - b/w2
AND x2 = -1.0*x1 +1.5
OR x2 = -1.0*x1 +0.5
=== 5. Aktivatsiyasiz nima bo'ladi ===
ikki qatlam (f yo'q): [0. 2.79 1.45 4.24]
bitta matritsa: [0. 2.79 1.45 4.24]
bir xilmi: True
⭐ Aktivatsiyasiz N qatlam = 1 qatlamNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Perseptron o'rgatish qoidasi
"""Rosenblatt qoidasi: yaqinlashish va aylanish (real numpy)."""
import numpy as np
def perseptron_orgat(X, y, eta=0.1, davrlar=50):
"""Og'irliklarni qaytaradi + har davrdagi xatolar soni."""
w = np.zeros(X.shape[1])
b = 0.0
tarix = []
for _ in range(davrlar):
xatolar = 0
for xi, yi in zip(X, y):
bashorat = 1.0 if xi @ w + b > 0 else 0.0
xato = yi - bashorat
if xato != 0:
w = w + eta * xato * xi
b = b + eta * xato
xatolar += 1
tarix.append(xatolar)
if xatolar == 0:
break
return w, b, tarix
def main() -> None:
X = np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
vazifalar = {
"AND": np.array([0.0, 0.0, 0.0, 1.0]),
"OR": np.array([0.0, 1.0, 1.0, 1.0]),
"XOR": np.array([0.0, 1.0, 1.0, 0.0]),
}
print("=== 1. Uch mantiqiy vazifa ===")
print(f" {'vazifa':<6} {'davrlar':>8} {'yaqinlashdi':>12} "
f"{'w':>18} {'b':>7}")
natijalar = {}
for nom, y in vazifalar.items():
w, b, tarix = perseptron_orgat(X, y)
natijalar[nom] = (w, b, tarix)
print(f" {nom:<6} {len(tarix):>8} "
f"{str(tarix[-1] == 0):>12} "
f"{str(w.round(2)):>18} {b:>7.2f}")
print("\n=== 2. Xatolar tarixi ===")
for nom in vazifalar:
tarix = natijalar[nom][2]
print(f" {nom:<6} {tarix[:12]}")
print(" XOR hech qachon nolga tushmaydi - abadiy aylanadi")
print("\n=== 3. Qadamma-qadam (OR, birinchi davr) ===")
w, b = np.zeros(2), 0.0
y = vazifalar["OR"]
print(f" {'x':<10} {'y':>3} {'bashorat':>9} {'xato':>6} "
f"{'yangi w':<14} {'yangi b':>8}")
for xi, yi in zip(X, y):
bashorat = 1.0 if xi @ w + b > 0 else 0.0
xato = yi - bashorat
w = w + 0.1 * xato * xi
b = b + 0.1 * xato
print(f" {str(xi):<10} {yi:>3.0f} {bashorat:>9.0f} {xato:>6.0f} "
f"{str(w.round(2)):<14} {b:>8.2f}")
print("\n=== 4. Boshlang'ich nuqta natijaga ta'sir qiladimi ===")
rng = np.random.default_rng(0)
y_and = vazifalar["AND"]
print(f" {'urinish':>8} {'davrlar':>8} {'w':>18} {'b':>7}")
for i in range(4):
w = rng.normal(0, 1, 2)
b = float(rng.normal())
davr = 0
for davr in range(1, 51):
xatolar = 0
for xi, yi in zip(X, y_and):
bashorat = 1.0 if xi @ w + b > 0 else 0.0
xato = yi - bashorat
if xato != 0:
w = w + 0.1 * xato * xi
b = b + 0.1 * xato
xatolar += 1
if xatolar == 0:
break
print(f" {i + 1:>8} {davr:>8} {str(w.round(2)):>18} {b:>7.2f}")
print(" yechim BITTA emas - cheksiz ko'p to'g'ri chiziq bor")
print("\n=== 5. Chiziqli ajraladigan real ma'lumot ===")
rng = np.random.default_rng(42)
A = rng.normal([-2, -2], 0.7, size=(60, 2))
B = rng.normal([2, 2], 0.7, size=(60, 2))
Xr = np.vstack([A, B])
yr = np.r_[np.zeros(60), np.ones(60)]
w, b, tarix = perseptron_orgat(Xr, yr, eta=0.01, davrlar=100)
aniqlik = ((Xr @ w + b > 0).astype(float) == yr).mean()
print(f" davrlar: {len(tarix)}, oxirgi xatolar: {tarix[-1]}")
print(f" aniqlik: {aniqlik:.4f}")
print(f" w = {w.round(3)}, b = {b:.3f}")
print(" ⭐ Ajraladigan bo'lsa - kafolatlangan yaqinlashish")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Uch mantiqiy vazifa ===
vazifa davrlar yaqinlashdi w b
AND 6 True [0.2 0.1] -0.20
OR 4 True [0.1 0.1] 0.00
XOR 50 False [-0.1 0. ] 0.10
=== 2. Xatolar tarixi ===
AND [1, 3, 3, 2, 1, 0]
OR [1, 2, 1, 0]
XOR [2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
XOR hech qachon nolga tushmaydi - abadiy aylanadi
=== 3. Qadamma-qadam (OR, birinchi davr) ===
x y bashorat xato yangi w yangi b
[0. 0.] 0 0 0 [0. 0.] 0.00
[0. 1.] 1 0 1 [0. 0.1] 0.10
[1. 0.] 1 1 0 [0. 0.1] 0.10
[1. 1.] 1 1 0 [0. 0.1] 0.10
=== 4. Boshlang'ich nuqta natijaga ta'sir qiladimi ===
urinish davrlar w b
1 10 [0.23 0.07] -0.26
2 11 [0.2 0.06] -0.24
3 4 [1. 0.85] -1.10
4 19 [0.23 0.08] -0.26
yechim BITTA emas - cheksiz ko'p to'g'ri chiziq bor
=== 5. Chiziqli ajraladigan real ma'lumot ===
davrlar: 2, oxirgi xatolar: 0
aniqlik: 1.0000
w = [0.013 0.021], b = 0.010
⭐ Ajraladigan bo'lsa - kafolatlangan yaqinlashishNima ko'rsatdi: 2.3, 2.4-bo'limlar.
Misol 3 — XOR ni ikki qatlam bilan yechish
"""Yashirin qatlam ma'lumotni yangi fazoga ko'chiradi (real numpy)."""
import numpy as np
def step(z):
return (z > 0).astype(float)
def main() -> None:
X = np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = np.array([0.0, 1.0, 1.0, 0.0])
print("=== 1. Qo'lda qurilgan tarmoq ===")
W1 = np.array([[1.0, 1.0],
[1.0, 1.0]]) # (kirish=2, yashirin=2)
b1 = np.array([-0.5, -1.5]) # h1 = OR, h2 = AND
W2 = np.array([[1.0], [-1.0]]) # (yashirin=2, chiqish=1)
b2 = np.array([-0.5])
print(f" W1 =\n{W1}")
print(f" b1 = {b1} -> h1 = OR, h2 = AND")
print(f" W2 = {W2.ravel()}, b2 = {b2} -> y = h1 VA h2 EMAS")
print("\n=== 2. Qadamma-qadam hisob ===")
H = step(X @ W1 + b1)
Y = step(H @ W2 + b2)
print(f" {'x1':>3} {'x2':>3} | {'h1(OR)':>7} {'h2(AND)':>8} | "
f"{'y':>3} {'kerak':>6}")
for i in range(4):
print(f" {X[i, 0]:>3.0f} {X[i, 1]:>3.0f} | {H[i, 0]:>7.0f} "
f"{H[i, 1]:>8.0f} | {Y[i, 0]:>3.0f} {y[i]:>6.0f}")
print(f" hammasi to'g'rimi: {np.array_equal(Y.ravel(), y)}")
print("\n=== 3. Yashirin qatlam nima qildi ===")
print(f" {'asl (x1,x2)':<14} {'sinf':>5} {'yangi (h1,h2)':<16}")
for i in range(4):
print(f" {str(X[i]):<14} {y[i]:>5.0f} {str(H[i]):<16}")
print(" (0,1) va (1,0) YANGI fazoda AYNI nuqtaga tushdi")
print(" endi bitta chiziq yetarli")
print("\n=== 4. Yangi fazoda chiziqli ajralish ===")
nol = H[y == 0]
bir = H[y == 1]
print(f" sinf 0 nuqtalari: {[tuple(t) for t in nol]}")
print(f" sinf 1 nuqtalari: {[tuple(t) for t in bir]}")
print(f" ajratuvchi: h1 - h2 - 0.5 = 0")
for i in range(4):
qiymat = float(H[i] @ W2.ravel() + b2[0])
print(f" {str(H[i]):<12} -> {qiymat:>5.1f} "
f"({'1' if qiymat > 0 else '0'})")
print("\n=== 5. Bitta neyron urinib ko'radi ===")
eng_yaxshi = (-1.0, None)
rng = np.random.default_rng(0)
for _ in range(20000):
w = rng.uniform(-3, 3, 2)
b = rng.uniform(-3, 3)
ball = (step(X @ w + b) == y).mean()
if ball > eng_yaxshi[0]:
eng_yaxshi = (ball, (w.round(2), round(b, 2)))
print(f" 20000 ta tasodifiy chiziqdan eng yaxshisi: "
f"{eng_yaxshi[0]:.2f}")
print(f" og'irliklar: {eng_yaxshi[1]}")
print(" 4 tadan 3 tasi - bu chegara, izlash muammosi EMAS")
print(" ⭐ XOR uchun yashirin qatlam SHART")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Qo'lda qurilgan tarmoq ===
W1 =
[[1. 1.]
[1. 1.]]
b1 = [-0.5 -1.5] -> h1 = OR, h2 = AND
W2 = [ 1. -1.], b2 = [-0.5] -> y = h1 VA h2 EMAS
=== 2. Qadamma-qadam hisob ===
x1 x2 | h1(OR) h2(AND) | y kerak
0 0 | 0 0 | 0 0
0 1 | 1 0 | 1 1
1 0 | 1 0 | 1 1
1 1 | 1 1 | 0 0
hammasi to'g'rimi: True
=== 3. Yashirin qatlam nima qildi ===
asl (x1,x2) sinf yangi (h1,h2)
[0. 0.] 0 [0. 0.]
[0. 1.] 1 [1. 0.]
[1. 0.] 1 [1. 0.]
[1. 1.] 0 [1. 1.]
(0,1) va (1,0) YANGI fazoda AYNI nuqtaga tushdi
endi bitta chiziq yetarli
=== 4. Yangi fazoda chiziqli ajralish ===
sinf 0 nuqtalari: [(np.float64(0.0), np.float64(0.0)), (np.float64(1.0), np.float64(1.0))]
sinf 1 nuqtalari: [(np.float64(1.0), np.float64(0.0)), (np.float64(1.0), np.float64(0.0))]
ajratuvchi: h1 - h2 - 0.5 = 0
[0. 0.] -> -0.5 (0)
[1. 0.] -> 0.5 (1)
[1. 0.] -> 0.5 (1)
[1. 1.] -> -0.5 (0)
=== 5. Bitta neyron urinib ko'radi ===
20000 ta tasodifiy chiziqdan eng yaxshisi: 0.75
og'irliklar: (array([1.81, 2.54]), -1.4)
4 tadan 3 tasi - bu chegara, izlash muammosi EMAS
⭐ XOR uchun yashirin qatlam SHARTNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Perseptron va logistik regressiya
"""Step va sigmoid: nima farqi bor (real numpy/sklearn)."""
import numpy as np
from sklearn.linear_model import LogisticRegression, Perceptron
from sklearn.metrics import accuracy_score
def main() -> None:
rng = np.random.default_rng(7)
A = rng.normal([-1.5, -1.0], 1.0, size=(120, 2))
B = rng.normal([1.5, 1.0], 1.0, size=(120, 2))
X = np.vstack([A, B])
y = np.r_[np.zeros(120), np.ones(120)]
print("=== 1. Aktivatsiya funksiyalari ===")
z = np.array([-4.0, -1.0, -0.1, 0.0, 0.1, 1.0, 4.0])
step = (z > 0).astype(float)
sigmoid = 1 / (1 + np.exp(-z))
print(f" {'z':>6} {'step(z)':>9} {'sigmoid(z)':>12}")
for i in range(len(z)):
print(f" {z[i]:>6.1f} {step[i]:>9.0f} {sigmoid[i]:>12.4f}")
print(" step - sakrash, sigmoid - silliq o'tish")
print("\n=== 2. Hosilalar ===")
h = 1e-5
step_hosila = ((z + h > 0).astype(float)
- (z - h > 0).astype(float)) / (2 * h)
sig_hosila = sigmoid * (1 - sigmoid)
print(f" {'z':>6} {'step hosilasi':>15} {'sigmoid hosilasi':>18}")
for i in range(len(z)):
print(f" {z[i]:>6.1f} {step_hosila[i]:>15.1f} "
f"{sig_hosila[i]:>18.6f}")
print(" ⭐ step hosilasi z=0 dan boshqa joyda NOL")
print(" gradient tushish uchun yaroqsiz")
print("\n=== 3. Ikkala modelni o'rgatamiz ===")
p = Perceptron(max_iter=1000, tol=1e-3, random_state=0).fit(X, y)
lr = LogisticRegression(max_iter=2000).fit(X, y)
print(f" {'model':<22} {'aniqlik':>9} {'w':>20} {'b':>8}")
for nom, m in [("Perceptron", p), ("LogisticRegression", lr)]:
a = accuracy_score(y, m.predict(X))
print(f" {nom:<22} {a:>9.4f} "
f"{str(m.coef_[0].round(3)):>20} {m.intercept_[0]:>8.3f}")
print("\n=== 4. Chiqish turi ===")
namuna = X[[0, 1, 120, 121]]
print(f" {'nuqta':<20} {'perseptron':>11} {'logreg P(1)':>13}")
for i, x in enumerate(namuna):
pp = int(p.predict(x.reshape(1, -1))[0])
lp = float(lr.predict_proba(x.reshape(1, -1))[0, 1])
print(f" {str(x.round(2)):<20} {pp:>11} {lp:>13.4f}")
print(" perseptron faqat SINF, logreg ISHONCH darajasini beradi")
print("\n=== 5. Chegaraga yaqin nuqtalar ===")
masofa = np.abs(lr.decision_function(X))
yaqin = np.argsort(masofa)[:5]
print(f" {'masofa':>9} {'P(1)':>8} {'haqiqiy':>8}")
for i in yaqin:
print(f" {masofa[i]:>9.4f} "
f"{lr.predict_proba(X[i:i + 1])[0, 1]:>8.4f} "
f"{y[i]:>8.0f}")
print(" logreg chegaraga yaqin nuqtalarda ~0.5 beradi")
print(" ⭐ Ehtimollik - qaror qabul qilish uchun ZARUR")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Aktivatsiya funksiyalari ===
z step(z) sigmoid(z)
-4.0 0 0.0180
-1.0 0 0.2689
-0.1 0 0.4750
0.0 0 0.5000
0.1 1 0.5250
1.0 1 0.7311
4.0 1 0.9820
step - sakrash, sigmoid - silliq o'tish
=== 2. Hosilalar ===
z step hosilasi sigmoid hosilasi
-4.0 0.0 0.017663
-1.0 0.0 0.196612
-0.1 0.0 0.249376
0.0 50000.0 0.250000
0.1 0.0 0.249376
1.0 0.0 0.196612
4.0 0.0 0.017663
⭐ step hosilasi z=0 dan boshqa joyda NOL
gradient tushish uchun yaroqsiz
=== 3. Ikkala modelni o'rgatamiz ===
model aniqlik w b
Perceptron 0.9792 [2.944 1.026] 1.000
LogisticRegression 0.9833 [2.477 1.557] 0.591
=== 4. Chiqish turi ===
nuqta perseptron logreg P(1)
[-1.5 -0.7] 0 0.0146
[-1.77 -1.89] 0 0.0012
[1.04 1.74] 1 0.9972
[1.42 1.08] 1 0.9969
perseptron faqat SINF, logreg ISHONCH darajasini beradi
=== 5. Chegaraga yaqin nuqtalar ===
masofa P(1) haqiqiy
0.0032 0.5008 1
0.3498 0.5866 1
0.3961 0.5977 1
0.4945 0.3788 0
0.6576 0.6587 0
logreg chegaraga yaqin nuqtalarda ~0.5 beradi
⭐ Ehtimollik - qaror qabul qilish uchun ZARURNima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Neyron miya neyroni kabi" | Juda soddalashtirilgan matematik model |
| "Qatlam ko'paysa kuch ortadi" | Aktivatsiyasiz — yo'q, baribir chiziqli |
| "Bias ixtiyoriy" | Usiz chegara koordinata boshidan o'tadi |
| "Perseptron har doim yaqinlashadi" | Faqat chiziqli ajraladigan ma'lumotda |
| "XOR — izlash muammosi" | Chegara: bitta chiziq yeta olmaydi |
| "Step yaxshi aktivatsiya" | Hosilasi nol — o'rgatib bo'lmaydi |
| "Perseptron = logistik regressiya" | Chiqish, loss va xossalar boshqa |
| "Yashirin qatlam sehrli" | U shunchaki koordinatani almashtiradi |
6. Keng tarqalgan xatolar va yechimlari
1. Aktivatsiyasiz qatlamlar
a = (X @ W1) @ W2 # ⚠️ baribir chiziqli
a = f(f(X @ W1 + b1) @ W2 + b2) # ✅2. Bias yo'q
z = X @ w # ⚠️ chegara (0,0) dan o'tadi
z = X @ w + b # ✅3. Perseptronni ajralmaydigan ma'lumotda
while xatolar > 0: ... # ⚠️ abadiy aylanadi
for _ in range(davrlar): ... # ✅ + eng yaxshisini saqlang4. Step bilan gradient
grad = hosila(step)(z) # ⚠️ hamma joyda nol
grad = sigmoid(z) * (1 - sigmoid(z)) # ✅5. Og'irliklarni nol bilan boshlash
W1 = np.zeros((2, 8)) # ⚠️ 8 neyron bir xil qoladi
W1 = rng.normal(0, 0.5, (2, 8)) # ✅ simmetriyani buzadi6. XOR ni bitta neyron bilan
Perceptron().fit(X_xor, y_xor) # ⚠️ 0.75 dan oshmaydi
MLPClassifier(hidden_layer_sizes=(2,)) # ✅7. Chegarani ehtimollik deb o'qish
p.predict(x) # ⚠️ 0/1, ishonch yo'q
lr.predict_proba(x) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 14-qism (o'tilgan): Logistik regressiya
- 10-qism (o'tilgan): Matritsa ko'paytmasi
- 20.2-dars: Aktivatsiya funksiyalari
- 20.4-dars: Oldinga tarqalish
- 21-qism: PyTorch
8. Eng yaxshi amaliyotlar
Har doim bias qo'shing.
Aktivatsiyasiz qatlam qo'shmang.
Og'irliklarni tasodifiy boshlang.
Davrlar soniga chegara qo'ying.
Chiqish sifatida ehtimollik oling.
Kirishlarni masshtablang.
Avval chiziqli modelni sinang.
Qatlamni koordinata almashtirish deb o'ylang.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # neyron necha qadamdan iborat?
2. # bias nima qiladi?
3. # aktivatsiyasiz 5 qatlam nimaga teng?
4. # perseptron qachon yaqinlashadi?
5. # XOR nega yechilmaydi?
6. # yashirin qatlam nima qiladi?
7. # step hosilasi nechaga teng?
8. # perseptron ehtimollik beradimi?
9. # og'irlikni nol qilsa nima bo'ladi?
10. # chegara tenglamasi qanday?
11. # xato = +1 bo'lsa w qayoqqa suriladi?
12. # eta nima?Javoblar
- Ikki: chiziqli va nochiziqli
- Chegarani suradi
- Bitta chiziqli qatlamga
- Ma'lumot chiziqli ajralganda
- 1 lar diagonal joylashgan
- Koordinatani almashtiradi
- Nol (z=0 dan boshqa joyda)
- Yo'q, faqat sinf
- Bir qatlamdagi neyronlar bir xil qoladi
w·x + b = 0xyo'nalishida- O'rganish tezligi
Vazifa 2: Xatolarni tuzating
1. a = (X @ W1) @ W2
2. z = X @ w
3. while xatolar > 0: ...
4. W1 = np.zeros((2, 8))
5. Perceptron().fit(X_xor, y_xor)Javoblar
1. a = f(f(X @ W1 + b1) @ W2 + b2)
2. z = X @ w + b
3. for _ in range(davrlar): ...
4. W1 = rng.normal(0, 0.5, (2, 8))
5. MLPClassifier(hidden_layer_sizes=(2,))Vazifa 3: Neyron
Modellang:
- AND
- OR
- Bias
- Chegara
Vazifa 4: Perseptron
Modellang:
- Qoida
- Tarix
- Boshlang'ich
- Real ma'lumot
Vazifa 5: XOR
Modellang:
- Tarmoq
- Hisob
- Yangi fazo
- Bitta neyron
Vazifa 6: Taqqoslash
Modellang:
- Aktivatsiya
- Hosila
- Modellar
- Chiqish
Vazifa 7: O'ylash
Hamkasbingiz aytdi: "Men 50 qatlamli tarmoq qurdim, lekin u chiziqli regressiyadan yaxshi ishlamayapti." Birinchi navbatda nimani tekshirasiz?
Javob
Birinchi savol: qatlamlar orasida aktivatsiya bormi?
Aktivatsiyasiz 50 qatlam matematik jihatdan bitta qatlamga teng:
W_umumiy = W1 @ W2 @ W3 @ ... @ W50 # shunchaki bitta matritsaBu eng keng tarqalgan xato va uni tekshirish bir daqiqa oladi:
for nom, qatlam in model.named_children():
print(nom, type(qatlam).__name__)
# Linear, Linear, Linear, ... -> ReLU yo'q -> muammo shuAgar aktivatsiya bo'lsa, keyingi tekshiruvlar:
| Tekshiruv | Nima izlaymiz | Belgi |
|---|---|---|
| Kirish masshtabi | X.std() 1 atrofidami |
1000 bo'lsa — gradient portlaydi |
| Og'irlik boshlanishi | Nol emasmi, juda kichik emasmi | Hammasi bir xil chiqish |
| O'rganish tezligi | Loss kamayayaptimi | Yassi yoki NaN |
| Gradient oqimi | Birinchi qatlam gradienti | ~0 bo'lsa — yo'qolayotgan gradient |
| Ma'lumot hajmi | Namuna / parametr nisbati | 50 qatlam uchun juda kam |
| Vazifa turi | Bog'liqlik chindan nochiziqlimi | Chiziqli bo'lsa — 50 qatlam ortiqcha |
Muhim nuans: 50 qatlam o'zi muammo bo'lishi mumkin. Chuqur tarmoqda gradient orqaga tarqalganda har qatlamda ko'payib boradi va yo'qolib yoki portlab ketadi. Shuning uchun zamonaviy chuqur tarmoqlarda BatchNorm, residual ulanishlar va ehtiyotkor boshlash ishlatiladi (20.8-dars).
Amaliy tartib:
- Aktivatsiyani tekshiring
- 50 qatlamni 2 qatlamga tushiring va taqqoslang
- 2 qatlam chiziqlidan yaxshi bo'lsa — chuqurlikni asta oshiring
- 2 qatlam ham yaxshi bo'lmasa — muammo ma'lumotda yoki vazifada
Eng muhimi: chiziqli regressiyadan yaxshi ishlamayotgan tarmoq ko'pincha chiziqli tarmoqdir.
Nimani mustahkamlaydi: 2.1, 2.5-bo'limlar.
Xulosa
Bu darsda neyronning ichini ochdik.
Eng muhim uch fikr:
Neyron ikki qadamdan iborat: chiziqli va nochiziqli.
z = w·x + bkirishlarni og'irliklar bilan aralashtiradi,a = f(z)esa natijani egadi. Ikkinchi qadamsiz qancha qatlam qo'ysangiz ham hammasi bitta matritsaga yig'iladi — bu 1-misolda raqam bilan ko'rsatildi. Bias esa chegarani koordinata boshidan ajratadi.Perseptron qoidasi oddiy, lekin cheklangan.
w += eta * xato * x— atigi bitta qator, va Novikoff teoremasi bo'yicha ma'lumot chiziqli ajraladigan bo'lsa u chekli qadamda to'xtaydi. Ajralmasa — abadiy aylanadi.XORda 20 000 tasodifiy chiziqdan eng yaxshisi ham 4 tadan 3 tasini topdi.Yashirin qatlam — koordinata almashtirish.
XORni yechgan tarmoq sehrgarlik qilmadi: u(0,1)va(1,0)nuqtalarini yangi fazoda ayni nuqtaga ko'chirdi, shundan keyin oxirgi qatlam oddiy chiziq chizdi. Chuqur o'rganishning butun g'oyasi shu — oson ajraladigan tasvir qurish.
Keyingi darsda aktivatsiya funksiyalarini batafsil ko'ramiz: sigmoid, tanh, ReLU va uning avlodlari; qaysi biri qachon, nima uchun ReLU standart bo'lib qolgani va "o'lgan neyron" muammosi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!