From 85d28150be7da311d5393d473e99ad044e71f63a Mon Sep 17 00:00:00 2001 From: HypoxiE Date: Sun, 17 Aug 2025 15:18:07 +0700 Subject: [PATCH] first commit --- __pycache__/generate.cpython-313.pyc | Bin 0 -> 3302 bytes __pycache__/neuro_defs.cpython-313.pyc | Bin 0 -> 3429 bytes __pycache__/visual.cpython-313.pyc | Bin 0 -> 2983 bytes generate.py | 36 ++++++++++++++++++ main.py | 19 ++++++++++ neuro_defs.py | 49 +++++++++++++++++++++++++ visual.py | 41 +++++++++++++++++++++ 7 files changed, 145 insertions(+) create mode 100644 __pycache__/generate.cpython-313.pyc create mode 100644 __pycache__/neuro_defs.cpython-313.pyc create mode 100644 __pycache__/visual.cpython-313.pyc create mode 100644 generate.py create mode 100644 main.py create mode 100644 neuro_defs.py create mode 100644 visual.py diff --git a/__pycache__/generate.cpython-313.pyc b/__pycache__/generate.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb0c2316dfd1ea6a721a3d2daa85e0dcfde025cd GIT binary patch literal 3302 zcmbVPO>7fa5PolW{hz-k0fq1r2STU;2SI`eE))W^qN?haZh|PdEQ_--2FDI>H&K%V ziYQd{N5WA_2{)&z1Zg>hLse8!xN=-$Dqzc@QZLQTC{&1^I`h^)`QuQY)oj5Lt7L>3x}EN&O<6^!yR3C0|y zF+p}lXon!X8p&yiiLwu50c1DIrzw*n4%rhrLWueXArT35dbiVpK4-+WmPDLI*-v6L zMgtWyI314Ki)`vF2(#V5jFSjqR3=Q2DST0gNU{h&Np^HNWhb}8AxjZw$to8}?xIc1 zQ;l0|F@vsJ^fQYNTTZ4KgDe@20$`=)01oBZqd>;Vk(xwl>WDv4 zaEy>+xQ@3TD$}5wkRC7=`yh-7HY znjN`@&e4|Ng=Mp_g+xmLf`FRvH+vAsIO!oDL%*=WXdyc1&cJ9fs^<)Mh%ID_hNr|b zLd*yAQ~b-DG+)^y9&*0I)!mPd`j zY-7;$w3$L1tAQ2s94W=jE|`G?qf5I|1rf2dJ1`@*JHU7;Y|%GIgw1}71_HtyH|o)} zx%MlHZZJ3-Zht{QU-c#+{Aez9Uq1Zh;Y$b8`_jhMp|PR#sR`Be_)WpT*aM6@eiVm+ zc})+{ws$sDB$w5QY6=jNWQ+T*B#Dx=#WqmJ@ zFGyYxg`MfaJb^B=jCVIWo}-laQejJ4drqLsJE_o|jw0WTd}msJ0eq*e9Q8)wS8Am? zin+A7jz%09t5{77+}xV#gu3Y})l_#u;&mQss)u=@ih3>A0o71-&6t65kFYQ`p0p%z z*sWzb!9k)Tm zRM%hF__(U}Vt^wxFJBQPZq;#MFxrom%F@#LS*+oh!SmK4{tH@pZMy^+Erv&2-H1`h zKjQLs156=5__iK)m3>>75j?o8>au%0*O$W{eFG58huSOckk%t(Bj4^ZYu9BuZ|v>svaIc$0p!oe&m~xtVOa8h$SWBfCu`*Q`5$> zl#Z+wClDq(MX=nnK#^e3>R6^R{{*3Kq9Y?-+nFc8-Z(H_H}xK8Z?`Y1g+m8Ib zBC`i#4UvM!j+*RE^;@pNWV|oM`WGN%RTi&)r5Ey>?Sws;vpNRqD0%Akee>?+@K<5L zt1efu{)eIK=e|ET-Ftg~Zo}T3yUV0qi=z#(;n8*+325stdOEKKMqF1CVF1hRz_W z04_#>}U@3QaEx7jJI+2ay_i Gbo~d)U~;(t literal 0 HcmV?d00001 diff --git a/__pycache__/neuro_defs.cpython-313.pyc b/__pycache__/neuro_defs.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c90ed35215e07d8e8cc8543bbe13243c5048f46 GIT binary patch literal 3429 zcmbVOU2GIp6ux(M_J{74mQpAn(CxDAGOOD{Q$m7(At8Yv-9VS6K$}dayVLE${**gg zDL$A5MJXnBtJW@0lqak&>Vq*c>Z4CSbSyD-;K4*6PzDtR8^AfBS8j!QR47d*=cL4Z}7paXmYMW40XQ9vg|k|av@SvF#z ziTMc$lQ|*&2$hmxhd~2L_Xx%Cx~tMJ=xk&c8qZ_52t5 z>+@gEe>VS>eqDciFs*8-QgL)}loc?=x1O`8fitqyCQqgM^D zmd)gg*)+qzVTiQtAj)LXAE?mxkIo!__jpyQ_PuvfZw%`Gwt2B_8Rp5V7~uVR40c0j znhZGcNjmo|&?H1ANn>zK3}O~03=fkiKUWf%4@L&nG>lj<$kySo$?^@HW$1kN6_u@r z2`@a_RuEVR9=0|gCJpPEAcCHB4@FM*BQP9Hmoio=?KR`sV zVU;8~+p+(;4^QOnKc0u){-1pa^#8LDXlS;C3vP?4<1IrZG5+W;Xbdf9{+#>uyWXKw zFG)Vb!<0h0m^Zv*h3s&VzRWVHzT%OnweDO~!AIWJr#1c!lZS5|u7;}0fz&WfMFz=+YHgC@4oHGZINW8&%Cl$7iIQ)dvI0=T87^No~XnAd2t+qTxRzA@z zPmtHVt@5PN*4Ey3MFdY)`rK4oVfUa`(zsN|HiLq-px6S!5MJHOi-{p9dl^;-w#`&` zgQi<@F)VC`Fb-H6@76FvLA%g+0cKYemNpt4yjYq|uuRK?D3c!pjg!YFj#Y*xPF8#F z?7zK#w(s^qJrMaY{Bg%zhaT8tB4}gf=*+RHV+(=pI9`NJCnio*oA0#TZqWn5*`9j` z?jFzsu{9U3tDkI{XeoD^z*(7I>~r8W11P33`Ji~RC0$rv3u00nZ~y=+SK6_**ulp1 z72HX3h^_?=*z2UPc2?4DCH)z2h(Ss;p$0*2eQiKJ)4FBD0qnU`Yx#$Mth(tMFkE$0 z5BFsa@IB+E9)43!N6RC}V{T~;aQ>qule}hpR)8F$-&~8Y-TNm?mN!lYGK2+TpX6s@ zc=3-U+l4*OgXgdpLV=86Z75cgNAhxZuy&m40AbLphFfK<$P9Oy*IHj%9?7QDYC*#q z4%ESB)!QK@b&2z*R&Q<94p^*x0|E$Cw|+7*5vd%Rc)r~J*hBn{_nX4AXYTdi?O$k$ z>2JVoJ7Ptal17AHRT$;~?PA&fi$s{LZ1W@#>x zWcl)#lCx$SWO+Etv{EixPzyy_W=Mfr)YyI)8k=NUE5RRaN>)lGmK_=^shTX$5soj; zDu!i>3;f~K(789slHe7ZmYO`mhNZ@Oq4oEjqOilB_` u7G)2b-XCT!fsVqXwSsu;qLe-${s*LfNu)HiIol_FK;*3d)Ms;yd8ZPmb`x5|k_i(W&es=effl3X~o^LA~=M1iytBfXh< zGqW@E-pe|W?MuvgUl8^MkbtwnTIqqvH<1r{ z3aT}x2A#tOw-*^)4SHh-LeVNuKF>8H^lFZmL3g?iAs_a@>DI$p?(|NCN|6icoQ_{` zJaK(Ago@(XUQE2ue?1@n!s9*ve1eWI*z-5wF>5TpvuF$I-|59(&TH%7U1(F=UN7$z zEZZ==dlxJn4{pM_#Xc&8iK6JE(g{sA4A(w4M}=TiixMhm@_?dI8&N`eZL3?PLY&B| zPRoPLUL90}a$Jq-6elT8QCm!lQ^^2XTp?gAh2*$wC~;~FMdOr9?xS1^R-Le<^B2WPj#H=Eux;b5}FpXTHw-FgHH;owP{BOd!dCS9f%_u&Wb!%utZDtLLe$={ft*fzc`?YVVu z#yyV@EEe|dGbLHP|H-lwNyqUMDjtK?#g?%LPBB&6Q_g=<320WT?Wy5sn=2XauI*{y z?`^4M_+V|%OZ@$cO2EP5A;8Mb93;QMc!9x%6QGSjxtX;00;nz6XmqroBK-zKgB7k1 zw=@3$o7(oS*|z6$G_wd7J-I#6(e@nclb)x|$AqzIKUZSda)WaV zLS`0|F!Y>jKJ#4v!2W zp4vROM&WkDJ_j2Mtl>LE7s|D}8G8^xOS`$He*l(PeoOlSQPC4RubtGxZ6;*9-8L#} z%CMptln+Ma7!_nKHYB@CDW}J%J)#&xVWNhpC=*!^E1)JshVC9!!Ia4GAeCY;7t|nh zI{|As21X_!Wh|gQ7}ev^1Q`UElCH!@qT~{FfMrxmnBzi71|l#;7?G1yNLf1|u;Y@j zQYpf!l&}{|@mmI?)~qlwVOK-ztR7c_ssS@7U_d}QsE}6Bv5Pl81q97rS$CyrtS(0u z9c5Fy-raR$-~;u2^^P!eFRH%t%`^fCYr{Z(gV}-9d4%K+nOvs@?@n1Rh-4Um6#^ZJNCOi} zR*i|ENf7I8oAaIWNllGVKE*K9cUaLwZjO|*2igCQ!LG~YvP#EpmX54xqywZ)Onn^C z7-HkMalCQ5cOEw`;`-^41>C%do$2rbu4lT2@rHCuTD}ItbsKojaSH^+wZ}+5^y4svZcq zaro`p&rbe1dZXLzq*W0)&h9`{2jFwbI4WAy3RtW+e+UdJ=BO0OF@m0m#8PBC%ZYtq z&CW9~)Xa&6*5!y22#_O8Ta6s$On1ArdeFvgEi^CPtLcT~MBO1N#c ix)dK>ZWM9(awW!PkL`#rOOIx4TOVTKu?_LoA^!#E!%V#Z literal 0 HcmV?d00001 diff --git a/generate.py b/generate.py new file mode 100644 index 0000000..ea67684 --- /dev/null +++ b/generate.py @@ -0,0 +1,36 @@ +import random +class Dot: + def __init__(self, x: float, y: float) -> None: + self.x = x + self.y = y + self.classification = float(((x**2 + y**2)**0.5)>=0.5) + + def get_tup(self) -> tuple: + return (self.x, self.y, self.classification) + + def __str__(self) -> str: + return f"({self.x}, {self.y})" + + def __repr__(self) -> str: + return f"({self.x}, {self.y}, {self.classification})" + +class Dataset: + def __init__(self, train: list[Dot], test: list[Dot]) -> None: + self.train = train + self.test = test + + def __str__(self) -> str: + return f"Train: {str(self.train)}\nTest: {str(self.test)}" + + def __repr__(self) -> str: + return f"Train: {self.train}\nTest: {self.test}" + +def generate_data() -> Dot: + return Dot(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0)) + +def generate_dataset(N = 1000) -> Dataset: + return Dataset([generate_data() for i in range(N//5*4)], [generate_data() for i in range(N//5)]) + +if __name__ == "__main__": + data = generate_dataset(10) + print(data) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..007425d --- /dev/null +++ b/main.py @@ -0,0 +1,19 @@ + +import generate +import visual +import neuro_defs + + +dataset = generate.generate_dataset(10_000) + + +# Создаём и обучаем сеть +nn = neuro_defs.SimpleNN() +nn.train(dataset.train, epochs=10) + +# Проверяем на новой точке +for dot in dataset.test[:10]: + print(nn.forward(dot.x, dot.y), dot.__repr__()) + +# visual.plot_dataset(dataset) +# visual.plt_show() \ No newline at end of file diff --git a/neuro_defs.py b/neuro_defs.py new file mode 100644 index 0000000..a1f9274 --- /dev/null +++ b/neuro_defs.py @@ -0,0 +1,49 @@ +import math +import random + +def sigmoid(x): + return 1 / (1 + math.exp(-x)) + +def sigmoid_derivative(x): + s = sigmoid(x) + return s * (1 - s) + +class SimpleNN: + def __init__(self): + # инициализация весов случайными числами + self.w1 = random.uniform(-1, 1) + self.w2 = random.uniform(-1, 1) + self.b = random.uniform(-1, 1) # смещение + self.w_out = random.uniform(-1, 1) + self.b_out = random.uniform(-1, 1) + self.lr = 0.001 # скорость обучения + + def forward(self, x1, x2): + # прямой проход + self.z1 = self.w1 * x1 + self.w2 * x2 + self.b + self.a1 = sigmoid(self.z1) # активация скрытого слоя + self.z2 = self.w_out * self.a1 + self.b_out + self.a2 = sigmoid(self.z2) # выход сети + return self.a2 + + def backward(self, x1, x2, y): + # вычисляем ошибку + error = self.a2 - y # dL/da2 + + # производные для выходного слоя + d_out = error * sigmoid_derivative(self.z2) + self.w_out -= self.lr * d_out * self.a1 + self.b_out -= self.lr * d_out + + # производные для скрытого слоя + d_hidden = d_out * self.w_out * sigmoid_derivative(self.z1) + self.w1 -= self.lr * d_hidden * x1 + self.w2 -= self.lr * d_hidden * x2 + self.b -= self.lr * d_hidden + + def train(self, data, epochs=1000): + for _ in range(epochs): + for x1, x2, y in [i.get_tup() for i in data]: + self.forward(x1, x2) + self.backward(x1, x2, y) + diff --git a/visual.py b/visual.py new file mode 100644 index 0000000..5a0b75f --- /dev/null +++ b/visual.py @@ -0,0 +1,41 @@ +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import numpy as np + + +def plot_dataset(dataset): + x0 = [dot.x for dot in dataset.train if not dot.classification] + y0 = [dot.y for dot in dataset.train if not dot.classification] + x1 = [dot.x for dot in dataset.train if dot.classification] + y1 = [dot.y for dot in dataset.train if dot.classification] + + plt.scatter(x0, y0, color='green', label='Class 0') + plt.scatter(x1, y1, color='red', label='Class 1') + +def plot_decision_surface(network, resolution=0.02): + x_min, x_max = -1, 1 + y_min, y_max = -1, 1 + xx, yy = np.meshgrid(np.arange(x_min, x_max, resolution), + np.arange(y_min, y_max, resolution)) + + # прогоняем сетку через сеть + Z = np.array([network.predict([x, y]) for x, y in zip(xx.ravel(), yy.ravel())]) + Z = Z.reshape(xx.shape) + + # закрашиваем фон по вероятности + plt.contourf(xx, yy, Z, levels=50, cmap='RdYlGn', alpha=0.3) + +def plot_all(dataset, network): + plt.figure(figsize=(6,6)) + plot_decision_surface(network) + plot_dataset(dataset) + plt.xlim(-1, 1) + plt.ylim(-1, 1) + plt.legend() + +def plt_show(): + plt.show() + + +if __name__ == "__main__": + pass \ No newline at end of file