Skip to content

Commit 5791190

Browse files
authored
Create artificial_neural_network.py
1 parent dba8eec commit 5791190

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import numpy as np
2+
3+
4+
class SimpleANN:
5+
"""
6+
Simple Artificial Neural Network (ANN)
7+
8+
- Feedforward Neural Network with 1 hidden layer and Sigmoid activation.
9+
- Uses Gradient Descent for backpropagation and Mean Squared Error (MSE) as the loss function.
10+
- Example demonstrates solving the XOR problem.
11+
"""
12+
13+
def __init__(
14+
self,
15+
input_size: int,
16+
hidden_size: int,
17+
output_size: int,
18+
learning_rate: float = 0.1,
19+
) -> None:
20+
"""
21+
Initialize the neural network with random weights and biases.
22+
23+
Args:
24+
input_size (int): Number of input features.
25+
hidden_size (int): Number of neurons in the hidden layer.
26+
output_size (int): Number of neurons in the output layer.
27+
learning_rate (float): Learning rate for gradient descent.
28+
29+
Example:
30+
>>> ann = SimpleANN(2, 2, 1)
31+
>>> isinstance(ann, SimpleANN)
32+
True
33+
"""
34+
rng = np.random.default_rng()
35+
self.weights_input_hidden = rng.standard_normal((input_size, hidden_size))
36+
self.weights_hidden_output = rng.standard_normal((hidden_size, output_size))
37+
self.bias_hidden = np.zeros((1, hidden_size))
38+
self.bias_output = np.zeros((1, output_size))
39+
self.learning_rate = learning_rate
40+
41+
def sigmoid(self, value: np.ndarray) -> np.ndarray:
42+
"""
43+
Sigmoid activation function.
44+
45+
Args:
46+
value (ndarray): Input value for activation.
47+
48+
Returns:
49+
ndarray: Activated output using sigmoid function.
50+
51+
Example:
52+
>>> ann = SimpleANN(2, 2, 1)
53+
>>> ann.sigmoid(np.array([0]))
54+
array([0.5])
55+
"""
56+
return 1 / (1 + np.exp(-value))
57+
58+
def sigmoid_derivative(self, sigmoid_output: np.ndarray) -> np.ndarray:
59+
"""
60+
Derivative of the sigmoid function.
61+
62+
Args:
63+
sigmoid_output (ndarray): Output after applying the sigmoid function.
64+
65+
Returns:
66+
ndarray: Derivative of the sigmoid function.
67+
68+
Example:
69+
>>> ann = SimpleANN(2, 2, 1)
70+
>>> output = ann.sigmoid(np.array([0.5]))
71+
>>> ann.sigmoid_derivative(output)
72+
array([0.25])
73+
"""
74+
return sigmoid_output * (1 - sigmoid_output)
75+
76+
def feedforward(self, inputs: np.ndarray) -> np.ndarray:
77+
"""
78+
Perform forward propagation through the network.
79+
80+
Args:
81+
inputs (ndarray): Input features for the network.
82+
83+
Returns:
84+
ndarray: Output from the network after feedforward pass.
85+
86+
Example:
87+
>>> ann = SimpleANN(2, 2, 1)
88+
>>> inputs = np.array([[0, 0], [1, 1]])
89+
>>> ann.feedforward(inputs).shape
90+
(2, 1)
91+
"""
92+
self.hidden_input = np.dot(inputs, self.weights_input_hidden) + self.bias_hidden
93+
self.hidden_output = self.sigmoid(self.hidden_input)
94+
self.final_input = (
95+
np.dot(self.hidden_output, self.weights_hidden_output) + self.bias_output
96+
)
97+
self.final_output = self.sigmoid(self.final_input)
98+
return self.final_output
99+
100+
def backpropagation(
101+
self, inputs: np.ndarray, targets: np.ndarray, outputs: np.ndarray
102+
) -> None:
103+
"""
104+
Perform backpropagation to adjust the weights and biases.
105+
106+
Args:
107+
inputs (ndarray): Input features.
108+
targets (ndarray): True output labels.
109+
outputs (ndarray): Output predicted by the network.
110+
111+
Example:
112+
>>> ann = SimpleANN(2, 2, 1)
113+
>>> inputs = np.array([[0, 0], [1, 1]])
114+
>>> outputs = ann.feedforward(inputs)
115+
>>> targets = np.array([[0], [1]])
116+
>>> ann.backpropagation(inputs, targets, outputs)
117+
"""
118+
error = targets - outputs
119+
output_gradient = error * self.sigmoid_derivative(outputs)
120+
hidden_error = output_gradient.dot(self.weights_hidden_output.T)
121+
hidden_gradient = hidden_error * self.sigmoid_derivative(self.hidden_output)
122+
123+
self.weights_hidden_output += (
124+
self.hidden_output.T.dot(output_gradient) * self.learning_rate
125+
)
126+
self.bias_output += (
127+
np.sum(output_gradient, axis=0, keepdims=True) * self.learning_rate
128+
)
129+
130+
self.weights_input_hidden += inputs.T.dot(hidden_gradient) * self.learning_rate
131+
self.bias_hidden += (
132+
np.sum(hidden_gradient, axis=0, keepdims=True) * self.learning_rate
133+
)
134+
135+
def train(
136+
self, inputs: np.ndarray, targets: np.ndarray, epochs: int = 10000
137+
) -> None:
138+
"""
139+
Train the neural network on the given input and target data.
140+
141+
Args:
142+
inputs (ndarray): Input features for training.
143+
targets (ndarray): True labels for training.
144+
epochs (int): Number of training iterations.
145+
146+
Example:
147+
>>> ann = SimpleANN(2, 2, 1)
148+
>>> inputs = np.array([[0, 0], [1, 1]])
149+
>>> targets = np.array([[0], [1]])
150+
>>> ann.train(inputs, targets, epochs=1)
151+
"""
152+
for epoch in range(epochs):
153+
outputs = self.feedforward(inputs)
154+
self.backpropagation(inputs, targets, outputs)
155+
if epoch % 1000 == 0:
156+
loss = np.mean(np.square(targets - outputs))
157+
print(f"Epoch {epoch}, Loss: {loss}")
158+
159+
def predict(self, inputs: np.ndarray) -> np.ndarray:
160+
"""
161+
Predict the output for new input data.
162+
163+
Args:
164+
inputs (ndarray): Input data for prediction.
165+
166+
Returns:
167+
ndarray: Predicted output from the network.
168+
169+
Example:
170+
>>> ann = SimpleANN(2, 2, 1)
171+
>>> inputs = np.array([[0, 0], [1, 1]])
172+
>>> ann.predict(inputs).shape
173+
(2, 1)
174+
"""
175+
return self.feedforward(inputs)

0 commit comments

Comments
 (0)