Глава 3. Частотный взгляд на мир
Скольжение окна по картинке и умножение спектров — не две разные магии.
Это один и тот же факт, записанный на двух языках.
В главе 2 свёртка появилась как инженерный ответ на локальность.
Теперь посмотрим на неё глазами обработки сигналов. Не ради красоты формул — ради другого вопроса:
Что именно фильтр оставляет в изображении, а что выбрасывает?
Когда этот вопрос становится привычным, обучение CNN перестаёт быть чёрным ящиком «веса сами подстроились». Появляется язык, на котором можно спорить о гипотезах.
3.1. Изображение как сигнал
Любую картинку можно читать двумя способами.
Пространственный взгляд: сетка пикселей. Яркость в точке (x, y).
Частотный взгляд: сумма волн разной частоты и направления. Медленные волны — крупные пятна и фон. Быстрые — тонкие штрихи, шум, резкие границы.
Это не метафора «для гуманитариев». Преобразование Фурье буквально раскладывает изображение в такой базис. После него у вас не карта «где что нарисовано», а карта «какие частоты с какой силой присутствуют».
Зачем архитектору эта картинка в голове?
Потому что почти любой полезный локальный фильтр — это выбор частот:
| Ручной фильтр | Что делает по смыслу |
|---|---|
| Размытие (Gaussian) | Режет высокие частоты |
| Выделение краёв (Sobel и друзья) | Подчёркивает высокие |
| Полосовой фильтр | Оставляет «средний» диапазон текстур |
До глубокого обучения инженер рисовал эти фильтры руками.
CNN делает то же самое — только коэффициенты подбирает обучение.
3.2. Теорема о свёртке: два языка одной операции
Здесь как раз тот факт, который часто всплывает в разговорах и так же часто путается.
Есть три «мира»:
- Пространственный — пиксели и скользящее окно.
- Частотный — спектры после Фурье.
- Мир обучения — градиенты, которые крутят коэффициенты фильтра.
Теорема о свёртке связывает первые два:
Свёртка двух сигналов в пространстве
↔
поэлементное произведение их спектров в частотной области.
Схематично:
Практический смысл для инженера:
- «Прогнать картинку через фильтр» = «усилитить одни частоты и подавить другие».
- Форма ядра
gв пространстве задаёт маскуGв частотах. - Обучение свёрточного слоя — это, среди прочего, поиск полезных частотных масок под задачу.
Важная оговорка, чтобы не словить ложную интуицию:
Произведение спектров — это про свёртку.
Не путать с тем, что «нейросеть всегда считает через FFT».
На практике Conv2d на GPU чаще считают прямыми алгоритмами по окнам (или Winograd и т.п.). Теорема объясняет смысл операции, а не обязательно путь в CUDA-ядре. Для архитектора важнее смысл: фильтр = частотный селектор.
Ещё одна тонкость из главы 2: в DL часто считают кросс-корреляцию без отражения ядра. Для теоремы это нюанс фазы/отражения; обучаемые веса снова делают спор почти академическим. Идея «фильтр режет спектр» остаётся рабочей.
3.3. Эволюция фильтров: как сеть переоткрывает классику
Поставьте мысленный эксперимент.
Берём простой стек свёрток. Задача — классификация. Смотрим на первые слои после нескольких эпох.
Очень часто (не всегда буквально, но узнаваемо) всплывают паттерны, которые человек рисовал десятилетиями:
Это не доказательство, что CNN «изобрела Собеля».
Это доказательство более сильного тезиса:
Если архитектура умеет выражать частотные селекторы,
а задача требует границ и текстур,
оптимизатор сам нащупает семейство решений,
близкое к классической обработке сигналов.
Ручной путь: инженер знает, что краям нужны высокие частоты → рисует Sobel.
Обучаемый путь: инженер знает, что миру нужна локальность → ставит Conv → данные дорисовывают коэффициенты.
Второй путь победил не потому, что Фурье устарел.
Он победил потому, что вручную не масштабируется сборка иерархии таких фильтров под каждый датасет.
flowchart TD
A[Задача на изображениях] --> B[Нужны края / текстуры / формы]
B --> C{Как получить фильтры?}
C --> D[Руками: Sobel, Gabor, SIFT…]
C --> E[Обучением: стек Conv]
D --> F[Хорошо на узкой задаче]
D --> G[Плохо масштабируется на новые классы]
E --> H[Те же частотные идеи внутри]
E --> I[Иерархия и адаптация под данные]
3.4. Что частотный взгляд даёт архитектору
Частотный язык полезен не для того, чтобы на каждой планёрке рисовать спектры. Он полезен как набор быстрых гипотез.
1. Размытие и stride — это не только «уменьшили тензор».
MaxPool / stride-2 выбрасывают часть высоких частот и огрубляют координаты. Для классификации часто терпимо. Для детекции мелких объектов — уже статья расходов.
2. Глубокий стек маленьких 3×3 — это не только экономия параметров.
Несколько маленьких ядер подряд могут набрать поле зрения большого ядра и при этом выразить более богатый набор частотных ответов (плюс нелинейности между ними). Отсюда исторический ход VGG: лучше стек 3×3, чем одно огромное окно.
3. «Сеть не видит объект» иногда значит «нужная частота умерла по дороге».
Слишком агрессивный downsampling, слишком ранний сильный low-pass — и от спички на горизонте не остаётся носителя признака.
4. Augmentations тоже имеют частотную тень.
Сильный blur режет верх спектра. JPEG-артефакты добавляют свои частоты. Если валидация «чистая», а прод — сжатый видеопоток, вы сравниваете модели на разных спектральных мирах.
| Пространственный язык | Частотный язык |
|---|---|
| ядро 3×3 | локальный частотный селектор |
| много фильтров | набор разных масок спектра |
| stride / pool | огрубление + потеря highs |
| глубокий стек | иерархия от highs к структуре |
| feature map | где выбранные частоты сильны |
3.5. Где частотный взгляд врёт или упрощает
Честность важнее красивой аналогии.
Нелинейности ломают чистую картину.
Теорема о свёртке — про линейные системы. Между свёртками у нас ReLU и компания. После нелинейности «просто умножить спектры» уже нельзя в лоб. Частотный язык остаётся интуицией для локального линейного куска, а не полной теорией сети.
Глобальный смысл ≠ низкие частоты.
«Это кошка» — не то же самое, что «в кадре много низких частот». Семантика живёт в комбинациях признаков по пространству и по слоям. Спектр — инструмент, не замена представлениям.
Attention и глобальные связи говорят на другом диалекте.
Когда позже появятся трансформеры, чистой локальной частотной интуиции станет мало: модель сможет связывать далёкие патчи напрямую. Это не отменяет главу — это ограничивает её юрисдикцию.
Итоговая рамка:
Частотный взгляд объясняет, почему свёртка вообще имеет право на жизнь
и что она делает с сигналом.
Он не объясняет всю современную архитектуру целиком.
Для Части I этого достаточно как рамка.
Ниже — углубление: когда FFT-путь реально выгоднее, как downsampling врёт про частоты, и зачем архитектору антиалиасинг.
3.6. FFT-свёртка vs прямое окно: когда какой путь
Теорема говорит: можно посчитать свёртку через частоты.
Железо спрашивает: нужно ли?
Грубая инженерная развилка:
прямое окно выгодно, когда:
• ядро маленькое (3×3, 5×5)
• карта не гигантская
• есть хорошие GPU-kernels (Winograd / implicit GEMM)
FFT-путь начинает блестеть, когда:
• ядро большое или «полный» фильтр по карте
• нужно много больших корреляций
• накладные FFT/IFFT окупаются
стоимость (очень схематично)
прямой Conv: ~ H·W·K²·C_in·C_out
FFT-путь: ~ C · (H·W log(H·W)) + поточечные произведения
(плюс память на спектры, плюс padding до удобных размеров)
Практический вывод для читателя книги:
Теорема объясняет смысл.
Выбор алгоритма объясняет счёт на вашем размере задачи.
Именно поэтому nn.Conv2d(3×3) почти никогда не «идёт в FFT внутри» на обучении классических CNN — не потому что математика врёт, а потому что для малых K прямой путь быстрее и проще.
3.7. Downsampling как частотная ловушка
Stride-2 и pooling — не только «сделали тензор меньше».
Это дискретизация заново.
Если в сигнале были высокие частоты, а вы проредили сетку без предварительного сглаживания, получаете алиасинг: высокие частоты притворяются низкими.
до /2 после наивного /2
высокая частота «ложный» низкочастотный узор
▓▓░░▓▓░░▓▓░░ ▓░░▓░░▓░░
Почему это важно архитектору детекции/сегментации:
- мелкие периодические текстуры «ломаются» в странные паттерны;
- сдвиговая устойчивость ухудшается: объект на чётном/нечётном пикселе ведёт себя по-разному;
- часть «магии» современных stem/anti-alias блоков — просто признание этой ловушки.
Связь с главой 2:
Padding/stride крутили как ручки размера.
Частотный взгляд добавляет: ручка stride ещё и врёт спектру, если её крутить грубо.
Отсюда гипотезы, которые стоит проверять абляциями:
- AvgPool / blur перед subsample вместо голого stride-2 MaxPool.
- Более плавный stem в начале сети.
- Аккуратный upsample в FPN (не только «ближайший сосед», если важны края).
3.8. Обучение как подбор банка фильтров
Сложите три уровня языка в одну схему:
уровень 1: пиксели и окна (гл. 2)
уровень 2: частоты и маски (гл. 3)
уровень 3: оптимизация коэффициентов под loss задачи
Ручной путь классики:
инженер → выбирает Sobel/Gabor/… → фиксированный банк → классификатор сверху
CNN-путь:
архитектор → фиксирует форму (локальность, K, число каналов, stride)
оптимизатор → подбирает коэффициенты банка под данные
глубокий стек → строит иерархию ответов банка
Что остаётся за архитектором, даже когда «фильтры сами»:
- сколько частотных селекторов (ширина);
- как быстро мы выбрасываем highs (stride/pool);
- где ставим нелинейность (после каких смесителей);
- какой prior важнее данных (чисто CNN vs позже ViT).
flowchart TD
A[Сигнал/изображение] --> B[Банк локальных фильтров]
B --> C{Кто задаёт коэффициенты?}
C --> D[Руками: классический CV]
C --> E[Обучением: CNN]
B --> F{Кто задаёт downsampling?}
F --> G[Архитектор: stride/pool/anti-alias]
G --> H[Какие частоты доживут до головы]
3.9. Закрываем Часть I
Три главы — один сюжет:
Глава 1 Brute force умер
↓
Глава 2 Локальность + sharing → свёртка
↓
Глава 3 Свёртка = частотный селектор;
обучение подбирает маски;
stride/pool решают, какие частоты выживут
Мы встроили в архитектуру знание о мире: соседние пиксели связаны, паттерны повторяются, полезное часто лежит в структуре спектра — и легко убивается грубым прореживанием.
Следующий кризис будет другим.
Мы научимся делать сети глубже — и обнаружим, что «больше слоёв» внезапно означает «хуже обучается».
Если бы вы были автором статьи…
-
Если свёртка в пространстве = произведение спектров, зачем считать окна, а не FFT → multiply → IFFT?
Для какихKиH×WFFT-путь выгоднее на вашем GPU? Где побеждает прямой алгоритм / Winograd? -
Модель отлично работает на PNG и проваливается на сильно сжатом JPEG.
Сформулируйте частотную гипотезу. Какой эксперимент её подтвердит или убьёт? -
Спроектируйте антиалиас-downsample (blur + stride) и сравните с голым MaxPool stride-2.
На какой метрике ждёте выигрыш: сдвиговая стабильность, мелкие объекты, шумные текстуры? -
Можно ли сознательно запретить диапазон частот слоем?
Когда это робастность, а когда вы просто выкололи полезный сигнал?
В Части II мы разберём, почему глубокий стек таких фильтров начинает задыхаться — и какое простое на вид архитектурное решение вернуло градиентам дорогу назад.