Turning ideasinto Products
I design user-focused, aesthetic and functional digital experiences across AI, Web Design, Mobile Design and Frontend.
Technologies I work with
Drag them, fling them, smash them together. I'll even let you build the connections between them yourself.
The bridge
between design
& code
From corporate websites to congress automation, from multi-agent AI platforms to native iOS apps, I build end to end. The other half of my time goes to data: neural networks, RAG pipelines, numerical optimization and the visualizations that make a result understandable. I combine design sensibility with systems engineering, and I chase measurable SEO/GEO results and reliable automations.
Live projects
From corporate sites to congress automation, from a RAG-based memory network to a graph-indexed iOS app. Every line of code serves a measurable goal.
Data Lab
The output of a model matters, and so does how that output is read. This section has three things: visualizations drawn from real project data, formulas turned into code line by line, and the applications that use them.
I tried to explain things without jargon; still, if you tap any dotted-underlined term, it explains what it means.
Making data readable
Every chart below was produced from real output in my repositories: epoch series extracted from notebook logs, a committed sensor CSV and the optimization scripts' own run results. The badges show which library drew the original.
What exactly does early stopping catch?
Training accuracy climbs to 90% while validation flattens at 80% — that gap is itself. The dashed line marks 14, where bottoms out; restores the weights from there.
The four numbers behind accuracy
91.25% accuracy tells you nothing on its own; the real question is where the errors fall. The opens that up: the model misses 3 real buyers and targets 4 people for nothing — and those two errors do not cost the same.
Where does the regression network saturate?
Validation drops quickly over the first ten and then separates from the training curve. and manage that gap; the final model finishes at 0.92 and an average error of $15,617.
Reliable readings from a noisy signal
10,138 raw measurements from the serial port, a ~85-minute heating experiment. The two raw sensors jitter; the 30-second and the band show the underlying trend and the measurement uncertainty together.
Why does the second derivative matter so much?
Absolute error to the target, on a log scale. Gradient descent with a fixed only cuts the error to 0.8× each iteration — barely half the way in 4 steps. Newton, by dividing by the , converges : the error roughly squares each step and reaches machine precision in 5 steps. Both curves are real output from the repositories below.
Turning formulas into lines of code
Five optimization repos, one shared idea: no derivatives written by hand. In every one the function is defined as a SymPy expression, the gradient is derived with sp.diff, then made numeric with .subs(). The cards below progress from fixed step sizes to symbolic line search — the code blocks are real lines from the repos.
Gradient descent — single variable
sp.diff derives it from the function expression.import sympy as sp # Define symbolic variablex = sp.symbols('x') # define the functionf = (x)**2 + 6*(x) + 1 # derivativef_derivative = sp.diff(f, x) # define inital valuesx_value = 0alfa = 0.1 for i in range(1, 5): result = f_derivative.subs(x, x_value) # new x value x_value -= alfa * result print(f"Yeni x_{i} değeri: {x_value}\n")x0 = 0 → x1 = -0.6 → x2 = -1.08 → x3 = -1.464 → x4 = -1.7712The entire formula collapses into one line: x_value -= alfa * result. Everything else is obtaining the derivative symbolically.
Gradient descent — vector form
for i in range(iterations): # new values new_x_1_value = x_1_value - alpha_value * df_dx1.subs({x_1: x_1_value, x_2: x_2_value}) new_x_2_value = x_2_value - alpha_value * df_dx2.subs({x_1: x_1_value, x_2: x_2_value}) print(f"Iterasyon {i + 1}:") # update the new values x_1_value = new_x_1_value x_2_value = new_x_2_valueThe order matters here: both components are computed from the old iterate and then written together — a correct simultaneous update. Updating x_1_value early would silently turn it into Gauss–Seidel. Also, because the curvature of x2 is 12, the step factor (1 − 12α) comes out as −0.2: with the same α one coordinate oscillates while the other converges smoothly — that is exactly what ill-conditioning looks like.
Newton's method — optimization form
import sympy as spx = sp.symbols('x')f = (x) ** 3 - 3 * (x) ** 2 #first and second derivativef_derivative = sp.diff(f, x)f_second_derivative = sp.diff(f_derivative, x) x_value = 3iteration = 5for i in range(1, iteration+1): first_derivative = f_derivative.subs(x, x_value) second_derivative = f_second_derivative.subs(x, x_value) if second_derivative != 0: x_value = x_value - (first_derivative / second_derivative) print(f"new x_{i} value: {sp.N(x_value)}") else: print("Division by zero. Choose a different initial value.") breakx0 = 3.000000 → x1 = 2.250000 → x2 = 2.025000 → x3 = 2.000305 → x4 = 2.000000 → x5 = 2.000000The repo name says "Raphson" but the code uses f′/f″, not the classic root-finding form f/f′. So this is a search for a stationary point, not a root: the roots of x3 − 3x2 are 0 and 3, yet starting from x0 = 3 the code moves away from the root toward x = 2, the local minimum.
Quasi-Newton — direction from an approximate Hessian
sp.solve from the orthogonality condition pT∇f(x + Sp) = 0.h_0 = np.array([[1/2, 0], [0, 1/6]]) #Find p_0p_0 = np.dot(h_0, q_0.transpose())*-1X_1 = X_0_transpose + S*p_0 # ... q_1 = gradient at X_1 ...result_sum = np.dot(p_0_transpose, q_1_transpose).sum() ## Find Sif result_sum != 0: S_solve = sp.solve(result_sum, S) ϴ = reel_q_1_transpose - q_0_transpose # y = Δgradientα = reel_X_1 - X_0_transpose # s = Δxβ = np.divide(α, ϴ)print(f"β = {β}")To be honest: this is not BFGS. The code builds both components of the secant update correctly (ϴ = Δgradient, α = Δx), but the np.divide on the last line is an element-wise division — not a rank-2 outer-product update — and h_0 is never updated to h_1. So the line-search half of a quasi-Newton step is done; the matrix update is missing.
Conjugate gradient — Fletcher–Reeves
# ilk yön: en dik inişp_0 = -q_0X_1 = X_0 + S*p_0 # ... q_1 = gradient at X_1 ... # tam çizgi araması: p_0 · q_1 = 0 koşulundan Sresult_sum = np.dot(p_0, q_1_transpose).sum()if result_sum != 0: S_solve = sp.solve(result_sum, S) #find betabeta = np.dot(reel_q_1, reel_q_1_transpose).sum()/np.dot(q_0, q_0_transpose).sum() p_1 = -(reel_q_1_transpose)+(beta)*(p_0_transpose)print(p_1)Most textbook implementations pick the step size as a constant; here S is solved symbolically from the orthogonality condition with sp.solve, and comes out as exactly 13/34. In a single step the gradient norm drops so far that β lands at a tiny 1/1156.
Note: the conjugate gradient and quasi-Newton files are hand-unrolled iterations, not converging loops. None of them has a stopping tolerance; the iteration counts are hard-coded.
From model to result
From image classification to tabular regression, from hardware telemetry to regularization analysis. The numbers on the cards are measured results from the repositories.
FurVision
A convolutional network built from scratch for cat/dog classification. Intermediate-layer activations were extracted with a separate Model and the feature maps visualized — to see what the network is actually looking at.
ANN Real Estate Regression
House price prediction on the Ames Housing dataset. An end-to-end tabular ML pipeline including missing-value imputation, standardization and dropout regularization.
Arduino IoT Telemetry
A data pipeline that timestamps the sensor stream coming from the serial port and writes it to CSV, then validates it and analyzes it interactively with Plotly. Dual-sensor comparison, moving average, outlier detection and R² fit analysis.
K-NN Classification
k-nearest-neighbor classification with the Minkowski metric (p=2, i.e. Euclidean). A study showing why scaling is mandatory for distance-based methods and how the choice of k sets the bias–variance balance.
ANN Energy Prediction
Prediction of the hourly net electrical output of a combined-cycle power plant from four variables: ambient temperature, exhaust vacuum, pressure and humidity; with a deliberately small network.
Ridge vs Lasso
A comparison of how L2 and L1 penalties affect the coefficients: Ridge shrinks them while Lasso drives them exactly to zero, performing implicit feature selection.
Career journey
From internship to full-time engineering — professional experience focused on software, automation and AI.
I built corporate websites, congress/SaaS automation and AI products. For congress.writetecbt.com I developed an end-to-end platform on the Google Drive v3 API that generates the congress proceedings book automatically; 5+ live client sites were launched.
Computer engineering duties within the holding company; I provided technical support in system infrastructure, software development and operational processes.
I supported the development of desktop GUI applications with PyQt6 and improved the user experience. I contributed to cross-platform mobile app development with React Native (Expo).
I worked as a freelance AI trainer on prompt design and prompt engineering to improve the quality of training data for large language models.
As an intern network engineer I gained experience in field and system administration on computer networks, Windows Server and corporate network infrastructure.
Let's build
something together
For new projects, consulting, congress/SaaS automation or just a hello, filling in the form is all it takes. I usually reply within 24 hours.
