Въпроси за интервю за инженер по компютърно зрение
15 подбрани въпроса за интервю по компютърно зрение, групирани по ниво на опит. Използвайте ги, за да преговорите основите, практическите компромиси и аргументацията на Senior ниво за производствена среда.
1Какво е дискретна 2D конволюция върху изображение и как е свързана с ядра, филтри и кръстосана корелация?
Дискретната 2D конволюция върху изображение е линейна, пространствена филтрираща операция, при която матрица от тегла (ядро) се плъзга по входното изображение. На всяка пространствена позиция, тя изчислява поелементен продукт между теглата на ядрото и припокриващия се локален участък от изображението (рецептивно поле) и сумира резултатите (често добавяйки член на отместване), за да произведе единична стойност на пиксел в изходната карта на признаците (feature map). В класическата математика и обработката на сигнали, истинската конволюция включва обръщане (завъртане на 180 градуса) на ядрото хоризонтално и вертикално, преди да се изчисли плъзгащият се вътрешен продукт: $(I * K)(i, j) = \sum_m \sum_n I(i - m, j - n) K(m, n)$. За разлика от това, кръстосаната корелация изчислява плъзгащия се скаларен продукт директно, без да обръща ядрото: $(I \star K)(i, j) = \sum_m \sum_n I(i + m, j + n) K(m, n)$. Във фреймуъркове за дълбоко обучение като PyTorch и TensorFlow, операцията, имплементирана под името „конволюция“, всъщност е кръстосана корелация. Тъй като теглата на ядрото са обучаеми параметри, оптимизирани директно чрез обратно разпространение (backpropagation), мрежата просто научава подходящо ориентираните тегла, което прави математическото обръщане на ядрото изчислително излишно по време както на обучението, така и на инференцията.
2Кога бихте използвали RGB, HSV, Lab, YCbCr или черно-бели (grayscale) представяния в един конвейер за визуална обработка (vision pipeline)?
Различните цветови пространства разделят специфични физически, перцептивни и статистически свойства на визуалните данни, което ги прави подходящи за конкретни визуални задачи:
1. **RGB / BGR**: Стандартен формат за сензори на камери и хардуер за дисплеи, който представя адитивни основни цветове (червено, зелено, синьо). Цветовите канали са силно корелирани с осветеността (промените в осветлението засягат и трите канала едновременно). Това е стандартен вход за дълбоки невронни мрежи (като CNNs, Vision Transformers). Основен производствен проблем е размяната на канали RGB спрямо BGR (напр. OpenCV зарежда BGR, докато PIL/PyTorch очакват RGB), което незабелязано намалява точността на модела.
2. **HSV / HSL**: Изрично разделя хроматичността (Hue = цветови нюанс, Saturation = чистота на цвета) от интензитета (Value/Lightness). Идеален е за класическо цветово праговане, проследяване на обекти по цвят и сегментиране на цветове при променливо осветление, тъй като Hue е относително инвариантен спрямо сенки и промени в яркостта.
3. **CIE Lab**: Перцептивно еднородно цветово пространство, където евклидовото разстояние между две точки ($\Delta E$) директно отразява човешката перцептивна разлика. Той разделя светлината ($L^*$) от цветовите оси на опонентите ($a^*$ зелено-червено, $b^*$ синьо-жълто). Използва се при проверка на цветови разлики, корекция на цветове, оценка на качеството на изображението и задачи по колоризация.
4. **YCbCr**: Разделя осветеността ($Y$) от компонентите на синьо-различната ($Cb$) и червено-различната ($Cr$) хрома. Той е гръбнакът на стандартите за компресия на видео и изображения (JPEG, MPEG, H.264/H.265), тъй като човешката зрителна система е по-малко чувствителна към детайлите на хромата, което позволява подсемплиране на хромата (напр. 4:2:0) за намаляване на пропускателната способност и изчислителната мощност.
5. **Черно-бяло (Grayscale)**: Едноканален интензитет ($Y \approx 0.299R + 0.587G + 0.114B$). Идеален е за задачи, базирани на геометрия и текстура, където цветът е без значение (напр. оптичен поток, SLAM, класическо извличане на признаци като SIFT/ORB, откриване на ръбове), за да спести 66% от паметта и изчислителната мощност. Въпреки това, не трябва да се използва, когато цветът е ключов дискриминативен признак (напр. класификация на състоянието на светофар).
import cv2
import numpy as np
# Sample image: saturated red under normal and shaded lighting
img_bgr = np.zeros((100, 100, 3), dtype=np.uint8)
img_bgr[:, :50] = [0, 0, 255] # Bright Red in BGR
img_bgr[:, 50:] = [0, 0, 120] # Shaded/Dark Red in BGR
# Convert to HSV (OpenCV H: 0-179, S: 0-255, V: 0-255)
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
# Red Hue wraps around 0/180; track red with single Hue range [0, 10] & high saturation
lower_red = np.array([0, 100, 50])
upper_red = np.array([10, 255, 255])
mask_hsv = cv2.inRange(img_hsv, lower_red, upper_red)
print("HSV segmented pixels:", np.count_nonzero(mask_hsv), "out of", mask_hsv.size)
3Защо каналната нормализация на изображенията, нормализацията на изображение и последователното мащабиране на пикселите са важни във визуалните системи?
Нормализацията на изображенията е жизненоважна във визуалните пайплайни за поддържане на числова стабилност, ускоряване на сходимостта на градиентния спускане и предотвратяване на изместване на разпределението между тренировка и обслужване (train-serving distribution shift): 1. **Мащабиране на пикселите ([0, 1] или [-1, 1])**: Суровите пиксели на изображението се съхраняват като беззнакови 8-битови цели числа (`uint8` $\in [0, 255]$). Подаването на сурови стойности $[0, 255]$ към невронни мрежи причинява изключително големи ранни активации и експлозия или насищане на градиентите. Мащабирането до $[0.0, 1.0]$ (чрез деление на 255.0) или $[-1.0, 1.0]$ центрира входовете около нула, съобразявайки се със стандартните методи за инициализация на теглата (He, Xavier). 2. **Канална нормализация на ниво набор от данни (стандартизация по средна стойност и стандартно отклонение)**: Стандартизира входовете чрез $x_{norm} = \frac{x - \mu_c}{\sigma_c}$, използвайки предварително изчислени глобални статистики за всеки канал (напр., средна стойност на ImageNet `[0.485, 0.456, 0.406]` и стандартно отклонение `[0.229, 0.224, 0.225]`). Това центрира всеки канал около нулева средна стойност с единична дисперсия в целия набор от данни, осигурявайки балансиран поток на градиенти между каналите. Критична оперативна грешка е **разминаване тренировка-обслужване (train-serving skew)**: ако инференцията пропусне делението на 255, използва несъответстващи константи за средна стойност/стандартно отклонение или ги приложи в грешен ред на каналите (RGB срещу BGR), производителността на модела рязко спада. 3. **Нормализация на изображение (за всяко изображение) (нормализация на инстанциите / Min-Max / Z-оценка)**: Изчислява средната стойност и стандартното отклонение за всяко отделно изображение: $x_{norm} = \frac{x - \mu_{img}}{\sigma_{img}}$. Това премахва глобалните вариации на контраста и осветеността при различни условия на заснемане. Въпреки че е ефективна при пренос на стил, ЯМР/КТ медицински изображения или сателитни изображения, тя може да бъде вредна, когато абсолютната интензивност на пиксела носи физически смисъл (напр. класификация ден срещу нощ, отражателна способност на материала или откриване на дефекти при калибрирано осветление).
import torch
import torchvision.transforms as T
from PIL import Image
import numpy as np
# Create a mock uint8 RGB image
raw_img = Image.fromarray(np.random.randint(0, 256, (224, 224, 3), dtype=np.uint8))
# Standard transform pipeline:
# 1. ToTensor scales uint8 [0, 255] -> float32 [0.0, 1.0] and permutes HWC -> CHW
# 2. Normalize standardizes per-channel using dataset mean and std
preprocess = T.Compose([
T.ToTensor(),
T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
tensor_img = preprocess(raw_img)
print("Tensor shape:", tensor_img.shape)
print("Tensor dtype:", tensor_img.dtype)
print("Channel 0 min/max:", round(tensor_img[0].min().item(), 2), round(tensor_img[0].max().item(), 2))
4Как геометричните и фотометричните аугментации насърчават инвариантността и как решавате дали една аугментация запазва етикетите?
Геометричните аугментации (като ротация, транслация, мащабиране и обръщане) променят пространственото картиране на координатите на пикселите, докато фотометричните аугментации (като яркост, контраст, трептене на нюанса и замъгляване) променят интензитета на пикселите и цветовите канали, без да променят пространствените координати. При класификацията и двете категории излагат модела на реалистични вариации, насърчавайки го да научи инвариантни представяния, където предвижданията остават стабилни въпреки промените в позата, гледната точка или условията на осветление. При задачите за пространствено предсказване (детекция и сегментация) геометричните трансформации изискват съответстващи трансформации към референтните кутии (ground-truth boxes) или маски, за да се запази еквивариантността. Решаването дали дадена аугментация запазва етикетите изисква оценка на домейн семантиката и физическите априорни знания. Една трансформация запазва етикета, ако полученото изображение остава правдоподобен екземпляр на оригиналния целеви клас, без да променя неговата семантична идентичност. Например, хоризонталното обръщане запазва идентичността за общи обекти (като коли или животни), но променя идентичността или прави невалидни символи при оптично разпознаване на символи (OCR) и класификация на цифри. По подобен начин, пълната ротация на 360 градуса е валидна в хистологията или сателитните изображения, където няма канонична ориентация, но е неестествена при автономно шофиране, където обекти с главата надолу нарушават физическите ограничения от реалния свят.
5Какво представляват интерполациите по най-близък съсед (nearest-neighbor), билинейна (bilinear), бикубична (bicubic) и по площ (area interpolation), и как преоразмеряването може да въведе алиасинг (aliasing) или размазване (blur)?
Методите за интерполация оценяват интензитета на пикселите при непрекъснати координати при пресемплиране върху нова дискретна мрежа:
- **Най-близък съсед (Nearest-Neighbor):** Присвоява интензитета на най-близкия дискретен пиксел. Изчислително е $O(1)$ и запазва точните оригинални стойности, но създава блокови артефакти при увеличаване на размера (upsampling) и силно назъбени ръбове при намаляване на размера (downsampling).
- **Билинейна интерполация (Bilinear Interpolation):** Изчислява средно аритметично, претеглено по разстояние, на $2 \times 2$ (4 най-близки) съседни пиксела, използвайки линейна интерполация по двете оси, което води до плавни преходи с умерено размазване.
- **Бикубична интерполация (Bicubic Interpolation):** Взима проби от съседство $4 \times 4$ (16 най-близки) с помощта на кубични полиномни ядра. Тя улавя локални градиенти на интензитета, произвеждайки по-остри ръбове и по-плавни криви от билинейната, но може да създаде артефакти на превишаване/звънене (overshoot/ringing) около резки преходи.
- **Интерполация по площ (Area (Box) Interpolation):** Изчислява частичното припокриване на площта на целеви пиксели, проектирани върху изходни пиксели, и осреднява основните изходни интензитети. Особено ефективна е за намаляване на размера (downsampling) без моаре.
**Механизми на алиасинг срещу размазване:**
- **Алиасингът (Aliasing)** възниква по време на намаляване на размера (downsampling), когато високочестотното съдържание надвишава честотата на Найкуист ($f_s / 2$) на новата честота на семплиране без достатъчно нискочестотно филтриране. Високите честоти се преобразуват в по-ниски честотни ленти, произвеждайки фалшиви шарки, моаре и назъбени ръбове.
- **Размазването (Blur)** възниква, когато интерполационните ядра действат като нискочестотни филтри за изглаждане, които отслабват легитимни високи честоти (напр., билинейно изглаждане) или когато високочестотни детайли се осредняват по време на намаляване на размера (downsampling).
6Спрямо какви реални режими на визуална повреда (visual failure modes) трябва да бъде оценявана една визуална система и как те изместват разпределението на входа?
Реалните режими на визуална повреда попадат в няколко широки категории: условия на околната среда (слаба светлина, пряк отблясък, дъжд, сняг, мъгла), сензорни и оптични ефекти (размазване от движение, размазване от дефокусиране, шум от сензор с високо ISO, изкривяване от търкалящ се затвор), деградация от компресия и предаване (блоковост на JPEG, ограничаване на битрейта на видео, намаляване на семплирането) и семантични/пространствени измествания (частично запушване, отрязване, пози на обекти извън разпределението). Тези режими на повреда изместват разпределението на входа далеч от номиналните домейни за обучение на множество нива. На ниво пиксел те променят хистограмите на яркостта и цветността, унищожават локалния контраст, намаляват съотношението сигнал/шум (SNR) и въвеждат изкуствени високочестотни артефакти или ядра за размазване. На структурно и семантично ниво те отслабват градиентите на ръбовете, прикриват ключови визуални характеристики, изкривяват силуетите и скриват критични диагностични региони. Когато модели, обучени на чисти данни, срещнат тези изместени входове, нисконивовите конволюционни или атеншън екстрактори на характеристики не се активират правилно, което води до пропуснати откривания, халюцинирани фалшиви позитиви при шумови модели и прекалено уверени грешки.
7Как класическите дескриптори като HOG представят структурата на изображението и какви ограничения имат те в сравнение с научените характеристики от CNN?
HOG (Histogram of Oriented Gradients) е класически, ръчно създаден дескриптор на характеристики, предназначен да улавя локалната форма и изглед на обекти чрез разпределението на ориентациите на градиента на интензитета. Процесът на изчисляване на HOG включва: (1) изчисляване на хоризонтални и вертикални градиенти на изображението (напр. с едноизмерни производни филтри `[-1, 0, 1]`), за да се получат големина и ориентация на градиента; (2) разделяне на изображението на малки пространствени региони, наречени „клетки“ (като 8x8 пиксела), и натрупване на едноизмерни хистограми на ориентациите на градиента, претеглени по големината на градиента; (3) групиране на съседни клетки в по-големи, припокриващи се „блокове“ (като 2x2 клетки) и нормализиране на векторните характеристики на блока (използвайки L2-норма или L1-sqrt), за да се постигне устойчивост срещу локални вариации на осветлението, контраста и засенчването; и (4) конкатениране на нормализираните блокови вектори в окончателно едноизмерно представяне на характеристиките, исторически съчетано с линейни SVM (Support Vector Machine) за разпознаване на пешеходци и обекти. В сравнение с научените характеристики от CNN (Convolutional Neural Network), HOG има основни ограничения: Първо, HOG характеристиките са фиксирани и ръчно създадени, улавяйки само нисконивови статистики за ориентацията на локални ръбове без възможност да научават йерархични представяния, специфични за задачата (като текстури, части на обекти и семантични концепции). Второ, HOG предоставя много ограничена геометрична инвариантност: докато нормализацията на блока обработва монотонни промени в осветлението и малки пространствени измествания в клетките, HOG е неустойчив при 3D ротации извън равнината, значителни вариации в мащаба, неригидни артикулации на позата и силен фонов шум. За разлика от това, CNN научават многослойни нелинейни абстракции, оптимизирани от край до край за целевата задача.
8Как *stride*, *padding*, *dilation* и размерът на ядрото (*kernel size*) определят размера на изхода на конволюцията и рецептивното поле?
Пространствените изходни измерения на конволюционен слой и неговото кумулативно рецептивно поле се определят от размера на ядрото $k$, стъпката (*stride*) $s$, запълването (*padding*) $p$ и дилатацията (*dilation*) $d$:
1. **Изходен пространствен размер**: Дилатацията въвежда $(d - 1)$ празнини между елементите на ядрото, давайки ефективен размер на ядрото $k' = d(k - 1) + 1$. Изходното измерение по ос е дадено от:
$$O = \left\lfloor \frac{I + 2p - k'}{s} \right\rfloor + 1 = \left\lfloor \frac{I + 2p - d(k - 1) - 1}{s} \right\rfloor + 1$$
Тук стъпката (*stride*) намалява резолюцията, като премества ядрото с $s$ пиксела на стъпка, запълването (*padding*) добавя виртуални гранични пиксели за запазване или регулиране на пространствените измерения, а дилатацията (*dilation*) разширява отпечатъка на филтъра, без да добавя допълнителни параметри.
2. **Рецептивно поле (RF)**: Теоретичното рецептивно поле описва пространственото разпространение във входното изображение, което влияе на конкретна активация. При насложени слоеве, рецептивното поле $RF_l$ и кумулативната стъпка (*jump* $j_l$) се актуализират рекурсивно:
* Скок (*Jump*): $j_l = j_{l-1} \cdot s_l$, с $j_0 = 1$
* Рецептивно поле (*Receptive Field*): $RF_l = RF_{l-1} + (k'_l - 1) \cdot j_{l-1}$, с $RF_0 = 1$
Стъпките (*strides*) и обединяването (*pooling*) разширяват рецептивното поле мултипликативно по дълбочина, тъй като стъпките на ядрото на следващия слой съответстват на по-големи пикселни скокове в оригиналното входно координатно пространство. Дилатацията разширява рецептивното поле адитивно в рамките на един слой, като увеличава $k'_l$ без пространствено намаляване на мащаба (*downsampling*).
9Как конволюционното ядро съответства на класически линеен филтър за изображения и кога един 2D филтър може да бъде направен отделим?
В класическата линейна обработка на сигнали и изображения, конволюционното ядро представлява пространствения импулсен отклик (функция на разпространение на точката) на една LSI (Linear Shift-Invariant – линейна инвариантна спрямо изместване) система. Прилагането на ядрото е операция за линейно филтриране в пространствената област, която оформя честотния отклик на изображението (неговата 2D Фурие трансформация). Нискочестотните ядра (напр. Гаусово, кутия за размазване) отслабват високите пространствени честоти, за да потиснат шума и да изгладят текстурите, докато високочестотните или лентово-пропускащи ядра (напр. Sobel, Laplacian, Prewitt) усилват високите честоти, за да откриват ръбове и градиенти. Едно 2D филтърно ядро $K \in \mathbb{R}^{M \times N}$ е пространствено отделимо, ако може да бъде разложено на външно произведение на два 1D филтъра: $K = u \cdot v^T$, където $u \in \mathbb{R}^{M \times 1}$ и $v \in \mathbb{R}^{N \times 1}$. В терминологията на линейната алгебра, една 2D матрица е отделима тогава и само тогава, когато нейният ранг на матрицата е 1. Това може да бъде проверено чрез SVD (Singular Value Decomposition – декомпозиция по сингулярни стойности), където точно една сингулярна стойност е ненулева ($\sigma_1 > 0, \sigma_2 = \dots = 0$). Отделимостта значително намалява изчислителната сложност. Прилагането на неотделимо ядро $K \times K$ към изображение $H \times W$ изисква $O(H \cdot W \cdot K^2)$ умножения и събирания. Когато е разложено на две последователни 1D преминавания (хоризонтално, след това вертикално), сложността намалява до $O(H \cdot W \cdot 2K)$. За ядро $15 \times 15$, това осигурява приблизително $7.5\times$ ускорение.
Различните стратегии за преоразмеряване и изрязване променят разпределението на входните данни по отношение на геометрията, мащаба, покритието на съдържанието и пространствените граници: 1. **Директно преоразмеряване (разтягане/свиване):** Преоразмерява изображението неизотропно до целеви размери $(H, W)$, изкривявайки оригиналните съотношения на страните. Това принуждава модела да обработва деформирани форми на обекти (напр. кръгли обекти стават удължени елипси). 2. **Централно изрязване:** Извлича централен изрез с фиксиран размер или съотношение. То запазва естественото съотношение на страните и локалния мащаб, но въвежда силна централна пристрастност (ако се предполага, че целите са центрирани) и отхвърля периферния контекст или отрязва обекти, позиционирани по краищата. 3. **Случайно преоразмерявано изрязване (RRC - Random-Resized Cropping):** Извлича случайни подрегиони в различни мащаби на площ и съотношения на страните, след което ги преоразмерява до фиксирани размери. Това разширява разпределението на мащаба за обучение и насърчава обучението на характеристики, базирани на части, но екстремни изрязвания могат напълно да изключат целевия обект. 4. **Летербоксинг (Изотропно преоразмеряване с подплънки):** Мащабира изображението равномерно, докато най-дългото му измерение не отговаря на целевия размер, след което запълва останалите граници с постоянна стойност. Той поддържа истински пропорции на обектите и съотношения на страните, но въвежда изкуствени висококонтрастни граници и неинформативни пиксели с подплънки.
11Какви режими на шума в анотациите се срещат в набори от данни за компютърно зрение и как бихте ги открили или смекчили?
Наборите от данни за компютърно зрение обикновено проявяват четири основни режима на шума в анотациите:
1. **Шум в категорийните етикети (Categorical Label Noise):** Изображение или обект е присвоен към грешен клас етикет (напр. погрешно класифициране на котка като куче или объркване на фини, детайлни класове).
2. **Липсващи анотации (Шум от пропускане / Omission Noise):** Валидни обекти на преден план са оставени без анотация. При откриването на обекти пропуснатите цели се третират като негативи от фона, директно наказвайки правилните откривания от модела по време на обучение.
3. **Разклащане на ограничителната кутия / ключовите точки (Шум от локализация / Localization Noise):** Неточни, свободни или изместени координати на ограничителна кутия и местоположения на забележителни точки, причинени от непоследователност на човешкия анотатор.
4. **Неяснота на границата на маската (Mask Boundary Ambiguity):** Непоследователни или груби очертания на сегментацията по сложни или размити граници (напр. коса, полупрозрачни повърхности, размазване от движение).
**Стратегии за откриване и смекчаване:**
* **Проследяване на аномалии в загубата и уверено обучение (Loss Outlier Tracking & Confident Learning):** Проследяването на загубата на извадка през епохите на обучение идентифицира постоянни аномалии с висока загуба, които често показват грешно етикетирани или пропуснати инстанции. Алгоритми като Confident Learning оценяват разпределенията на шума, за да изчистят или коригират грешки.
* **Разлики в предсказанията извън сгъвката (Out-of-Fold (OOF) Prediction Discrepancies):** Обучението на модели за кръстосана валидация и сравняването на предсказанията от задържания набор с истинските данни (ground truth) подчертава грешно етикетирани изображения и липсващи ограничителни кутии.
* **Съгласие между анотатори (Inter-Annotator Agreement (IAA)) и арбитраж:** Измерването на метрики като Капа на Коен (за класификация) или средна Intersection-over-Union (IoU) (за локализация) между множество анотатори маркира извадки с ниско съгласие за консенсусен преглед.
* **Устойчиви формулировки на функцията на загуба:** Използването на изглаждане на етикети (label smoothing), толерантни към шум функции на загуба за класификация или устойчиви IoU-базирани функции на загуба за регресия намалява чувствителността към разклащане и грешно етикетиране.
import torch
import torch.nn.functional as F
def find_label_noise_candidates(model, dataloader, device, top_k=50):
model.eval()
sample_losses = []
with torch.no_grad():
for batch_idx, (images, targets, sample_ids) in enumerate(dataloader):
images, targets = images.to(device), targets.to(device)
logits = model(images)
loss_per_sample = F.cross_entropy(logits, targets, reduction='none')
for sid, l, target, pred in zip(sample_ids, loss_per_sample.cpu(), targets.cpu(), logits.argmax(dim=-1).cpu()):
sample_losses.append({'id': sid, 'loss': l.item(), 'target': target.item(), 'pred': pred.item()})
sample_losses.sort(key=lambda x: x['loss'], reverse=True)
return sample_losses[:top_k]
12Как класовият дисбаланс влияе на обучението за класификация на изображения, засичане и плътна прогноза?
Класовият дисбаланс засяга динамиката на оптимизацията и ландшафтите на функцията на загуба при задачи в компютърното зрение:
1. **Класификация на изображения:** Когато доминиращите класове превъзхождат малцинствените класове, емпиричното минимизиране на риска кара актуализациите на параметрите да бъдат доминирани от градиентите на доминиращите класове. Моделът научава емпиричната априорна вероятност на класа $P(Y)$ и измества своята разделителна граница срещу редките класове. Това води до висока обща Top-1 точност, като същевременно страда от сериозен срив на *recall* метриката за малцинствените класове.
2. **Засичане на обекти:**
* **Дисбаланс между преден план и фон:** При плътни еднофазни детектори, базирани на котви (anchor-based detectors), стотици хиляди кандидат-местоположения се оценяват за изображение, като над 99% са фон. Дори ако индивидуалните лесни фонови котви водят до малки загуби, техният огромен агрегиран градиент заглушава информативните градиентни сигнали от разредените обекти от предния план.
* **Класов дисбаланс на предния план:** Често срещаните категории обекти се появяват порядъци по-често от редките категории, намалявайки ефективния размер на извадката и учебния сигнал за редките класове.
3. **Плътна прогноза (Сегментация):** Дисбалансът на ниво пиксел е сериозен, тъй като големите класове фон и „общ фон“ (напр. път, небе) заемат милиони пиксели, докато малките класове „обекти“ (напр. пътни знаци, пешеходци) могат да заемат по-малко от 0,1% от пикселите на изображението. Стандартната крос-ентропийна загуба за всеки пиксел е доминирана от класовете с голяма площ, което води до под-сегментация или пълно изчезване на малки, тънки структури.
13Как бихте дебъгвали NaN (Not a Number) стойности или нестабилна загуба по време на мащабно разпределено обучение за компютърно зрение?
Дебъгването на NaN стойности или нестабилност на загубата при мащабно Разпределен паралелизъм на данните (DDP) обучение за компютърно зрение изисква изолиране на това дали коренната причина произлиза от лоши входни данни, числено препълване/подпълване при смесена точност (AMP - Automatic Mixed Precision) или нестабилност на оптимизацията между работниците. Първо, установете детерминизъм и защитни куки: активирайте откриване на аномалии (`torch.autograd.set_detect_anomaly(True)`), регистрирайте куки за градиенти/активации, за да уловите точния слой, където се появяват NaN, и добавете стриктна валидация на данните в DataLoader (утвърждаване на крайни стойности, проверка за повредени изображения с размер 0 байта, празни ограничителни кутии или нормализиращи делители с нулева дисперсия). Логването на ниво мини-пакет трябва да проследява загубата за всеки ранг, входни URI, норма на градиента преди отрязване и скалиращи фактори на GradScaler. Второ, инспектирайте автоматичната смесена точност (AMP) и динамичното мащабиране на загубата: в FP16, големите градиенти лесно препълват (`> 65504`), което кара скалерът на загубата да пропуска стъпки и многократно да намалява наполовина своя скалиращ фактор, докато скалата достигне нула; превключването на нестабилни операции (напр. softmax, LayerNorm, експоненти на focal loss или знаменатели на IoU за ограничителни кутии) към FP32 или приемането на BF16 (което съответства на динамичния обхват на FP32) обикновено стабилизира обучението. И накрая, проверете специфични за DDP клопки като операции all-reduce, разпространяващи NaNs от един работник към всички рангове, мащабиране на загряването на скоростта на обучение (напр. правило за линейно мащабиране с големи глобални размери на пакети) и отрязване на градиента.
import torch
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4)
for step, (images, targets, uris) in enumerate(dataloader):
# 1. Input sanitization
if not torch.isfinite(images).all():
print(f"Corrupt input detected from URIs: {uris}")
continue
optimizer.zero_grad(set_to_none=True)
with autocast(dtype=torch.float16):
outputs = model(images)
loss = criterion(outputs, targets)
if not torch.isfinite(loss):
print(f"NaN/Inf loss at step {step} on rank {torch.distributed.get_rank()}; skipping step.")
continue
scaler.scale(loss).backward()
# Unscale before clipping to inspect true gradient norms
scaler.unscale_(optimizer)
grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
if torch.isnan(grad_norm) or torch.isinf(grad_norm):
print(f"Warning: Grad norm is {grad_norm}. Scaler will adjust.")
scaler.step(optimizer)
scaler.update()
14Как бихте проектирали компонент за онлайн цифрова видео стабилизация за камера с трептене на кадъра?
Проектирането на тръбопровод за онлайн цифрова видео стабилизация за трептене на камера в реално време включва четири основни етапа: оценка на движението, изглаждане на движението, компенсация на движението (деформация) и обработка на границите.
1. **Оценка на движението между кадри:** Извличане на 2D разредени ключови точки в последователни кадри с помощта на бързи детектори на характеристики (напр. ORB, FAST или Shi-Tomasi ъгли) и изчисляване на съответствия с помощта на оптичен поток на Лукас-Канаде или съпоставяне на дескриптори на характеристики. Оценка на геометрична трансформация между кадри (като Афин или Хомографски модел) с помощта на RANSAC за отхвърляне на отклоняващи се съвпадения, причинени от независимо движещи се обекти на преден план.
2. **Натрупване на траектория на движението и онлайн изглаждане:** Интегриране на трансформациите от кадър до кадър във времето, за да се поддържа кумулативната траектория на камерата $P_t = P_{t-1} \cdot H_t$. Прилагане на онлайн филтър за изглаждане – като 1D/2D филтър на Калман или причинно движеща се средна с кратък прозорец – за отделяне на високочестотното нежелано трептене от нискочестотното преднамерено панорамиране на камерата.
3. **Компенсация и деформация на изображението:** Изчисляване на коригиращата трансформация $C_t = S_t \cdot P_t^{-1}$ (където $S_t$ е изгладената траектория) и деформиране на текущия кадър с помощта на билинейна/бикубична интерполация.
4. **Обработка на границите и ограничения на латентността:** Деформацията въвежда липсващи пиксели по ръбовете / черни граници; решаване на това чрез прилагане на фиксиран динамичен коефициент на изрязване (напр. 5-10% увеличение) с екстраполация на границите или адаптивен мащаб. В онлайн среда поддържайте минимално буфериране (1–3 предварителни кадъра), за да ограничите закъснението при обработката.
15Как бихте оптимизирали визуален поток в реално време, когато детекторът е по-бавен от целевата честота на кадрите?
Когато детекторът на обекти не може да поддържа целевата честота на кадрите (напр. работи с 15-20 FPS при видео подаване от 60 FPS), надеждната производствена архитектура разделя детектирането от цикъла на представяне в реално време, използвайки асинхронен многонишков тръбопровод, съчетаващ тежко детектиране с лек тракинг. В тази хибридна архитектура, нишка за поглъщане непрекъснато заснема видео кадри. Тежкият детектор работи асинхронно като „детектор на ключови кадри“ във фонова работна нишка. Междувременно лек тракер (като оптичен поток на Лукас-Канаде, ByteTrack/BoT-SORT или бърз корелационен филтър/филтър на Калман) работи синхронно за всеки кадър при пълни 60 FPS, поддържайки състоянието и идентичността на обекта, както и плавни траектории на ограничителната кутия. За да се справят със забавянето и обратното налягане, без да се въвежда неограничено закъснение или остарели кадри, се използват ограничени кръгови буфери и политики за отпадане на най-новия кадър. Когато детекторът приключи с кадър T_0 в момент T_curr, неговият изход е остарял. Тръбопроводът извършва пренареждане на координатите / обратна проекция: асоциира забавените резултати от детектиране с историческото състояние на трасирането в T_0, актуализира идентичностите и пропуснатите трасета и разпространява корекциите напред до T_curr чрез векторите на движение при проследяване или стъпките за предсказване на филтъра на Калман.
import queue
import threading
frame_queue = queue.Queue(maxsize=1) # Drop stale frames, keep latest
det_result_queue = queue.Queue()
def detector_worker():
while True:
frame, frame_id, timestamp = frame_queue.get()
boxes, scores, classes = heavy_detector.infer(frame)
det_result_queue.put({'frame_id': frame_id, 'boxes': boxes, 'timestamp': timestamp})
def realtime_pipeline(video_stream):
tracker = FastTracker() # e.g. Optical flow or Kalman tracker
for frame, frame_id, timestamp in video_stream:
if frame_queue.empty():
frame_queue.put((frame, frame_id, timestamp))
if not det_result_queue.empty():
det_result = det_result_queue.get()
tracker.reconcile_and_correct(det_result, current_frame_id=frame_id)
active_tracks = tracker.update(frame)
display_or_downstream(frame, active_tracks)