pykeres 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
keres/__init__.py ADDED
@@ -0,0 +1,100 @@
1
+ """
2
+ keres: A cell-by-cell Deep Learning Practicals Code Guide Library.
3
+ """
4
+
5
+ from .guide import Keres, DLPracticals
6
+
7
+ # Default instance for convenient top-level access
8
+ _default_instance = Keres()
9
+
10
+ def list_practicals():
11
+ """List all available practicals."""
12
+ _default_instance.list_practicals()
13
+
14
+ def mock_practical(cell=None, tweaks=False):
15
+ """View Mock Practical cell-by-cell or with tweak recipes."""
16
+ _default_instance.mock_practical(cell=cell, tweaks=tweaks)
17
+
18
+ def practical_1(cell=None, tweaks=False):
19
+ """View Practical 01 (Perceptron AND/OR) cell-by-cell or with tweak recipes."""
20
+ _default_instance.practical_1(cell=cell, tweaks=tweaks)
21
+
22
+ def practical_2(cell=None, tweaks=False):
23
+ """View Practical 02 (MLP on Fashion-MNIST) cell-by-cell or with tweak recipes."""
24
+ _default_instance.practical_2(cell=cell, tweaks=tweaks)
25
+
26
+ def practical_3(cell=None, tweaks=False):
27
+ """View Practical 03 (L2 vs Dropout Regularization) cell-by-cell or with tweak recipes."""
28
+ _default_instance.practical_3(cell=cell, tweaks=tweaks)
29
+
30
+ def practical_4(cell=None, tweaks=False):
31
+ """View Practical 04 (Activation Functions Analysis) cell-by-cell or with tweak recipes."""
32
+ _default_instance.practical_4(cell=cell, tweaks=tweaks)
33
+
34
+ def practical_5(cell=None, tweaks=False):
35
+ """View Practical 05 (CNN vs MLP on Images) cell-by-cell or with tweak recipes."""
36
+ _default_instance.practical_5(cell=cell, tweaks=tweaks)
37
+
38
+ def practical_6(cell=None, tweaks=False):
39
+ """View Practical 06 (LSTM for IMDB Sentiment) cell-by-cell or with tweak recipes."""
40
+ _default_instance.practical_6(cell=cell, tweaks=tweaks)
41
+
42
+ def practical_7(cell=None, tweaks=False):
43
+ """View Practical 07 (Transfer Learning with MobileNetV2) cell-by-cell or with tweak recipes."""
44
+ _default_instance.practical_7(cell=cell, tweaks=tweaks)
45
+
46
+ def practical_8(cell=None, tweaks=False):
47
+ """View Practical 08 (Hyperparameter Tuning & TensorBoard) cell-by-cell or with tweak recipes."""
48
+ _default_instance.practical_8(cell=cell, tweaks=tweaks)
49
+
50
+ def get_practical(num, cell=None, tweaks=False):
51
+ """Retrieve practical text, specific cell code, or code with tweak recipes."""
52
+ return _default_instance.get_practical(num, cell=cell, tweaks=tweaks)
53
+
54
+ def tweaks(num):
55
+ """View quick tweak recipes (dataset switching, optimizers, viva notes) for a practical."""
56
+ _default_instance.tweaks(num)
57
+
58
+ def get_tweaks(num):
59
+ """Retrieve quick tweak recipe string for a practical."""
60
+ return _default_instance.get_tweaks(num)
61
+
62
+ def guide():
63
+ """Display the built-in quickstart guide and cheat sheet."""
64
+ _default_instance.guide()
65
+
66
+ help = guide
67
+ quickstart = guide
68
+
69
+ def export_all_texts(output_dir):
70
+ """Export all practicals as plaintext files (.txt) to output_dir."""
71
+ _default_instance.export_all_texts(output_dir)
72
+
73
+ def get_cells(num):
74
+ """Retrieve list of cell dicts for a practical."""
75
+ return _default_instance.get_cells(num)
76
+
77
+ __all__ = [
78
+ "Keres",
79
+ "DLPracticals",
80
+ "list_practicals",
81
+ "guide",
82
+ "help",
83
+ "quickstart",
84
+ "mock_practical",
85
+ "practical_1",
86
+ "practical_2",
87
+ "practical_3",
88
+ "practical_4",
89
+ "practical_5",
90
+ "practical_6",
91
+ "practical_7",
92
+ "practical_8",
93
+ "get_practical",
94
+ "get_cells",
95
+ "tweaks",
96
+ "get_tweaks",
97
+ "export_all_texts",
98
+ ]
99
+
100
+ __version__ = "1.0.0"
keres/cli.py ADDED
@@ -0,0 +1,64 @@
1
+ """
2
+ Command-line interface for keres.
3
+ """
4
+
5
+ import argparse
6
+ import sys
7
+ from keres.guide import Keres
8
+
9
+
10
+ def main():
11
+ parser = argparse.ArgumentParser(
12
+ prog="keres",
13
+ description="keres: Deep Learning Practicals Code Guide CLI (Roll No. 23 - Shreyas Daptare)"
14
+ )
15
+ subparsers = parser.add_subparsers(dest="command", help="Command to run")
16
+
17
+ # guide / help
18
+ subparsers.add_parser("guide", help="Show built-in quickstart guide and cheat sheet")
19
+ subparsers.add_parser("help", help="Show built-in quickstart guide and cheat sheet")
20
+
21
+ # list
22
+ subparsers.add_parser("list", help="List all available practicals")
23
+
24
+ # show
25
+ show_parser = subparsers.add_parser("show", help="Display practical code cell-by-cell")
26
+ show_parser.add_argument("number", help="Practical number (0 for Mock, 1..8 for Practicals 1..8)")
27
+ show_parser.add_argument("--cell", type=int, default=None, help="Specific cell number (1-based)")
28
+ show_parser.add_argument("--tweaks", "-t", action="store_true", help="Include quick tweak recipes at the end")
29
+
30
+ # tweaks
31
+ tweaks_parser = subparsers.add_parser("tweaks", help="Display quick tweak recipes (dataset, optimizer, viva)")
32
+ tweaks_parser.add_argument("number", help="Practical number (0 for Mock, 1..8 for Practicals 1..8)")
33
+
34
+ # export
35
+ export_parser = subparsers.add_parser("export", help="Export practicals to a directory")
36
+ export_parser.add_argument("--out", "--out-dir", "-o", dest="out", default="./keres_practicals_txt", help="Output directory")
37
+
38
+ args = parser.parse_args()
39
+ guide = Keres()
40
+
41
+ if args.command in ("guide", "help") or args.command is None:
42
+ guide.guide()
43
+ elif args.command == "list":
44
+ guide.list_practicals()
45
+ elif args.command == "show":
46
+ try:
47
+ guide._display_or_return(args.number, cell=args.cell, tweaks=args.tweaks)
48
+ except Exception as e:
49
+ print(f"Error: {e}", file=sys.stderr)
50
+ sys.exit(1)
51
+ elif args.command == "tweaks":
52
+ try:
53
+ guide.tweaks(args.number)
54
+ except Exception as e:
55
+ print(f"Error: {e}", file=sys.stderr)
56
+ sys.exit(1)
57
+ elif args.command == "export":
58
+ guide.export_all_texts(args.out)
59
+ else:
60
+ parser.print_help()
61
+
62
+
63
+ if __name__ == "__main__":
64
+ main()
keres/data/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # keres data package
@@ -0,0 +1,220 @@
1
+ ================================================================================
2
+ # Mock Practical: Neural Network Training with Different Loss Functions
3
+ # Library: keres | Framework: PyTorch | Total Cells: 5
4
+ ================================================================================
5
+
6
+
7
+ # --------------------------------------------------------------------------------
8
+ # [CELL 1 / 5] : Imports & Environment Setup
9
+ # --------------------------------------------------------------------------------
10
+ import random
11
+ import numpy as np
12
+ import matplotlib.pyplot as plt
13
+ import torch
14
+ import torch.nn as nn
15
+ from torch.utils.data import TensorDataset, DataLoader
16
+ from sklearn.datasets import load_digits
17
+ from sklearn.model_selection import train_test_split
18
+ from sklearn.preprocessing import StandardScaler
19
+
20
+
21
+ # --------------------------------------------------------------------------------
22
+ # [CELL 2 / 5] : Random Seed & Reproducibility Setup
23
+ # --------------------------------------------------------------------------------
24
+ SEED = 42
25
+ torch.manual_seed(SEED)
26
+ np.random.seed(SEED)
27
+ random.seed(SEED)
28
+
29
+
30
+ # --------------------------------------------------------------------------------
31
+ # [CELL 3 / 5] : Synthetic Dataset Generation (Binary Classification)
32
+ # --------------------------------------------------------------------------------
33
+ # Dataset
34
+ digits = load_digits()
35
+ X = digits.data.astype(np.float32)
36
+ y = digits.target
37
+
38
+ X_train, X_val, y_train, y_val = train_test_split(
39
+ X, y, test_size=0.20, stratify=y, random_state=SEED
40
+ )
41
+
42
+ scaler = StandardScaler()
43
+ X_train = scaler.fit_transform(X_train).astype(np.float32)
44
+ X_val = scaler.transform(X_val).astype(np.float32)
45
+
46
+ train_loader = DataLoader(
47
+ TensorDataset(torch.tensor(X_train), torch.tensor(y_train)),
48
+ batch_size=64, shuffle=True
49
+ )
50
+ val_loader = DataLoader(
51
+ TensorDataset(torch.tensor(X_val), torch.tensor(y_val)),
52
+ batch_size=256
53
+ )
54
+
55
+
56
+ # --------------------------------------------------------------------------------
57
+ # [CELL 4 / 5] : MLP Architecture, Training Loop & Loss Function Experiments
58
+ # --------------------------------------------------------------------------------
59
+ # Same MLP architecture for all experiments
60
+ class MLP(nn.Module):
61
+ def __init__(self, activation):
62
+ super().__init__()
63
+ self.net = nn.Sequential(
64
+ nn.Linear(64, 128), activation(),
65
+ nn.Linear(128, 128), activation(),
66
+ nn.Linear(128, 64), activation(),
67
+ nn.Linear(64, 10)
68
+ )
69
+
70
+ def forward(self, x):
71
+ return self.net(x)
72
+
73
+ activations = {
74
+ "Sigmoid": nn.Sigmoid,
75
+ "Tanh": nn.Tanh,
76
+ "ReLU": nn.ReLU
77
+ }
78
+
79
+ criterion = nn.CrossEntropyLoss()
80
+ results = {}
81
+
82
+ for name, activation in activations.items():
83
+ torch.manual_seed(SEED)
84
+ model = MLP(activation)
85
+ optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
86
+
87
+ losses, accuracies, gradients = [], [], []
88
+
89
+ print(f"\nTraining with {name}")
90
+
91
+ for epoch in range(5):
92
+ model.train()
93
+ total_loss = 0
94
+ batch_gradients = []
95
+
96
+ for xb, yb in train_loader:
97
+ optimizer.zero_grad()
98
+
99
+ output = model(xb)
100
+ loss = criterion(output, yb)
101
+ loss.backward()
102
+
103
+ # Global L2 gradient norm
104
+ sq_norm = sum(
105
+ p.grad.detach().pow(2).sum().item()
106
+ for p in model.parameters()
107
+ if p.grad is not None
108
+ )
109
+ batch_gradients.append(np.sqrt(sq_norm))
110
+
111
+ optimizer.step()
112
+ total_loss += loss.item() * len(yb)
113
+
114
+ epoch_loss = total_loss / len(X_train)
115
+
116
+ model.eval()
117
+ correct = total = 0
118
+ with torch.no_grad():
119
+ for xb, yb in val_loader:
120
+ pred = model(xb).argmax(dim=1)
121
+ correct += (pred == yb).sum().item()
122
+ total += len(yb)
123
+
124
+ accuracy = 100 * correct / total
125
+ gradient = np.mean(batch_gradients)
126
+
127
+ losses.append(epoch_loss)
128
+ accuracies.append(accuracy)
129
+ gradients.append(gradient)
130
+
131
+ print(
132
+ f"Epoch {epoch+1}: "
133
+ f"Loss={epoch_loss:.4f}, "
134
+ f"Val Acc={accuracy:.2f}%"
135
+ )
136
+
137
+ results[name] = {
138
+ "loss": losses,
139
+ "accuracy": accuracies,
140
+ "gradient": gradients
141
+ }
142
+
143
+
144
+ # --------------------------------------------------------------------------------
145
+ # [CELL 5 / 5] : Comparative Loss & Accuracy Curve Visualization
146
+ # --------------------------------------------------------------------------------
147
+ # Plot results
148
+ epochs = np.arange(1, 6)
149
+ fig, axes = plt.subplots(1, 3, figsize=(13, 4.5))
150
+
151
+ for name in activations:
152
+ axes[0].plot(epochs, results[name]["loss"], marker="o", label=name)
153
+ axes[1].plot(epochs, results[name]["accuracy"], marker="o", label=name)
154
+ axes[2].plot(epochs, results[name]["gradient"], marker="o", label=name)
155
+
156
+ axes[0].set_title("Training Loss")
157
+ axes[0].set_xlabel("Epoch")
158
+ axes[0].set_ylabel("Loss")
159
+
160
+ axes[1].set_title("Validation Accuracy")
161
+ axes[1].set_xlabel("Epoch")
162
+ axes[1].set_ylabel("Accuracy (%)")
163
+
164
+ axes[2].set_title("Gradient Norms (Flow)")
165
+ axes[2].set_xlabel("Epoch")
166
+ axes[2].set_ylabel("Average Gradient Norm")
167
+
168
+ for ax in axes:
169
+ ax.set_xticks(epochs)
170
+ ax.grid(alpha=0.2)
171
+ ax.legend()
172
+
173
+ plt.tight_layout()
174
+ plt.savefig("activation_functions_output.png", dpi=180)
175
+ plt.show()
176
+
177
+ ================================================================================
178
+ 💡 QUICK TWEAK RECIPES FOR MOCK PRACTICAL (Multi-Loss MLP in PyTorch):
179
+ ================================================================================
180
+ 1. SWITCH TO LOCAL CSV VIA PANDAS:
181
+ import pandas as pd
182
+ from sklearn.model_selection import train_test_split
183
+ from sklearn.preprocessing import StandardScaler
184
+ df = pd.read_csv('your_dataset.csv')
185
+ X_raw = df.drop('target', axis=1).values
186
+ y_raw = df['target'].values
187
+ X_tr, X_te, y_tr, y_te = train_test_split(X_raw, y_raw, test_size=0.2, random_state=42)
188
+ scaler = StandardScaler()
189
+ X_train = torch.tensor(scaler.fit_transform(X_tr), dtype=torch.float32)
190
+ X_test = torch.tensor(scaler.transform(X_te), dtype=torch.float32)
191
+ y_train = torch.tensor(y_tr, dtype=torch.long)
192
+ y_test = torch.tensor(y_te, dtype=torch.long)
193
+
194
+ 2. SWITCH OPTIMIZERS:
195
+ # Adam (Default):
196
+ optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
197
+ # SGD with Momentum:
198
+ optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
199
+ # RMSprop:
200
+ optimizer = torch.optim.RMSprop(model.parameters(), lr=0.005)
201
+ # AdamW (Adam + decoupled Weight Decay):
202
+ optimizer = torch.optim.AdamW(model.parameters(), lr=0.01, weight_decay=1e-4)
203
+
204
+ 3. SWITCH LOSS FUNCTIONS:
205
+ # Multi-class Classification:
206
+ criterion = nn.CrossEntropyLoss()
207
+ # Regression / Continuous:
208
+ criterion = nn.MSELoss() # or nn.L1Loss()
209
+ # Robust Regression (less sensitive to outliers):
210
+ criterion = nn.SmoothL1Loss(beta=1.0)
211
+ # Binary Classification:
212
+ criterion = nn.BCEWithLogitsLoss()
213
+
214
+ 4. ADD DROPOUT & BATCH NORMALIZATION:
215
+ # Inside SimpleMLP __init__:
216
+ self.fc1 = nn.Linear(input_dim, 64)
217
+ self.bn1 = nn.BatchNorm1d(64)
218
+ self.dropout = nn.Dropout(0.3)
219
+ self.fc2 = nn.Linear(64, num_classes)
220
+ ================================================================================
@@ -0,0 +1,204 @@
1
+ ================================================================================
2
+ # Practical 01: Single-Layer Perceptron for AND and OR Gates
3
+ # Library: keres | Framework: NumPy / Matplotlib | Total Cells: 2
4
+ ================================================================================
5
+
6
+
7
+ # --------------------------------------------------------------------------------
8
+ # [CELL 1 / 2] : Perceptron Class & AND Gate Decision Boundary Plot
9
+ # --------------------------------------------------------------------------------
10
+ import numpy as np
11
+ import matplotlib.pyplot as plt
12
+
13
+ def step_function(x):
14
+ return np.where(x >= 0, 1, 0)
15
+
16
+ class Perceptron:
17
+ def __init__(self, input_size, learning_rate=0.1, epochs=10):
18
+ self.weights = np.zeros(input_size + 1)
19
+ self.lr = learning_rate
20
+ self.epochs = epochs
21
+
22
+ def predict(self, x):
23
+ x = np.insert(x, 0, 1)
24
+ return step_function(np.dot(self.weights, x))
25
+
26
+ def train(self, X, y):
27
+ for epoch in range(self.epochs):
28
+ total_error = 0
29
+
30
+ for xi, target in zip(X, y):
31
+ xi_bias = np.insert(xi, 0, 1)
32
+
33
+ output = step_function(np.dot(self.weights, xi_bias))
34
+ error = target - output
35
+ total_error += abs(error)
36
+
37
+ self.weights += self.lr * error * xi_bias
38
+
39
+ print(f"Epoch {epoch+1}: Error = {total_error}")
40
+
41
+ X = np.array([
42
+ [0, 0],
43
+ [0, 1],
44
+ [1, 0],
45
+ [1, 1]
46
+ ])
47
+
48
+ y = np.array([0, 0, 0, 1])
49
+
50
+ p = Perceptron(input_size=2)
51
+ p.train(X, y)
52
+
53
+ print("\nFinal Weights:", p.weights)
54
+
55
+ print("\nPredictions:")
56
+ for sample in X:
57
+ print(sample, "->", p.predict(sample))
58
+
59
+ def plot_decision_boundary(model, X, y):
60
+ x_min, x_max = -0.2, 1.2
61
+ y_min, y_max = -0.2, 1.2
62
+
63
+ xx, yy = np.meshgrid(
64
+ np.linspace(x_min, x_max, 100),
65
+ np.linspace(y_min, y_max, 100)
66
+ )
67
+
68
+ Z = np.array([
69
+ model.predict(np.array([x, y]))
70
+ for x, y in zip(xx.ravel(), yy.ravel())
71
+ ])
72
+
73
+ Z = Z.reshape(xx.shape)
74
+
75
+ plt.figure(figsize=(6,5))
76
+ plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
77
+ plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.coolwarm,
78
+ edgecolors='black', s=120)
79
+
80
+ plt.title("Decision Boundary of Perceptron (AND Gate)")
81
+ plt.xlabel("Input 1")
82
+ plt.ylabel("Input 2")
83
+ plt.grid(True)
84
+ plt.show()
85
+
86
+ plot_decision_boundary(p, X, y)
87
+
88
+
89
+ # --------------------------------------------------------------------------------
90
+ # [CELL 2 / 2] : Perceptron Class & OR Gate Decision Boundary Plot
91
+ # --------------------------------------------------------------------------------
92
+ import numpy as np
93
+ import matplotlib.pyplot as plt
94
+
95
+ def step_function(x):
96
+ return np.where(x >= 0, 1, 0)
97
+
98
+ class Perceptron:
99
+ def __init__(self, input_size, learning_rate=0.1, epochs=10):
100
+ self.weights = np.zeros(input_size + 1)
101
+ self.lr = learning_rate
102
+ self.epochs = epochs
103
+
104
+ def predict(self, x):
105
+ x = np.insert(x, 0, 1)
106
+ return step_function(np.dot(self.weights, x))
107
+
108
+ def train(self, X, y):
109
+ for epoch in range(self.epochs):
110
+ total_error = 0
111
+
112
+ for xi, target in zip(X, y):
113
+ xi_bias = np.insert(xi, 0, 1)
114
+
115
+ output = step_function(np.dot(self.weights, xi_bias))
116
+ error = target - output
117
+ total_error += abs(error)
118
+
119
+ self.weights += self.lr * error * xi_bias
120
+
121
+ print(f"Epoch {epoch+1}: Error = {total_error}")
122
+
123
+ X = np.array([
124
+ [0, 0],
125
+ [0, 1],
126
+ [1, 0],
127
+ [1, 1]
128
+ ])
129
+
130
+ y = np.array([0, 1, 1, 1])
131
+
132
+ p = Perceptron(input_size=2)
133
+ p.train(X, y)
134
+
135
+ print("\nFinal Weights:", p.weights)
136
+
137
+ print("\nPredictions:")
138
+ for sample in X:
139
+ print(sample, "->", p.predict(sample))
140
+
141
+ def plot_decision_boundary(model, X, y):
142
+ x_min, x_max = -0.2, 1.2
143
+ y_min, y_max = -0.2, 1.2
144
+
145
+ xx, yy = np.meshgrid(
146
+ np.linspace(x_min, x_max, 100),
147
+ np.linspace(y_min, y_max, 100)
148
+ )
149
+
150
+ Z = np.array([
151
+ model.predict(np.array([x, y]))
152
+ for x, y in zip(xx.ravel(), yy.ravel())
153
+ ])
154
+
155
+ Z = Z.reshape(xx.shape)
156
+
157
+ plt.figure(figsize=(6,5))
158
+ plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
159
+ plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.coolwarm,
160
+ edgecolors='black', s=120)
161
+
162
+ plt.title("Decision Boundary of Perceptron (OR Gate)")
163
+ plt.xlabel("Input 1")
164
+ plt.ylabel("Input 2")
165
+ plt.grid(True)
166
+ plt.show()
167
+
168
+ plot_decision_boundary(p, X, y)
169
+
170
+ ================================================================================
171
+ 💡 QUICK TWEAK RECIPES FOR PRACTICAL 01 (Perceptron for Logic Gates in NumPy):
172
+ ================================================================================
173
+ 1. SWITCH TO LOCAL CSV VIA PANDAS:
174
+ import pandas as pd
175
+ df = pd.read_csv('logic_gate.csv') # CSV with columns: x1, x2, target
176
+ X = df[['x1', 'x2']].values
177
+ y = df['target'].values
178
+
179
+ 2. SWITCH LOGIC GATES:
180
+ # AND Gate (Default):
181
+ y = np.array([0, 0, 0, 1])
182
+ # OR Gate:
183
+ y = np.array([0, 1, 1, 1])
184
+ # NAND Gate:
185
+ y = np.array([1, 1, 1, 0])
186
+ # NOR Gate:
187
+ y = np.array([1, 0, 0, 0])
188
+ # XOR Gate (VIVA TRICK: Single perceptron CANNOT solve XOR because XOR is non-linearly separable!):
189
+ y = np.array([0, 1, 1, 0])
190
+
191
+ 3. HYPERPARAMETER TWEAKS:
192
+ # Slower, smoother learning:
193
+ p = Perceptron(input_size=2, learning_rate=0.01, epochs=30)
194
+ # Faster, aggressive updates:
195
+ p = Perceptron(input_size=2, learning_rate=0.5, epochs=10)
196
+
197
+ 4. SWITCH ACTIVATION FUNCTION:
198
+ # Bipolar Step Function (-1 or +1 output):
199
+ def step_function_bipolar(x):
200
+ return np.where(x >= 0, 1, -1)
201
+ # Sigmoid Perceptron (Continuous output [0, 1]):
202
+ def sigmoid(x):
203
+ return 1 / (1 + np.exp(-x))
204
+ ================================================================================