INPUT_DIM = 2
OUT_DIM = 1
H_DIM = 2
W1 = np.random.randn(INPUT_DIM, H_DIM)
b1 = np.random.randn(H_DIM)
W2 = np.random.randn(H_DIM, OUT_DIM)
b2 = np.random.randn(OUT_DIM)
def train(data, all_trues):
learn_rate = 0.1
epochs = 1000
for epoch in range(epochs):
for x,y_true in zip(data,all_trues):
t = x @ W1 + b1
h = sigmoid(t)
t2 = h @ W2 + b2
o = sigmoid(t2)
y_pred = o
d_L_d_ypred = -2*(y_true - y_pred)
d_h_d_w1 = diff(t,W1)*sigmoid(t) #можно ли как-нибудь посчитать все частные производные по элементам матрицы?
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def d_sigmoid(x):
fx = sigmoid(x)
return fx*(1-fx)
def mse_loss(y_trued, y_pred):
return ((y_trued - y_pred)**2).mean()
class NeuralNetwork:
def __init__(self):
self.w = np.random.normal(0,1,6)
self.b = np.random.normal(0,1,3)
def feedforward(self, x):
h1 = sigmoid(self.w[0]*x[0]+self.w[1]*x[1]+self.b[0])
h2 = sigmoid(self.w[2]*x[0]+self.w[3]*x[1]+self.b[1])
o1 = sigmoid(self.w[4]*h1+self.w[5]*h2+self.b[2])
return o1
def train(self, data, all_y_trues):
learn_rate = 0.1 #оценка обучения
epochs = 10000 # количество циклов во всём наборе данных
for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
#считаем выход для каждого элемента
sum_h1 = self.w[0]*x[0]+self.w[1]*x[1]+self.b[0]
h1 = sigmoid(sum_h1)
sum_h2 = self.w[2]*x[0]+self.w[3]*x[1]+self.b[1]
h2 = sigmoid(sum_h2)
sum_o1 = self.w[4]*h1+self.w[5]*h2+self.b[2]
o1 = sigmoid(sum_o1)
y_pred = o1 # выход
#считаем частные производные
d_L_d_ypred = -2*(y_true - y_pred)
#нейрон h1
d_h1_d_w1 = x[0]*d_sigmoid(sum_h1)
d_h1_d_w2 = x[1]*d_sigmoid(sum_h1)
d_h1_d_b1 = d_sigmoid(sum_h1)
#нейрон h2
d_h2_d_w3 = x[0]*d_sigmoid(sum_h2)
d_h2_d_w4 = x[1]*d_sigmoid(sum_h2)
d_h2_d_b2 = d_sigmoid(sum_h2)
#нейрон o1
d_ypred_d_w5 = h1*d_sigmoid(sum_o1)
d_ypred_d_w6 = h2*d_sigmoid(sum_o1)
d_ypred_d_b3 = d_sigmoid(sum_o1)
d_ypred_d_h1 = self.w[4]*d_sigmoid(sum_o1)
d_ypred_d_h2 = self.w[5]*d_sigmoid(sum_o1)
#Обновляем веса и смещения
#нейрон h1
self.w[0] -= learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_w1
self.w[1] -= learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_w2
self.b[0] -= learn_rate*d_L_d_ypred*d_ypred_d_h1*d_h1_d_b1
#нейрон h2
self.w[2] -= learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_w3
self.w[3] -= learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_w4
self.b[1] -= learn_rate*d_L_d_ypred*d_ypred_d_h2*d_h2_d_b2
#нейрон o1
self.w[4] -= learn_rate*d_L_d_ypred*d_ypred_d_w5
self.w[5] -= learn_rate*d_L_d_ypred*d_ypred_d_w6
self.b[2] -= learn_rate*d_L_d_ypred*d_ypred_d_b3
if epoch%10==0:
y_preds = np.apply_along_axis(self.feedforward,1,data)
loss = mse_loss(all_y_trues,y_preds)
print("Epoch %d loss: %.3f" % (epoch, loss))
import numpy as np
h = 1e-8
#---------- Функция расчета значений частных производных по формуле Тейлора ----------
# f - функция
# p - точка
def calc_gradient(f, p):
(x, y) = p
return np.array([
(f(x + h, y) - f(x - h, y)) * 0.5 / h,
(f(x, y + h) - f(x, y - h)) * 0.5 / h])