Spaces:
Running
Running
update deep learning
Browse files- DeepLearning/index.html +145 -111
- index.html +308 -0
DeepLearning/index.html
CHANGED
|
@@ -3315,70 +3315,104 @@
|
|
| 3315 |
},
|
| 3316 |
"rnn": {
|
| 3317 |
overview: `
|
| 3318 |
-
<h3>
|
| 3319 |
-
<p>
|
| 3320 |
-
|
| 3321 |
-
<h3>The Vanishing Gradient Problem</h3>
|
| 3322 |
-
<p><strong>Problem:</strong> Standard RNNs can't learn long-term dependencies (gradients vanish over many time steps)</p>
|
| 3323 |
-
<p><strong>Solution:</strong> LSTM (Long Short-Term Memory) with gating mechanisms</p>
|
| 3324 |
-
|
| 3325 |
-
<h3>LSTM Gates</h3>
|
| 3326 |
-
<ul>
|
| 3327 |
-
<li><strong>Forget Gate:</strong> What to remove from cell state</li>
|
| 3328 |
-
<li><strong>Input Gate:</strong> What new information to add</li>
|
| 3329 |
-
<li><strong>Output Gate:</strong> What to output as hidden state</li>
|
| 3330 |
-
</ul>
|
| 3331 |
|
| 3332 |
<div class="callout warning">
|
| 3333 |
-
<div class="callout-title">⚠️
|
| 3334 |
-
|
|
|
|
| 3335 |
</div>
|
|
|
|
|
|
|
|
|
|
| 3336 |
`,
|
| 3337 |
-
|
| 3338 |
-
<
|
| 3339 |
-
|
| 3340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3341 |
</div>
|
| 3342 |
-
|
| 3343 |
-
|
| 3344 |
-
<div class="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3345 |
</div>
|
| 3346 |
`,
|
| 3347 |
math: `
|
| 3348 |
-
<h3>
|
| 3349 |
-
<p>
|
| 3350 |
-
|
| 3351 |
<div class="formula">
|
| 3352 |
-
|
| 3353 |
-
yₜ = Wₕᵧhₜ + bᵧ
|
| 3354 |
</div>
|
| 3355 |
-
|
| 3356 |
-
<
|
| 3357 |
-
<
|
| 3358 |
-
|
| 3359 |
-
∂L/∂h₁ = (∂L/∂hₜ) × (∂hₜ/∂hₜ₋₁) × (∂hₜ₋₁/∂hₜ₋₂) × ... × (∂h₂/∂h₁)<br>
|
| 3360 |
-
<br>
|
| 3361 |
-
Where ∂hⱼ/∂hⱼ₋₁ = Wₕₕᵀ diag(tanh'(zⱼ))
|
| 3362 |
</div>
|
| 3363 |
-
|
| 3364 |
-
|
| 3365 |
-
|
| 3366 |
-
|
| 3367 |
-
<strong>
|
|
|
|
| 3368 |
</div>
|
| 3369 |
|
| 3370 |
-
<h3>
|
|
|
|
| 3371 |
<div class="list-item">
|
| 3372 |
-
<div class="list-num"
|
| 3373 |
-
<div>Forget Gate
|
| 3374 |
</div>
|
| 3375 |
<div class="list-item">
|
| 3376 |
-
<div class="list-num"
|
| 3377 |
-
<div>
|
| 3378 |
</div>
|
| 3379 |
-
|
| 3380 |
-
|
| 3381 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3382 |
</div>
|
| 3383 |
`
|
| 3384 |
},
|
|
@@ -5142,23 +5176,23 @@
|
|
| 5142 |
ctx.beginPath();
|
| 5143 |
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
| 5144 |
ctx.fill();
|
| 5145 |
-
|
| 5146 |
// Draw connections to next layer
|
| 5147 |
if (layerIdx < layers.length - 1) {
|
| 5148 |
const nextLayerHeight = canvas.height / (layers[layerIdx + 1] + 1);
|
| 5149 |
const nextX = (layerIdx + 2) * layerWidth;
|
| 5150 |
-
|
| 5151 |
for (let j = 0; j < layers[layerIdx + 1]; j++) {
|
| 5152 |
const nextY = (j + 1) * nextLayerHeight;
|
| 5153 |
const signalProgress = ((time / 500) + layerIdx * 0.5) % 1;
|
| 5154 |
-
|
| 5155 |
ctx.strokeStyle = `rgba(0, 212, 255, ${0.3 + signalProgress * 0.3})`;
|
| 5156 |
ctx.lineWidth = 1;
|
| 5157 |
ctx.beginPath();
|
| 5158 |
ctx.moveTo(x + radius, y);
|
| 5159 |
ctx.lineTo(nextX - 12, nextY);
|
| 5160 |
ctx.stroke();
|
| 5161 |
-
|
| 5162 |
// Animated signal dot
|
| 5163 |
const dotX = x + radius + (nextX - 12 - x - radius) * signalProgress;
|
| 5164 |
const dotY = y + (nextY - y) * signalProgress;
|
|
@@ -5170,13 +5204,13 @@
|
|
| 5170 |
}
|
| 5171 |
}
|
| 5172 |
});
|
| 5173 |
-
|
| 5174 |
ctx.fillStyle = '#00d4ff';
|
| 5175 |
ctx.font = 'bold 14px Arial';
|
| 5176 |
ctx.textAlign = 'center';
|
| 5177 |
ctx.fillText('🔄 Neural Network Animation', centerX, 25);
|
| 5178 |
}
|
| 5179 |
-
|
| 5180 |
// Animated GNN with message passing
|
| 5181 |
function drawAnimatedGNN(ctx, canvas, time) {
|
| 5182 |
ctx.fillStyle = '#9900ff';
|
|
@@ -5225,86 +5259,86 @@
|
|
| 5225 |
ctx.fillText(i, n.x, n.y + 4);
|
| 5226 |
});
|
| 5227 |
}
|
| 5228 |
-
|
| 5229 |
// Animated attention matrix
|
| 5230 |
function drawAnimatedAttention(ctx, canvas, time) {
|
| 5231 |
const words = ['The', 'cat', 'sat', 'on', 'mat'];
|
| 5232 |
const cellSize = 50;
|
| 5233 |
const startX = (canvas.width - words.length * cellSize) / 2;
|
| 5234 |
const startY = 80;
|
| 5235 |
-
|
| 5236 |
ctx.fillStyle = '#00d4ff';
|
| 5237 |
ctx.font = 'bold 16px Arial';
|
| 5238 |
ctx.textAlign = 'center';
|
| 5239 |
ctx.fillText('Self-Attention Animation', canvas.width / 2, 30);
|
| 5240 |
-
|
| 5241 |
// Draw words
|
| 5242 |
ctx.font = '12px Arial';
|
| 5243 |
words.forEach((word, i) => {
|
| 5244 |
ctx.fillStyle = '#e4e6eb';
|
| 5245 |
-
ctx.fillText(word, startX + i * cellSize + cellSize/2, startY - 10);
|
| 5246 |
ctx.save();
|
| 5247 |
-
ctx.translate(startX - 20, startY + i * cellSize + cellSize/2);
|
| 5248 |
ctx.fillText(word, 0, 0);
|
| 5249 |
ctx.restore();
|
| 5250 |
});
|
| 5251 |
-
|
| 5252 |
// Animated attention weights
|
| 5253 |
for (let i = 0; i < words.length; i++) {
|
| 5254 |
for (let j = 0; j < words.length; j++) {
|
| 5255 |
const baseWeight = i === j ? 0.8 : 0.2 + Math.abs(i - j) * 0.1;
|
| 5256 |
const animatedWeight = baseWeight + Math.sin(time / 500 + i + j) * 0.2;
|
| 5257 |
const alpha = Math.max(0.1, Math.min(1, animatedWeight));
|
| 5258 |
-
|
| 5259 |
ctx.fillStyle = `rgba(0, 212, 255, ${alpha})`;
|
| 5260 |
ctx.fillRect(startX + j * cellSize + 2, startY + i * cellSize + 2, cellSize - 4, cellSize - 4);
|
| 5261 |
-
|
| 5262 |
ctx.fillStyle = '#e4e6eb';
|
| 5263 |
ctx.font = '10px Arial';
|
| 5264 |
-
ctx.fillText(animatedWeight.toFixed(2), startX + j * cellSize + cellSize/2, startY + i * cellSize + cellSize/2 + 4);
|
| 5265 |
}
|
| 5266 |
}
|
| 5267 |
}
|
| 5268 |
-
|
| 5269 |
// Animated gradient flow for backprop
|
| 5270 |
function drawAnimatedGradientFlow(ctx, canvas, time) {
|
| 5271 |
ctx.fillStyle = '#ff6b35';
|
| 5272 |
ctx.font = 'bold 16px Arial';
|
| 5273 |
ctx.textAlign = 'center';
|
| 5274 |
ctx.fillText('Backpropagation - Gradient Flow', canvas.width / 2, 30);
|
| 5275 |
-
|
| 5276 |
const layers = [2, 4, 4, 1];
|
| 5277 |
const layerWidth = canvas.width / (layers.length + 1);
|
| 5278 |
-
|
| 5279 |
// Forward pass (left to right) - blue
|
| 5280 |
const forwardProgress = (time / 2000) % 1;
|
| 5281 |
-
|
| 5282 |
layers.forEach((neurons, layerIdx) => {
|
| 5283 |
const x = (layerIdx + 1) * layerWidth;
|
| 5284 |
const layerHeight = canvas.height / (neurons + 1);
|
| 5285 |
-
|
| 5286 |
for (let i = 0; i < neurons; i++) {
|
| 5287 |
const y = (i + 1) * layerHeight;
|
| 5288 |
-
|
| 5289 |
// Pulse effect based on forward pass
|
| 5290 |
const isActive = forwardProgress > layerIdx / layers.length;
|
| 5291 |
const radius = isActive ? 15 + Math.sin(time / 200) * 3 : 12;
|
| 5292 |
-
|
| 5293 |
ctx.fillStyle = isActive ? '#00d4ff' : 'rgba(0, 212, 255, 0.3)';
|
| 5294 |
ctx.beginPath();
|
| 5295 |
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
| 5296 |
ctx.fill();
|
| 5297 |
}
|
| 5298 |
});
|
| 5299 |
-
|
| 5300 |
// Backward pass (right to left) - orange/red gradients
|
| 5301 |
const backwardProgress = ((time / 2000) + 0.5) % 1;
|
| 5302 |
-
|
| 5303 |
for (let layerIdx = layers.length - 2; layerIdx >= 0; layerIdx--) {
|
| 5304 |
const x1 = (layerIdx + 1) * layerWidth;
|
| 5305 |
const x2 = (layerIdx + 2) * layerWidth;
|
| 5306 |
const gradientActive = backwardProgress > (layers.length - 2 - layerIdx) / (layers.length - 1);
|
| 5307 |
-
|
| 5308 |
if (gradientActive) {
|
| 5309 |
const gradX = x2 - (x2 - x1) * ((backwardProgress * (layers.length - 1)) % 1);
|
| 5310 |
ctx.fillStyle = '#ff6b35';
|
|
@@ -5313,44 +5347,44 @@
|
|
| 5313 |
ctx.fill();
|
| 5314 |
}
|
| 5315 |
}
|
| 5316 |
-
|
| 5317 |
ctx.fillStyle = '#e4e6eb';
|
| 5318 |
ctx.font = '12px Arial';
|
| 5319 |
ctx.fillText('Forward: Blue → | Backward: Orange ←', canvas.width / 2, canvas.height - 20);
|
| 5320 |
}
|
| 5321 |
-
|
| 5322 |
// Animated network for nn-basics
|
| 5323 |
function drawAnimatedNetwork(ctx, canvas, time) {
|
| 5324 |
drawDefaultAnimation(ctx, canvas, time);
|
| 5325 |
}
|
| 5326 |
-
|
| 5327 |
// Animated decision boundary for perceptron
|
| 5328 |
function drawAnimatedDecisionBoundary(ctx, canvas, time) {
|
| 5329 |
const centerX = canvas.width / 2;
|
| 5330 |
const centerY = canvas.height / 2;
|
| 5331 |
-
|
| 5332 |
ctx.fillStyle = '#ff6b35';
|
| 5333 |
ctx.font = 'bold 16px Arial';
|
| 5334 |
ctx.textAlign = 'center';
|
| 5335 |
ctx.fillText('Perceptron Decision Boundary', canvas.width / 2, 30);
|
| 5336 |
-
|
| 5337 |
// Animated rotating decision boundary
|
| 5338 |
const angle = time / 2000;
|
| 5339 |
const length = 200;
|
| 5340 |
-
|
| 5341 |
ctx.strokeStyle = '#ff6b35';
|
| 5342 |
ctx.lineWidth = 3;
|
| 5343 |
ctx.beginPath();
|
| 5344 |
ctx.moveTo(centerX - Math.cos(angle) * length, centerY - Math.sin(angle) * length);
|
| 5345 |
ctx.lineTo(centerX + Math.cos(angle) * length, centerY + Math.sin(angle) * length);
|
| 5346 |
ctx.stroke();
|
| 5347 |
-
|
| 5348 |
// Fixed sample points
|
| 5349 |
const points = [
|
| 5350 |
-
{x: 100, y: 80, c: 1}, {x: 150, y: 100, c: 1}, {x: 120, y: 150, c: 1},
|
| 5351 |
-
{x: 400, y: 200, c: 0}, {x: 450, y: 180, c: 0}, {x: 380, y: 250, c: 0}
|
| 5352 |
];
|
| 5353 |
-
|
| 5354 |
points.forEach(p => {
|
| 5355 |
ctx.fillStyle = p.c === 1 ? '#00d4ff' : '#00ff88';
|
| 5356 |
ctx.beginPath();
|
|
@@ -5358,25 +5392,25 @@
|
|
| 5358 |
ctx.fill();
|
| 5359 |
});
|
| 5360 |
}
|
| 5361 |
-
|
| 5362 |
function drawAnimatedMLP(ctx, canvas, time) {
|
| 5363 |
drawDefaultAnimation(ctx, canvas, time);
|
| 5364 |
}
|
| 5365 |
-
|
| 5366 |
function drawAnimatedActivations(ctx, canvas, time) {
|
| 5367 |
drawActivationFunctions(ctx, canvas);
|
| 5368 |
-
|
| 5369 |
// Add animated input marker
|
| 5370 |
const x = Math.sin(time / 500) * 4;
|
| 5371 |
const centerX = canvas.width / 2;
|
| 5372 |
const centerY = canvas.height / 2;
|
| 5373 |
const scale = 40;
|
| 5374 |
-
|
| 5375 |
ctx.fillStyle = '#ffffff';
|
| 5376 |
ctx.beginPath();
|
| 5377 |
ctx.arc(centerX + x * scale, centerY, 6, 0, Math.PI * 2);
|
| 5378 |
ctx.fill();
|
| 5379 |
-
|
| 5380 |
ctx.strokeStyle = '#ffffff';
|
| 5381 |
ctx.setLineDash([5, 5]);
|
| 5382 |
ctx.beginPath();
|
|
@@ -5385,45 +5419,45 @@
|
|
| 5385 |
ctx.stroke();
|
| 5386 |
ctx.setLineDash([]);
|
| 5387 |
}
|
| 5388 |
-
|
| 5389 |
function drawAnimatedConvolution(ctx, canvas, time) {
|
| 5390 |
drawConvolutionAnimation(ctx, canvas);
|
| 5391 |
}
|
| 5392 |
-
|
| 5393 |
function drawAnimatedGAN(ctx, canvas, time) {
|
| 5394 |
ctx.fillStyle = '#ffaa00';
|
| 5395 |
ctx.font = 'bold 16px Arial';
|
| 5396 |
ctx.textAlign = 'center';
|
| 5397 |
ctx.fillText('GAN Training Animation', canvas.width / 2, 30);
|
| 5398 |
-
|
| 5399 |
const phase = Math.floor(time / 1000) % 4;
|
| 5400 |
-
|
| 5401 |
// Generator
|
| 5402 |
ctx.fillStyle = phase <= 1 ? '#00ff88' : 'rgba(0, 255, 136, 0.3)';
|
| 5403 |
ctx.fillRect(50, 100, 100, 80);
|
| 5404 |
ctx.fillStyle = '#e4e6eb';
|
| 5405 |
ctx.font = '12px Arial';
|
| 5406 |
ctx.fillText('Generator', 100, 145);
|
| 5407 |
-
|
| 5408 |
// Fake image
|
| 5409 |
const noiseToFake = Math.sin(time / 300) * 0.5 + 0.5;
|
| 5410 |
ctx.fillStyle = `rgba(255, 170, 0, ${noiseToFake})`;
|
| 5411 |
ctx.fillRect(200, 110, 60, 60);
|
| 5412 |
ctx.fillStyle = '#e4e6eb';
|
| 5413 |
ctx.fillText('Fake', 230, 200);
|
| 5414 |
-
|
| 5415 |
// Discriminator
|
| 5416 |
ctx.fillStyle = phase >= 2 ? '#ff6b35' : 'rgba(255, 107, 53, 0.3)';
|
| 5417 |
ctx.fillRect(320, 100, 100, 80);
|
| 5418 |
ctx.fillStyle = '#e4e6eb';
|
| 5419 |
ctx.fillText('Discriminator', 370, 145);
|
| 5420 |
-
|
| 5421 |
// Output
|
| 5422 |
const output = phase === 3 ? 'Real?' : 'Fake?';
|
| 5423 |
ctx.fillStyle = '#00d4ff';
|
| 5424 |
ctx.font = 'bold 14px Arial';
|
| 5425 |
ctx.fillText(output, 370, 220);
|
| 5426 |
-
|
| 5427 |
// Arrows
|
| 5428 |
ctx.strokeStyle = '#e4e6eb';
|
| 5429 |
ctx.lineWidth = 2;
|
|
@@ -5436,29 +5470,29 @@
|
|
| 5436 |
ctx.lineTo(320, 140);
|
| 5437 |
ctx.stroke();
|
| 5438 |
}
|
| 5439 |
-
|
| 5440 |
function drawAnimatedDiffusion(ctx, canvas, time) {
|
| 5441 |
ctx.fillStyle = '#9900ff';
|
| 5442 |
ctx.font = 'bold 16px Arial';
|
| 5443 |
ctx.textAlign = 'center';
|
| 5444 |
ctx.fillText('Diffusion Process Animation', canvas.width / 2, 30);
|
| 5445 |
-
|
| 5446 |
const steps = 5;
|
| 5447 |
const stepWidth = canvas.width / (steps + 1);
|
| 5448 |
-
|
| 5449 |
const progress = (time / 3000) % 1;
|
| 5450 |
const currentStep = Math.floor(progress * steps);
|
| 5451 |
-
|
| 5452 |
for (let i = 0; i < steps; i++) {
|
| 5453 |
const x = (i + 1) * stepWidth;
|
| 5454 |
const y = 150;
|
| 5455 |
const noiseLevel = i / (steps - 1);
|
| 5456 |
const isActive = i <= currentStep;
|
| 5457 |
-
|
| 5458 |
// Draw square with noise
|
| 5459 |
ctx.fillStyle = isActive ? '#9900ff' : 'rgba(153, 0, 255, 0.3)';
|
| 5460 |
ctx.fillRect(x - 30, y - 30, 60, 60);
|
| 5461 |
-
|
| 5462 |
// Add noise dots
|
| 5463 |
if (noiseLevel > 0) {
|
| 5464 |
for (let j = 0; j < noiseLevel * 20; j++) {
|
|
@@ -5468,43 +5502,43 @@
|
|
| 5468 |
ctx.fillRect(nx, ny, 2, 2);
|
| 5469 |
}
|
| 5470 |
}
|
| 5471 |
-
|
| 5472 |
ctx.fillStyle = '#e4e6eb';
|
| 5473 |
ctx.font = '10px Arial';
|
| 5474 |
ctx.fillText(`t=${i}`, x, y + 50);
|
| 5475 |
}
|
| 5476 |
-
|
| 5477 |
ctx.fillStyle = '#e4e6eb';
|
| 5478 |
ctx.font = '12px Arial';
|
| 5479 |
ctx.fillText('Clean → Noisy (Forward) | Noisy → Clean (Reverse)', canvas.width / 2, canvas.height - 20);
|
| 5480 |
}
|
| 5481 |
-
|
| 5482 |
function drawAnimatedRNN(ctx, canvas, time) {
|
| 5483 |
ctx.fillStyle = '#00d4ff';
|
| 5484 |
ctx.font = 'bold 16px Arial';
|
| 5485 |
ctx.textAlign = 'center';
|
| 5486 |
ctx.fillText('RNN Unrolled Through Time', canvas.width / 2, 30);
|
| 5487 |
-
|
| 5488 |
const steps = 5;
|
| 5489 |
const stepWidth = canvas.width / (steps + 1);
|
| 5490 |
const progress = (time / 500) % steps;
|
| 5491 |
const activeStep = Math.floor(progress);
|
| 5492 |
-
|
| 5493 |
for (let i = 0; i < steps; i++) {
|
| 5494 |
const x = (i + 1) * stepWidth;
|
| 5495 |
const y = 150;
|
| 5496 |
const isActive = i === activeStep;
|
| 5497 |
-
|
| 5498 |
// Hidden state
|
| 5499 |
ctx.fillStyle = isActive ? '#00d4ff' : 'rgba(0, 212, 255, 0.3)';
|
| 5500 |
ctx.beginPath();
|
| 5501 |
ctx.arc(x, y, 25, 0, Math.PI * 2);
|
| 5502 |
ctx.fill();
|
| 5503 |
-
|
| 5504 |
ctx.fillStyle = '#e4e6eb';
|
| 5505 |
ctx.font = '10px Arial';
|
| 5506 |
ctx.fillText(`h${i}`, x, y + 4);
|
| 5507 |
-
|
| 5508 |
// Input arrow
|
| 5509 |
ctx.strokeStyle = isActive ? '#00ff88' : 'rgba(0, 255, 136, 0.3)';
|
| 5510 |
ctx.lineWidth = 2;
|
|
@@ -5513,7 +5547,7 @@
|
|
| 5513 |
ctx.lineTo(x, y + 25);
|
| 5514 |
ctx.stroke();
|
| 5515 |
ctx.fillText(`x${i}`, x, y + 75);
|
| 5516 |
-
|
| 5517 |
// Recurrent connection
|
| 5518 |
if (i < steps - 1) {
|
| 5519 |
ctx.strokeStyle = isActive ? '#ff6b35' : 'rgba(255, 107, 53, 0.3)';
|
|
@@ -5521,7 +5555,7 @@
|
|
| 5521 |
ctx.moveTo(x + 25, y);
|
| 5522 |
ctx.lineTo(x + stepWidth - 25, y);
|
| 5523 |
ctx.stroke();
|
| 5524 |
-
|
| 5525 |
// Animated signal
|
| 5526 |
if (isActive) {
|
| 5527 |
const signalX = x + 25 + (stepWidth - 50) * (progress % 1);
|
|
|
|
| 3315 |
},
|
| 3316 |
"rnn": {
|
| 3317 |
overview: `
|
| 3318 |
+
<h3>The Problem of Long-Term Dependencies</h3>
|
| 3319 |
+
<p>Imagine trying to predict the last word in the text: "I grew up in France... [200 words] ... I speak fluent <strong>French</strong>."</p>
|
| 3320 |
+
<p>Standard RNNs fail here. As the gap grows, the gradient from "French" has to travel back 200 steps to "France".</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3321 |
|
| 3322 |
<div class="callout warning">
|
| 3323 |
+
<div class="callout-title">⚠️ The Vanishing Gradient Failure</div>
|
| 3324 |
+
If the weight W < 1, the gradient shrinks exponentially: 0.9²⁰⁰ ≈ 0.0000000007.<br>
|
| 3325 |
+
The network literally "forgets" the context.
|
| 3326 |
</div>
|
| 3327 |
+
|
| 3328 |
+
<h3>The LSTM Solution: "The Conveyor Belt"</h3>
|
| 3329 |
+
<p>The core idea of LSTM is the <strong>Cell State (C)</strong>. It runs straight down the entire chain, with only minor linear interactions. It's like a conveyor belt—information can flow along it unchanged.</p>
|
| 3330 |
`,
|
| 3331 |
+
concepts: `
|
| 3332 |
+
<h3>Step-by-Step LSTM Walkthrough</h3>
|
| 3333 |
+
<p>LSTMs control the cell state via "Gates".</p>
|
| 3334 |
+
|
| 3335 |
+
<div class="list-item">
|
| 3336 |
+
<div class="list-num">01</div>
|
| 3337 |
+
<div><strong>Forget Gate layer:</strong> "What do we throw away?"<br>
|
| 3338 |
+
<span class="formula-caption">σ(W_f · [h_{t-1}, x_t] + b_f)</span><br>
|
| 3339 |
+
Output 0 = complete forget, 1 = keep everything.</div>
|
| 3340 |
</div>
|
| 3341 |
+
|
| 3342 |
+
<div class="list-item">
|
| 3343 |
+
<div class="list-num">02</div>
|
| 3344 |
+
<div><strong>Input Gate layer:</strong> "What new info do we add?"<br>
|
| 3345 |
+
1. Sigmoid layer decides <strong>which values</strong> to update.<br>
|
| 3346 |
+
2. Tanh layer creates <strong>new candidate values</strong> (~C_t).</div>
|
| 3347 |
+
</div>
|
| 3348 |
+
|
| 3349 |
+
<div class="list-item">
|
| 3350 |
+
<div class="list-num">03</div>
|
| 3351 |
+
<div><strong>Update Cell State:</strong> The Critical Step<br>
|
| 3352 |
+
<span class="formula" style="font-size:1.1rem">C_t = f_t * C_{t-1} + i_t * ~C_t</span><br>
|
| 3353 |
+
We multiply old state by f_t (forgetting things) and add i_t * ~C_t (adding new things).</div>
|
| 3354 |
+
</div>
|
| 3355 |
+
|
| 3356 |
+
<div class="list-item">
|
| 3357 |
+
<div class="list-num">04</div>
|
| 3358 |
+
<div><strong>Output Gate:</strong> "What do we reveal?"<br>
|
| 3359 |
+
We filter the cell state: h_t = o_t * tanh(C_t).</div>
|
| 3360 |
+
</div>
|
| 3361 |
+
|
| 3362 |
+
<div class="callout insight">
|
| 3363 |
+
<div class="callout-title">💡 Intuition: Sigmoid vs Tanh</div>
|
| 3364 |
+
• <strong>Sigmoid (0 to 1):</strong> Acts like a valve or gate. Open/Close.<br>
|
| 3365 |
+
• <strong>Tanh (-1 to 1):</strong> Creates content/information. Normalized centered data.
|
| 3366 |
</div>
|
| 3367 |
`,
|
| 3368 |
math: `
|
| 3369 |
+
<h3>Paper & Pain: Why LSTMs Don't Vanish</h3>
|
| 3370 |
+
<p>Let's look at the gradient flow in the Cell State equation:</p>
|
|
|
|
| 3371 |
<div class="formula">
|
| 3372 |
+
C_t = f_t \cdot C_{t-1} + i_t \cdot \tilde{C}_t
|
|
|
|
| 3373 |
</div>
|
| 3374 |
+
|
| 3375 |
+
<p>During backpropagation (BPTT), the derivative of C_t with respect to C_{t-1} is:</p>
|
| 3376 |
+
<div class="formula" style="color: #00ff88;">
|
| 3377 |
+
\frac{\partial C_t}{\partial C_{t-1}} = f_t + \dots
|
|
|
|
|
|
|
|
|
|
| 3378 |
</div>
|
| 3379 |
+
|
| 3380 |
+
<div class="callout tip">
|
| 3381 |
+
<div class="callout-title">✅ The Additive Gradient Highway</div>
|
| 3382 |
+
In standard RNNs, we had multiplicative gradients (W^t). <br>
|
| 3383 |
+
In LSTMs, the gradient is <strong>additive</strong>. If the Forget Gate f_t ≈ 1, the gradient passes through UNCHANGED (1.0).<br>
|
| 3384 |
+
The error signal can travel back 1000 steps without vanishing!
|
| 3385 |
</div>
|
| 3386 |
|
| 3387 |
+
<h3>Paper & Pain: Manual "Echo" Task</h3>
|
| 3388 |
+
<p>Task: Input stream of 0s. If explicit "1" appears, remember it and output "1" 3 steps later.</p>
|
| 3389 |
<div class="list-item">
|
| 3390 |
+
<div class="list-num">📝</div>
|
| 3391 |
+
<div><strong>Strategy:</strong> Set Input Gate to Open (1) only on trigger. Set Forget Gate to Closed (1) to maintain memory.</div>
|
| 3392 |
</div>
|
| 3393 |
<div class="list-item">
|
| 3394 |
+
<div class="list-num">🧮</div>
|
| 3395 |
+
<div><strong>Weights:</strong> We can manually solve for weights that force i_t high only when x_t=1.</div>
|
| 3396 |
</div>
|
| 3397 |
+
`,
|
| 3398 |
+
applications: `
|
| 3399 |
+
<div class="info-box">
|
| 3400 |
+
<div class="box-title">🗣️ Sequence-to-Sequence</div>
|
| 3401 |
+
<div class="box-content">
|
| 3402 |
+
<strong>Translation:</strong> Google Translate (pre-Transformer) used massive LSTM stacks (GNMT).
|
| 3403 |
+
</div>
|
| 3404 |
+
</div>
|
| 3405 |
+
<div class="info-box">
|
| 3406 |
+
<div class="box-title">✍️ Handwriting Generation</div>
|
| 3407 |
+
<div class="box-content">
|
| 3408 |
+
<strong>Alex Graves (2013):</strong> LSTMs can generate realistic cursive handwriting by predicting pen coordinates.
|
| 3409 |
+
</div>
|
| 3410 |
+
</div>
|
| 3411 |
+
<div class="info-box">
|
| 3412 |
+
<div class="box-title">🎵 Music Composition</div>
|
| 3413 |
+
<div class="box-content">
|
| 3414 |
+
Generating melody and chords where context (key signature, tempo) must be maintained for minutes.
|
| 3415 |
+
</div>
|
| 3416 |
</div>
|
| 3417 |
`
|
| 3418 |
},
|
|
|
|
| 5176 |
ctx.beginPath();
|
| 5177 |
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
| 5178 |
ctx.fill();
|
| 5179 |
+
|
| 5180 |
// Draw connections to next layer
|
| 5181 |
if (layerIdx < layers.length - 1) {
|
| 5182 |
const nextLayerHeight = canvas.height / (layers[layerIdx + 1] + 1);
|
| 5183 |
const nextX = (layerIdx + 2) * layerWidth;
|
| 5184 |
+
|
| 5185 |
for (let j = 0; j < layers[layerIdx + 1]; j++) {
|
| 5186 |
const nextY = (j + 1) * nextLayerHeight;
|
| 5187 |
const signalProgress = ((time / 500) + layerIdx * 0.5) % 1;
|
| 5188 |
+
|
| 5189 |
ctx.strokeStyle = `rgba(0, 212, 255, ${0.3 + signalProgress * 0.3})`;
|
| 5190 |
ctx.lineWidth = 1;
|
| 5191 |
ctx.beginPath();
|
| 5192 |
ctx.moveTo(x + radius, y);
|
| 5193 |
ctx.lineTo(nextX - 12, nextY);
|
| 5194 |
ctx.stroke();
|
| 5195 |
+
|
| 5196 |
// Animated signal dot
|
| 5197 |
const dotX = x + radius + (nextX - 12 - x - radius) * signalProgress;
|
| 5198 |
const dotY = y + (nextY - y) * signalProgress;
|
|
|
|
| 5204 |
}
|
| 5205 |
}
|
| 5206 |
});
|
| 5207 |
+
|
| 5208 |
ctx.fillStyle = '#00d4ff';
|
| 5209 |
ctx.font = 'bold 14px Arial';
|
| 5210 |
ctx.textAlign = 'center';
|
| 5211 |
ctx.fillText('🔄 Neural Network Animation', centerX, 25);
|
| 5212 |
}
|
| 5213 |
+
|
| 5214 |
// Animated GNN with message passing
|
| 5215 |
function drawAnimatedGNN(ctx, canvas, time) {
|
| 5216 |
ctx.fillStyle = '#9900ff';
|
|
|
|
| 5259 |
ctx.fillText(i, n.x, n.y + 4);
|
| 5260 |
});
|
| 5261 |
}
|
| 5262 |
+
|
| 5263 |
// Animated attention matrix
|
| 5264 |
function drawAnimatedAttention(ctx, canvas, time) {
|
| 5265 |
const words = ['The', 'cat', 'sat', 'on', 'mat'];
|
| 5266 |
const cellSize = 50;
|
| 5267 |
const startX = (canvas.width - words.length * cellSize) / 2;
|
| 5268 |
const startY = 80;
|
| 5269 |
+
|
| 5270 |
ctx.fillStyle = '#00d4ff';
|
| 5271 |
ctx.font = 'bold 16px Arial';
|
| 5272 |
ctx.textAlign = 'center';
|
| 5273 |
ctx.fillText('Self-Attention Animation', canvas.width / 2, 30);
|
| 5274 |
+
|
| 5275 |
// Draw words
|
| 5276 |
ctx.font = '12px Arial';
|
| 5277 |
words.forEach((word, i) => {
|
| 5278 |
ctx.fillStyle = '#e4e6eb';
|
| 5279 |
+
ctx.fillText(word, startX + i * cellSize + cellSize / 2, startY - 10);
|
| 5280 |
ctx.save();
|
| 5281 |
+
ctx.translate(startX - 20, startY + i * cellSize + cellSize / 2);
|
| 5282 |
ctx.fillText(word, 0, 0);
|
| 5283 |
ctx.restore();
|
| 5284 |
});
|
| 5285 |
+
|
| 5286 |
// Animated attention weights
|
| 5287 |
for (let i = 0; i < words.length; i++) {
|
| 5288 |
for (let j = 0; j < words.length; j++) {
|
| 5289 |
const baseWeight = i === j ? 0.8 : 0.2 + Math.abs(i - j) * 0.1;
|
| 5290 |
const animatedWeight = baseWeight + Math.sin(time / 500 + i + j) * 0.2;
|
| 5291 |
const alpha = Math.max(0.1, Math.min(1, animatedWeight));
|
| 5292 |
+
|
| 5293 |
ctx.fillStyle = `rgba(0, 212, 255, ${alpha})`;
|
| 5294 |
ctx.fillRect(startX + j * cellSize + 2, startY + i * cellSize + 2, cellSize - 4, cellSize - 4);
|
| 5295 |
+
|
| 5296 |
ctx.fillStyle = '#e4e6eb';
|
| 5297 |
ctx.font = '10px Arial';
|
| 5298 |
+
ctx.fillText(animatedWeight.toFixed(2), startX + j * cellSize + cellSize / 2, startY + i * cellSize + cellSize / 2 + 4);
|
| 5299 |
}
|
| 5300 |
}
|
| 5301 |
}
|
| 5302 |
+
|
| 5303 |
// Animated gradient flow for backprop
|
| 5304 |
function drawAnimatedGradientFlow(ctx, canvas, time) {
|
| 5305 |
ctx.fillStyle = '#ff6b35';
|
| 5306 |
ctx.font = 'bold 16px Arial';
|
| 5307 |
ctx.textAlign = 'center';
|
| 5308 |
ctx.fillText('Backpropagation - Gradient Flow', canvas.width / 2, 30);
|
| 5309 |
+
|
| 5310 |
const layers = [2, 4, 4, 1];
|
| 5311 |
const layerWidth = canvas.width / (layers.length + 1);
|
| 5312 |
+
|
| 5313 |
// Forward pass (left to right) - blue
|
| 5314 |
const forwardProgress = (time / 2000) % 1;
|
| 5315 |
+
|
| 5316 |
layers.forEach((neurons, layerIdx) => {
|
| 5317 |
const x = (layerIdx + 1) * layerWidth;
|
| 5318 |
const layerHeight = canvas.height / (neurons + 1);
|
| 5319 |
+
|
| 5320 |
for (let i = 0; i < neurons; i++) {
|
| 5321 |
const y = (i + 1) * layerHeight;
|
| 5322 |
+
|
| 5323 |
// Pulse effect based on forward pass
|
| 5324 |
const isActive = forwardProgress > layerIdx / layers.length;
|
| 5325 |
const radius = isActive ? 15 + Math.sin(time / 200) * 3 : 12;
|
| 5326 |
+
|
| 5327 |
ctx.fillStyle = isActive ? '#00d4ff' : 'rgba(0, 212, 255, 0.3)';
|
| 5328 |
ctx.beginPath();
|
| 5329 |
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
| 5330 |
ctx.fill();
|
| 5331 |
}
|
| 5332 |
});
|
| 5333 |
+
|
| 5334 |
// Backward pass (right to left) - orange/red gradients
|
| 5335 |
const backwardProgress = ((time / 2000) + 0.5) % 1;
|
| 5336 |
+
|
| 5337 |
for (let layerIdx = layers.length - 2; layerIdx >= 0; layerIdx--) {
|
| 5338 |
const x1 = (layerIdx + 1) * layerWidth;
|
| 5339 |
const x2 = (layerIdx + 2) * layerWidth;
|
| 5340 |
const gradientActive = backwardProgress > (layers.length - 2 - layerIdx) / (layers.length - 1);
|
| 5341 |
+
|
| 5342 |
if (gradientActive) {
|
| 5343 |
const gradX = x2 - (x2 - x1) * ((backwardProgress * (layers.length - 1)) % 1);
|
| 5344 |
ctx.fillStyle = '#ff6b35';
|
|
|
|
| 5347 |
ctx.fill();
|
| 5348 |
}
|
| 5349 |
}
|
| 5350 |
+
|
| 5351 |
ctx.fillStyle = '#e4e6eb';
|
| 5352 |
ctx.font = '12px Arial';
|
| 5353 |
ctx.fillText('Forward: Blue → | Backward: Orange ←', canvas.width / 2, canvas.height - 20);
|
| 5354 |
}
|
| 5355 |
+
|
| 5356 |
// Animated network for nn-basics
|
| 5357 |
function drawAnimatedNetwork(ctx, canvas, time) {
|
| 5358 |
drawDefaultAnimation(ctx, canvas, time);
|
| 5359 |
}
|
| 5360 |
+
|
| 5361 |
// Animated decision boundary for perceptron
|
| 5362 |
function drawAnimatedDecisionBoundary(ctx, canvas, time) {
|
| 5363 |
const centerX = canvas.width / 2;
|
| 5364 |
const centerY = canvas.height / 2;
|
| 5365 |
+
|
| 5366 |
ctx.fillStyle = '#ff6b35';
|
| 5367 |
ctx.font = 'bold 16px Arial';
|
| 5368 |
ctx.textAlign = 'center';
|
| 5369 |
ctx.fillText('Perceptron Decision Boundary', canvas.width / 2, 30);
|
| 5370 |
+
|
| 5371 |
// Animated rotating decision boundary
|
| 5372 |
const angle = time / 2000;
|
| 5373 |
const length = 200;
|
| 5374 |
+
|
| 5375 |
ctx.strokeStyle = '#ff6b35';
|
| 5376 |
ctx.lineWidth = 3;
|
| 5377 |
ctx.beginPath();
|
| 5378 |
ctx.moveTo(centerX - Math.cos(angle) * length, centerY - Math.sin(angle) * length);
|
| 5379 |
ctx.lineTo(centerX + Math.cos(angle) * length, centerY + Math.sin(angle) * length);
|
| 5380 |
ctx.stroke();
|
| 5381 |
+
|
| 5382 |
// Fixed sample points
|
| 5383 |
const points = [
|
| 5384 |
+
{ x: 100, y: 80, c: 1 }, { x: 150, y: 100, c: 1 }, { x: 120, y: 150, c: 1 },
|
| 5385 |
+
{ x: 400, y: 200, c: 0 }, { x: 450, y: 180, c: 0 }, { x: 380, y: 250, c: 0 }
|
| 5386 |
];
|
| 5387 |
+
|
| 5388 |
points.forEach(p => {
|
| 5389 |
ctx.fillStyle = p.c === 1 ? '#00d4ff' : '#00ff88';
|
| 5390 |
ctx.beginPath();
|
|
|
|
| 5392 |
ctx.fill();
|
| 5393 |
});
|
| 5394 |
}
|
| 5395 |
+
|
| 5396 |
function drawAnimatedMLP(ctx, canvas, time) {
|
| 5397 |
drawDefaultAnimation(ctx, canvas, time);
|
| 5398 |
}
|
| 5399 |
+
|
| 5400 |
function drawAnimatedActivations(ctx, canvas, time) {
|
| 5401 |
drawActivationFunctions(ctx, canvas);
|
| 5402 |
+
|
| 5403 |
// Add animated input marker
|
| 5404 |
const x = Math.sin(time / 500) * 4;
|
| 5405 |
const centerX = canvas.width / 2;
|
| 5406 |
const centerY = canvas.height / 2;
|
| 5407 |
const scale = 40;
|
| 5408 |
+
|
| 5409 |
ctx.fillStyle = '#ffffff';
|
| 5410 |
ctx.beginPath();
|
| 5411 |
ctx.arc(centerX + x * scale, centerY, 6, 0, Math.PI * 2);
|
| 5412 |
ctx.fill();
|
| 5413 |
+
|
| 5414 |
ctx.strokeStyle = '#ffffff';
|
| 5415 |
ctx.setLineDash([5, 5]);
|
| 5416 |
ctx.beginPath();
|
|
|
|
| 5419 |
ctx.stroke();
|
| 5420 |
ctx.setLineDash([]);
|
| 5421 |
}
|
| 5422 |
+
|
| 5423 |
function drawAnimatedConvolution(ctx, canvas, time) {
|
| 5424 |
drawConvolutionAnimation(ctx, canvas);
|
| 5425 |
}
|
| 5426 |
+
|
| 5427 |
function drawAnimatedGAN(ctx, canvas, time) {
|
| 5428 |
ctx.fillStyle = '#ffaa00';
|
| 5429 |
ctx.font = 'bold 16px Arial';
|
| 5430 |
ctx.textAlign = 'center';
|
| 5431 |
ctx.fillText('GAN Training Animation', canvas.width / 2, 30);
|
| 5432 |
+
|
| 5433 |
const phase = Math.floor(time / 1000) % 4;
|
| 5434 |
+
|
| 5435 |
// Generator
|
| 5436 |
ctx.fillStyle = phase <= 1 ? '#00ff88' : 'rgba(0, 255, 136, 0.3)';
|
| 5437 |
ctx.fillRect(50, 100, 100, 80);
|
| 5438 |
ctx.fillStyle = '#e4e6eb';
|
| 5439 |
ctx.font = '12px Arial';
|
| 5440 |
ctx.fillText('Generator', 100, 145);
|
| 5441 |
+
|
| 5442 |
// Fake image
|
| 5443 |
const noiseToFake = Math.sin(time / 300) * 0.5 + 0.5;
|
| 5444 |
ctx.fillStyle = `rgba(255, 170, 0, ${noiseToFake})`;
|
| 5445 |
ctx.fillRect(200, 110, 60, 60);
|
| 5446 |
ctx.fillStyle = '#e4e6eb';
|
| 5447 |
ctx.fillText('Fake', 230, 200);
|
| 5448 |
+
|
| 5449 |
// Discriminator
|
| 5450 |
ctx.fillStyle = phase >= 2 ? '#ff6b35' : 'rgba(255, 107, 53, 0.3)';
|
| 5451 |
ctx.fillRect(320, 100, 100, 80);
|
| 5452 |
ctx.fillStyle = '#e4e6eb';
|
| 5453 |
ctx.fillText('Discriminator', 370, 145);
|
| 5454 |
+
|
| 5455 |
// Output
|
| 5456 |
const output = phase === 3 ? 'Real?' : 'Fake?';
|
| 5457 |
ctx.fillStyle = '#00d4ff';
|
| 5458 |
ctx.font = 'bold 14px Arial';
|
| 5459 |
ctx.fillText(output, 370, 220);
|
| 5460 |
+
|
| 5461 |
// Arrows
|
| 5462 |
ctx.strokeStyle = '#e4e6eb';
|
| 5463 |
ctx.lineWidth = 2;
|
|
|
|
| 5470 |
ctx.lineTo(320, 140);
|
| 5471 |
ctx.stroke();
|
| 5472 |
}
|
| 5473 |
+
|
| 5474 |
function drawAnimatedDiffusion(ctx, canvas, time) {
|
| 5475 |
ctx.fillStyle = '#9900ff';
|
| 5476 |
ctx.font = 'bold 16px Arial';
|
| 5477 |
ctx.textAlign = 'center';
|
| 5478 |
ctx.fillText('Diffusion Process Animation', canvas.width / 2, 30);
|
| 5479 |
+
|
| 5480 |
const steps = 5;
|
| 5481 |
const stepWidth = canvas.width / (steps + 1);
|
| 5482 |
+
|
| 5483 |
const progress = (time / 3000) % 1;
|
| 5484 |
const currentStep = Math.floor(progress * steps);
|
| 5485 |
+
|
| 5486 |
for (let i = 0; i < steps; i++) {
|
| 5487 |
const x = (i + 1) * stepWidth;
|
| 5488 |
const y = 150;
|
| 5489 |
const noiseLevel = i / (steps - 1);
|
| 5490 |
const isActive = i <= currentStep;
|
| 5491 |
+
|
| 5492 |
// Draw square with noise
|
| 5493 |
ctx.fillStyle = isActive ? '#9900ff' : 'rgba(153, 0, 255, 0.3)';
|
| 5494 |
ctx.fillRect(x - 30, y - 30, 60, 60);
|
| 5495 |
+
|
| 5496 |
// Add noise dots
|
| 5497 |
if (noiseLevel > 0) {
|
| 5498 |
for (let j = 0; j < noiseLevel * 20; j++) {
|
|
|
|
| 5502 |
ctx.fillRect(nx, ny, 2, 2);
|
| 5503 |
}
|
| 5504 |
}
|
| 5505 |
+
|
| 5506 |
ctx.fillStyle = '#e4e6eb';
|
| 5507 |
ctx.font = '10px Arial';
|
| 5508 |
ctx.fillText(`t=${i}`, x, y + 50);
|
| 5509 |
}
|
| 5510 |
+
|
| 5511 |
ctx.fillStyle = '#e4e6eb';
|
| 5512 |
ctx.font = '12px Arial';
|
| 5513 |
ctx.fillText('Clean → Noisy (Forward) | Noisy → Clean (Reverse)', canvas.width / 2, canvas.height - 20);
|
| 5514 |
}
|
| 5515 |
+
|
| 5516 |
function drawAnimatedRNN(ctx, canvas, time) {
|
| 5517 |
ctx.fillStyle = '#00d4ff';
|
| 5518 |
ctx.font = 'bold 16px Arial';
|
| 5519 |
ctx.textAlign = 'center';
|
| 5520 |
ctx.fillText('RNN Unrolled Through Time', canvas.width / 2, 30);
|
| 5521 |
+
|
| 5522 |
const steps = 5;
|
| 5523 |
const stepWidth = canvas.width / (steps + 1);
|
| 5524 |
const progress = (time / 500) % steps;
|
| 5525 |
const activeStep = Math.floor(progress);
|
| 5526 |
+
|
| 5527 |
for (let i = 0; i < steps; i++) {
|
| 5528 |
const x = (i + 1) * stepWidth;
|
| 5529 |
const y = 150;
|
| 5530 |
const isActive = i === activeStep;
|
| 5531 |
+
|
| 5532 |
// Hidden state
|
| 5533 |
ctx.fillStyle = isActive ? '#00d4ff' : 'rgba(0, 212, 255, 0.3)';
|
| 5534 |
ctx.beginPath();
|
| 5535 |
ctx.arc(x, y, 25, 0, Math.PI * 2);
|
| 5536 |
ctx.fill();
|
| 5537 |
+
|
| 5538 |
ctx.fillStyle = '#e4e6eb';
|
| 5539 |
ctx.font = '10px Arial';
|
| 5540 |
ctx.fillText(`h${i}`, x, y + 4);
|
| 5541 |
+
|
| 5542 |
// Input arrow
|
| 5543 |
ctx.strokeStyle = isActive ? '#00ff88' : 'rgba(0, 255, 136, 0.3)';
|
| 5544 |
ctx.lineWidth = 2;
|
|
|
|
| 5547 |
ctx.lineTo(x, y + 25);
|
| 5548 |
ctx.stroke();
|
| 5549 |
ctx.fillText(`x${i}`, x, y + 75);
|
| 5550 |
+
|
| 5551 |
// Recurrent connection
|
| 5552 |
if (i < steps - 1) {
|
| 5553 |
ctx.strokeStyle = isActive ? '#ff6b35' : 'rgba(255, 107, 53, 0.3)';
|
|
|
|
| 5555 |
ctx.moveTo(x + 25, y);
|
| 5556 |
ctx.lineTo(x + stepWidth - 25, y);
|
| 5557 |
ctx.stroke();
|
| 5558 |
+
|
| 5559 |
// Animated signal
|
| 5560 |
if (isActive) {
|
| 5561 |
const signalX = x + 25 + (stepWidth - 50) * (progress % 1);
|
index.html
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="UTF-8">
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>Data Science & AI Masterclass | Aashish Garg</title>
|
| 8 |
+
<style>
|
| 9 |
+
:root {
|
| 10 |
+
--bg-color: #0d1117;
|
| 11 |
+
--card-bg: #161b22;
|
| 12 |
+
--text-primary: #c9d1d9;
|
| 13 |
+
--text-secondary: #8b949e;
|
| 14 |
+
--accent-dl: #ff6b35;
|
| 15 |
+
/* Deep Learning Orange */
|
| 16 |
+
--accent-ml: #00d4ff;
|
| 17 |
+
/* ML Cyan */
|
| 18 |
+
--accent-math: #a371f7;
|
| 19 |
+
/* Math Purple */
|
| 20 |
+
--accent-stats: #2ecc71;
|
| 21 |
+
/* Stats Green */
|
| 22 |
+
--border: #30363d;
|
| 23 |
+
--hover-border: #8b949e;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
* {
|
| 27 |
+
margin: 0;
|
| 28 |
+
padding: 0;
|
| 29 |
+
box-sizing: border-box;
|
| 30 |
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
body {
|
| 34 |
+
background-color: var(--bg-color);
|
| 35 |
+
color: var(--text-primary);
|
| 36 |
+
line-height: 1.6;
|
| 37 |
+
padding: 40px;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.container {
|
| 41 |
+
max-width: 1200px;
|
| 42 |
+
margin: 0 auto;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
header {
|
| 46 |
+
text-align: center;
|
| 47 |
+
margin-bottom: 60px;
|
| 48 |
+
border-bottom: 1px solid var(--border);
|
| 49 |
+
padding-bottom: 40px;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
h1 {
|
| 53 |
+
font-size: 3rem;
|
| 54 |
+
margin-bottom: 10px;
|
| 55 |
+
background: linear-gradient(45deg, #00d4ff, #a371f7, #ff6b35);
|
| 56 |
+
-webkit-background-clip: text;
|
| 57 |
+
-webkit-text-fill-color: transparent;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
p.subtitle {
|
| 61 |
+
font-size: 1.2rem;
|
| 62 |
+
color: var(--text-secondary);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
.grid {
|
| 66 |
+
display: grid;
|
| 67 |
+
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
| 68 |
+
gap: 25px;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.card {
|
| 72 |
+
background: var(--card-bg);
|
| 73 |
+
border: 1px solid var(--border);
|
| 74 |
+
border-radius: 12px;
|
| 75 |
+
padding: 25px;
|
| 76 |
+
text-decoration: none;
|
| 77 |
+
color: inherit;
|
| 78 |
+
transition: transform 0.2s, border-color 0.2s;
|
| 79 |
+
display: flex;
|
| 80 |
+
flex-direction: column;
|
| 81 |
+
justify-content: space-between;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.card:hover {
|
| 85 |
+
transform: translateY(-5px);
|
| 86 |
+
border-color: var(--hover-border);
|
| 87 |
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.badge {
|
| 91 |
+
display: inline-block;
|
| 92 |
+
padding: 4px 10px;
|
| 93 |
+
border-radius: 20px;
|
| 94 |
+
font-size: 0.8rem;
|
| 95 |
+
font-weight: bold;
|
| 96 |
+
margin-bottom: 15px;
|
| 97 |
+
text-transform: uppercase;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.card h2 {
|
| 101 |
+
font-size: 1.5rem;
|
| 102 |
+
margin-bottom: 10px;
|
| 103 |
+
color: #fff;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.card p {
|
| 107 |
+
color: var(--text-secondary);
|
| 108 |
+
font-size: 0.95rem;
|
| 109 |
+
margin-bottom: 20px;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.card-footer {
|
| 113 |
+
display: flex;
|
| 114 |
+
align-items: center;
|
| 115 |
+
font-size: 0.9rem;
|
| 116 |
+
font-weight: bold;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.arrow {
|
| 120 |
+
margin-left: auto;
|
| 121 |
+
transition: transform 0.2s;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.card:hover .arrow {
|
| 125 |
+
transform: translateX(5px);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
/* Module Specific Styles */
|
| 129 |
+
.dl-card .badge {
|
| 130 |
+
background: rgba(255, 107, 53, 0.15);
|
| 131 |
+
color: #ff6b35;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
.dl-card:hover {
|
| 135 |
+
border-color: #ff6b35;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.ml-card .badge {
|
| 139 |
+
background: rgba(0, 212, 255, 0.15);
|
| 140 |
+
color: #00d4ff;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
.ml-card:hover {
|
| 144 |
+
border-color: #00d4ff;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.math-card .badge {
|
| 148 |
+
background: rgba(163, 113, 247, 0.15);
|
| 149 |
+
color: #a371f7;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.math-card:hover {
|
| 153 |
+
border-color: #a371f7;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.stats-card .badge {
|
| 157 |
+
background: rgba(46, 204, 113, 0.15);
|
| 158 |
+
color: #2ecc71;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.stats-card:hover {
|
| 162 |
+
border-color: #2ecc71;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
.viz-card .badge {
|
| 166 |
+
background: rgba(255, 206, 86, 0.15);
|
| 167 |
+
color: #ffce56;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.viz-card:hover {
|
| 171 |
+
border-color: #ffce56;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.prompt-card .badge {
|
| 175 |
+
background: rgba(247, 113, 182, 0.15);
|
| 176 |
+
color: #f771b6;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
.prompt-card:hover {
|
| 180 |
+
border-color: #f771b6;
|
| 181 |
+
}
|
| 182 |
+
</style>
|
| 183 |
+
</head>
|
| 184 |
+
|
| 185 |
+
<body>
|
| 186 |
+
<div class="container">
|
| 187 |
+
<header>
|
| 188 |
+
<h1>Data Science & AI Masterclass</h1>
|
| 189 |
+
<p class="subtitle">Comprehensive curriculum from Fundamentals to Deep Learning</p>
|
| 190 |
+
</header>
|
| 191 |
+
|
| 192 |
+
<div class="grid">
|
| 193 |
+
<!-- Deep Learning -->
|
| 194 |
+
<a href="DeepLearning/index.html" class="card dl-card">
|
| 195 |
+
<div>
|
| 196 |
+
<span class="badge">🔥 Flagship Course</span>
|
| 197 |
+
<h2>Deep Learning Masterclass</h2>
|
| 198 |
+
<p>Complete Zero to Hero journey. CNNs, RNNs, LSTMs, Transformers, GANs, and Diffusion Models.
|
| 199 |
+
Featuring rigorous "Paper & Pain" math and interactive visualizations.</p>
|
| 200 |
+
</div>
|
| 201 |
+
<div class="card-footer">
|
| 202 |
+
<span style="color: var(--accent-dl)">Explore Curriculum</span>
|
| 203 |
+
<span class="arrow">→</span>
|
| 204 |
+
</div>
|
| 205 |
+
</a>
|
| 206 |
+
|
| 207 |
+
<!-- Machine Learning -->
|
| 208 |
+
<a href="ml_complete-all-topics/index.html" class="card ml-card">
|
| 209 |
+
<div>
|
| 210 |
+
<span class="badge">Core</span>
|
| 211 |
+
<h2>Machine Learning Complete</h2>
|
| 212 |
+
<p>The foundation. Regression, Classification, Clustering, SVMs, Decision Trees, and Ensembles.
|
| 213 |
+
Master Scikit-Learn.</p>
|
| 214 |
+
</div>
|
| 215 |
+
<div class="card-footer">
|
| 216 |
+
<span style="color: var(--accent-ml)">Start Learning</span>
|
| 217 |
+
<span class="arrow">→</span>
|
| 218 |
+
</div>
|
| 219 |
+
</a>
|
| 220 |
+
|
| 221 |
+
<!-- ML Lab / Projects -->
|
| 222 |
+
<a href="ML/index.html" class="card ml-card">
|
| 223 |
+
<div>
|
| 224 |
+
<span class="badge">Lab</span>
|
| 225 |
+
<h2>ML Experiments & Data</h2>
|
| 226 |
+
<p>Hands-on laboratory for datasets, experimental scripts, and practical ML applications.</p>
|
| 227 |
+
</div>
|
| 228 |
+
<div class="card-footer">
|
| 229 |
+
<span style="color: var(--accent-ml)">Enter Lab</span>
|
| 230 |
+
<span class="arrow">→</span>
|
| 231 |
+
</div>
|
| 232 |
+
</a>
|
| 233 |
+
|
| 234 |
+
<!-- Math -->
|
| 235 |
+
<a href="math-ds-complete/index.html" class="card math-card">
|
| 236 |
+
<div>
|
| 237 |
+
<span class="badge">Foundation</span>
|
| 238 |
+
<h2>Mathematics for AI</h2>
|
| 239 |
+
<p>Calculus, Linear Algebra, and Probability. The engine room of AI. Derivatives, Matrix Operations,
|
| 240 |
+
and Eigenvalues.</p>
|
| 241 |
+
</div>
|
| 242 |
+
<div class="card-footer">
|
| 243 |
+
<span style="color: var(--accent-math)">Study Math</span>
|
| 244 |
+
<span class="arrow">→</span>
|
| 245 |
+
</div>
|
| 246 |
+
</a>
|
| 247 |
+
|
| 248 |
+
<!-- Statistics -->
|
| 249 |
+
<a href="complete-statistics/index.html" class="card stats-card">
|
| 250 |
+
<div>
|
| 251 |
+
<span class="badge">Foundation</span>
|
| 252 |
+
<h2>Statistics Complete</h2>
|
| 253 |
+
<p>Descriptive and Inferential Statistics. Hypothesis testing, Distributions, P-values, and Bayesian
|
| 254 |
+
concepts.</p>
|
| 255 |
+
</div>
|
| 256 |
+
<div class="card-footer">
|
| 257 |
+
<span style="color: var(--accent-stats)">Analyze Data</span>
|
| 258 |
+
<span class="arrow">→</span>
|
| 259 |
+
</div>
|
| 260 |
+
</a>
|
| 261 |
+
|
| 262 |
+
<!-- Feature Engineering -->
|
| 263 |
+
<a href="feature-engineering/index.html" class="card viz-card">
|
| 264 |
+
<div>
|
| 265 |
+
<span class="badge">Skill</span>
|
| 266 |
+
<h2>Feature Engineering</h2>
|
| 267 |
+
<p>Data cleaning, transformation, scaling, encoding, and selection. The art of preparing data for
|
| 268 |
+
models.</p>
|
| 269 |
+
</div>
|
| 270 |
+
<div class="card-footer">
|
| 271 |
+
<span style="color: #ffce56">Master Data</span>
|
| 272 |
+
<span class="arrow">→</span>
|
| 273 |
+
</div>
|
| 274 |
+
</a>
|
| 275 |
+
|
| 276 |
+
<!-- Visualization -->
|
| 277 |
+
<a href="Visualization/index.html" class="card viz-card">
|
| 278 |
+
<div>
|
| 279 |
+
<span class="badge">Skill</span>
|
| 280 |
+
<h2>Data Visualization</h2>
|
| 281 |
+
<p>Matplotlib, Seaborn, Plotly. Communicating insights effectively through beautiful charts and
|
| 282 |
+
dashboards.</p>
|
| 283 |
+
</div>
|
| 284 |
+
<div class="card-footer">
|
| 285 |
+
<span style="color: #ffce56">Visualize</span>
|
| 286 |
+
<span class="arrow">→</span>
|
| 287 |
+
</div>
|
| 288 |
+
</a>
|
| 289 |
+
|
| 290 |
+
<!-- Prompt Engineering -->
|
| 291 |
+
<a href="prompt-engineering-guide/index.html" class="card prompt-card">
|
| 292 |
+
<div>
|
| 293 |
+
<span class="badge">New</span>
|
| 294 |
+
<h2>Prompt Engineering</h2>
|
| 295 |
+
<p>Mastering LLMs. Zero-shot, Few-shot, Chain-of-Thought, and advanced prompting strategies for
|
| 296 |
+
GPT-4/Claude.</p>
|
| 297 |
+
</div>
|
| 298 |
+
<div class="card-footer">
|
| 299 |
+
<span style="color: #f771b6">Learn Prompting</span>
|
| 300 |
+
<span class="arrow">→</span>
|
| 301 |
+
</div>
|
| 302 |
+
</a>
|
| 303 |
+
|
| 304 |
+
</div>
|
| 305 |
+
</div>
|
| 306 |
+
</body>
|
| 307 |
+
|
| 308 |
+
</html>
|