init commit

This commit is contained in:
2025-11-08 19:15:39 +01:00
parent ecffcb08e8
commit c7adacf53b
470 changed files with 73751 additions and 0 deletions

43
__init__.py Normal file
View File

@@ -0,0 +1,43 @@
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
__version__ = "8.3.204"
import importlib
import os
# Set ENV variables (place before imports)
if not os.environ.get("OMP_NUM_THREADS"):
os.environ["OMP_NUM_THREADS"] = "1" # default for reduced CPU utilization during training
from ultralytics.utils import ASSETS, SETTINGS
from ultralytics.utils.checks import check_yolo as checks
from ultralytics.utils.downloads import download
settings = SETTINGS
MODELS = ("YOLO", "YOLOWorld", "YOLOE", "NAS", "SAM", "FastSAM", "RTDETR")
__all__ = (
"__version__",
"ASSETS",
*MODELS,
"checks",
"download",
"settings",
)
def __getattr__(name: str):
"""Lazy-import model classes on first access."""
if name in MODELS:
return getattr(importlib.import_module("ultralytics.models"), name)
raise AttributeError(f"module {__name__} has no attribute {name}")
def __dir__():
"""Extend dir() to include lazily available model names for IDE autocompletion."""
return sorted(set(globals()) | set(MODELS))
if __name__ == "__main__":
print(__version__)

101
datasets/MC_NDCC.py Executable file
View File

@@ -0,0 +1,101 @@
# TITLE: Multi-Class Normal Distribution Cubic Clusters Dataset Generator
# AUTHOR: Dr. Hossein Moosaei, Saeed Khosravi
# Date: 10/09/2020
# NORMALLY DISTRIBUTED CLUSTERS is a data generator.
# It generates a series of random centers for multivariate
#normal distributions. NDC randomly generates a fraction
# of data for each center, i.e. what fraction of data points
# will come from this center. NDC randomly generates a
# separating plane. Based on this plane, classes for are
# chosen for each center. NDC then randomly generates the
# points from the distributions. NDC can increase
# inseparability by increasng variances of distributions.
# A measure of "true" separability is obtained by looking
# at how many points end up on the wrong side of the
# separating plane. All values are taken as integers
# for simplicity.
import numpy as np
import pandas as pd
class MC_NDCC:
def __init__(self,n_centers, n_samples, n_features, n_classes):
# self.n_samples = int(input("Enter number of samples: \n"))
# self.n_features = int(input("Enter number of features: \n"))
# self.n_classes = int(input("Enter number of classes: \n"))
centers = [100, 300, 500, 700]
self.centers_list = centers[0:n_centers]
self.n_samples = n_samples
self.n_features = n_features
self.n_classes = n_classes
self.center_points = self.centers_matrix(self.centers_list, self.n_features)
self.n_centers = 2*len(self.centers_list)*self.n_features
self.class_locations = self.class_center_locations(self.n_classes, self.n_centers)
self.ss = self.sample_spliter(self.n_samples, self.n_classes, self.n_centers)
r, c = self.class_locations.shape
self.M = np.zeros((0, self.n_features))
self.l = np.zeros((0, 1))
for i in range(r):
for j in range(c):
self.temp = np.random.normal(loc = self.center_points[int(self.class_locations[i, j])],size = (int(self.ss[i,j]), self.n_features),scale = 5)
self.label_temp = np.ones((int(self.ss[i,j]), 1))*(i+1)
self.l = np.concatenate((self.l, self.label_temp), axis = 0)
self.M = np.concatenate((self.M, self.temp) , axis = 0)
self.M = np.concatenate((self.M, self.l), axis = 1).astype('int32')
np.random.shuffle(self.M)
def sample_spliter(self, n_samples, n_classes, n_centers):
# This function generates the number of samples belongs to each class
# Centers approximately have n_centers/n_classes samples with a small variance
count = 0
n_cen_fe_cls = int(np.floor(n_centers/n_classes))
n_each_c = np.zeros((n_classes, n_cen_fe_cls))
while(n_samples > count):
r = np.random.randint(n_classes)
r2 = np.random.randint(n_cen_fe_cls)
n_each_c[r, r2] += 1
count += 1
return n_each_c
def class_center_locations(self, n_classes, n_centers):
# This function specifies which center
# points belong to which classes
# It returns a matrix in size of n_classess by
# n_centers_for_each_class that means a row for each class
rng = np.random.default_rng()
# Generate list of random non-repeatative numbers from 1 to n_center
locs = rng.choice(n_centers, n_centers, replace=False)
# number of centers for each class
n_cen_fe_cls = int(np.floor(n_centers/n_classes))
cls_locs = np.zeros((n_classes,n_cen_fe_cls))
k = 0
for i in range(n_classes):
for j in range(n_cen_fe_cls):
cls_locs[i,j] = locs[k]
k += 1
return cls_locs
def centers_matrix(self, centers_list, n_features):
# This function returns the matrix of center locations
# based on centers_list in n_features space
n_centers = 2*len(centers_list)*n_features
centers_matrix = np.zeros((n_centers, n_features))
for i in range(len(centers_list)):
for j in range(n_features):
centers_matrix[i*2*n_features + 2*j , j] = centers_list[i]
centers_matrix[i*2*n_features + 2*j+1, j] = -centers_list[i]
return centers_matrix
def get_matrix(self):
# Get the dataset as a numpy matrix
return self.M
def get_csv(self, filename):
# Save the dataset as csv file
df = pd.DataFrame(self.M)
df.to_csv(filename, header = False, index = False)
print(f'Dataset saved as {filename} in current directory. ')

0
datasets/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

17
datasets/datasets.py Normal file
View File

@@ -0,0 +1,17 @@
DATASETS = [
"bill",
"brain",
"glass",
"hcv",
"heart",
"ionosphere",
"iris",
"raisin",
"sonar",
"wholesale",
"wine",
"yeast"
]

22
main.py Normal file
View File

@@ -0,0 +1,22 @@
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from routes import resume, articles, projects
app = FastAPI()
app.mount("/static", StaticFiles(directory="templates/static"), name="static")
templates = Jinja2Templates(directory="templates")
app.include_router(articles.router)
app.include_router(projects.router)
app.include_router(resume.router)
@app.get("/{full_path:path}")
async def catch_all(request: Request, full_path: str):
return templates.TemplateResponse(
"404.html",
{"request": request, "path": full_path},
status_code=404
)

104
models/LSTSVM.py Normal file
View File

@@ -0,0 +1,104 @@
"""
Article : Least squares twin support vector machines for pattern classification
Link : https://sci-hub.tw/https://www.sciencedirect.com/science/article/abs/pii/S0957417408006854
Author : Saeed Khosravi
"""
import numpy as np
class LSTSVM:
"""
Least Squares Support Vector Machines
A = Instances with label +1
B = Instances with label -1
C1 = hyperparameter for hyperplane 1
C2 = hyperparameter for hyperplane 2
"""
def __init__(self, X, y, C1, C2, eps = 1e-4):
self.A = X[np.ix_(y[:,0] == 1),:][0,:,:]
self.B = X[np.ix_(y[:,0] == -1),:][0,:,:]
self.C1 = C1
self.C2 = C2
self.eps = eps
def fit(self):
A = self.A
B = self.B
C1 = self.C1
C2 = self.C2
eps = self.eps
m1, n = A.shape
m2, n = B.shape
e1 = np.ones((m1, 1))
e2 = np.ones((m2, 1))
X = np.concatenate((A, B), axis=0)
G = np.concatenate((A, e1), axis=1)
H = np.concatenate((B, e2), axis=1)
if(m1 < m2):
Y = self.calc_Y_or_Z(H)
#w1, b1
GYGT = np.dot(np.dot(G, Y), G.T)
I = np.eye(GYGT.shape[0], GYGT.shape[1])
w1_b1 = - np.dot(Y - np.dot(np.dot(np.dot(Y, G.T), np.linalg.inv(C1*I + GYGT)), np.dot(G, Y)),
np.dot(H.T, np.ones((H.T.shape[1], 1))))
w1 = w1_b1[:-1, :]
b1 = w1_b1[ -1, :]
#w2, b2
w2_b2 = C2 * np.dot(Y - np.dot(np.dot(np.dot(Y, G.T), np.linalg.inv((I/C2)+GYGT)), np.dot(G, Y)),
np.dot(G.T, np.ones((G.T.shape[1], 1))))
w2 = w2_b2[:-1, :]
b2 = w2_b2[ -1, :]
else:
Z = self.calc_Y_or_Z(G)
#w1, b1
HZHT = np.dot(np.dot(H, Z), H.T)
I = np.eye(HZHT.shape[0], HZHT.shape[1])
w1_b1 = -C1*np.dot(Z - np.dot(np.dot(np.dot(Z, H.T), np.linalg.inv((I/C1) + HZHT)), np.dot(H, Z)),
np.dot(H.T, np.ones((H.T.shape[1], 1))))
w1 = w1_b1[:-1, :]
b1 = w1_b1[ -1, :]
#w2, b2
w2_b2 = np.dot(Z - np.dot(np.dot(np.dot(Z, H.T), np.linalg.inv(C2*I + HZHT)), np.dot(H, Z)),
np.dot(G.T, np.ones((G.T.shape[1], 1))))
w2 = w2_b2[:-1, :]
b2 = w2_b2[ -1, :]
self.w1 = w1
self.w2 = w2
self.b1 = b1
self.b2 = b2
def predict(self, x_test, y_test):
distance1 = np.abs(np.dot(x_test, self.w1) + self.b1)
distance2 = np.abs(np.dot(x_test, self.w2) + self.b2)
y_pred = np.zeros_like(y_test)
for d in range(y_pred.shape[0]):
if (distance1[d] < distance2[d]):
y_pred[d][0] = 1;
else:
y_pred[d][0] = -1;
self.preds = y_pred
def calc_Y_or_Z(self, M):
MMT = np.dot(M, M.T)
I = np.eye(MMT.shape[0], MMT.shape[1])
tmp = np.dot(np.dot(M.T, np.linalg.inv(self.eps*I + MMT)), M)
I = np.eye(tmp.shape[0], tmp.shape[1])
return (1/self.eps)*(I-tmp)
def get_params(self):
return self.w1, self.b1, self.w2, self.b2
def get_preds(self):
return self.preds
def score(self, y_test):
accuracy = np.sum(self.preds == y_test)/y_test.shape[0]
return accuracy

160
models/NewtonUTSVM.py Executable file
View File

@@ -0,0 +1,160 @@
import numpy as np
class NewtonUTSVM:
def __init__(self, X, y, U, C, eps=1e-4):
self.X = np.asarray(X, dtype=np.float64)
self.y = np.asarray(y, dtype=np.float64).reshape(-1, 1)
self.U = np.asarray(U, dtype=np.float64)
self.C = np.asarray(C, dtype=np.float64)
self.eps = eps
def fit(self):
np.random.seed(42)
self.w1 = np.random.normal(0, 0.01, (self.X.shape[1], 1))
self.b1 = 0.0
self.w2 = np.random.normal(0, 0.01, (self.X.shape[1], 1))
self.b2 = 0.0
for _ in range(5):
self.w1, self.b1 = self.plane1(self.X, self.y, self.U,
self.C[0], self.C[1], self.C[2], self.eps)
self.w2, self.b2 = self.plane2(self.X, self.y, self.U,
self.C[3], self.C[4], self.C[5], self.eps)
def predict(self, x_test):
x_test = np.asarray(x_test, dtype=np.float64)
dist1 = self._safe_distance(x_test, self.w1, self.b1)
dist2 = self._safe_distance(x_test, self.w2, self.b2)
y_pred = np.where(dist1 < dist2, 1, -1).reshape(-1, 1)
self.preds = y_pred
return y_pred
def _safe_distance(self, X, w, b):
norm = np.linalg.norm(w)
if norm < 1e-10:
return np.full((X.shape[0],), np.inf)
return np.abs(X @ w + b) / norm
def plane1(self, X, y, U, C1, C2, C3, eps):
A = X[y[:,0] == 1]
B = X[y[:,0] == -1]
T1 = np.hstack([A, np.ones((A.shape[0], 1))])
T2 = np.hstack([B, np.ones((B.shape[0], 1))])
T3 = np.hstack([U, np.ones((U.shape[0], 1))])
Z = np.random.normal(0, 0.01, (X.shape[1]+1, 1))
prev_Z = np.zeros_like(Z)
learning_rate = 0.1
best_loss = float('inf')
for count in range(100):
e2 = np.ones((B.shape[0], 1))
eu = np.ones((U.shape[0], 1))
margin_B = e2 + T2 @ Z
margin_U = (-1 + eps)*eu - T3 @ Z
grad = (T1.T @ (T1 @ Z) +
C1 * T2.T @ self.func(margin_B, 'pf') +
C2 * Z -
C3 * T3.T @ self.func(margin_U, 'pf'))
D1 = self.mat_diag(self.func(margin_B, 'pf') > 0)
D2 = self.func(margin_U, 'pf') > 0
hessian = (T1.T @ T1 +
C1 * T2.T @ D1 @ T2 +
C2 * np.eye(Z.shape[0]) +
C3 * T3.T @ np.diag(D2.flatten()) @ T3)
hessian += 1e-4 * np.eye(hessian.shape[0])
delta = np.linalg.solve(hessian, grad)
Z -= learning_rate * delta
current_loss = np.linalg.norm(grad)
if current_loss < best_loss:
best_loss = current_loss
learning_rate = min(learning_rate * 1.1, 1.0)
else:
learning_rate = max(learning_rate * 0.5, 1e-4)
if np.linalg.norm(Z - prev_Z) < self.eps:
break
prev_Z = Z.copy()
return Z[:-1], Z[-1][0]
def plane2(self, X, y, U, C4, C5, C6, eps):
A = X[y[:,0] == 1]
B = X[y[:,0] == -1]
# Add bias terms
G1 = np.hstack([B, np.ones((B.shape[0], 1))])
G2 = np.hstack([A, np.ones((A.shape[0], 1))])
G3 = np.hstack([U, np.ones((U.shape[0], 1))])
Y = np.random.normal(0, 0.01, (X.shape[1]+1, 1))
prev_Y = np.zeros_like(Y)
learning_rate = 0.1
best_loss = float('inf')
for count in range(100):
e1 = np.ones((A.shape[0], 1))
eu = np.ones((U.shape[0], 1))
margin_A = e1 - G2 @ Y
margin_U = (-1 + eps)*eu + G3 @ Y
grad = (G1.T @ (G1 @ Y) -
C4 * G2.T @ self.func(margin_A, 'pf') +
C5 * Y +
C6 * G3.T @ self.func(margin_U, 'pf'))
D3 = self.func(margin_A, 'pf') > 0
D4 = self.func(margin_U, 'pf') > 0
hessian = (G1.T @ G1 +
C4 * G2.T @ np.diag(D3.flatten()) @ G2 +
C5 * np.eye(Y.shape[0]) +
C6 * G3.T @ np.diag(D4.flatten()) @ G3)
hessian += 1e-4 * np.eye(hessian.shape[0])
delta = np.linalg.solve(hessian, grad)
Y -= learning_rate * delta
current_loss = np.linalg.norm(grad)
if current_loss < best_loss:
best_loss = current_loss
learning_rate = min(learning_rate * 1.1, 1.0)
else:
learning_rate = max(learning_rate * 0.5, 1e-4)
if np.linalg.norm(Y - prev_Y) < self.eps:
break
prev_Y = Y.copy()
return Y[:-1], Y[-1][0]
def func(self, x, type='pf', ro=1e20):
if type == 'pf':
return np.maximum(0, x)
elif type == 'sm':
return x + (1/ro)*np.log(1+np.exp(-ro*x))
def mat_diag(self, m):
return np.diag(m.flatten())
def get_params(self):
return self.w1, self.b1, self.w2, self.b2
def get_preds(self):
return self.preds
def score(self, y_test):
y = np.asarray(y_test).flatten()
return np.mean(self.preds.flatten() == y)

144
models/S3VM_constrained.py Normal file
View File

@@ -0,0 +1,144 @@
import numpy as np
from scipy.optimize import minimize
from sklearn.base import BaseEstimator, ClassifierMixin
class S3VM_Constrained(BaseEstimator, ClassifierMixin):
def __init__(self, C = 1.0, M=1e5, eps=1e-4, max_iter=100):
self.C = C
self.M = M
self.eps = eps
self.max_iter = max_iter
self.w = None
self.b = None
self.y_pred = 0
self.y = 0
def fit(self, X_labeled, y_labeled, X_unlabeled):
X_labeled = np.asarray(X_labeled, dtype=np.float64)
y_labeled = np.asarray(y_labeled, dtype=np.float64).reshape(-1, 1)
X_unlabeled = np.asarray(X_unlabeled, dtype=np.float64)
unique_labels = np.unique(y_labeled)
if not (set(unique_labels) <= {1.0, -1.0}):
raise ValueError("Labels must be +1 or -1")
n_labeled, n_features = X_labeled.shape
n_unlabeled = X_unlabeled.shape[0]
self._initialize_parameters(n_features, n_labeled, n_unlabeled)
X = np.vstack([X_labeled, X_unlabeled])
for iteration in range(self.max_iter):
y_unlabeled = self._predict_unlabeled(X_unlabeled)
self._optimize_mip(X_labeled, y_labeled, X_unlabeled, y_unlabeled)
new_labels = self._predict_unlabeled(X_unlabeled)
if np.mean(new_labels != y_unlabeled) < self.eps:
break
return self
def _initialize_parameters(self, n_features, n_labeled, n_unlabeled):
self.w = np.random.normal(0, 0.01, (n_features, 1))
self.b = 0.0
self.eta = np.zeros(n_labeled)
self.xi = np.zeros(n_unlabeled)
self.z = np.zeros(n_unlabeled)
self.d = np.random.rand(n_unlabeled)
def _predict_unlabeled(self, X_unlabeled):
scores = X_unlabeled @ self.w + self.b
return np.where(scores >= 0, 1, -1)
def _optimize_mip(self, X_labeled, y_labeled, X_unlabeled, y_unlabeled):
n_labeled, n_features = X_labeled.shape
n_unlabeled = X_unlabeled.shape[0]
x0 = np.concatenate([
self.w.flatten(),
[self.b],
self.eta,
self.xi,
self.z,
self.d
])
bounds = (
[(None, None)] * n_features +
[(None, None)] +
[(0, None)] * n_labeled +
[(0, None)] * n_unlabeled +
[(0, None)] * n_unlabeled +
[(0, 1)] * n_unlabeled
)
constraints = [
{
'type': 'ineq',
'fun': lambda x: y_labeled.flatten() *
(X_labeled @ x[:n_features] + x[n_features]) +
x[n_features+1:n_features+1+n_labeled] - 1
},
{
'type': 'ineq',
'fun': lambda x: (X_unlabeled @ x[:n_features] - x[n_features] +
x[n_features+1+n_labeled:n_features+1+n_labeled+n_unlabeled] +
self.M*(1 - x[-n_unlabeled:])) - 1
},
{
'type': 'ineq',
'fun': lambda x: (-(X_unlabeled @ x[:n_features] - x[n_features]) +
x[n_features+1+n_labeled+n_unlabeled:n_features+1+n_labeled+2*n_unlabeled] +
self.M*x[-n_unlabeled:]) - 1
}
]
def objective(x):
w = x[:n_features]
eta = x[n_features+1:n_features+1+n_labeled]
xi = x[n_features+1+n_labeled:n_features+1+n_labeled+n_unlabeled]
z = x[n_features+1+n_labeled+n_unlabeled:n_features+1+n_labeled+2*n_unlabeled]
return (self.C * (np.sum(eta) + np.sum(xi + z)) + np.sum(np.abs(w)))
res = minimize(
objective,
x0,
method='SLSQP',
bounds=bounds,
constraints=constraints,
options={'maxiter': 1000}
)
self.w = res.x[:n_features].reshape(-1, 1)
self.b = res.x[n_features]
self.eta = res.x[n_features+1:n_features+1+n_labeled]
self.xi = res.x[n_features+1+n_labeled:n_features+1+n_labeled+n_unlabeled]
self.z = res.x[n_features+1+n_labeled+n_unlabeled:n_features+1+n_labeled+2*n_unlabeled]
self.d = res.x[-n_unlabeled:]
def predict(self, X):
if self.w is None or self.b is None:
raise ValueError("Model not fitted yet")
X = np.asarray(X, dtype=np.float64)
scores = X @ self.w + self.b
self.y_pred = np.where(scores >= 0, 1, -1)
return self.y_pred
def score(self, y_test):
y = np.asarray(y_test).flatten()
return np.mean(self.y_pred.flatten() == y)

View File

@@ -0,0 +1,80 @@
import numpy as np
from scipy.optimize import minimize
class S3VM_Unconstrained:
def __init__(self, C=1.0, eps=1e-4):
self.C = C
self.eps = eps
self.w = None
self.b = None
def fit(self, X_labeled, y_labeled, X_unlabeled):
X_labeled = np.asarray(X_labeled, dtype=np.float64)
y_labeled = np.asarray(y_labeled, dtype=np.float64).reshape(-1, 1)
X_unlabeled = np.asarray(X_unlabeled, dtype=np.float64)
unique_labels = np.unique(y_labeled)
if not (set(unique_labels) <= {1.0, -1.0}):
raise ValueError("Labels must be +1 or -1")
n_features = X_labeled.shape[1]
self.w = np.zeros((n_features, 1))
self.b = 0.0
X_labeled_aug = np.hstack([X_labeled, np.ones((X_labeled.shape[0], 1))])
X_unlabeled_aug = np.hstack([X_unlabeled, np.ones((X_unlabeled.shape[0], 1))])
unlabeled_scores = X_unlabeled_aug @ np.vstack([self.w, self.b])
y_unlabeled = np.sign(unlabeled_scores)
y_unlabeled[y_unlabeled == 0] = 1
X_aug = np.vstack([X_labeled_aug, X_unlabeled_aug])
y = np.vstack([y_labeled, y_unlabeled])
self._optimize(X_aug, y)
new_scores = X_unlabeled_aug @ np.vstack([self.w, self.b])
if np.all(np.sign(new_scores) == y_unlabeled):
return
return self
def _optimize(self, X_aug, y):
_, n_features = X_aug.shape
def objective(params):
w = params[:-1].reshape(-1, 1)
b = params[-1]
margins = y * (X_aug[:, :-1] @ w + X_aug[:, -1] * b)
hinge_loss = np.sum(np.maximum(0, 1 - margins))
norm1_w = np.sum(np.abs(w))
return self.C * hinge_loss + norm1_w
x0 = np.zeros(n_features)
x0[-1] = 0
bounds = [(None, None) if i == n_features-1 else (None, None)
for i in range(n_features)]
res = minimize(objective, x0, method='L-BFGS-B', bounds=bounds)
self.w = res.x[:-1].reshape(-1, 1)
self.b = res.x[-1]
def predict(self, X):
if self.w is None or self.b is None:
raise ValueError("Model not fitted yet")
X = np.asarray(X, dtype=np.float64)
scores = X @ self.w + self.b
self.y_pred = np.where(scores >= 0, 1, -1).ravel()
return self.y_pred
def score(self, y_test):
y_test = np.asarray(y_test).flatten()
return np.mean(self.y_pred.flatten() == y_test)

87
models/TSVM.py Normal file
View File

@@ -0,0 +1,87 @@
"""
Article : Twin Support Vector Machine
Link : https://sci-hub.tw/https://ieeexplore.ieee.org/document/4135685
Author : Saeed Khosravi
"""
import numpy as np
from cvxopt import solvers, matrix
class TSVM:
def __init__(self, X, y, C1, C2, eps=1e-4):
self.A = X[y[:, 0] == 1, :]
self.B = X[y[:, 0] == -1, :]
self.C1 = C1
self.C2 = C2
self.eps = eps
def fit(self):
self.w1, self.b1 = self.plane1(self.A, self.B, self.C1, self.eps)
self.w2, self.b2 = self.plane2(self.A, self.B, self.C2, self.eps)
def predict(self, x_test):
norm2_w1 = np.linalg.norm(self.w1)
norm2_w2 = np.linalg.norm(self.w2)
distance_1 = np.abs(np.dot(x_test, self.w1) + self.b1)/norm2_w1
distance_2 = np.abs(np.dot(x_test, self.w2) + self.b2)/norm2_w2
y_pred = np.zeros_like(distance_1)
for i in range(y_pred.shape[0]):
if (distance_1[i] < distance_2[i]):
y_pred[i][0] = 1;
else:
y_pred[i][0] = -1;
self.preds = y_pred
return y_pred # Return predictions
def plane1(self, A, B, c, eps):
e1 = np.ones((A.shape[0],1))
e2 = np.ones((B.shape[0],1))
H = np.concatenate((A,e1), axis=1)
G = np.concatenate((B,e2), axis=1)
HTH = np.dot(H.T, H)
if np.linalg.matrix_rank(H)<H.shape[1]:
HTH += eps*np.eye(HTH.shape[0], HTH.shape[1])
_P = matrix(np.dot(np.dot(G, np.linalg.inv(HTH)),G.T), tc = 'd')
_q = matrix(-1 * e2, tc = 'd')
_G = matrix(np.concatenate((np.identity(B.shape[0]),-np.identity(B.shape[0])), axis=0), tc = 'd')
_h = matrix(np.concatenate((c*e2,np.zeros_like(e2)), axis=0), tc = 'd')
qp_sol = solvers.qp(_P, _q, _G, _h, kktsolver='ldl', options={'kktreg':1e-9, 'show_progress':False})
qp_sol = np.array(qp_sol['x'])
z = -np.dot(np.dot(np.linalg.inv(HTH), G.T), qp_sol)
w = z[:z.shape[0]-1]
b = z[z.shape[0]-1]
return w, b[0]
def plane2(self, A, B, c, eps):
e1 = np.ones((A.shape[0],1))
e2 = np.ones((B.shape[0],1))
H = np.concatenate((A,e1), axis=1)
G = np.concatenate((B,e2), axis=1)
GTG = np.dot(G.T, G)
if np.linalg.matrix_rank(G)<G.shape[1]:
GTG += eps*np.eye(GTG.shape[0], GTG.shape[1])
#solving the qp by cvxopt
_P = matrix(np.dot(np.dot(H, np.linalg.inv(GTG)), H.T), tc = 'd')
_q = matrix(-1 * e1, tc = 'd')
_G = matrix(np.concatenate((np.identity(A.shape[0]),-np.identity(A.shape[0])), axis=0), tc = 'd')
_h = matrix(np.concatenate((c*e1,np.zeros_like(e1)), axis=0), tc = 'd')
qp_sol = solvers.qp(_P, _q, _G, _h, kktsolver='ldl', options={'kktreg':1e-9, 'show_progress':False})
qp_sol = np.array(qp_sol['x'])
z = -np.dot(np.dot(np.linalg.inv(GTG), H.T), qp_sol)
w = z[:z.shape[0]-1]
b = z[z.shape[0]-1]
return w, b[0]
def get_params(self):
return self.w1, self.b1, self.w2, self.b2
def get_preds(self):
return self.preds
def score(self, y_test):
accuracy = np.sum(self.preds == y_test)/y_test.shape[0]
return accuracy

0
models/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

93
models/models.py Normal file
View File

@@ -0,0 +1,93 @@
from models.S3VM_constrained import S3VM_Constrained
from models.S3VM_unconstrained import S3VM_Unconstrained
from models.NewtonUTSVM import NewtonUTSVM
from models.TSVM import TSVM
from models.LSTSVM import LSTSVM
from models.utils import load_dataset
MODELS = [
"Semi-Supervised_SVM",
"Semi-Supervised_SVM_Unconstrained",
"Newton_Universum_Twin_SVM",
"Least-Square_Twin_SVM",
"Twin_SVM"
]
def runner(model, dataset, params):
csv_file = f"datasets/{dataset}.csv"
x_train, y_train, x_test, y_test, U = load_dataset(csv_file)
accuracy = 0
print('model: ', model)
match model:
case "Semi-Supervised_SVM":
C = params['C'] or 1.0
max_iter = params.get('max_iter') or 100
modelObj = S3VM_Constrained(C, max_iter)
modelObj.fit(x_train, y_train, U)
modelObj.predict(x_test)
accuracy = modelObj.score(y_test)
params = {"C": C, "max_iter": max_iter}
case "Semi-Supervised_SVM_Unconstrained":
C = params['C'] or 1.0
modelObj = S3VM_Unconstrained(C)
modelObj.fit(x_train, y_train, U)
modelObj.predict(x_test)
accuracy = modelObj.score(y_test)
params = {"C": C}
case "Newton_Universum_Twin_SVM":
C = params['C'] or [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
modelObj = NewtonUTSVM(x_train, y_train, U, C)
modelObj.fit()
modelObj.predict(x_test)
accuracy = modelObj.score(y_test)
params = {"C": C}
case "Least-Square_Twin_SVM":
C = params['C'] or [1.0, 1.0]
modelObj = LSTSVM(x_train, y_train, C[0], C[1])
modelObj.fit()
modelObj.predict(x_test, y_test)
accuracy = modelObj.score(y_test)
params = {"C": C}
case "Twin_SVM":
C = params['C'] or [1.0, 1.0]
modelObj = TSVM(x_train, y_train, C[0], C[1])
modelObj.fit()
modelObj.predict(x_test)
accuracy = modelObj.score(y_test)
params = {"C": C}
accuracy = round(accuracy, 4)
return {
"model":model,
"dataset":dataset,
"params": params,
"accuracy": accuracy
}

106
models/utils.py Normal file
View File

@@ -0,0 +1,106 @@
from datetime import datetime
from ultralytics import YOLO
import numpy as np
import cv2
import csv
import os
def min_max_normalize(matrix):
min_vals = np.min(matrix, axis=0)
max_vals = np.max(matrix, axis=0)
range_vals = max_vals - min_vals
range_vals[range_vals == 0] = 1
normalized_matrix = (matrix - min_vals) / range_vals
return normalized_matrix
def load_dataset(csv_file,unlabeled_ratio=0.15, test_ratio=0.4):
data = np.genfromtxt(csv_file, delimiter=",", dtype=str, skip_header=1)
class_names = np.unique(data[:, -1])
print(f"classes: {class_names[0]} / {class_names[1]}")
print(f"dataset samples: {data.shape[0]} / features: {data.shape[1] - 1}")
if class_names[0] in np.unique(data[:, -1]) or class_names[1] in np.unique(data[:, -1]):
data[:, -1] = np.where(data[:, -1] == class_names[0], 1, -1)
data = data.astype(np.float32)
features = min_max_normalize(data[:, :-1])
np.random.seed(10000)
indices = np.random.permutation(len(features))
split_idx = int(len(features) * (1 - unlabeled_ratio))
labeled_test_features = features[indices[:split_idx]]
labeled_test_labels = data[indices[:split_idx]][:, -1]
U = features[indices[split_idx:]]
test_split_idx = int(len(labeled_test_features) * (1 - test_ratio))
X = labeled_test_features[:test_split_idx]
y = labeled_test_labels[:test_split_idx]
X_test = labeled_test_features[test_split_idx:]
y_test = labeled_test_labels[test_split_idx:]
y = y.reshape(y.shape[0], 1)
y_test = y_test.reshape(y_test.shape[0], 1)
return X, y, X_test, y_test, U
def save_result(model, dataset, accuracy, params, results_file):
file_exists = os.path.isfile(results_file)
with open(results_file, mode="a", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["timestamp", "model", "dataset", "parameters", "accuracy"])
if not file_exists:
writer.writeheader()
writer.writerow({
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"model": model,
"dataset": dataset,
"parameters": params,
"accuracy": accuracy
})
def load_results(limit, results_file):
if not os.path.isfile(results_file):
return []
with open(results_file, mode="r") as f:
reader = list(csv.DictReader(f))
return reader[::-1][:limit]
def predict_yolo(image_path, confidence):
print("Predicting:", image_path)
# Load YOLO model
model = YOLO("templates/static/public/files/repair/weights/14_class_best.pt")
# Run prediction on the input image
results = model.predict(
source=f"templates/static/public/files/repair/images/{image_path}",
save=False,
conf=confidence,
device = "cpu",
batch=4,
imgsz=320
)
predicted_img = results[0].plot() # OpenCV image with boxes drawn
# Save location (always overwrite the same file)
output_dir = "templates/static/public/files/repair/predicted"
os.makedirs(output_dir, exist_ok=True)
output_filename = "predicted_image.jpg" # fixed name
output_path = os.path.join(output_dir, output_filename)
print(f"image {predicted_img} written in : ", output_path)
# Write image
cv2.imwrite(output_path, predicted_img)
# Return only the filename so template can use it
return output_filename

0
routes/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
routes/articles.py Normal file
View File

@@ -0,0 +1,15 @@
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
router = APIRouter(prefix="", tags=["articles"])
templates = Jinja2Templates(directory="templates")
@router.get("/articles")
async def get_articles(request: Request):
return templates.TemplateResponse("articles.html", {"request": request, "title": "Articles"})
async def s3vm(request: Request):
return templates.TemplateResponse("S3VM.html", {"request": request, "title": "Semi-Supervised SVM"})

205
routes/projects.py Normal file
View File

@@ -0,0 +1,205 @@
from fastapi import APIRouter, Request, Form
from fastapi.templating import Jinja2Templates
from models.models import MODELS, runner
from datasets.datasets import DATASETS
from models.utils import save_result, load_results, predict_yolo
from datasets.MC_NDCC import MC_NDCC
import glob
import os
import time
router = APIRouter(prefix="/projects", tags=["projects"])
templates = Jinja2Templates(directory="templates")
@router.get("")
async def get_projects(request: Request):
return templates.TemplateResponse("projects.html", {"request": request, "title": "Projects"})
@router.get("/run-models")
async def run_models(request: Request):
results = load_results(limit = 20, results_file='templates/static/public/files/results.csv')
return templates.TemplateResponse("projects/run_models.html", {"request": request, "title": "Run Models", "models": MODELS, "datasets": DATASETS, "results": results})
@router.post("/run-models")
async def run_models(request: Request,
model: str = Form(...),
dataset: str = Form(...),
C1: float = Form(None),
C2: float = Form(None),
C3: float = Form(None),
C4: float = Form(None),
C5: float = Form(None),
C6: float = Form(None),
):
params = None
if model == MODELS[0]:
params = {'C': C1}
elif model == MODELS[1]:
params = {'C': C1}
elif model == MODELS[2]:
params = {'C': [C1, C2, C3, C4, C5, C6]}
elif model == MODELS[3]:
params = {'C': [C1, C2]}
elif model == MODELS[4]:
params = {'C': [C1, C2]}
result = runner(model, dataset, params)
save_result(result['model'], result['dataset'], result['accuracy'], result['params'], results_file='templates/static/public/files/results.csv')
results = load_results(limit = 20, results_file='templates/static/public/files/results.csv')
return templates.TemplateResponse("projects/run_models.html",
{"request": request,
"title": "Run Models",
"models": MODELS,
"datasets": DATASETS,
"selected_model": model,
"selected_dataset": dataset,
"results": results
})
@router.get("/generate-ndcc")
async def generate_ndcc(request: Request):
return templates.TemplateResponse("projects/generate_ndcc.html",
{"request": request,
"centers": 1,
"nos": 100,
"nof": 10,
"noc": 2,
"title": "Generate NDCC Dataset"
})
@router.post("/generate-ndcc")
async def generate_ndcc(request: Request,
centers: int = Form(None),
nos: int = Form(None),
nof: int = Form(None),
noc: int = Form(None)
):
tmp_dir = "templates/static/public/files"
for f in glob.glob(os.path.join(tmp_dir, "NDCC_*.csv")):
try:
os.remove(f)
except Exception as e:
print(f"Could not remove {f}: {e}")
ndccObj = MC_NDCC(centers, nos, nof, noc)
dataset_name = f"NDCC_{nos}_{nof}_{noc}.csv"
_ = ndccObj.get_csv(f"templates/static/public/files/NDCC_{nos}_{nof}_{noc}.csv")
print(dataset_name)
return templates.TemplateResponse("projects/generate_ndcc.html",
{"request": request,
"title": "Generate NDCC Dataset",
"centers": centers,
"nos": nos,
"nof": nof,
"noc": noc,
"dataset_name": dataset_name,
})
@router.get("/run-yolo")
async def run_yolo(request: Request,
):
images = [
"RPf_00152.png",
"RPf_00153.png",
"RPf_00156.png",
"RPf_00200.png",
"RPf_00201.png",
"RPf_00202.png",
"RPf_00281.png",
"RPf_00282.png",
"RPf_00283.png",
"RPf_00291.png",
"RPf_00293.png",
"RPf_00294.png",
"RPf_00302.png",
"RPf_00303.png",
"RPf_00304.png",
"RPf_00310.png",
"RPf_00311.png",
"RPf_00312.png",
]
return templates.TemplateResponse("projects/run_yolo.html", {
"request": request,
"title": "Run Yolo",
"images": images,
"selected_image": images[0]
})
@router.post("/run-yolo")
async def run_yolo_post(
request: Request,
selected_image: str = Form(...),
confidence: float = Form(...)
):
images = [
"RPf_00152.png",
"RPf_00153.png",
"RPf_00156.png",
"RPf_00200.png",
"RPf_00201.png",
"RPf_00202.png",
"RPf_00281.png",
"RPf_00282.png",
"RPf_00283.png",
"RPf_00291.png",
"RPf_00293.png",
"RPf_00294.png",
"RPf_00302.png",
"RPf_00303.png",
"RPf_00304.png",
"RPf_00310.png",
"RPf_00311.png",
"RPf_00312.png",
]
# Run YOLO prediction
file_path = "templates/static/public/files/repair/predicted/predicted_image.jpg"
if os.path.exists(file_path):
os.remove(file_path)
print("File removed.")
else:
print("File does not exist.")
_ = predict_yolo(selected_image, confidence)
# Add cache-busting query string (timestamp)
result_url = f"../static/public/files/repair/predicted/predicted_image.jpg?{int(time.time())}"
return templates.TemplateResponse("projects/run_yolo.html", {
"request": request,
"title": "Run Yolo",
"images": images,
"selected_image": selected_image,
"selected_confidence": confidence,
"result_path": result_url
})

11
routes/resume.py Normal file
View File

@@ -0,0 +1,11 @@
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
router = APIRouter(prefix="", tags=["resume"])
templates = Jinja2Templates(directory="templates")
@router.get("/")
async def get_resume(request: Request):
return templates.TemplateResponse("resume.html", {"request": request, "title": "Resume"})

BIN
templates/.DS_Store vendored Normal file

Binary file not shown.

17
templates/404.html Normal file
View File

@@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block content %}
<!-- Primary Page Layout
-->
<div class="container">
<section class="header">
<h1>404 - Page Not Found</h1>
<p>Sorry, the page you are looking for does not exist.</p>
<a href="/">Go back home</a>
</section>
<!-- End Document
-->
{% endblock %}

43
templates/articles.html Normal file
View File

@@ -0,0 +1,43 @@
{% extends "base.html" %}
{% block title %}
Articles
{% endblock %}
{% block content %}
<!-- Primary Page Layout
-->
<div class="container">
<!-- <section class="header">
</section> -->
<section>
<h2>Articles</h2>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="/articles/NUTSVM">
<img class="item-screenshot" src="static/public/images/NUTSVM.jpg">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">A novel method for solving universum twin bounded support vector machine in the primal space</h6>
<p class="item-project-summary"> In this Article we propose (NUTBSVM), a Newton-based approach for solving in the primal space the optimization problems related to Twin Bounded Support Vector Machines with Universum data (UTBSVM). In the NUTBSVM, the constrained programming problems of UTBSVM are converted into unconstrained optimization problems, and a generalization of Newtons method for solving the unconstrained problems is introduced. </p>
<p class="docs-subheader">Introduction to Artificial Intelligence <span class="date">Nov 2023</span></p>
<a class="button" href="static/public/files/NUTSVM.pdf" target="_blank">Download</a>
<a class="button" href="/projects/run-models">Run</a>
<a class="button" href="https://github.com/saeedkhosravi94/resume" target="_blank">Source</a>
</div>
</div>
</section>
<!-- End Document
-->
{% endblock %}

19
templates/base.html Normal file
View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "includes/head.html" %}
<title>
{% block title %}
{% endblock %}
</title>
</head>
<body>
{% include "includes/navbar.html" %}
{% block content %}
{% endblock %}
{% include "includes/footer.html"%}
</body>
</html>

View File

@@ -0,0 +1,105 @@
<script type="text/javascript">
const paramsDiv = document.getElementById("model-params");
const modelSelect = document.getElementById("model");
function renderParams(model) {
let html = "";
if (model === "Semi-Supervised_SVM") {
html = `
<div class="six columns">
<label for="C">Penalty parameter (C):</label>
<input style="width: 100%;" type="number" step="0.01" id="C" name="C1" value="{{ C or 1.0 }}">
</div>
`;
} else if (model === "Semi-Supervised_SVM_Unconstrained") {
html = `
<div class="six columns">
<label for="C">Penalty parameter (C):</label>
<input style="width: 100%;" type="number" step="0.01" id="C" name="C1" value="{{ C or 1.0 }}">
</div>
`;
} else if (model === "Newton_Universum_Twin_SVM") {
html = `
<div class="two columns"><label for="C1">C1:</label><input style="width:100%;" type="number" step="0.01" id="C1" name="C1" value="{{ C1 or 1.0 }}"></div>
<div class="two columns"><label for="C2">C2:</label><input style="width:100%;" type="number" step="0.01" id="C2" name="C2" value="{{ C2 or 1.0 }}"></div>
<div class="two columns"><label for="C3">C3:</label><input style="width:100%;" type="number" step="0.01" id="C3" name="C3" value="{{ C3 or 1.0 }}"></div>
<div class="two columns"><label for="C4">C4:</label><input style="width:100%;" type="number" step="0.01" id="C4" name="C4" value="{{ C4 or 1.0 }}"></div>
<div class="two columns"><label for="C5">C5:</label><input style="width:100%;" type="number" step="0.01" id="C5" name="C5" value="{{ C5 or 1.0 }}"></div>
<div class="two columns"><label for="C6">C6:</label><input style="width:100%;" type="number" step="0.01" id="C6" name="C6" value="{{ C6 or 1.0 }}"></div>
`;
} else if (model === "Least-Square_Twin_SVM") {
html = `
<div class="six columns"><label for="C1">C1:</label><input style="width:100%;" type="number" step="0.01" id="C1" name="C1" value="{{ C1 or 0.1 }}"></div>
<div class="six columns"><label for="C2">C2:</label><input style="width:100%;" type="number" step="0.01" id="C2" name="C2" value="{{ C2 or 1.0 }}"></div>
`;
} else if (model === "Twin_SVM") {
html = `
<div class="six columns"><label for="C1">C1:</label><input style="width:100%;" type="number" step="0.01" id="C1" name="C1" value="{{ C1 or 0.1 }}"></div>
<div class="six columns"><label for="C2">C2:</label><input style="width:100%;" type="number" step="0.01" id="C2" name="C2" value="{{ C2 or 1.0 }}"></div>
`;
}
paramsDiv.innerHTML = html;
}
if(modelSelect){
// Run on page load with selected value
renderParams(modelSelect.value);
// Update dynamically when model changes
modelSelect.addEventListener("change", (e) => {
renderParams(e.target.value);
});
}
document.addEventListener('DOMContentLoaded', function() {
const select = document.getElementById('select-image');
const preview = document.getElementById('preview');
if (!select || !preview) {
console.warn('Select or preview element not found.');
return;
}
function updatePreview() {
const opt = select.options[select.selectedIndex];
const src = opt && opt.dataset && opt.dataset.img ? opt.dataset.img : '';
preview.src = src;
console.log('Preview set to:', src);
}
// Ensure there's a selected index (fallback to first option)
if (select.selectedIndex === -1 && select.options.length > 0) {
select.selectedIndex = 0;
}
// initial set
updatePreview();
// update when user changes selection
select.addEventListener('change', updatePreview);
// optional: handle broken image
preview.addEventListener('error', function() {
console.warn('Failed to load preview image:', preview.src);
// preview.src = '/static/img/placeholder.png'; // uncomment if you have a placeholder
});
});
// document.addEventListener('DOMContentLoaded', function() {
// const select = document.getElementById('select-image');
// const preview = document.getElementById('preview');
// if (!select || !preview) return;
// function updatePreview() {
// const opt = select.options[select.selectedIndex];
// preview.src = opt.dataset.img;
// }
// select.addEventListener('change', updatePreview);
// });
</script>

View File

@@ -0,0 +1,38 @@
<!-- Basic Page Needs
-->
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<!-- Mobile Specific Metas
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- FONT
-->
<link href='//fonts.googleapis.com/css?family=Raleway:400,300,600' rel='stylesheet' type='text/css'>
<!-- ...existing code... -->
<!-- CSS
-->
<link rel="stylesheet" href="/static/skeleton/css/normalize.css">
<link rel="stylesheet" href="/static/skeleton/css/skeleton.css">
<link rel="stylesheet" href="/static/css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Doto:wght@100..900&display=swap" rel="stylesheet">
<!-- Scripts
-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<link rel="stylesheet" href="/static/skeleton/css/github-prettify-theme.css">
<script src="/static/js/main.js"></script>
<!-- Favicon
-->
<link rel="icon" type="image/png" href="/static/public/images/favicon.png">
<!-- ...existing code... -->

View File

@@ -0,0 +1,11 @@
{% block navbar %}
<nav class="navbar">
<div class="container">
<ul class="navbar-list">
<li class="navbar-item"><a class="navbar-link" href="/">Resume</a></li>
<li class="navbar-item"><a class="navbar-link" href="/articles">Articles</a></li>
<li class="navbar-item"><a class="navbar-link" href="/projects">Projects</a></li>
</ul>
</div>
</nav>
{% endblock %}

114
templates/projects.html Normal file
View File

@@ -0,0 +1,114 @@
{% extends "base.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
<!-- Primary Page Layout
-->
<div class="container">
<!-- <section class="header">
</section> -->
<section>
<h2>Projects</h2>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="https://activerecaller.com">
<img class="item-screenshot" src="static/public/images/active_recaller.png" style="object-fit:fill;">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">A web app for studying better powered by AI and MERN stack</h6>
<p class="item-project-summary">
Recently, I have been developing a web app for active recall learning, You can Upload a file, or CSV, or manually generate you own decks, to help you study better. I'm going to make it more powerful by adding more features and integrations with other tools. You can upload your book,
it will automatically make it into chunks, you can use an Agent from OpenAI, Gemini, or Claude to generate the decks. cards have 3 difficulty levels, and you can review them in a spaced repetition manner based on that difficulty.
</p>
<p class="docs-subheader">Productivity Project <span class="date">Oct 2025</span></p>
<a class="button" href="https://activerecaller.com">activerecaller.com</a>
</div>
</div>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="/projects/run-yolo">
<img class="item-screenshot" src="static/public/images/repair.png" style="object-fit:fill;">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">Yolov8 on Repair Dataset</h6>
<p class="item-project-summary"> The main goal of <a href="https://www.repairproject.eu/">RePAIR project</a> is to develop a ground-breaking technology to virtually eliminate one of the most labour intensive and frustrating steps in archaeological research, namely the physical reconstruction of shattered artworks. Indeed, countless vases, amphoras, frescos and other ancient artefacts, all over the world, have not survived intact and were dug out from excavation sites as large collections of fragments, many of which are damaged, worn out or missing altogether.</p>
<p class="docs-subheader">Introduction to Machine Learning <span class="date">Sep 2024</span></p>
<a class="button" href="/projects/run-yolo">Run</a>
<a class="button" href="https://github.com/saeedkhosravi94/resume" target="_blank">Source</a>
</div>
</div>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="https://n8n.saeedkhosravi.it">
<img class="item-screenshot" src="static/public/images/article_automation.png" style="object-fit:fill;">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">Article Reading Automation</h6>
<p class="item-project-summary"> I started to read new articles on a daily basis. I made an automation using n8n, Google Gemini, Postgres, and a website using Fast-API that made this more productive, and time efficient.
I would appreciate if you check it out and give me feedback, to make it better.
If you are interested in using n8n automation, contact me to launch one for you. ;)
</p>
<p class="docs-subheader">Productivity Project <span class="date">Oct 2025</span></p>
<a class="button" href="https://art.saeedkhosravi.it">Visit</a>
<a class="button" href="static/public/files/Computer Vision Articles Summary.json" download>Download n8n file</a>
</div>
</div>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="/projects/run-models">
<img class="item-screenshot" src="static/public/images/S3VM_vs_NUTSVM.png">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">Semi-Supervised SVM vs Newton Universum Twin SVM</h6>
<p class="item-project-summary"> In this project, we implemented two models: the Semi-Supervised SVM (S3VM) and the Newton-based Universum Twin SVM (Newton-UTSVM). S3VM strengthens learning with unlabeled data, while Newton-UTSVM improves generalization using Universum data. After comparing their performance, we propose a new method—the Unconstrained S3VM—that combines the advantages of both approaches for a more flexible solution. </p>
<p class="docs-subheader">Introduction to Artificial Intelligence <span class="date">Apr 2023</span></p>
<a class="button" href="static/public/files/S3VM_vs_NUTSVM.pdf" target="_blank">Report</a>
<a class="button" href="/projects/run-models">Run</a>
<a class="button" href="https://github.com/saeedkhosravi94/resume" target="_blank">Source</a>
</div>
</div>
<div class="row item">
<a class="item-screenshot-wrapper" target="_blank" href="/projects/run-models">
<img class="item-screenshot" src="static/public/images/ndcc.jpg">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">Multi-Class Normally Distributed Cluster Centers Data Generator</h6>
<p class="item-project-summary"> NORMALLY DISTRIBUTED CUBIC CLUSTERS is a data generator. It generates a series of random centers for multivariate normal distributions. NDC randomly generates a fraction of data for each center, i.e. what fraction of data points will come from this center. NDC randomly generates a separating plane. Based on this plane, classes for are chosen for each center. NDC then randomly generates the points from the distributions. NDC can increase inseparability by increasing variances of distributions. A measure of "true" separability is obtained by looking at how many points end up on the wrong side of the separating plane. All values are taken as integers for simplicity.</p>
<p class="docs-subheader"><a href="https://scholar.google.com/citations?user=4aZwjNUAAAAJ&hl=en">Hossein Moosaei</a>, Saeed Khosravi, <a href="https://www.cs.carleton.edu/faculty/dmusicant/">Dave Musicant</a> <span class="date">Sep 2021</span></p>
<a class="button" href="/projects/generate-ndcc">Run</a>
<a class="button" href="https://github.com/saeedkhosravi94/resume" target="_blank">Source</a>
</div>
</div>
</section>
</div>
<!-- End Document
-->
{% endblock %}

View File

@@ -0,0 +1,58 @@
{% extends "base.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
<div class="container">
<section>
<h3>Generate Multi-Class Normally Distributed Cluster Centers Dataset </h3>
<form id="model-form" method="post" action="/projects/generate-ndcc">
<div class="row">
<div class="three columns">
<label for="centers">Number of Centers:</label>
<select id="centers" name="centers">
<option value="1" {% if centers == "1" %}selected{% endif %}>100</option>
<option value="2" {% if centers == "2" %}selected{% endif %}>300</option>
<option value="3" {% if centers == "3" %}selected{% endif %}>500</option>
<option value="4" {% if centers == "4" %}selected{% endif %}>700</option>
</select>
</div>
<div class="three columns">
<label for="dataset">Number of Samples</label>
<input style="width: 100%;" type="number" step="1" id="nos" name="nos" value="{{nos}}">
</div>
<div class="three columns">
<label for="dataset">Number of features</label>
<input style="width: 100%;" type="number" step="1" id="nof" name="nof" value="{{nof}}">
</div>
<div class="three columns">
<label for="dataset">Number of classes</label>
<input style="width: 100%;" type="number" step="1" id="noc" name="noc" value="{{noc}}">
</div>
</div>
<div id="model-params" class="row" style="margin-top:15px;"></div>
<button type="submit">Generate Dataset</button>
{% if dataset_name %}
<a id="downloadLink" href="/static/public/files/{{ dataset_name }}" download style="display:none;"></a>
<button class="date" onclick="document.getElementById('downloadLink').click() " >
⬇ Download Dataset
</button>
{% endif %}
</form>
</section>
</div>
{% endblock %}

View File

@@ -0,0 +1,78 @@
{% extends "base.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
<div class="container">
<section>
<h3>Run Model</h3>
<form id="model-form" method="post" action="/projects/run-models">
<div class="row">
<div class="six columns">
<label for="model">Select Model:</label>
<select id="model" name="model">
{% for model in models %}
<option value="{{ model|replace(' ', '_') }}"
{% if selected_model is defined and selected_model == model|replace(' ', '_') %}selected{% endif %}>
{{ model }}
</option>
{% endfor %}
</select>
</div>
<div class="six columns">
<label for="dataset">Select Dataset:</label>
<select id="dataset" name="dataset">
{% for dataset in datasets %}
<option value="{{ dataset }}"
{% if selected_dataset is defined and selected_dataset == dataset %}selected{% endif %}>
{{ dataset }}
</option>
{% endfor %}
</select>
</div>
</div>
<div id="model-params" class="row" style="margin-top:15px;"></div>
<button type="submit">Run</button>
</form>
</section>
{% if results %}
<h3>Last 20 Results</h3>
<div style="overflow-x:auto; font-size: 1.2rem;">
<table class="u-full-width">
<thead>
<tr>
<th>Time</th>
<th>Model</th>
<th>Dataset</th>
<th>Parameters</th>
<th>Accuracy</th>
</tr>
</thead>
<tbody>
{% for row in results %}
<tr>
<td>{{ row.timestamp }}</td>
<td>{{ row.model }}</td>
<td>{{ row.dataset }}</td>
<td>{{ row.parameters }}</td>
<td>{{ row.accuracy }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,145 @@
{% extends "base.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
<div class="container">
<section>
<h3 style="margin-top: 10rem; ">Predict Pre-trained Customized Yolov8 model</h3>
<p>Table below shows results of <a href = "https://repairproject.github.io/fragment-restoration/">Semantic Motif Segmentation of Archaeological Fresco Fragments</a> article.</p>
<img src="../static/public/images/yolov8_result_table.png" alt="YOLO Example" style="max-width:100%; height:auto;">
<img src="../static/public/images/yolov8_result.png" alt="YOLO Example" style="max-width:100%; height:auto;">
<div class="table-responsive">
<table class="table" >
<th>
<strong>model</strong>
</th>
<th>
<strong>box precision</strong>
</th>
<th>
<strong>box recall</strong>
</th>
<th>
<strong>box map50</strong>
</th>
<tr>
<td>
Customized YOLOv8l
</td>
<td>
0.7866
</td>
<td>
0.8659
</td>
<td>
0.8439
</td>
</tr>
</table>
<table>
<th>
<strong>model</strong>
</th>
<th>
<strong>seg precision</strong>
</th>
<th>
<strong>seg recall</strong>
</th>
<th>
<strong>seg map50</strong>
</th>
<tr>
<td>
Customized YOLOv8l
</td>
<td>
0.8961
</td>
<td>
0.8113
</td>
<td>
0.9025
</td>
</tr>
</table>
</div>
<form id="model-form" method="post" action="/projects/run-yolo">
<div class="row">
<!-- Select Image -->
<div class="six columns">
<label for="select-image">Select Image</label>
<select id="select-image" name="selected_image">
{% for image in images %}
<option value="{{ image }}"
{% if selected_image is defined and selected_image == image %}selected{% endif %}>
{{ image }}
</option>
{% endfor %}
</select>
</div>
<!-- Confidence Input -->
<div class="six columns">
<label for="confidence">Confidence Threshold</label>
<input type="number"
style="width: 100%;"
id="confidence"
name="confidence"
min="0" max="1" step="0.01"
value="{{ selected_confidence if selected_confidence is defined else 0.8 }}">
</div>
</div>
<div class="row">
<div class="six columns">
<img id="original-preview"
src="../static/public/files/repair/images/{{ selected_image }}"
alt="Original Image" style="max-width:100%; height:auto;">
</div>
<!-- Predicted image -->
<div class="six columns">
{% if result_path %}
<img id="predicted-preview"
src="{{ result_path }}"
alt="Predicted Image" style="max-width:100%; height:auto;">
{% else %}
<p>No prediction yet.</p>
{% endif %}
</div>
</div>
<button type="submit">Predict</button>
</form>
</section>
</div>
{% endblock %}

211
templates/resume.html Normal file
View File

@@ -0,0 +1,211 @@
{% extends "base.html" %}
{% block title %}
Resume
{% endblock %}
{% block content %}
<!-- Primary Page Layout
-->
<div class="container">
<!-- <section class="header"> -->
<!-- </section> -->
<section class="res-intro">
<div class="header">
<h4> Hi, I'm
<span class="typing-slider">
<p>Saeed Khosravi.</p>
</span>
</h4>
<div class="header-buttons">
<button onclick="downloadPDF()">Download Resume</button>
</div>
</div>
<p id="about-me">
I have over four years of experience as a Backend Developer, during which I have encountered diverse technical challenges
that strengthened my problem-solving abilities and broadened my expertise across various technologies and tools. However,
my journey in software development began much earlier. I have been engaged in this field since 2011, even before my formal
academic education. My passion for programming started when my older brother introduced me to it by gifting me the book
“How to Program in C++” by Deitel & Deitel, which sparked a lifelong curiosity and dedication to understanding how software
works. Recently, I have become increasingly interested in Artificial Intelligence and its transformative potential, recognizing
that the world is moving toward intelligent, data-driven systems. I aspire to contribute meaningfully to this evolution by joining
an organization that tackles real-world challenges, works with large-scale data, and designs efficient AI models that can help
make our world a better and more connected place for everyone.
</p>
</section>
<!-- Experience -->
<section id="work-experience" class="res-exp docs-section">
<h4>Work Experience</h4>
<div id="queries">
<h6 class="docs-header">Backend Developer</h6>
<p class="docs-subheader">Respina Network & Beyond, Tehran, Iran <span class="date">Aug 2022 Mar 2024</span></p>
<p class="work-summary">
Respina is a leading provider of telecommunications solutions in Iran, offering dedicated internet access, SIP-Trunk,
Hosted-PBX phone services, and data center colocation. Trusted for reliability and innovation, Respina enables seamless
connectivity and robust communication for businesses, contributing to Iran's digital infrastructure and economic growth.
This was one of the most impactful periods of my career, where I gained deep hands-on experience in analyzing, testing,
and optimizing large-scale backend systems. As part of the Hosted-PBX (Nexfon) team, I worked on improving the performance,
scalability, and reliability of enterprise-grade telecommunication services. Redesigned and optimized the billing system using
CGRATES, implementing a real-time charging solution that improved billing accuracy and efficiency. Reduced monthly reporting
time from 30 minutes to 40 seconds by optimizing database queries, parallelizing tasks with Celery, and improving data aggregation workflows.
Refactored the Asterisk-ARI integration into an event-driven Flask microservice, containerized with Docker, and enhanced with multi-processing,
increasing concurrent call capacity per instance from 25 to 130 and reducing infrastructure load by nearly 5×. Implemented comprehensive monitoring
and troubleshooting using Prometheus, Loki, and Grafana, improving observability and system reliability. Collaborated with the DevOps team to
migrate deployments to a Kubernetes-based cloud infrastructure, enhancing scalability, fault tolerance, and CI/CD automation.
</p>
<p class="work-technologies">
<strong>Technologies & Tools: </strong> Python, Django, Flask, RESTful APIs, Celery, RabbitMQ,
PostgreSQL, Docker, Kubernetes, Git, CI/CD (GitLab CI), Prometheus, Loki, Grafana, Linux, Nginx,
Troubleshooting & Performance Optimization
</p>
</div>
<div id="queries">
<h6 class="docs-header">Backend Developer</h6>
<p class="docs-subheader">ANIL Web design studio, Tehran, Iran <span class="date">Nov 2021 Jul 2022</span></p>
<p class="work-summary">
Collaborated with a highly skilled development team composed of top university talents, gaining valuable exposure to
modern software design practices and collaborative workflows. Contributed to two major web projects — RadmanPack and
PelikanIran — by developing and integrating backend systems using PHP and the Laravel Framework, while coordinating
closely with frontend developers working in React.js. Focused on designing RESTful APIs, implementing secure authentication,
and ensuring smooth data exchange between backend and frontend components. Additionally, gained hands-on experience in version
control (Git), containerization with Docker, and deployment on Linux-based environments, emphasizing maintainability,
scalability, and team collaboration.
</p>
<p class="work-technologies">
<strong>Technologies & Tools:</strong> PHP, Laravel, React.js, JavaScript (ES6+), CSS3, RESTful APIs, Postman,
MySQL, Git, Docker, Linux, Nginx, Agile Collaboration
</p>
</div>
<div id="queries">
<h6 class="docs-header">Backend Developer</h6>
<p class="docs-subheader">AvinAvisa Lab, Tehran, Iran <span class="date">Oct 2020 Jul 2021</span></p>
<p class="work-summary">
Worked in a research-driven environment within the Blockchain Laboratory of Amirkabir University of Technology, focusing on the development of decentralized systems and blockchain-based applications. Contributed to the design and implementation of a cryptocurrency exchange platform (Polychain) enabling peer-to-peer trading with advanced matching logic based on trade volume, customer tier (VIP levels), and other dynamic factors. Implemented a custom matching algorithm inspired by the Knapsack problem, optimizing trade pair selection and transaction efficiency. Additionally, integrated the platform with Ethereum and TRON networks, handling blockchain interactions and ensuring secure, real-time transaction processing. Collaborated with a small, multidisciplinary team, applying the MERN stack (MongoDB, Express.js, React.js, Node.js) and blockchain APIs to build a robust, scalable backend system.
</p>
<p class="work-technologies">
<strong>Technologies & Tools:</strong> Node.js, Express.js, MongoDB, React.js, JavaScript (ES6+), Blockchain Integration (Ethereum, TRON), RESTful APIs, Algorithm Design, Git, Docker, Linux, WebSocket Communication
</p>
</div>
<div id="queries">
<h6 class="docs-header">Military Service</h6>
<p class="docs-subheader">Army, Tehran, Iran <span class="date">Jul 2018 Jul 2020</span></p>
<p class="work-summary">
In Iran, military service is compulsory for men and must be completed in order to obtain permission to
leave the country. The service lasts for two years. During this period, I collaborated with Dr. Moosaei (Charles University)
and Dr. David Musicant (Carleton College) on one publication and one research project, while also engaging in self-study in
machine learning and image processing to enhance my technical expertise.
</p>
</div>
<div id="queries">
<h6 class="docs-header">Android Developer</h6>
<p class="docs-subheader">Ishaya, Tehran, Iran <span class="date">Aug 2016 Apr 2018</span></p>
<p class="work-summary">
Started my professional journey in software development as an Android Developer, initially joining as an intern and later continuing as a full-time engineer due to strong performance and enthusiasm for mobile technologies. Contributed to the development of Ponila, the first intelligent content recommendation system for Persian-language users. The platform utilized semantic and syntactic analysis of Persian text to deliver personalized article recommendations based on user interests, improving content discovery and engagement. Collaborated with backend and data science teams to integrate recommendation algorithms and ensure seamless data synchronization between the mobile app and server-side APIs. Focused on building a responsive, stable, and scalable Android application aligned with modern UI/UX principles.
</p>
<p class="work-technologies">
<strong>Technologies & Tools:</strong>Java, Android SDK, RESTful APIs, JSON, SQLite, Git, XML, Material Design, Recommender Systems
</p>
</div>
</section>
<!-- /Experience -->
<!-- Education -->
<section id="education" class="res-edu docs-section">
<h4>Education</h4>
<div id="queries">
<h6 class="docs-header">Ca' Foscari University of Venice</h6>
<p class="docs-subheader">Masters Degree in Artificial Intelligence and Data Engineering, <span class="date">Sep 2024 Present</span></p>
<!-- Courses table: replace the placeholder rows below with your actual courses and grades -->
</div>
<div id="queries">
<h6 class="docs-header">University of Bojnord</h6>
<p class="docs-subheader">Bachelors Degree in Computer Science, <span class="date">Sep 2012 Jun 2016</span></p>
</div>
<div id="queries">
<h6 class="docs-header">Rajaei High School</h6>
<p class="docs-subheader">Pre-University & Diploma in Mathematics and Physics, <span class="date">Sep 2010 Jun 2012</span></p>
</div>
<!-- /Education -->
<!-- Cetificates -->
<section class="res-edu docs-section">
<h4>Certificates</h4>
<div class="row item" style="height: 300px; margin-bottom: 3rem;">
<a class="item-screenshot-wrapper" target="_blank" href="https://coursera.org/verify/specialization/628IUAIYMQAO">
<img class="item-screenshot" src="static/public/images/Machine Learning Specialization.png">
</a>
<div class="one-half offset-by-one-half column">
<h6 class="item-header">Machine Learning Specialization</h6>
<p class="item-project-summary"> </p>
<p class="docs-subheader"> DeepLearning.AI, Stanford University, Prof. Andrew Ng <span class="date">Oct 2025</span></p>
<a class="button" href="https://coursera.org/verify/specialization/628IUAIYMQAO" target="_blank">Verification</a>
</div>
</div>
<!-- /Education -->
</section>
<!-- End Document
-->
{% endblock %}

BIN
templates/static/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,665 @@
.container {
max-width: 800px;
}
.table-responsive {
width: 100% !important;
overflow-x: auto;
}
.header {
margin-top: 6rem;
text-align: center;
}
.value-prop {
margin-top: 1rem;
}
.value-props {
margin-top: 4rem;
margin-bottom: 4rem;
}
.docs-header {
text-transform: uppercase;
font-size: 1.4rem;
letter-spacing: .2rem;
font-weight: 600;
margin-bottom: 0.1rem;
}
.docs-section {
border-top: 1px solid #eee;
padding: 4rem 0;
margin: 6rem 0 6rem 0;
}
.value-img {
display: block;
text-align: center;
margin: 2.5rem auto 0;
}
.item-grid .column,
.item-grid .columns {
background: #EEE;
text-align: center;
border-radius: 4px;
font-size: 1rem;
text-transform: uppercase;
height: 30px;
line-height: 30px;
margin-bottom: .75rem;
font-weight: 600;
letter-spacing: .1rem;
}
.docs-item .row,
.docs-item.row,
.docs-item form {
margin-bottom: 0;
}
.docs-item h1,
.docs-item h2,
.docs-item h3,
.docs-item h4,
.docs-item h5,
.docs-item h6 {
margin-bottom: 1rem;
}
.heading-font-size {
font-size: 1.2rem;
color: #999;
letter-spacing: normal;
}
.code-item {
margin-top: 1.5rem;
margin-bottom: 0;
}
.code-item-body {
white-space: pre;
word-wrap: break-word;
}
.item {
position: relative;
margin-top: 4rem;
}
.item-header {
font-weight: 600;
margin-top: 1.5rem;
margin-bottom: .5rem;
}
.item-description {
margin-bottom: 1.5rem;
}
.item-project-summary{
font-size: 1rem;
}
select{
width: 100%;
}
.params{
width: 100%;
}
.item-screenshot-wrapper {
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
border-radius: 6px;
border: 1px solid #eee;
height: 250px;
}
.item-screenshot {
width: auto;
max-width: 100%;
max-height: 100%;
margin: 0;
display: block;
object-fit: contain;
}
.item-screenshot.coming-soon {
width: auto;
position: absolute;
background: #eee;
top: 5px;
right: 5px;
bottom: 5px;
left: 5px;
}
.docs-subheader {
font-size: 1.1rem;
margin: 0 0 1rem 1rem;
}
/* ------ */
.dark-theme #about-me {
margin: 3rem 0 3rem 0;
}
#about-me{
margin: 3rem 0 3rem 0;
text-align: justify;
font-size: 1.2rem;
}
.date {
color:#33C3F0;
}
.pdf-light {
background: white !important;
color: black !important;
}
/* Navbar - mobile default */
.navbar {
display: flex;
flex-direction: row; /* horizontal on mobile */
justify-content: center; /* center items horizontally */
align-items: center; /* vertically align items */
flex-wrap: wrap; /* wrap to next line if too many items */
background: #fff;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
margin-bottom: 6rem;
width: 100%;
z-index: 99;
}
.navbar-list {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
list-style: none;
padding: 0;
margin: 0;
width: auto;
}
.navbar-item {
margin: 0.5rem 1rem; /* horizontal spacing between items */
}
.navbar-link {
text-transform: uppercase;
font-size: 1rem;
font-weight: 600;
letter-spacing: 0.1rem;
text-decoration: none;
color: #222;
}
.res-intro #name {
font-weight:800;
color:#555;
}
@keyframes cursor {
from, to {
border-color: transparent;
}
50% {
border-color: #33C3F0; /* Skeleton's accent blue */
}
}
@keyframes typing {
from {
width: 100%;
}
to {
width: 0; /* deletes once */
}
}
@keyframes slide {
33.3333% {
font-size: 3.3rem;
letter-spacing: 3px;
color: #222; /* Dark text for light theme */
}
to {
font-size: 3.3rem;
letter-spacing: 3px;
color: #222; /* Keep it visible */
}
}
.typing-slider {
font-family: "Doto", monospace;
font-weight: 500;
text-align: center;
white-space: nowrap;
margin-left: 1rem;
}
.typing-slider p {
position: relative;
display: inline;
font-size: 0;
text-transform: uppercase;
letter-spacing: 0;
animation: slide 2s step-start forwards; /* run once, keep state */
}
.typing-slider p::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
border-left: 3px solid #33C3F0; /* Accent cursor */
background-color: #fff; /* Light background */
animation: typing 2s steps(15) forwards, cursor 1.5s infinite;
}
.pointer {
cursor: pointer;
-webkit-animation: blink 1.5s steps(1, start) infinite;
animation: blink 1.5s steps(1, start) infinite;
color:#33C3F0;
}
@-webkit-keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
/* Larger than phone */
@media (min-width: 550px) {
.header {
margin-top: 18rem;
}
.value-props {
margin-top: 9rem;
margin-bottom: 7rem;
}
.value-img {
margin-bottom: 1rem;
}
.item-grid .column,
.item-grid .columns {
margin-bottom: 1.5rem;
}
.docs-section {
padding: 4rem 0;
}
#work-experience .work-summary{
text-align: justify;
font-size: 1.2rem;
}
#work-experience .work-technologies{
text-align: justify;
font-size: 1.2rem;
}
.item-send-yourself-copy {
float: right;
margin-top: 12px;
}
.item-screenshot-wrapper {
position: absolute;
width: 48%;
height: 100%;
left: 0;
max-height: none;
}
.table-responsive {
width: 100% !important;
overflow-x: auto;
}
}
/* Larger than tablet */
@media (min-width: 750px) {
/* Navbar */
.navbar + .docs-section {
border-top-width: 0;
}
.navbar {
flex-direction: row; /* horizontal on desktop */
justify-content: flex-start; /* align left */
height: 6.5rem;
padding: 0 2rem;
}
.navbar-list {
display: flex;
justify-content: flex-start;
align-items: center;
width: auto;
}
.navbar-item {
margin: 0 1.5rem 0 0;
}
.navbar-link {
line-height: 6.5rem;
font-size: 11px;
letter-spacing: .2rem;
margin-right: 35px;
}
.navbar-link.active {
color: #33C3F0;
}
.has-docked-nav .navbar {
position: fixed;
top: 0;
left: 0;
}
.has-docked-nav .navbar-spacer {
display: block;
}
.has-docked-nav .navbar > .container {
width: 80%;
}
/* Popover */
.popover.open {
display: block;
}
.popover {
display: none;
position: absolute;
top: 92%;
left: -50%;
background: #fff;
border: 1px solid #eee;
border-radius: 4px;
-webkit-filter: drop-shadow(0 0 6px rgba(0,0,0,.1));
-moz-filter: drop-shadow(0 0 6px rgba(0,0,0,.1));
filter: drop-shadow(0 0 6px rgba(0,0,0,.1));
}
.popover-item:first-child .popover-link:after,
.popover-item:first-child .popover-link:before {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.popover-item:first-child .popover-link:after {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #fff;
border-width: 10px;
margin-left: -10px;
}
.popover-item:first-child .popover-link:before {
border-color: rgba(238, 238, 238, 0);
border-bottom-color: #eee;
border-width: 11px;
margin-left: -11px;
}
.popover-list {
padding: 0;
margin: 0;
list-style: none;
}
.popover-item {
padding: 0;
margin: 0;
}
.popover-link {
position: relative;
color: #222;
display: block;
padding: 8px 20px;
border-bottom: 1px solid #eee;
text-decoration: none;
text-transform: uppercase;
font-size: 1rem;
font-weight: 600;
text-align: center;
letter-spacing: .1rem;
}
.popover-item:first-child .popover-link {
border-radius: 4px 4px 0 0;
}
.popover-item:last-child .popover-link {
border-radius: 0 0 4px 4px;
border-bottom-width: 0;
}
.popover-link:hover {
color: #fff;
background: #33C3F0;
}
.popover-link:hover,
.popover-item:first-child .popover-link:hover:after {
border-bottom-color: #33C3F0;
}
}
.header .header-buttons {
margin: 6rem;
}
/* ---------------- DARK THEME SUPPORT ---------------- */
.dark-theme {
background-color: #121212;
color: #e0e0e0; /* base text color */
}
/* Generic text elements */
.dark-theme p,
.dark-theme ul,
.dark-theme ol,
.dark-theme li,
.dark-theme div,
.dark-theme a,
.dark-theme h1,
.dark-theme h2,
.dark-theme h3,
.dark-theme h4,
.dark-theme h5,
.dark-theme h6 {
color: #aaa; /* brighter default text */
}
/* Links */
.dark-theme a {
color: #33C3F0; /* accent blue */
}
.dark-theme a:hover {
color: #66d5f5; /* lighter blue on hover */
}
/* Navbar */
.dark-theme .navbar {
background: #1e1e1e;
border-top: 1px solid #333;
border-bottom: 1px solid #333;
}
.dark-theme .navbar-link {
color: #ddd;
}
.dark-theme .navbar-link.active {
color: #33C3F0;
}
/* Sections */
.dark-theme .docs-section {
border-top: 1px solid #333;
}
.dark-theme .item-grid .column,
.dark-theme .item-grid .columns {
background: #2a2a2a;
color: #eee;
}
/* Cards / images */
.dark-theme .item-screenshot-wrapper {
border: 1px solid #333;
}
.dark-theme .item-screenshot.coming-soon {
background: #2a2a2a;
}
/* Popovers */
.dark-theme .popover {
background: #1e1e1e;
border: 1px solid #333;
}
.dark-theme .popover-link {
color: #ddd;
border-bottom: 1px solid #333;
}
.dark-theme .popover-link:hover {
background: #33C3F0;
color: #fff;
border-bottom-color: #33C3F0;
}
/* Headers and intro */
.dark-theme .docs-header,
.dark-theme .docs-subheader,
.dark-theme .heading-font-size,
.dark-theme .res-intro #name {
color: #fafafa; /* brighter headers */
}
.dark-theme .code-item {
margin-top: 1.5rem;
margin-bottom: 0;
background-color: #555;
}
.dark-theme .code-item-body {
white-space: pre;
word-wrap: break-word;
background-color: #555;
}
.dark-theme code{
background-color: #333;
}
.dark-theme input {
background-color: #333;
color:#eee;
}
@keyframes cursor {
from, to {
border-color: transparent;
}
50% {
border-color: #33C3F0;
}
}
@keyframes typing {
from {
width: 100%;
}
to {
width: 0; /* deletes once */
}
}
@keyframes slide {
33.3333% {
font-size: 3.3rem;
letter-spacing: 3px;
}
to {
font-size: 3.3rem; /* stay visible */
letter-spacing: 3px; /* keep spacing */
}
}
.dark-theme .typing-slider {
font-family: "Doto", monospace;
font-weight: 500;
text-align: center;
white-space: nowrap;
margin-left: 1rem;
}
.dark-theme .typing-slider p {
position: relative;
display: inline;
font-size: 0;
text-transform: uppercase;
letter-spacing: 0;
animation: slide 2s step-start forwards; /* run once, keep state */
}
.dark-theme .typing-slider p::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
border-left: 3px solid black;
background-color: #121212;
animation: typing 2s steps(15) forwards, cursor 1.5s infinite;
}

View File

@@ -0,0 +1,97 @@
$(document).ready(function() {
// Variables
var $codeSnippets = $('.code-example-body'),
$nav = $('.navbar'),
$body = $('body'),
$window = $(window),
$popoverLink = $('[data-popover]'),
navOffsetTop = $nav.offset().top,
$document = $(document),
entityMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': '&quot;',
"'": '&#39;',
"/": '&#x2F;'
}
function init() {
$window.on('scroll', onScroll)
$window.on('resize', resize)
$popoverLink.on('click', openPopover)
$document.on('click', closePopover)
$('a[href^="#"]').on('click', smoothScroll)
buildSnippets();
}
function smoothScroll(e) {
e.preventDefault();
$(document).off("scroll");
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top-40
}, 0, 'swing', function () {
window.location.hash = target;
$(document).on("scroll", onScroll);
});
}
function openPopover(e) {
e.preventDefault()
closePopover();
var popover = $($(this).data('popover'));
popover.toggleClass('open')
e.stopImmediatePropagation();
}
function closePopover(e) {
if($('.popover.open').length > 0) {
$('.popover').removeClass('open')
}
}
$("#button").click(function() {
$('html, body').animate({
scrollTop: $("#elementtoScrollToID").offset().top
}, 2000);
});
function resize() {
$body.removeClass('has-docked-nav')
navOffsetTop = $nav.offset().top
onScroll()
}
function onScroll() {
if(navOffsetTop < $window.scrollTop() && !$body.hasClass('has-docked-nav')) {
$body.addClass('has-docked-nav')
}
if(navOffsetTop > $window.scrollTop() && $body.hasClass('has-docked-nav')) {
$body.removeClass('has-docked-nav')
}
}
function escapeHtml(string) {
return String(string).replace(/[&<>"'\/]/g, function (s) {
return entityMap[s];
});
}
function buildSnippets() {
$codeSnippets.each(function() {
var newContent = escapeHtml($(this).html())
$(this).html(newContent)
})
}
init();
});

BIN
templates/static/public/.DS_Store vendored Normal file

Binary file not shown.

BIN
templates/static/public/files/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,420 @@
{
"name": "Computer Vision Articles Summary",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"id": "4da75220-2795-45ff-b505-1c381de0de2a",
"name": "Schedule Trigger"
},
{
"parameters": {
"language": "python",
"pythonCode": "from bs4 import BeautifulSoup\n\nresults = []\n\n# Loop through incoming items (each should have HTML in `item.json.data`)\nfor item in _input.all():\n html = item.json.get(\"data\", \"\")\n if not html:\n continue\n\n soup = BeautifulSoup(html, \"html.parser\")\n\n # Each paper is defined by <dt> (meta) and <dd> (details)\n for dt, dd in zip(soup.find_all(\"dt\"), soup.find_all(\"dd\")):\n # --- Extract title ---\n title_tag = dd.find(\"div\", class_=\"list-title mathjax\")\n title = (\n title_tag.get_text(strip=True).replace(\"Title:\", \"\")\n if title_tag else \"No title\"\n )\n\n # --- Extract abstract ---\n abstract_tag = dd.find(\"p\", class_=\"mathjax\")\n abstract = (\n abstract_tag.get_text(strip=True)\n if abstract_tag else \"No abstract\"\n )\n\n # --- Extract PDF link ---\n pdf_link = None\n for a in dt.find_all(\"a\"):\n href = a.get(\"href\", \"\")\n if \"pdf\" in href:\n pdf_link = f\"https://arxiv.org{href}.pdf\"\n break\n\n # --- Append one result per paper ---\n results.append({\n \"title\": title,\n \"download\": pdf_link\n })\n\n# Return the list of results. Each dictionary in the list will become a separate item.\nreturn results"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
432,
0
],
"id": "9b4702c0-144f-4236-8d5d-ef6d53dfe617",
"name": "Code in Python (Beta)"
},
{
"parameters": {
"url": "https://www.arxiv.org/list/cs.CV/recent",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "skip",
"value": "0"
},
{
"name": "show",
"value": "2000"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "accept",
"value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
},
{
"name": "accept-language",
"value": "en-US,en;q=0.9,fa;q=0.8"
},
{
"name": "priority",
"value": "u=0, i"
},
{
"name": "sec-ch-ua",
"value": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\""
},
{
"name": "sec-ch-ua-mobile",
"value": "?0"
},
{
"name": "sec-ch-ua-platform",
"value": "\"macOS\""
},
{
"name": "sec-fetch-dest",
"value": "document"
},
{
"name": "sec-fetch-mode",
"value": "navigate"
},
{
"name": "sec-fetch-site",
"value": "none"
},
{
"name": "sec-fetch-user",
"value": "?1"
},
{
"name": "upgrade-insecure-requests",
"value": "1"
},
{
"name": "user-agent",
"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
},
{
"name": "cookie",
"value": "_ga=GA1.1.1933736800.1760440871;_ga_B1RR0QKWGQ=GS2.1.s1760440871$o1$g0$t1760440874$j57$l0$h0;arxiv_labs={%22sameSite%22:%22strict%22%2C%22expires%22:365};captchaAuth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiY2IzOGM4YS1iZGVlLTQ2OTMtOTY5NS1hOWJiMzI0MWU1MGIiLCJleHAiOjE3NjA0NjEzMTksImlwIjoxNTcuMTM4Ljc2LjEyLCJpYXQiOjE3NjA0NTk1MjAsImlzcyI6IkZhc3RseSJ9.MHgyOWQ3NjE2ZjMwNDg0MTkyNjE4MmIwZDczZjA1YWRjODc2ZDE4NmNiMDM0Njg0MWUzNmE0NGRiZDM5YjdkYmM0;"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
224,
0
],
"id": "057ea5dc-120c-4603-9d5d-6158f2ae621d",
"name": "HTTP Request"
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "models/gemini-2.5-flash",
"mode": "list",
"cachedResultName": "models/gemini-2.5-flash"
},
"messages": {
"values": [
{
"content": "=Summarize the following article into IEEE-style JSON with the following exact schema:\n\n{\n \"title\": \"string — concise, formal title of the article\",\n \"authors\": [\"Author 1\", \"Author 2\", \"Author 3\"],\n \"affiliation\": \"string — single-line institutional affiliation\",\n \"abstract\": \"string — 24 sentences summarizing purpose, method, and conclusion\",\n \"keywords\": [\"keyword1\", \"keyword2\", \"keyword3\", \"keyword4\", \"keyword5\"],\n \"sections\": [\n {\n \"heading\": \"I. Introduction\",\n \"content\": \"24 sentences summarizing context and problem statement.\n list here all models used in the article\"\n },\n {\n \"heading\": \"II. Related Work\",\n \"content\": \"24 sentences summarizing relevant literature or context.\"\n },\n {\n \"heading\": \"III. Methodology\",\n \"content\": \"24 sentences explaining methods or workflow steps.\"\n },\n {\n \"heading\": \"IV. Experimental Results\",\n \"content\": \"24 sentences describing findings, metrics, or comparisons.also return the table of results here in html format with 2 - 4 sentence of explaination\"\n },\n {\n \"heading\": \"V. Discussion\",\n \"content\": \"24 sentences interpreting results and suggesting implications.\"\n }\n ],\n \"acknowledgment\": \"string — one short sentence acknowledging contributions or support. Also put the link for downloading the article here as 'link': 'url'\"\n}\n\nOutput ONLY valid JSON. Do not include markdown or explanations.\n\nInput article:\ntitle: {{ $json[\"title\"] }}\nlink: {{ $json[\"download\"] }}"
}
]
},
"jsonOutput": true,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1,
"position": [
1104,
0
],
"id": "d1ad8585-922e-456b-93a4-e644cdcc08f0",
"name": "Message a model",
"credentials": {
"googlePalmApi": {
"id": "1c9wa457qSf8gf8N",
"name": "Google Gemini(PaLM) Api account"
}
}
},
{
"parameters": {
"type": "random"
},
"type": "n8n-nodes-base.sort",
"typeVersion": 1,
"position": [
640,
0
],
"id": "cf7fda19-d1ad-4600-a3e9-7409936592c4",
"name": "Sort"
},
{
"parameters": {},
"type": "n8n-nodes-base.limit",
"typeVersion": 1,
"position": [
864,
0
],
"id": "e1fa8189-7c8c-41bd-be8b-5ee32ab8cb8e",
"name": "Limit"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"language": "python",
"pythonCode": "import json\n\n# Extract and parse the AI output\nraw_text = _input.item.json.content.parts[0].text\nitem = json.loads(raw_text)\n\n# Format it into a structured dictionary\nresults = {\n 'title': str(item.get(\"title\")),\n 'authors': \", \".join(item.get(\"authors\", [])),\n 'affiliation': str(item.get(\"affiliation\")),\n 'abstract': str(item.get(\"abstract\")),\n 'keywords': \", \".join(item.get(\"keywords\", [])),\n 'sections': \"\\n\\n\".join([f\"{sec.get('heading', '')}\\n{sec.get('content', '')}\" for sec in item.get(\"sections\", [])]),\n 'acknowledgment': str(item.get(\"acknowledgment\"))\n}\n\nreturn results"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1408,
0
],
"id": "adca7415-7187-4fde-a8fa-94e0378042dd",
"name": "Code in Python (Beta)1"
},
{
"parameters": {
"schema": {
"__rl": true,
"value": "public",
"mode": "list",
"cachedResultName": "public"
},
"table": {
"__rl": true,
"mode": "list",
"value": "article"
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {},
"matchingColumns": [
"id"
],
"schema": [
{
"id": "id",
"displayName": "id",
"required": false,
"defaultMatch": true,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "title",
"displayName": "title",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "authors",
"displayName": "authors",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "affiliation",
"displayName": "affiliation",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "abstract",
"displayName": "abstract",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "keywords",
"displayName": "keywords",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "sections",
"displayName": "sections",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "acknowledgment",
"displayName": "acknowledgment",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "created_at",
"displayName": "created_at",
"required": false,
"defaultMatch": false,
"display": true,
"type": "dateTime",
"canBeUsedToMatch": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
1616,
0
],
"id": "f79d443b-4e0f-48a0-83cf-9f81397168e9",
"name": "Insert rows in a table",
"credentials": {
"postgres": {
"id": "7lV0bh2r3wwlG4wG",
"name": "Postgres account"
}
}
}
],
"pinData": {},
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Code in Python (Beta)": {
"main": [
[
{
"node": "Sort",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code in Python (Beta)",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Code in Python (Beta)1",
"type": "main",
"index": 0
}
]
]
},
"Sort": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Code in Python (Beta)1": {
"main": [
[
{
"node": "Insert rows in a table",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "cdc44fdd-e8a4-401b-baa5-c4ccdce1fe00",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "272b58375a8c80e7c3bb5d0fb520f3e6b99d262a371c9a89e5b79e4130600186"
},
"id": "Js9yzziCvWSWZmSp",
"tags": []
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
templates/static/public/images/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

View File

@@ -0,0 +1,149 @@
/* GitHub Theme */
.prettyprint {
background: #fff;
font-family: Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Consolas, monospace;
font-size: 1.2rem;
padding: 2.5rem 3rem;
-webkit-font-smoothing: antialiased;
}
.pln {
color: #333333;
}
@media screen {
.str {
color: #dd1144;
}
.kwd {
color: #333333;
}
.com {
color: #999988;
}
.typ {
color: #445588;
}
.lit {
color: #445588;
}
.pun {
color: #333333;
}
.opn {
color: #333333;
}
.clo {
color: #333333;
}
.tag {
color: navy;
}
.atn {
color: teal;
}
.atv {
color: #dd1144;
}
.dec {
color: #333333;
}
.var {
color: teal;
}
.fun {
color: #990000;
}
}
@media print, projection {
.str {
color: #006600;
}
.kwd {
color: #006;
font-weight: bold;
}
.com {
color: #600;
font-style: italic;
}
.typ {
color: #404;
font-weight: bold;
}
.lit {
color: #004444;
}
.pun, .opn, .clo {
color: #444400;
}
.tag {
color: #006;
font-weight: bold;
}
.atn {
color: #440044;
}
.atv {
color: #006600;
}
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
}
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
/* */
}
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 {
/* */
}
/* My additional styles */
/*li.L0, li.L1, li.L2, li.L3,
li.L5, li.L6, li.L7, li.L8
{ list-style-type: decimal !important }*/
.prettyprint li {
margin-bottom: .3rem;
}

View File

@@ -0,0 +1,427 @@
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove default margin.
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Correct `block` display not defined for any HTML5 element in IE 8/9.
* Correct `block` display not defined for `details` or `summary` in IE 10/11
* and Firefox.
* Correct `block` display not defined for `main` in IE 11.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
/**
* 1. Correct `inline-block` display not defined in IE 8/9.
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
*/
audio,
canvas,
progress,
video {
display: inline-block; /* 1 */
vertical-align: baseline; /* 2 */
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address `[hidden]` styling not present in IE 8/9/10.
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
*/
[hidden],
template {
display: none;
}
/* Links
========================================================================== */
/**
* Remove the gray background color from active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* Improve readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* Text-level semantics
========================================================================== */
/**
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/**
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/**
* Address styling not present in Safari and Chrome.
*/
dfn {
font-style: italic;
}
/**
* Address variable `h1` font-size and margin within `section` and `article`
* contexts in Firefox 4+, Safari, and Chrome.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Address styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/**
* Address inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* Embedded content
========================================================================== */
/**
* Remove border when inside `a` element in IE 8/9/10.
*/
img {
border: 0;
}
/**
* Correct overflow not hidden in IE 9/10/11.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* Address margin not present in IE 8/9 and Safari.
*/
figure {
margin: 1em 40px;
}
/**
* Address differences between Firefox and other browsers.
*/
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
/**
* Contain overflow in all browsers.
*/
pre {
overflow: auto;
}
/**
* Address odd `em`-unit font size rendering in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
/* Forms
========================================================================== */
/**
* Known limitation: by default, Chrome and Safari on OS X allow very limited
* styling of `select`, unless a `border` property is set.
*/
/**
* 1. Correct color not being inherited.
* Known issue: affects color of disabled elements.
* 2. Correct font properties not being inherited.
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
*/
button,
input,
optgroup,
select,
textarea {
color: inherit; /* 1 */
font: inherit; /* 2 */
margin: 0; /* 3 */
}
/**
* Address `overflow` set to `hidden` in IE 8/9/10/11.
*/
button {
overflow: visible;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
* Correct `select` style inheritance in Firefox.
*/
button,
select {
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* Remove inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/**
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
input {
line-height: normal;
}
/**
* It's recommended that you don't attempt to style these elements.
* Firefox's implementation doesn't respect box-sizing, padding, or width.
*
* 1. Address box sizing set to `content-box` in IE 8/9/10.
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
* `font-size` values of the `input`, it causes the cursor style of the
* decrement button to change from `default` to `text`.
*/
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/**
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
* Safari (but not Chrome) clips the cancel button when the search input has
* padding (and `textfield` appearance).
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct `color` not being inherited in IE 8/9/10/11.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/**
* Remove default vertical scrollbar in IE 8/9/10/11.
*/
textarea {
overflow: auto;
}
/**
* Don't inherit the `font-weight` (applied by a rule above).
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
*/
optgroup {
font-weight: bold;
}
/* Tables
========================================================================== */
/**
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}

View File

@@ -0,0 +1,418 @@
/*
* Skeleton V2.0.4
* Copyright 2014, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 12/29/2014
*/
/* Table of contents
- Grid
- Base Styles
- Typography
- Links
- Buttons
- Forms
- Lists
- Code
- Tables
- Spacing
- Utilities
- Clearing
- Media Queries
*/
/* Grid
*/
.container {
position: relative;
width: 100%;
max-width: 960px;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box; }
.column,
.columns {
width: 100%;
float: left;
box-sizing: border-box; }
/* For devices larger than 400px */
@media (min-width: 400px) {
.container {
width: 85%;
padding: 0; }
}
/* For devices larger than 550px */
@media (min-width: 550px) {
.container {
width: 80%; }
.column,
.columns {
margin-left: 4%; }
.column:first-child,
.columns:first-child {
margin-left: 0; }
.one.column,
.one.columns { width: 4.66666666667%; }
.two.columns { width: 13.3333333333%; }
.three.columns { width: 22%; }
.four.columns { width: 30.6666666667%; }
.five.columns { width: 39.3333333333%; }
.six.columns { width: 48%; }
.seven.columns { width: 56.6666666667%; }
.eight.columns { width: 65.3333333333%; }
.nine.columns { width: 74.0%; }
.ten.columns { width: 82.6666666667%; }
.eleven.columns { width: 91.3333333333%; }
.twelve.columns { width: 100%; margin-left: 0; }
.one-third.column { width: 30.6666666667%; }
.two-thirds.column { width: 65.3333333333%; }
.one-half.column { width: 48%; }
/* Offsets */
.offset-by-one.column,
.offset-by-one.columns { margin-left: 8.66666666667%; }
.offset-by-two.column,
.offset-by-two.columns { margin-left: 17.3333333333%; }
.offset-by-three.column,
.offset-by-three.columns { margin-left: 26%; }
.offset-by-four.column,
.offset-by-four.columns { margin-left: 34.6666666667%; }
.offset-by-five.column,
.offset-by-five.columns { margin-left: 43.3333333333%; }
.offset-by-six.column,
.offset-by-six.columns { margin-left: 52%; }
.offset-by-seven.column,
.offset-by-seven.columns { margin-left: 60.6666666667%; }
.offset-by-eight.column,
.offset-by-eight.columns { margin-left: 69.3333333333%; }
.offset-by-nine.column,
.offset-by-nine.columns { margin-left: 78.0%; }
.offset-by-ten.column,
.offset-by-ten.columns { margin-left: 86.6666666667%; }
.offset-by-eleven.column,
.offset-by-eleven.columns { margin-left: 95.3333333333%; }
.offset-by-one-third.column,
.offset-by-one-third.columns { margin-left: 34.6666666667%; }
.offset-by-two-thirds.column,
.offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
.offset-by-one-half.column,
.offset-by-one-half.columns { margin-left: 52%; }
}
/* Base Styles
*/
/* NOTE
html is set to 62.5% so that all the REM measurements throughout Skeleton
are based on 10px sizing. So basically 1.5rem = 15px :) */
html {
font-size: 62.5%; }
body {
font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
line-height: 1.6;
font-weight: 400;
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #222; }
/* Typography
*/
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 2rem;
font-weight: 300; }
h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;}
h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; }
h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; }
h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
/* Larger than phablet */
@media (min-width: 550px) {
h1 { font-size: 5.0rem; }
h2 { font-size: 4.2rem; }
h3 { font-size: 3.6rem; }
h4 { font-size: 3.0rem; }
h5 { font-size: 2.4rem; }
h6 { font-size: 1.5rem; }
}
p {
margin-top: 0; }
/* Links
*/
a {
color: #1EAEDB; }
a:hover {
color: #0FA0CE; }
/* Buttons
*/
.button,
button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
display: inline-block;
height: 38px;
padding: 0 30px;
color: #555;
text-align: center;
font-size: 11px;
font-weight: 600;
line-height: 38px;
letter-spacing: .1rem;
text-transform: uppercase;
text-decoration: none;
white-space: nowrap;
background-color: transparent;
border-radius: 4px;
border: 1px solid #bbb;
cursor: pointer;
box-sizing: border-box; }
.button:hover,
button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover,
.button:focus,
button:focus,
input[type="submit"]:focus,
input[type="reset"]:focus,
input[type="button"]:focus {
color: #333;
border-color: #888;
outline: 0; }
.button.button-primary,
button.button-primary,
input[type="submit"].button-primary,
input[type="reset"].button-primary,
input[type="button"].button-primary {
color: #FFF;
background-color: #33C3F0;
border-color: #33C3F0; }
.button.button-primary:hover,
button.button-primary:hover,
input[type="submit"].button-primary:hover,
input[type="reset"].button-primary:hover,
input[type="button"].button-primary:hover,
.button.button-primary:focus,
button.button-primary:focus,
input[type="submit"].button-primary:focus,
input[type="reset"].button-primary:focus,
input[type="button"].button-primary:focus {
color: #FFF;
background-color: #1EAEDB;
border-color: #1EAEDB; }
/* Forms
*/
input[type="email"],
input[type="number"],
input[type="search"],
input[type="text"],
input[type="tel"],
input[type="url"],
input[type="password"],
textarea,
select {
height: 38px;
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
background-color: #fff;
border: 1px solid #D1D1D1;
border-radius: 4px;
box-shadow: none;
box-sizing: border-box; }
/* Removes awkward default styles on some inputs for iOS */
input[type="email"],
input[type="number"],
input[type="search"],
input[type="text"],
input[type="tel"],
input[type="url"],
input[type="password"],
textarea {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none; }
textarea {
min-height: 65px;
padding-top: 6px;
padding-bottom: 6px; }
input[type="email"]:focus,
input[type="number"]:focus,
input[type="search"]:focus,
input[type="text"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="password"]:focus,
textarea:focus,
select:focus {
border: 1px solid #33C3F0;
outline: 0; }
label,
legend {
display: block;
margin-bottom: .5rem;
font-weight: 600; }
fieldset {
padding: 0;
border-width: 0; }
input[type="checkbox"],
input[type="radio"] {
display: inline; }
label > .label-body {
display: inline-block;
margin-left: .5rem;
font-weight: normal; }
/* Lists
*/
ul {
list-style: circle inside; }
ol {
list-style: decimal inside; }
ol, ul {
padding-left: 0;
margin-top: 0; }
ul ul,
ul ol,
ol ol,
ol ul {
margin: 1.5rem 0 1.5rem 3rem;
font-size: 90%; }
li {
margin-bottom: 1rem; }
/* Code
*/
code {
padding: .2rem .5rem;
margin: 0 .2rem;
font-size: 90%;
white-space: nowrap;
background: #F1F1F1;
border: 1px solid #E1E1E1;
border-radius: 4px; }
pre > code {
display: block;
padding: 1rem 1.5rem;
white-space: pre; }
/* Tables
*/
th,
td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #E1E1E1; }
th:first-child,
td:first-child {
padding-left: 0; }
th:last-child,
td:last-child {
padding-right: 0; }
/* Spacing
*/
button,
.button {
margin-bottom: 1rem; }
input,
textarea,
select,
fieldset {
margin-bottom: 1.5rem; }
pre,
blockquote,
dl,
figure,
table,
p,
ul,
ol,
form {
margin-bottom: 2.5rem; }
/* Utilities
*/
.u-full-width {
width: 100%;
box-sizing: border-box; }
.u-max-full-width {
max-width: 100%;
box-sizing: border-box; }
.u-pull-right {
float: right; }
.u-pull-left {
float: left; }
/* Misc
*/
hr {
margin-top: 3rem;
margin-bottom: 3.5rem;
border-width: 0;
border-top: 1px solid #E1E1E1; }
/* Clearing
*/
/* Self Clearing Goodness */
.container:after,
.row:after,
.u-cf {
content: "";
display: table;
clear: both; }
/* Media Queries
*/
/*
Note: The best way to structure the use of media queries is to create the queries
near the relevant code. For example, if you wanted to change the styles for buttons
on small devices, paste the mobile query code up in the buttons section and style it
there.
*/
/* Larger than mobile */
@media (min-width: 400px) {}
/* Larger than phablet (also point when grid becomes active) */
@media (min-width: 550px) {}
/* Larger than tablet */
@media (min-width: 750px) {}
/* Larger than desktop */
@media (min-width: 1000px) {}
/* Larger than Desktop HD */
@media (min-width: 1200px) {}

43
ultralytics/__init__.py Normal file
View File

@@ -0,0 +1,43 @@
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
__version__ = "8.3.204"
import importlib
import os
# Set ENV variables (place before imports)
if not os.environ.get("OMP_NUM_THREADS"):
os.environ["OMP_NUM_THREADS"] = "1" # default for reduced CPU utilization during training
from ultralytics.utils import ASSETS, SETTINGS
from ultralytics.utils.checks import check_yolo as checks
from ultralytics.utils.downloads import download
settings = SETTINGS
MODELS = ("YOLO", "YOLOWorld", "YOLOE", "NAS", "SAM", "FastSAM", "RTDETR")
__all__ = (
"__version__",
"ASSETS",
*MODELS,
"checks",
"download",
"settings",
)
def __getattr__(name: str):
"""Lazy-import model classes on first access."""
if name in MODELS:
return getattr(importlib.import_module("ultralytics.models"), name)
raise AttributeError(f"module {__name__} has no attribute {name}")
def __dir__():
"""Extend dir() to include lazily available model names for IDE autocompletion."""
return sorted(set(globals()) | set(MODELS))
if __name__ == "__main__":
print(__version__)

Binary file not shown.

BIN
ultralytics/assets/bus.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

1032
ultralytics/cfg/__init__.py Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More