This is a generative adversarial network trained completely from scratch on my own photographs. No pretrained weights from the internet. No borrowed knowledge from other models. No scraped datasets. Just my own camera roll and a lot of GPU time.
The Philosophy: I wanted to see what a neural network would learn if it only ever saw my life. Not the internet's collective visual memory, but specifically the things I chose to photograph - glass objects I made in my studio, moments I wanted to remember, textures that caught my eye, the particular way light falls through handblown glass. The question was: can a machine learn to dream my dreams?
How GANs Work: A Generative Adversarial Network consists of two neural networks locked in competition. The Generator tries to create fake images that look real. The Discriminator tries to identify which images are fake. They train together - as the Discriminator gets better at spotting fakes, the Generator must get better at creating convincing ones. Through this adversarial process, the Generator eventually learns the statistical patterns underlying the training data.
The Dataset: I started with 7,843 photographs from my camera roll, spanning several years. These were preprocessed to 512x512 pixels for training. Through data augmentation (random flips, color jitter, slight rotations), this expanded to 39,215 training images. The content is personal - glass pieces I blew, ceramic experiments, metal sculptures, found objects, and countless undefinable moments.
Enhanced Conditioning: Simple GANs generate random images from noise. To have more control, I implemented extensive feature extraction on every training image. This includes: spatial grids dividing each image into 16x16 cells with color, texture, and gradient information; material property analysis detecting reflectivity, roughness, and metallic qualities; lighting analysis; topological features using Betti numbers and Euler characteristics; fractal dimension measuring visual complexity; and spectral graph analysis. All of this - 6.2 gigabytes of extracted features - feeds into 512-dimensional conditioning vectors.
Architecture: The implementation uses StyleGAN2-ADA (Adaptive Discriminator Augmentation) as a base, with significant modifications. I built a compositional architecture with separate generators for foreground objects and backgrounds, combined through learned alpha masks. The discriminator evaluates images at three different scales simultaneously. Five specialized encoder networks process the conditioning features before injection into the generator.
Training: The model trained for approximately two weeks on an RTX 3060 with 12GB VRAM. Mixed precision (FP16) training kept memory usage manageable while maintaining quality. The training logs show 40+ million parameter updates.
A small language model trained on my own writing - emails, messages, notes, reflections spanning several years. The goal wasn't to create something useful in a practical sense. I wanted to see if patterns in my language could be captured and reflected back, even through a relatively simple neural network.
Architecture: This is a GPT-style decoder-only transformer, written entirely from scratch without using any pre-built transformer libraries. Every component - the multi-head self-attention mechanism, the position-wise feedforward networks, the layer normalization, the positional encoding - was implemented manually. The model has 6 transformer layers, 8 attention heads, and an embedding dimension of 512.
Multi-Head Self-Attention: The heart of the transformer. For each token, the model computes attention scores with every previous token, learning which parts of the context are relevant for predicting the next word. Multiple heads allow the model to attend to different types of relationships simultaneously.
Tokenizer: I built a custom BPE (Byte Pair Encoding) tokenizer trained specifically on my writing. BPE starts with individual characters and iteratively merges the most frequent pairs, eventually building a vocabulary of subword units that efficiently represent the patterns in the text.
Training Data: 221,411 lines of text from my personal writing. This includes years of correspondence, notes, and other text I've written. The model learned from this corpus without any external data.
RAG Implementation: To give the model access to specific information without having to memorize everything, I implemented Retrieval-Augmented Generation. When generating text, the model can retrieve relevant passages from a database and incorporate them into its context.
Results: The model produces text that occasionally captures my voice - certain turns of phrase, topic tendencies, stylistic quirks. It's not intelligent in any meaningful sense, but it's a mirror of sorts, showing patterns I might not have noticed in my own writing.
A system that translates outdoor temperature into kiln firing schedules. The weather on any given day determines how hot the kiln will go, how long it will hold at peak temperature, and how the entire firing curve unfolds. Cold days mean gentler fires. Warm days push toward the edge of what the glass can take.
The Concept: Glass slumping requires precise temperature control. Too hot and the glass collapses into a puddle. Too cool and it barely moves. The traditional approach uses fixed programs. Birthwave instead derives the firing parameters from the weather, making each piece a record of atmospheric conditions.
The Mathematics: The core equation relates outdoor temperature to kiln target temperature:
This means at -14.5C outside, the kiln goes to 416C (barely slumping). At 30.3C outside, it reaches 730C (full fuse). The constants were derived from empirical testing and personal preference for how weather should map to fire.
Year Normalization: To account for seasonal variation, the system calculates a "year position" value:
This normalizes the temperature range (-14.5C to 30.3C) to a 0-1 scale representing position in the yearly temperature cycle.
Hold Time: How long the kiln stays at peak temperature also varies with conditions:
Where W is a weather modifier (-0.2 for rain to +0.3 for blazing sun). Longer holds mean more dramatic slumping.
Personal Significance: April 4, 2025 - the day my son was born. Outside temperature ranged from 2C to 16C. The kiln peaked at 665C. That piece exists as a physical record of the weather on that day, transformed through fire into permanent form.
A tool that converts mathematical functions into sound. Type an equation, hear what it sounds like. The most direct translation between mathematics and audio possible.
Core Concept: Sound is pressure waves. Pressure waves can be described mathematically. Therefore, any mathematical function that produces values over time can become sound. sin(x*440*2*pi) produces a pure 440Hz tone - the note A above middle C.
Function Library: Beyond basic trigonometry (sin, cos, tan), the tool supports: square waves via sign(sin(x)), sawtooth waves via mod functions, noise via random(), and arbitrary combinations thereof. You can modulate frequency (FM synthesis), amplitude (AM synthesis), or combine waves in any way mathematics allows.
AM Synthesis: Amplitude modulation multiplies two signals together. A carrier frequency modulated by a lower frequency creates tremolo effects. Higher modulation frequencies create new harmonic content - the basis of AM radio and certain synthesizer patches.
FM Synthesis: Frequency modulation uses one oscillator to control the frequency of another. This creates complex, evolving timbres from simple sine waves - the foundation of the Yamaha DX7 and countless classic sounds.
Implementation: The tool generates audio at 44.1kHz sample rate (CD quality). Each sample is calculated by evaluating the user's function at that point in time. The result is written to a WAV file or played directly through the Web Audio API.
Examples: sin(x*440*2*pi) = pure tone. sin(x*440*2*pi)*sin(x*5*2*pi) = tremolo. sin(x*440*2*pi + sin(x*110*2*pi)*5) = FM bell tone. The possibilities are infinite.
When different glasses are fused together, they must have matching coefficients of expansion (COE). If they don't, internal stresses develop as the piece cools, leading to cracking - sometimes immediately, sometimes months later. Kompa calculates compatibility.
The Problem: Glass expands when heated and contracts when cooled. Different glass compositions expand at different rates. If you fuse two glasses with different expansion coefficients, the one that contracts more will be under tension, the other under compression. Above a threshold, the glass fails.
COE Calculation: The Coefficient of Expansion is measured in parts per million per degree Celsius (ppm/C). Common art glass runs around COE 90 (Bullseye) or COE 96 (Spectrum). A difference of more than 3-5 COE points is generally problematic.
Appen-Winkelmann Formula: For calculating COE from glass composition, the tool uses the Appen-Winkelmann formula. This empirical formula assigns expansion factors to each oxide component (SiO2, Na2O, CaO, etc.) and sums them weighted by mole fraction.
Compatibility Rules: Glasses within 3 COE points are generally compatible. 3-5 points is marginal - might work for small pieces. Beyond 5 points, expect failure. The tool calculates expected stress and warns accordingly.
Material Database: Over 200 materials with known expansion coefficients and compositions. Import recipes from glazy.org, the ceramics database, and calculate compatibility with existing glasses.
Stress Visualization: The calculator shows not just numbers but visual representations of expected stress patterns. Compression appears blue, tension appears red. The intensity indicates magnitude.
I write mathematics that become bodies. LAJFI is a self-evolving ecosystem written in Python where organisms live, eat, reproduce, and die. Each organism carries 30 parameters as DNA, derived from mathematical formulas that define its physical form.
The DNA: Every organism is built from three overlapping mathematical shapes. The 30 parameters control everything: number of symmetry axes, curvature, fractal depth, color, size. When two organisms mate, their DNA is interpolated. Mutations introduce random changes. Natural selection does the rest.
The Ecosystem: A closed world with a population cap of 30 organisms and 50 plants. Plants are polygon reservoirs: when eaten, surfaces are deleted and energy is released. Predators blend prey DNA through interpolation. The strongest organism is auto-exported as .stl for 3D printing.
From Formula to Glass: The pipeline goes:
The .stl file is 3D-printed in PLA. The print becomes a model for a casting mold in gypsum-quartz. The mold goes into the kiln. Glass fills the negative space. The PLA burns out at 450C. The formula becomes form. The form becomes matter.
Live Version: The ecosystem runs in the browser using Three.js at vetroal.se/lajf. Organisms can be exported as STL files for printing. There is also a GOD MODE.
Using WiFi signals to detect human presence and activity without cameras. When radio waves pass through a space, they're affected by everything in that space - including people. By analyzing these disturbances, we can sense movement, breathing, and even specific activities.
The Principle: WiFi uses OFDM (Orthogonal Frequency Division Multiplexing), which splits the signal across many subcarriers. Each subcarrier experiences different multipath effects. Channel State Information (CSI) captures these effects, providing a rich signal that changes when the environment changes.
What CSI Contains: For each packet, CSI provides amplitude and phase for every subcarrier (up to 114 with HT40 mode). This is essentially a snapshot of how the radio environment looks at that moment. Movement creates characteristic patterns in this data.
Hardware: Most consumer WiFi chips don't expose CSI. I'm using TP-Link routers with Atheros AR9344 chipsets, running custom OpenWRT firmware with modified ath9k drivers that extract CSI data from received packets.
The Challenge: Raw CSI is noisy. Phase is particularly problematic due to timing offsets and hardware imperfections. The signal processing pipeline includes: sanitization (removing phase jumps), filtering (Butterworth lowpass), normalization, and feature extraction before feeding to machine learning models.
Machine Learning: For activity classification, I've experimented with various architectures. CNN-GRU hybrids work well - the CNN extracts spatial features across subcarriers, while the GRU captures temporal patterns. Simple presence detection achieves good accuracy; activity classification is harder.
Privacy: Unlike cameras, WiFi sensing can't identify individuals or capture visual information. It detects presence and movement patterns only. This makes it suitable for applications where visual surveillance would be inappropriate.