init commit
43
__init__.py
Normal 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
@@ -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
BIN
datasets/__pycache__/MC_NDCC.cpython-310.pyc
Normal file
BIN
datasets/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
datasets/__pycache__/datasets.cpython-310.pyc
Normal file
17
datasets/datasets.py
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
DATASETS = [
|
||||
"bill",
|
||||
"brain",
|
||||
"glass",
|
||||
"hcv",
|
||||
"heart",
|
||||
"ionosphere",
|
||||
"iris",
|
||||
"raisin",
|
||||
"sonar",
|
||||
"wholesale",
|
||||
"wine",
|
||||
"yeast"
|
||||
]
|
||||
|
||||
|
||||
22
main.py
Normal 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
@@ -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
@@ -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
@@ -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)
|
||||
80
models/S3VM_unconstrained.py
Normal 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
@@ -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
BIN
models/__pycache__/LSTSVM.cpython-310.pyc
Normal file
BIN
models/__pycache__/NewtonUTSVM.cpython-310.pyc
Normal file
BIN
models/__pycache__/S3VM_constrained.cpython-310.pyc
Normal file
BIN
models/__pycache__/S3VM_constrained.cpython-313.pyc
Normal file
BIN
models/__pycache__/S3VM_unconstrained.cpython-310.pyc
Normal file
BIN
models/__pycache__/TSVM.cpython-310.pyc
Normal file
BIN
models/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
models/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
models/__pycache__/models.cpython-310.pyc
Normal file
BIN
models/__pycache__/models.cpython-313.pyc
Normal file
BIN
models/__pycache__/utils.cpython-310.pyc
Normal file
93
models/models.py
Normal 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
@@ -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
BIN
routes/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
routes/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
routes/__pycache__/articles.cpython-310.pyc
Normal file
BIN
routes/__pycache__/articles.cpython-313.pyc
Normal file
BIN
routes/__pycache__/projects.cpython-310.pyc
Normal file
BIN
routes/__pycache__/projects.cpython-313.pyc
Normal file
BIN
routes/__pycache__/resume.cpython-310.pyc
Normal file
BIN
routes/__pycache__/resume.cpython-313.pyc
Normal file
15
routes/articles.py
Normal 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
@@ -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
@@ -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
17
templates/404.html
Normal 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
@@ -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 Newton’s 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
@@ -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>
|
||||
105
templates/includes/footer.html
Normal 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>
|
||||
38
templates/includes/head.html
Normal 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... -->
|
||||
11
templates/includes/navbar.html
Normal 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
@@ -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 %}
|
||||
58
templates/projects/generate_ndcc.html
Normal 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 %}
|
||||
78
templates/projects/run_models.html
Normal 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 %}
|
||||
145
templates/projects/run_yolo.html
Normal 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
@@ -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">Master’s 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">Bachelor’s 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
665
templates/static/css/main.css
Normal 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;
|
||||
}
|
||||
|
||||
97
templates/static/js/main.js
Normal 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 = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"/": '/'
|
||||
}
|
||||
|
||||
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
BIN
templates/static/public/files/.DS_Store
vendored
Normal 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 — 2–4 sentences summarizing purpose, method, and conclusion\",\n \"keywords\": [\"keyword1\", \"keyword2\", \"keyword3\", \"keyword4\", \"keyword5\"],\n \"sections\": [\n {\n \"heading\": \"I. Introduction\",\n \"content\": \"2–4 sentences summarizing context and problem statement.\n list here all models used in the article\"\n },\n {\n \"heading\": \"II. Related Work\",\n \"content\": \"2–4 sentences summarizing relevant literature or context.\"\n },\n {\n \"heading\": \"III. Methodology\",\n \"content\": \"2–4 sentences explaining methods or workflow steps.\"\n },\n {\n \"heading\": \"IV. Experimental Results\",\n \"content\": \"2–4 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\": \"2–4 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": []
|
||||
}
|
||||
BIN
templates/static/public/files/NUTSVM.pdf
Normal file
BIN
templates/static/public/files/S3VM_vs_NUTSVM.pdf
Normal file
BIN
templates/static/public/files/repair/images/RPf_00152.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
templates/static/public/files/repair/images/RPf_00153.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
templates/static/public/files/repair/images/RPf_00156.png
Normal file
|
After Width: | Height: | Size: 447 KiB |
BIN
templates/static/public/files/repair/images/RPf_00200.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
BIN
templates/static/public/files/repair/images/RPf_00201.png
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
templates/static/public/files/repair/images/RPf_00202.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
templates/static/public/files/repair/images/RPf_00281.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
templates/static/public/files/repair/images/RPf_00282.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
templates/static/public/files/repair/images/RPf_00283.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
templates/static/public/files/repair/images/RPf_00291.png
Normal file
|
After Width: | Height: | Size: 341 KiB |
BIN
templates/static/public/files/repair/images/RPf_00293.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
templates/static/public/files/repair/images/RPf_00294.png
Normal file
|
After Width: | Height: | Size: 273 KiB |
BIN
templates/static/public/files/repair/images/RPf_00302.png
Normal file
|
After Width: | Height: | Size: 264 KiB |
BIN
templates/static/public/files/repair/images/RPf_00303.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
templates/static/public/files/repair/images/RPf_00304.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
templates/static/public/files/repair/images/RPf_00310.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
templates/static/public/files/repair/images/RPf_00311.png
Normal file
|
After Width: | Height: | Size: 249 KiB |
BIN
templates/static/public/files/repair/images/RPf_00312.png
Normal file
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 60 KiB |
BIN
templates/static/public/images/.DS_Store
vendored
Normal file
BIN
templates/static/public/images/Advanced Learning Algorithms.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
BIN
templates/static/public/images/NUTSVM.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
templates/static/public/images/S3VM_vs_NUTSVM.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
templates/static/public/images/Supervised Machine Learning.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
templates/static/public/images/active_recaller.png
Normal file
|
After Width: | Height: | Size: 510 KiB |
BIN
templates/static/public/images/article_automation.png
Normal file
|
After Width: | Height: | Size: 950 KiB |
BIN
templates/static/public/images/favicon.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
templates/static/public/images/ndcc.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
templates/static/public/images/repair.png
Normal file
|
After Width: | Height: | Size: 3.6 MiB |
BIN
templates/static/public/images/sample_image.jpg
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
templates/static/public/images/yolov8_result.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
templates/static/public/images/yolov8_result_table.png
Normal file
|
After Width: | Height: | Size: 282 KiB |
149
templates/static/skeleton/css/github-prettify-theme.css
Normal 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;
|
||||
}
|
||||
427
templates/static/skeleton/css/normalize.css
vendored
Normal 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;
|
||||
}
|
||||
418
templates/static/skeleton/css/skeleton.css
vendored
Normal 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
@@ -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__)
|
||||
BIN
ultralytics/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
ultralytics/assets/bus.jpg
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
ultralytics/assets/zidane.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |