Демо: отличаем кошку от собаки
Соберём наконец всю цепочку целиком: как из горстки цифр-пикселей рождается ответ «это кошка» — и почему сеть иногда уверенно ошибается.
Главная мысль урока: «отличить кошку от собаки» — это не магия и не понимание. Это конвейер: картинка превращается в признаки, признаки умножаются на веса, веса складываются в одно число, и по этому числу сеть говорит «кошка» или «собака». Сегодня ты проследишь весь конвейер от начала до конца на нашем сквозном примере.
Зачем тебе это демо
Представь, что ты листаешь ленту, и телефон сам подписывает фотки: «кот», «собака», «кот». Ты ни разу не задумывался, как он это делает — просто работает. А теперь давай вскроем капот. К концу урока ты сможешь сам, на бумажке или в голове, пройти путь, который проходит сеть: от «вот картинка» до «с вероятностью 0.9 это кошка». И, что важнее, ты поймёшь, где именно в этом пути прячется ошибка, когда сеть путает пушистую собаку с котом.
Этот урок — сборка. Мы уже разбирали по кусочкам: что такое признак, что такое вес, как сеть видит картинку, как она учится на ошибках. Сегодня мы соединим все кусочки в одну работающую цепочку на нашем сквозном примере «кошка или собака». Никакого нового матана — только то, что ты уже знаешь, но теперь целиком.
Классификация — это когда модель раскладывает объекты по заранее известным классам-папкам. У нас две папки: «кошка» и «собака». Задача сети — для новой картинки выбрать правильную папку.
Метафора: сортировщик на конвейере
Вообрази старшеклассника, который подрабатывает на складе. По ленте едут коробки, и его задача — раскидывать их в две тележки: «кошачий корм» и «собачий корм». Этикетки стёрлись, и решать приходится по приметам.
Что он делает? Он не разглядывает каждую коробку целиком. Он смотрит на несколько признаков: цвет коробки, размер, есть ли картинка с усами. Каждый признак для него весит по-разному. Картинка с усами — сильный сигнал «кошка», он доверяет ей больше всего. Цвет — так себе сигнал, корм бывает в любой упаковке. В голове он как бы складывает: «усы — это сильно за кошку, размер маленький — ещё чуть-чуть за кошку, цвет синий — да фиг с ним». Сложил, прикинул, бросил в нужную тележку.
Сеть, которая отличает кошку от собаки, — это и есть такой сортировщик. Только вместо коробок — картинки, вместо примет — признаки вроде формы ушей, а вместо «доверяю больше/меньше» — веса, те самые числа, которые подкручивались при обучении. Давай разложим это соответствие в таблицу:
| Сортировщик на складе | Нейросеть для кошек/собак |
| Коробка на ленте | Картинка на входе |
| Приметы: усы, размер, цвет | Признаки: форма ушей, текстура шерсти, форма морды |
| Насколько он доверяет примете | Вес у признака |
| Сложил приметы в голове | Сумма «признак × вес» |
| Две тележки | Два класса: кошка / собака |
| Бросил в тележку | Финальное предсказание |
Держи эту картинку в голове весь урок. Всё дальнейшее — просто детализация этого конвейера.
Шаг за шагом: от пикселей к ответу
Разобьём путь сети на четыре стадии. На каждой что-то превращается во что-то — и в конце мы получаем ответ.
Стадия 1. Картинка → числа
В уроке про то, как сеть видит картинку мы выяснили: для компьютера фотка кошки — это не «кошка», а здоровенная таблица чисел-яркостей пикселей. Сеть не видит мордочку, она видит сетку цифр. Это сырьё, с которым дальше предстоит работать.
Стадия 2. Числа → признаки
Сырые пиксели — это слишком много и слишком бестолково. Сеть постепенно сворачивает миллионы пикселей в горстку осмысленных признаков: насколько уши округлые, какая текстура у шерсти, какой формы морда, есть ли усы. В настоящих сетях эти признаки сеть находит сама в процессе обучения, и они куда хитрее, чем «уши». Но идея ровно та же, что у сортировщика: вместо целой коробки — несколько примет.
Стадия 3. Признаки → одно число (score)
Вот сердце конвейера. У каждого признака есть свой вес. Сеть умножает каждый признак на его вес и всё складывает — получается одно число, назовём его score. Чем оно больше, тем сильнее сеть склоняется к «кошке».
Стадия 4. Score → ответ и уверенность
Score — это пока просто число вроде 2.3 или -1.1. Чтобы превратить его в понятный ответ, сеть прогоняет score через сжимающую функцию, которая выдаёт вероятность от 0 до 1. Близко к 1 — «уверенно кошка», близко к 0 — «уверенно собака», около 0.5 — «сеть в растерянности». Вот и весь путь.
Разбираем на коде: конвейер целиком
Давай оживим эти четыре стадии. Возьмём три простых признака для нашего сквозного примера. Каждый признак — число от 0 до 1, где 1 — «ярко выражено». Веса — те, что сеть как будто бы уже выучила: положительный вес тянет к кошке, отрицательный — к собаке.
// Стадия 2: картинка уже свёрнута в три признака (0..1)
const cat = { roundEars: 0.9, furSoft: 0.8, longSnout: 0.1 };
const dog = { roundEars: 0.2, furSoft: 0.4, longSnout: 0.9 };
// Веса, которые сеть выучила при обучении
const weights = { roundEars: 2.0, furSoft: 1.0, longSnout: -2.5 };
const bias = -0.2; // лёгкий сдвиг "по умолчанию"
// Стадия 3: признаки * веса, всё складываем -> score
function score(animal) {
return (
animal.roundEars * weights.roundEars +
animal.furSoft * weights.furSoft +
animal.longSnout * weights.longSnout +
bias
);
}
// Стадия 4: сжимаем score в вероятность 0..1
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
function classify(name, animal) {
const s = score(animal);
const p = sigmoid(s);
const answer = p > 0.5 ? "кошка" : "собака";
console.log(
name + ": score=" + s.toFixed(2) +
", вероятность кошки=" + p.toFixed(2) +
" -> " + answer
);
}
classify("Картинка A", cat);
classify("Картинка B", dog);Вывод:
Картинка A: score=2.35, вероятность кошки=0.91 -> кошка Картинка B: score=-1.85, вероятность кошки=0.14 -> собака
Смотри, что произошло. Для картинки A признаки кошачьи: круглые уши (0.9), мягкая шерсть (0.8), морда короткая (longSnout = 0.1). Круглые уши с весом 2.0 дали большой плюс, длинная морда почти не сработала. Score взлетел до 2.35, сигмоида сжала его в 0.91 — сеть уверенно говорит «кошка».
Для картинки B всё наоборот: морда длинная (0.9) с весом -2.5 утащила score глубоко в минус, до -1.85. Вероятность кошки 0.14 — то есть вероятность собаки 0.86. Сеть говорит «собака». Заметь: нигде в коде нет слова «понять» или «узнать морду». Есть только умножения и сложения. Это и есть весь интеллект на данном уровне.
Где здесь веса из прошлых уроков
Объект weights — это ровно те самые числа, которые в прошлых уроках подкручивались на ошибках, спускаясь по склону. Я вписал их вручную, чтобы конвейер было видно целиком, но на деле сеть нашла бы их сама, прогнав тысячи размеченных картинок. Большой положительный вес 2.0 у круглых ушей означает «сеть выучила: круглые уши — сильный признак кошки». Отрицательный -2.5 у длинной морды — «длинная морда тянет к собаке». Веса — это вся память сети о том, что она видела.
Когда конвейер ошибается
Самое интересное начинается, когда картинка пограничная. Возьмём пушистую собаку с подозрительно круглыми ушами — например молодого шпица. Признаки перепутаются, и мы увидим, как сеть теряется.
const weights = { roundEars: 2.0, furSoft: 1.0, longSnout: -2.5 };
const bias = -0.2;
function sigmoid(x) { return 1 / (1 + Math.exp(-x)); }
function classify(name, a) {
const s = a.roundEars * weights.roundEars +
a.furSoft * weights.furSoft +
a.longSnout * weights.longSnout + bias;
const p = sigmoid(s);
console.log(
name + ": вероятность кошки=" + p.toFixed(2) +
" -> " + (p > 0.5 ? "кошка" : "собака")
);
}
// Пушистый шпиц: уши круглые, шерсть мягкая, но морда длинноватая
classify("Пушистый шпиц", { roundEars: 0.8, furSoft: 0.9, longSnout: 0.5 });
// Сфинкс: кошка без шерсти и с большими ушами
classify("Кошка-сфинкс", { roundEars: 0.5, furSoft: 0.0, longSnout: 0.2 });Вывод:
Пушистый шпиц: вероятность кошки=0.74 -> кошка Кошка-сфинкс: вероятность кошки=0.62 -> кошка
Опа! Пушистый шпиц — это собака, а сеть выдала «кошка» с вероятностью 0.74. Почему? Потому что круглые уши и мягкая шерсть — два сильных кошачьих сигнала — перевесили длинную морду. Сеть не видит шпица целиком, она видит только три числа, и по этим трём числам шпиц действительно похож на кошку. Это не «глупость» сети — это честный итог конвейера на неудачных признаках.
А сфинкс — настоящая кошка — еле-еле прошёл как кошка (0.62), хотя должен бы пройти уверенно: у него нет мягкой шерсти, и важный признак не сработал. Чуть-чуть других весов — и сеть записала бы его в собаки. Вот ровно так и рождаются ошибки распознавания, о которых ты, может, читал мемы.
Та же история, но со словами
Наш второй сквозной пример — фраза «Кошка пьёт ...» — устроен точь-в-точь так же, просто признаки там не «уши», а контекст из предыдущих слов. Сеть превращает слова в числа, умножает на веса, складывает и для каждого возможного следующего слова получает score. У слова «молоко» score высокий, у «кирпич» — низкий. После сжатия score'ов в вероятности сеть выдаёт что-то вроде: молоко — 0.6, вода — 0.3, кирпич — 0.001. Тот же конвейер «признаки → веса → score → вероятность», только классов не два, а весь словарь. Когда дойдём до ChatGPT, ты увидишь, что и там внутри живёт этот же конвейер, просто очень-очень большой.
Частые ошибки и подводные камни
На этом сборочном уроке новички спотыкаются о несколько штук. Разберём, чтобы у тебя в голове осталась честная картинка.
1. Думать, что сеть «видит» картинку, как ты
Тебе кажется, что сеть смотрит на мордочку и узнаёт кошку. Нет. К стадии 3 от картинки остаётся горстка чисел-признаков. Сеть решает по ним, а не по «образу». Поэтому две очень разные на вид картинки с похожими признаками для сети почти одинаковы — и наоборот.
2. Путать score и вероятность
Score — это сырое число, оно может быть и -5, и +8, его трудно сравнивать между картинками. Вероятность — это score, сжатый в диапазон от 0 до 1, её уже можно читать как «уверенность». Когда говорят «сеть на 90% уверена», имеют в виду вероятность 0.90, а не score.
3. Верить, что высокая уверенность = правильный ответ
Наш пушистый шпиц получил 0.74 — высокая уверенность! — и всё равно был классифицирован неверно. Сеть бывает уверенно неправа. Высокая вероятность говорит лишь «по моим признакам и весам это сильно похоже на кошку», а не «я точно права». Запомни это: позже это объяснит, почему ChatGPT уверенно выдаёт галлюцинации — выдуманные, но складно звучащие ответы.
4. Считать, что веса задаёт программист
В коде я вписал веса руками только для наглядности. В реальной сети их никто не пишет вручную — они получаются сами на этапе обучения, подкручиваясь на ошибках. Программист задаёт устройство сети и данные, а конкретные числа сеть находит сама.
5. Забывать про границу 0.5
Ответ «кошка или собака» получается сравнением вероятности с порогом 0.5. Но порог — это наше решение, а не закон природы. Если ошибиться, приняв собаку за кошку, для нас не страшно — можно сдвинуть порог. А вот в медицине или в беспилотнике цена ошибки разная для разных классов, и порог двигают осознанно. Граница 0.5 — удобная, но не священная.
Мини-практика: сломай и почини конвейер
Теперь твоя очередь покрутить ручки. Возьми за основу первый пример (объекты cat, dog, weights и функцию classify) и поэкспериментируй:
- Добавь четвёртый признак — например
loudBark(громко лает, 0..1) с весом, который тянет к собаке. Какой знак у этого веса — плюс или минус? Включи признак вscoreи проверь, изменился ли ответ для шпица. - Найди такие три признака, при которых сеть выдаёт ровно
0.50— полную растерянность. Что это говорит о картинке? - Урони вес круглых ушей с
2.0до0.1. Что станет с ответом для кошки-сфинкса и почему? Так ты увидишь, как «забывание» одного признака ломает распознавание. - Сделай мысленный эксперимент со вторым сквозным примером: придумай три «слова-признака» для фразы «Кошка пьёт ...» и реши, у какого следующего слова score должен быть выше — у «молоко» или у «бетон».
Лучший способ понять конвейер — не прочитать про него, а сломать его своими руками и посмотреть, в каком месте посыпался ответ.
Итоги
Сегодня ты собрал всю цепочку распознавания воедино — на нашем сквозном примере кошки и собаки.
- Распознавание — это классификация: разложить объект по заранее известным папкам-классам.
- Путь сети — это конвейер из четырёх стадий: картинка → числа-пиксели → признаки → score → вероятность и ответ.
- В сердце конвейера — простая арифметика: каждый признак умножается на свой вес, всё складывается. Веса — это вся выученная память сети.
- Сеть ошибается не от «глупости», а честно: на пограничных картинках (пушистый шпиц, кошка-сфинкс) признаки перепутываются, и конвейер выдаёт уверенно неверный ответ.
- Высокая уверенность не значит правоту — это важная мысль, которая позже объяснит галлюцинации больших моделей.
- Та же схема работает и для фразы «Кошка пьёт ...»: меняются признаки и число классов, но конвейер «признаки → веса → score → вероятность» остаётся тем же.
Теперь у тебя в голове есть полная работающая картинка одного нейрона-классификатора. В следующих уроках мы начнём наращивать масштаб: много таких блоков, много слоёв, и наша задача «кошка или собака» поднимется ещё выше — к тому, как сеть сама находит хитрые сочетания признаков, до которых мы бы вручную не додумались. Конвейер останется прежним, просто станет глубже.