diff options
| author | Private Island Networks Inc <opensource@privateisland.tech> | 2026-08-24 20:05:22 -0400 |
|---|---|---|
| committer | Private Island Networks Inc <opensource@privateisland.tech> | 2026-08-24 20:05:22 -0400 |
| commit | aaae2e60f196cbe0ee84f5d9076c4449a4ba0c28 (patch) | |
| tree | d61bd4f3bd878e38406020ab9687f3060cebcc63 /mlp/mlp_1.py | |
Diffstat (limited to 'mlp/mlp_1.py')
| -rw-r--r-- | mlp/mlp_1.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/mlp/mlp_1.py b/mlp/mlp_1.py new file mode 100644 index 0000000..d6d513d --- /dev/null +++ b/mlp/mlp_1.py @@ -0,0 +1,94 @@ +""" + "Building a Simple MLP from Scratch Using PyTorch" by Aymen Noor + https://medium.com/@mn05052002/building-a-simple-mlp-from-scratch-using-pytorch-7d50ca66512b +""" +import torch +import matplotlib.pyplot as plt +from sklearn.datasets import make_moons +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler + +class SimpleMLP(torch.nn.Module): + def __init__(self, input_size, hidden_size, output_size): + super(SimpleMLP, self).__init__() + self.W1 = torch.randn(input_size, hidden_size, requires_grad=True) + self.b1 = torch.randn(1, hidden_size, requires_grad=True) + self.W2 = torch.randn(hidden_size, output_size, requires_grad=True) + self.b2 = torch.randn(1, output_size, requires_grad=True) + + def forward(self, X): + self.z1 = torch.matmul(X, self.W1) + self.b1 + self.a1 = torch.sigmoid(self.z1) # Hidden layer activation + self.z2 = torch.matmul(self.a1, self.W2) + self.b2 + self.a2 = torch.sigmoid(self.z2) # Output layer activation + return self.a2 + + def backward(self,X,y,output,lr=0.01): + m=X.shape[0] + dz2=output-y + dW2=torch.matmul(self.a1.T,dz2) + db2=torch.sum(dz2,axis=0)/m + + da1=torch.matmul(dz2,self.W2.T) + dz1=da1*(self.a1*(1-self.a1)) + dw1=torch.matmul(X.T,dz1)/m + db1 = torch.sum(dz1, axis=0) / m + + with torch.no_grad(): + self.W1 -= lr * dw1 + self.b1 -= lr * db1 + self.W2 -= lr * dW2 + self.b2 -= lr * db2 + + def train(self, X, y, epochs=1000, lr=0.01): + losses = [] + for epoch in range(epochs): + output = self.forward(X) + #Compute loss using (Mean Squared Error) + loss = torch.mean((output - y) ** 2) + losses.append(loss.item()) + #update weights + self.backward(X, y, output, lr) + if (epoch + 1) % 100 == 0: + print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}") + return losses + + +if __name__ == '__main__': + + # Generate dataset + X, y = make_moons(n_samples=1000, noise=0.2, random_state=42) + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + + # Standardize the data + scaler = StandardScaler() + X_train = scaler.fit_transform(X_train) + X_test = scaler.transform(X_test) + + # Convert to PyTorch tensors + X_train = torch.tensor(X_train, dtype=torch.float32) + y_train = torch.tensor(y_train, dtype=torch.float32).reshape(-1, 1) + X_test = torch.tensor(X_test, dtype=torch.float32) + y_test = torch.tensor(y_test, dtype=torch.float32).reshape(-1, 1) + + input_size = 2 + hidden_size = 4 + output_size = 1 + model = SimpleMLP(input_size, hidden_size, output_size) + + #Train model and store the losses + losses = model.train(X_train, y_train, epochs=1000, lr=0.1) + + plt.plot(losses) + plt.xlabel("Epoch") + plt.ylabel("Loss") + plt.title("Training Loss over Epochs") + plt.show() + + with torch.no_grad(): + test_output = model.forward(X_test) + test_output = (test_output > 0.5).float() + accuracy = torch.mean((test_output == y_test).float()) + print(f"Test Accuracy: {accuracy.item() * 100:.2f}%") + + print('finished') |

