summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorPrivate Island Networks Inc <opensource@privateisland.tech>2026-08-24 20:05:22 -0400
committerPrivate Island Networks Inc <opensource@privateisland.tech>2026-08-24 20:05:22 -0400
commitaaae2e60f196cbe0ee84f5d9076c4449a4ba0c28 (patch)
treed61bd4f3bd878e38406020ab9687f3060cebcc63
initial commit to match up with https://privateisland.tech/dev/pi-w-inference-serverHEADmaster
-rw-r--r--.gitignore5
-rw-r--r--infer/__init__.py0
-rw-r--r--infer/http_infer_mlp.py97
-rw-r--r--mlp/.gitignore4
-rw-r--r--mlp/__init__.py0
-rw-r--r--mlp/mlp_1.py94
-rw-r--r--mlp/mlp_2.py79
7 files changed, 279 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..404ad9d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.project
+.pydevproject
+*.bin
+*.xml
+
diff --git a/infer/__init__.py b/infer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/infer/__init__.py
diff --git a/infer/http_infer_mlp.py b/infer/http_infer_mlp.py
new file mode 100644
index 0000000..f7fa227
--- /dev/null
+++ b/infer/http_infer_mlp.py
@@ -0,0 +1,97 @@
+#
+# http_infer_mlp
+#
+import sys
+import numpy as np
+import datetime
+import argparse
+import tritonclient.http as httpclient
+from sklearn.datasets import make_moons
+from sklearn.preprocessing import StandardScaler
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Sends requests via KServe REST API using images in numpy format. '
+ 'It displays performance statistics and optionally the model accuracy')
+ parser.add_argument('--http_address', required=False, default='localhost', help='Specify url to http service. default:localhost')
+ parser.add_argument('--http_port', required=False, default=8000, help='Specify port to http service. default: 8000')
+ parser.add_argument('--input_name', required=False, default='input', help='Specify input tensor name. default: input')
+ parser.add_argument('--output_name', required=False, default='resnet_v1_50/predictions/Reshape_1',
+ help='Specify output name. default: resnet_v1_50/predictions/Reshape_1')
+ parser.add_argument('--iterations', default=1000,
+ help='Number of requests iterations',
+ dest='iterations', type=int)
+ parser.add_argument('--model_name', default='resnet', help='Define model name, must be same as is in service. default: resnet',
+ dest='model_name')
+ parser.add_argument('--pipeline_name', default='', help='Define pipeline name, must be same as is in service',
+ dest='pipeline_name')
+ parser.add_argument('--binary_data', default=False, action='store_true', help='Send input data in binary format', dest='binary_data')
+ parser.add_argument('--tls', default=False, action='store_true', help='use TLS communication with gRPC endpoint')
+ parser.add_argument('--server_cert', required=False, help='Path to server certificate', default=None)
+ parser.add_argument('--client_cert', required=False, help='Path to client certificate', default=None)
+ parser.add_argument('--client_key', required=False, help='Path to client key', default=None)
+
+ args = vars(parser.parse_args())
+ iterations = args.get('iterations')
+
+ # Create the data
+ X, y = make_moons(n_samples=iterations, noise=0.2, random_state=42)
+ scaler = StandardScaler()
+ X = scaler.fit_transform(X)
+
+ address = "{}:{}".format(args['http_address'], args['http_port'])
+ batch_size = 1
+
+ if args['tls']:
+ ssl_options = {
+ 'keyfile':args['client_key'],
+ 'cert_file':args['client_cert'],
+ 'ca_certs':args['server_cert']
+ }
+ else:
+ ssl_options = None
+
+ triton_client = httpclient.InferenceServerClient(
+ url=address,
+ ssl=args['tls'],
+ ssl_options=ssl_options,
+ verbose=False)
+
+ processing_times = np.zeros((0), int)
+
+ print('Start processing:')
+ print('\tModel name: {}'.format(args.get('pipeline_name') if bool(args.get('pipeline_name')) else args.get('model_name')))
+ print('\tIterations: {}'.format(iterations))
+
+ iteration = 0
+ is_pipeline_request = bool(args.get('pipeline_name'))
+ y_test = []
+ num_correct = 0
+
+ while iteration < iterations:
+ inputs = []
+ inputs.append(httpclient.InferInput(args['input_name'], [1,2], "FP32"))
+ point = np.array([X[iteration]],dtype=np.float32)
+ inputs[0].set_data_from_numpy(point)
+ start_time = datetime.datetime.now()
+ results = triton_client.infer(
+ model_name=args.get('pipeline_name') if is_pipeline_request else args.get('model_name'),
+ inputs=inputs)
+ end_time = datetime.datetime.now()
+ duration = (end_time - start_time).total_seconds() * 1000
+ processing_times = np.append(processing_times, np.array([int(duration)]))
+ output = results.as_numpy(args['output_name'])
+ y_test.append(float(output[0][0]))
+ if y[iteration] == round(float(output[0][0])):
+ num_correct += 1
+
+
+ # for object classification models show imagenet class
+ print('Iteration {}; Processing time: {:.2f} ms; speed {:.2f} fps'.format(iteration, round(np.average(duration), 2),
+ round(1000 * batch_size / np.average(duration), 2)
+ ))
+ iteration += 1
+
+
+
+ print('finished with {} out of {} correct'.format(num_correct, iterations))
+
+
diff --git a/mlp/.gitignore b/mlp/.gitignore
new file mode 100644
index 0000000..b4ca3a3
--- /dev/null
+++ b/mlp/.gitignore
@@ -0,0 +1,4 @@
+*.bin
+*.xml
+.project
+.pydevproject
diff --git a/mlp/__init__.py b/mlp/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mlp/__init__.py
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')
diff --git a/mlp/mlp_2.py b/mlp/mlp_2.py
new file mode 100644
index 0000000..4616fb2
--- /dev/null
+++ b/mlp/mlp_2.py
@@ -0,0 +1,79 @@
+"""
+ Create and Train Simple MLP for scikit make_moons.
+ Convert and Save in OpenVino Intermediate Representation (IR)
+
+"""
+
+import openvino as ov
+import torch
+from torch import nn
+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(nn.Module):
+ def __init__(self):
+ super(SimpleMLP, self).__init__()
+ self.layer1 = nn.Linear(2, 4) # Hidden layer
+ self.layer2 = nn.Linear(4, 1) # Output layer
+
+ def forward(self, x):
+ x = self.layer1(x)
+ x = torch.sigmoid(x) # Activation function
+ x = self.layer2(x)
+ return x
+
+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)
+
+ # Plot make_moons
+ fig,ax1 = plt.subplots(nrows=1,ncols=1,figsize=(8,4))
+ ax1.scatter(X[:,0],X[:,1],c=y)
+ plt.show()
+
+ # 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)
+
+ model = SimpleMLP()
+ criterion = nn.MSELoss() # Mean Squared Error for regression
+ optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # Stochastic Gradient Descent
+
+ losses = []
+ for epoch in range(1000): # Number of epochs
+ optimizer.zero_grad() # Clear gradients
+ outputs = model(X_train) # Forward pass
+ loss = criterion(outputs, y_train) # Compute loss
+ loss.backward() # Backward pass
+ losses.append(loss.item())
+ optimizer.step() # Update parameters
+
+ plt.plot(losses)
+ plt.xlabel("Epoch")
+ plt.ylabel("Loss")
+ plt.title("Training Loss over Epochs")
+ plt.show()
+
+ with torch.no_grad():
+ raw_output = model.forward(X_test)
+ test_output = (raw_output > 0.5).float()
+ accuracy = torch.mean((test_output == y_test).float())
+ print(f"Test Accuracy: {accuracy.item() * 100:.2f}%")
+
+ # Convert and Save to OpenVino Intermediate Representation (IR)
+ ov_input=(ov.PartialShape([1, 2]), ov.Type.f32)
+ ov_model = ov.convert_model(model, input=ov_input)
+ compiled_model = ov.compile_model(ov_model, "AUTO")
+ ov.save_model(ov_model,'./mlp.xml')
+
+ print("finished")



Join the Betsy Beta