import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def sigmoid_derivative(z):
return sigmoid(z) * (1 - sigmoid(z))
def forward_pass(X, params):
W1, b1, W2, b2 = params['W1'], params['b1'], params['W2'], params['b2']
Z1 = np.dot(X, W1) + b1
A1 = sigmoid(Z1)
Z2 = np.dot(A1, W2) + b2
A2 = Z2 # Linear activation for output layer
return A1, A2
def compute_loss(A2, y):
return np.mean((A2 - y) ** 2)
def backward_pass(X, y, A1, A2, params):
m = X.shape[0]
W1, b1, W2, b2 = params['W1'], params['b1'], params['W2'], params['b2']
dZ2 = 2 * (A2 - y) / m
dW2 = np.dot(A1.T, dZ2)
db2 = np.sum(dZ2, axis=0)
dA1 = np.dot(dZ2, W2.T)
dZ1 = dA1 * sigmoid_derivative(np.dot(X, W1) + b1)
dW1 = np.dot(X.T, dZ1)
db1 = np.sum(dZ1, axis=0)
grads = {'dW1': dW1, 'db1': db1, 'dW2': dW2, 'db2': db2}
return grads
def neural_network(X, y, params):
A1, A2 = forward_pass(X, params)
loss = compute_loss(A2, y)
grads = backward_pass(X, y, A1, A2, params)
return loss, grads
# Driver example
X = np.array([[0.5, 0.2], [0.9, 0.7]])
y = np.array([1, 0])
params = {'W1': np.random.rand(2, 3), 'b1': np.random.rand(3), 'W2': np.random.rand(3, 1), 'b2': np.random.rand(1)}
loss, grads = neural_network(X, y, params)
print('Loss:', loss)
print('Gradients:', grads)