# your code goes here
import numpy as np
class TrainableXNOR:
def __init__(self, learning_rate=0.1):
# Инициализация весов случайными значениями
np.random.seed(42)
self.W1 = np.random.randn(2, 2) * 0.01
self.b1 = np.zeros((1, 2))
self.W2 = np.random.randn(2, 1) * 0.01
self.b2 = np.zeros((1, 1))
self.lr = learning_rate
def sigmoid(self, x):
return 1 / (1 + np.exp(-np.clip(x, -700, 700)))
def sigmoid_derivative(self, x):
return x * (1 - x)
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, output):
m = X.shape[0]
# Градиент выходного слоя
dz2 = output - y
dW2 = (1/m) * np.dot(self.a1.T, dz2)
db2 = (1/m) * np.sum(dz2, axis=0, keepdims=True)
# Градиент скрытого слоя
da1 = np.dot(dz2, self.W2.T)
dz1 = da1 * self.sigmoid_derivative(self.a1)
dW1 = (1/m) * np.dot(X.T, dz1)
db1 = (1/m) * np.sum(dz1, axis=0, keepdims=True)
# Обновление параметров
self.W2 -= self.lr * dW2
self.b2 -= self.lr * db2
self.W1 -= self.lr * dW1
self.b1 -= self.lr * db1
def train(self, X, y, epochs=10000):
losses = []
for epoch in range(epochs):
output = self.forward(X)
loss = np.mean((output - y) ** 2)
losses.append(loss)
self.backward(X, y, output)
if epoch % 1000 == 0:
print(f"Epoch {epoch}, Loss: {loss:.6f}")
return losses
# Данные для обучения
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[1], [0], [0], [1]]) # XNOR
# Обучение и тестирование
network = TrainableXNOR(learning_rate=0.5)
losses = network.train(X, y, epochs=10000)
print("\nРезультаты после обучения:")
print("Input Target Output Predicted")
for i in range(len(X)):
output = network.forward(X[i].reshape(1, -1))
predicted = 1 if output > 0.5 else 0
print(f"{X[i]} {y[i][0]} {output[0][0]:.4f} {predicted}")
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCmltcG9ydCBudW1weSBhcyBucAoKY2xhc3MgVHJhaW5hYmxlWE5PUjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBsZWFybmluZ19yYXRlPTAuMSk6CiAgICAgICAgIyDQmNC90LjRhtC40LDQu9C40LfQsNGG0LjRjyDQstC10YHQvtCyINGB0LvRg9GH0LDQudC90YvQvNC4INC30L3QsNGH0LXQvdC40Y/QvNC4CiAgICAgICAgbnAucmFuZG9tLnNlZWQoNDIpCiAgICAgICAgc2VsZi5XMSA9IG5wLnJhbmRvbS5yYW5kbigyLCAyKSAqIDAuMDEKICAgICAgICBzZWxmLmIxID0gbnAuemVyb3MoKDEsIDIpKQogICAgICAgIHNlbGYuVzIgPSBucC5yYW5kb20ucmFuZG4oMiwgMSkgKiAwLjAxCiAgICAgICAgc2VsZi5iMiA9IG5wLnplcm9zKCgxLCAxKSkKICAgICAgICBzZWxmLmxyID0gbGVhcm5pbmdfcmF0ZQogICAgCiAgICBkZWYgc2lnbW9pZChzZWxmLCB4KToKICAgICAgICByZXR1cm4gMSAvICgxICsgbnAuZXhwKC1ucC5jbGlwKHgsIC03MDAsIDcwMCkpKQogICAgCiAgICBkZWYgc2lnbW9pZF9kZXJpdmF0aXZlKHNlbGYsIHgpOgogICAgICAgIHJldHVybiB4ICogKDEgLSB4KQogICAgCiAgICBkZWYgZm9yd2FyZChzZWxmLCBYKToKICAgICAgICBzZWxmLnoxID0gbnAuZG90KFgsIHNlbGYuVzEpICsgc2VsZi5iMQogICAgICAgIHNlbGYuYTEgPSBzZWxmLnNpZ21vaWQoc2VsZi56MSkKICAgICAgICBzZWxmLnoyID0gbnAuZG90KHNlbGYuYTEsIHNlbGYuVzIpICsgc2VsZi5iMgogICAgICAgIHNlbGYuYTIgPSBzZWxmLnNpZ21vaWQoc2VsZi56MikKICAgICAgICByZXR1cm4gc2VsZi5hMgogICAgCiAgICBkZWYgYmFja3dhcmQoc2VsZiwgWCwgeSwgb3V0cHV0KToKICAgICAgICBtID0gWC5zaGFwZVswXQogICAgICAgIAogICAgICAgICMg0JPRgNCw0LTQuNC10L3RgiDQstGL0YXQvtC00L3QvtCz0L4g0YHQu9C+0Y8KICAgICAgICBkejIgPSBvdXRwdXQgLSB5CiAgICAgICAgZFcyID0gKDEvbSkgKiBucC5kb3Qoc2VsZi5hMS5ULCBkejIpCiAgICAgICAgZGIyID0gKDEvbSkgKiBucC5zdW0oZHoyLCBheGlzPTAsIGtlZXBkaW1zPVRydWUpCiAgICAgICAgCiAgICAgICAgIyDQk9GA0LDQtNC40LXQvdGCINGB0LrRgNGL0YLQvtCz0L4g0YHQu9C+0Y8KICAgICAgICBkYTEgPSBucC5kb3QoZHoyLCBzZWxmLlcyLlQpCiAgICAgICAgZHoxID0gZGExICogc2VsZi5zaWdtb2lkX2Rlcml2YXRpdmUoc2VsZi5hMSkKICAgICAgICBkVzEgPSAoMS9tKSAqIG5wLmRvdChYLlQsIGR6MSkKICAgICAgICBkYjEgPSAoMS9tKSAqIG5wLnN1bShkejEsIGF4aXM9MCwga2VlcGRpbXM9VHJ1ZSkKICAgICAgICAKICAgICAgICAjINCe0LHQvdC+0LLQu9C10L3QuNC1INC/0LDRgNCw0LzQtdGC0YDQvtCyCiAgICAgICAgc2VsZi5XMiAtPSBzZWxmLmxyICogZFcyCiAgICAgICAgc2VsZi5iMiAtPSBzZWxmLmxyICogZGIyCiAgICAgICAgc2VsZi5XMSAtPSBzZWxmLmxyICogZFcxCiAgICAgICAgc2VsZi5iMSAtPSBzZWxmLmxyICogZGIxCiAgICAKICAgIGRlZiB0cmFpbihzZWxmLCBYLCB5LCBlcG9jaHM9MTAwMDApOgogICAgICAgIGxvc3NlcyA9IFtdCiAgICAgICAgZm9yIGVwb2NoIGluIHJhbmdlKGVwb2Nocyk6CiAgICAgICAgICAgIG91dHB1dCA9IHNlbGYuZm9yd2FyZChYKQogICAgICAgICAgICBsb3NzID0gbnAubWVhbigob3V0cHV0IC0geSkgKiogMikKICAgICAgICAgICAgbG9zc2VzLmFwcGVuZChsb3NzKQogICAgICAgICAgICBzZWxmLmJhY2t3YXJkKFgsIHksIG91dHB1dCkKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIGVwb2NoICUgMTAwMCA9PSAwOgogICAgICAgICAgICAgICAgcHJpbnQoZiJFcG9jaCB7ZXBvY2h9LCBMb3NzOiB7bG9zczouNmZ9IikKICAgICAgICByZXR1cm4gbG9zc2VzCgojINCU0LDQvdC90YvQtSDQtNC70Y8g0L7QsdGD0YfQtdC90LjRjwpYID0gbnAuYXJyYXkoW1swLCAwXSwgWzAsIDFdLCBbMSwgMF0sIFsxLCAxXV0pCnkgPSBucC5hcnJheShbWzFdLCBbMF0sIFswXSwgWzFdXSkgICMgWE5PUgoKIyDQntCx0YPRh9C10L3QuNC1INC4INGC0LXRgdGC0LjRgNC+0LLQsNC90LjQtQpuZXR3b3JrID0gVHJhaW5hYmxlWE5PUihsZWFybmluZ19yYXRlPTAuNSkKbG9zc2VzID0gbmV0d29yay50cmFpbihYLCB5LCBlcG9jaHM9MTAwMDApCgpwcmludCgiXG7QoNC10LfRg9C70YzRgtCw0YLRiyDQv9C+0YHQu9C1INC+0LHRg9GH0LXQvdC40Y86IikKcHJpbnQoIklucHV0ICBUYXJnZXQgIE91dHB1dCAgICBQcmVkaWN0ZWQiKQpmb3IgaSBpbiByYW5nZShsZW4oWCkpOgogICAgb3V0cHV0ID0gbmV0d29yay5mb3J3YXJkKFhbaV0ucmVzaGFwZSgxLCAtMSkpCiAgICBwcmVkaWN0ZWQgPSAxIGlmIG91dHB1dCA+IDAuNSBlbHNlIDAKICAgIHByaW50KGYie1hbaV19ICAge3lbaV1bMF19ICAgICAge291dHB1dFswXVswXTouNGZ9ICAgIHtwcmVkaWN0ZWR9Iik=