⚙️ Konfigurace sítě
RUČNÍ TRÉNINK
AUTOMATICKÝ TRÉNINK
Zadej vstupní hodnoty a spusť síť:
📊 Tréninková data
⚖️ Váhy sítě
📋 Tréninkový log
💡 Síť neví, zda odpověděla správně – vidí jen číslo chyby.
OpenTechLab Jablonec nad Nisou · Science Micro Elementary School
Navrhni síť, připrav data, trénuj a pozoruj jak se učí vícevrstvá neuronová síť
💡 Co je tu nové? V tomto kurzu už síť neučíme ručně – necháváme ji počítat vlastní chybu a opravovat se sama.
RUČNÍ TRÉNINK
AUTOMATICKÝ TRÉNINK
Zadej vstupní hodnoty a spusť síť:
💡 Síť neví, zda odpověděla správně – vidí jen číslo chyby.
Pochopili jste, jak funguje vícevrstvá neuronová síť? Nyní ji použijte k něčemu užitečnému! Digit Trainer – síť s 15 vstupy (LCD mřížka 3×5), 11 skrytými neurony a 4 výstupy, která se dokáže naučit rozlišovat číslice 0–9 zakódované v binárním formátu.
⚠️ Síť se učí pouze z malého množství příkladů – proto může chybovat na nových vzorech.
Zatím žádná data.
Nakresli vzor a přiřaď číslici.
Pochopte, proč a jak funguje učení v MLP
Jednoduchý perceptron má pouze vstupní a výstupní vrstvu. Chybu můžeme přímo připsat každé váze – kolik přispěla k chybě, tolik ji upravíme.
Vícevrstvá síť (MLP) má problém: Jak zjistit, kolik k chybě přispěla váha ve skryté vrstvě?
💡 Řešení: Backpropagation
Chybu šíříme zpět od výstupu ke vstupu. Každý neuron dostane "díl viny" podle toho, jak moc se podílel na výstupu.
🎯 Klíčový vhled: Síť neví, která váha je špatná. Backpropagation je jen systematický způsob, jak to odhadnout.
Klíčový rozdíl: Perceptron = přímá úprava vah. MLP = chyba se "rozloží" mezi všechny vrstvy pomocí gradientu.
Kolik skrytých vrstev?
Kolik neuronů ve skryté vrstvě?
📏 Praktická pravidla:
(vstupy + výstupy) / 2
2/3 vstupů + výstupy
Sigmoid "zmáčkne" jakýkoliv vstup do rozsahu (0, 1):
σ(x) = 1 / (1 + e-x)
Proč je důležitá pro backpropagation?
σ'(x) = σ(x) × (1 - σ(x))
💡 Srovnej s perceptronem, který používal skokovou funkci (0 nebo 1).
Learning Rate (η) – jak velké kroky děláme:
Momentum (α) – "setrvačnost" učení:
Přidává část předchozí změny k aktuální. Pomáhá překonat lokální minima a urychluje konvergenci v "údolích".
Vzorec: Δw = η × δ × input + α × Δwpředchozí
XOR (exkluzivní OR) není lineárně separabilní – nemůžete nakreslit jednu přímku, která oddělí 0 od 1.
❌ Perceptron
Jen 1 vrstva = 1 přímka
✓ MLP
Skrytá vrstva = více přímek
Vyzkoušej v simulátoru nahoře! Načti XOR data a sleduj, jak síť najde řešení.
class NeuralNetwork {
constructor(inputSize, hiddenSize, outputSize) {
this.inputSize = inputSize;
this.hiddenSize = hiddenSize;
this.outputSize = outputSize;
// Inicializace vah (náhodné malé hodnoty)
// +1 pro bias v každé vrstvě
this.weightsIH = this.randomMatrix(inputSize + 1, hiddenSize, 0.5);
this.weightsHO = this.randomMatrix(hiddenSize + 1, outputSize, 0.5);
// Hodnoty aktivací
this.hiddenValues = new Array(hiddenSize).fill(0);
this.outputValues = new Array(outputSize).fill(0);
}
randomMatrix(rows, cols, range) {
return Array.from({ length: rows }, () =>
Array.from({ length: cols }, () =>
(Math.random() - 0.5) * 2 * range
)
);
}
sigmoid(x) { return 1 / (1 + Math.exp(-x)); }
sigmoidDerivative(y) { return y * (1 - y); }
}
forward(inputs) {
this.inputValues = [...inputs];
// Skrytá vrstva
for (let j = 0; j < this.hiddenSize; j++) {
let sum = this.weightsIH[this.inputSize][j]; // Bias
for (let i = 0; i < this.inputSize; i++) {
sum += inputs[i] * this.weightsIH[i][j];
}
this.hiddenValues[j] = this.sigmoid(sum);
}
// Výstupní vrstva
for (let k = 0; k < this.outputSize; k++) {
let sum = this.weightsHO[this.hiddenSize][k]; // Bias
for (let j = 0; j < this.hiddenSize; j++) {
sum += this.hiddenValues[j] * this.weightsHO[j][k];
}
this.outputValues[k] = this.sigmoid(sum);
}
return this.outputValues;
}
backward(targets, learningRate, momentum = 0.1) {
// 1. Výpočet chyby výstupní vrstvy
const outputDeltas = [];
for (let k = 0; k < this.outputSize; k++) {
const error = targets[k] - this.outputValues[k];
outputDeltas[k] = error * this.sigmoidDerivative(this.outputValues[k]);
}
// 2. Výpočet chyby skryté vrstvy (backprop)
const hiddenDeltas = [];
for (let j = 0; j < this.hiddenSize; j++) {
let error = 0;
for (let k = 0; k < this.outputSize; k++) {
error += this.weightsHO[j][k] * outputDeltas[k];
}
hiddenDeltas[j] = error * this.sigmoidDerivative(this.hiddenValues[j]);
}
// 3. Aktualizace vah Hidden→Output
for (let j = 0; j <= this.hiddenSize; j++) {
for (let k = 0; k < this.outputSize; k++) {
const input = j < this.hiddenSize ? this.hiddenValues[j] : 1;
const change = learningRate * outputDeltas[k] * input;
this.weightsHO[j][k] += change + momentum * this.deltaHO[j][k];
this.deltaHO[j][k] = change;
}
}
// 4. Aktualizace vah Input→Hidden (podobně)
for (let i = 0; i <= this.inputSize; i++) {
for (let j = 0; j < this.hiddenSize; j++) {
const input = i < this.inputSize ? this.inputValues[i] : 1;
const change = learningRate * hiddenDeltas[j] * input;
this.weightsIH[i][j] += change + momentum * this.deltaIH[i][j];
this.deltaIH[i][j] = change;
}
}
}
function trainEpoch(network, trainingData, learningRate) {
// Zamíchat data (důležité!)
const shuffled = [...trainingData].sort(() => Math.random() - 0.5);
for (const pattern of shuffled) {
network.forward(pattern.inputs);
network.backward(pattern.outputs, learningRate);
}
// Spočítat celkovou chybu
let totalError = 0;
for (const pattern of trainingData) {
network.forward(pattern.inputs);
totalError += calculateMSE(network.outputValues, pattern.outputs);
}
return totalError / trainingData.length;
}
function calculateMSE(outputs, targets) {
let error = 0;
for (let i = 0; i < outputs.length; i++) {
error += Math.pow(targets[i] - outputs[i], 2);
}
return error / outputs.length;
}
// Trénink
let epoch = 0;
while (totalError > 0.01 && epoch < 10000) {
totalError = trainEpoch(network, trainingData, 0.2);
epoch++;
}
© 2024 OpenTechLab Jablonec nad Nisou · Vytvořeno pro vzdělávací účely