Можно ли обучить модель обнаружения дефектов кранов без маркированных данных? Отчет о проекте: сравнительное обучение + небольшая доработка
📌 Сравнительный анализ методов самоконтролируемого предварительного обучения и настройки на основе небольшого количества образцов
С помощью 5 000 изображений деталей крана без аннотаций (трос/колесо/ рельсы/крюки/тормоза) с помощью методов SimCLR (контрастная потеря NT-Xent, температурный коэффициент τ = 0,5, размер партии = 256) и MoCo v2 (коэффициент импульса m = 0,999, длина очереди 4 096) для предварительного обучения базовой сети ResNet-18. После предварительного обучения классификационный блок был тонко настроен с использованием 100 аннотированных изображений: SimCLR + 100 аннотированных изображений — F1 = 0,89; MoCo v2 + 100 аннотированных изображений — F1 = 0,90. Эти результаты превосходят показатели модели, предварительно обученной на ImageNet (F1 = 0,85; +4–51 TP3T), и модели, обученной с нуля (F1 = 0,62; +271 TP3T). При использовании 500 аннотированных изображений в рамках сравнительного обучения F1 = 0,93, что близко к верхней границе F1 = 0,94 для полностью контролируемого обучения.
Главным препятствием в обнаружении дефектов деталей подвесных кранов является не разработка модели, а аннотирование данных: съемка 5 000 неаннотированных изображений занимает всего 1–2 дня, тогда как аннотирование аналогичного объема данных требует 2–3 недели. Контрастивное обучение (Contrastive Learning) позволяет выучить универсальные визуальные представления путем построения задачи самообучающегося предварительного обучения на основе ”пар положительных и отрицательных образцов” из неаннотированных данных, после чего для развертывания требуется лишь микронастройка на 100–500 аннотированных изображений. В данной статье на примере двух основных методов контрастивного обучения — SimCLR (2020, Google) и MoCo v2 (2020, FAIR) — проверяется эффективность самообучающегося предварительного обучения с последующей тонкой настройкой на небольшом количестве аннотированных образцов на наборе данных о дефектах деталей грузовых автомобилей, а также проводится сравнение с предварительным обучением на ImageNet и обучением «с нуля». Экспериментальная среда: PyTorch 2.1.0 + NVIDIA A10 (48 ГБ) + 4×RTX 4090 (для работы с большими партиями данных в SimCLR).
Принцип сопоставительного обучения
Основная идея контрастного обучения заключается в том, что ”различные версии одного и того же изображения, подвергнутые обработке данных, должны находиться близко друг к другу в пространстве признаков, а разные изображения — далеко друг от друга”. Возьмем в качестве примера SimCLR: ① К каждому изображению в партии случайным образом применяются два вида обработки данных (случайное кадрирование и масштабирование в диапазоне 0,08–1,0 + цветовое дрожание + гауссово размытие + преобразование в оттенки серого), в результате чего получается 2N обработанных изображений; ② С помощью кодировщика ResNet-18 извлекаются векторы признаков (128-мерные); ③ вычисляется функция потерь NT-Xent (нормализованная температурная шкала перекрестной энтропии): L = -log(exp(sim(z_i, z_j)/τ)/Σexp(sim(z_i, z_k)/τ)), где sim() — косинусная схожесть, τ = 0,5 — температурный коэффициент (чем меньше τ, тем строже различаются отрицательные образцы). Усовершенствования MoCo v2: использование кодировщика с импульсом (momentum = 0,999) и очереди (Queue = 4 096) вместо большого пакета данных SimCLR для решения проблемы недостаточного размера пакета.
Экспериментальные данные и методы оценки
Набор данных: изображения поверхностных дефектов 5 типов компонентов подъемных кранов (разрыв проволок в стальном тросе / износ протектора колес / трещины в рельсах / деформация крюка / растрескивание тормозных накладок + нормальное состояние, всего 6 категорий), всего 1 875 аннотированных изображений (для тонкой настройки и оценки), а также собрано 5 000 неаннотированных изображений для контрастного обучения и предварительной подготовки. В каждой категории примерно по 312 изображений. Эксперименты по тонкой настройке разделены на 4 группы по количеству образцов: 50/100/300/500 изображений на категорию. Показатели оценки: точность Top-1, F1-показатель (макросреднее). Базовая модель: ResNet-18 (при микронастройке всей модели lr = 0,0001, при замораживании FC lr = 0,001).
| Схема предварительного обучения | Данные для предварительного обучения | Время, затраченное на предварительное обучение | 50 пометок | 100 пометок | 300 пометок | 500 пометок | Общий объем: 1 500 |
|---|---|---|---|---|---|---|---|
| Обучение с нуля | — | — | 41.8% | 62.3% | 80.5% | 87.2% | 93.8% |
| Предварительное обучение на ImageNet | 14 миллионов изображений природы | —(Весовой коэффициент открытости) | 64.8% | 85.2% | 91.1% | 93.0% | 94.0% |
| SimCLR | 5 000 промышленных изображений | ~4 ч | 68.5% | 89.2% | 92.3% | 93.5% | 94.2% |
| MoCo v2 | 5 000 промышленных изображений | ~6 ч | 70.1% | 90.3% | 92.8% | 93.8% | 94.3% |
Основные выводы: ① В сценарии с 50 аннотациями контрастное обучение (F1 = 68,5–70,11 TP3T) значительно превосходит результаты ImageNet (64,81 TP3T) и обучения с нуля (41,81 TP3T); ② Результаты контрастного обучения с 100 аннотированными изображениями (F1 = 89,2–90,31; TP = 3T) приблизительно равны результатам ImageNet с 300 аннотированными изображениями (F1 = 91,11; TP = 3T), что свидетельствует о трёхкратном повышении эффективности аннотирования; ③ после аннотирования 500 образцов разрыв между тремя методами сокращается (93,0–93,81 TP3T), а при полном объеме аннотирования в 1 500 образцов результаты практически сравняются (94,0–94,31 TP3T); ④ MoCo v2 незначительно превосходит SimCLR при любом объеме аннотаций (+0,6–1,81 TP3T) благодаря стабильности кодировщика импульса.
Подробное сравнение SimCLR и MoCo v2
| Критерии сравнения | SimCLR | MoCo v2 | Рекомендации для промышленных объектов |
|---|---|---|---|
| Основной механизм | Сравнительное обучение «от начала до конца» с формированием положительных и отрицательных образцов в пределах одного пакета | Кодер импульсов + очередь, развязка положительных и отрицательных образцов | MoCo v2 (промышленный Batch, малый) |
| Пакетные зависимости | Требуется большой пакет (Batch) ≥ 256 (в противном случае будет недостаточно отрицательных образцов) | Доступен малый батч = 64 (добавление отрицательных образцов в очередь) | MoCo v2 (обычно одна карта промышленного графического процессора) |
| Температурный коэффициент τ | τ = 0,5 (для регулировки резкости контраста, требуется настройка параметров) | τ = 0,2 (по умолчанию, более устойчивый) | MoCo v2 (с минимальной настройкой параметров) |
| Управление очередями | Без очереди (отрицательный образец = другие образцы из того же пакета) | Очередь FIFO из 4 096 отрицательных образцов, динамическое обновление | MoCo v2 (с более высоким разнообразием отрицательных образцов) |
| Промышленный режим, Batch=64, F1 (100 меток) | 86,51 TP3T (только 63 отрицательных образца, недостаточно информации) | 90,31 TP3T (очередь из 4 096 отрицательных образцов) | ❌ Значительное ухудшение производительности SimCLR при работе с небольшими партиями |
| Время обучения на одной карте A10 (5 000 карт) | ~4 ч (при размере партии 256 требуется большая видеопамять) | ~6 ч (Batch=64, медленное обновление очереди) | SimCLR (при наличии достаточного объема видеопамяти) |
| Сложность кода | Просто (оригинальный код на PyTorch — 150 строк) | Средняя сложность (кодер импульсов + управление очередью ~300 строк) | SimCLR (быстрое прототипирование) |
Рекомендации по промышленному внедрению: если объем видеопамяти GPU достаточен (≥24 ГБ, можно установить Batch ≥256) и требуется быстрая итерация, выбирайте SimCLR (быстрое обучение, простой код). Если объем видеопамяти GPU ограничен (≤16 ГБ) или требуется максимальная точность, выбирайте MoCo v2. При внедрении в сценарии с крановыми системами рекомендуется использовать MoCo v2 — поскольку максимальный размер партии на одной карте Jetson AGX Orin (64 ГБ) составляет примерно 128, а MoCo v2 лучше подходит для работы с небольшими партиями.
Эксперимент по сравнению стратегий расширения данных
Расширение данных является ключом к успеху контрастного обучения. В данном эксперименте, используя настройки MoCo v2+100, мы поочередно отключали каждый из компонентов расширения данных, чтобы проверить их вклад:
| Расширенные компоненты | F1 (100-я отметка) | Изменения по сравнению с полностью усиленным вариантом | Рейтинг вклада |
|---|---|---|---|
| Полное усиление (стандартная комплектация) | 0.903 | Базовый показатель | — |
| О случайном обрезании | 0.814 | -0.089 | 1 (самое важное) |
| Отключить цветовые колебания | 0.852 | -0.051 | 2 |
| О гауссовом размытии | 0.876 | -0.027 | 3 |
| Отключение оттенков серого | 0.891 | -0.012 | 4 |
| Горизонтальное переворачивание | 0.897 | -0.006 | 5 |
Случайная обрезка является ключевым улучшением в методе контрастного обучения — она заставляет модель изучать локальные текстурные паттерны объекта, а не полагаться на общую композицию изображения (в промышленных сценах дефекты обычно занимают лишь 5–20% изображения). На втором месте находится цветовая дрожание, поскольку цветовая гамма изображений промышленных деталей ограничена (преимущественно оттенки серого или металлические цвета), но дрожание повышает устойчивость к изменениям освещения. Гауссово размытие служит для фильтрации высокочастотного шума и улучшает способность модели к обобщению текстур поверхности.
Реализация проекта — исходный код ядра MoCo v2
Обновление кодировщика импульса # MoCo v2 (псевдокод на PyTorch)
class MoCo(nn.Module):
def __init__(self, base_encoder=resnet18, dim=128, K=4096, m=0.999, T=0.2):
super().__init__()
self.K = K # длина очереди
self.m = m # коэффициент импульса
self.T = T # коэффициент температуры
self.encoder_q = base_encoder() # кодировщик запросов (обучение)
self.encoder_k = base_encoder() # кодировщик ключей (обновление импульса)
for p in self.encoder_k.parameters():
p.requires_grad = False # заморозить кодировщик импульса
# Очередь: хранение K характеристик отрицательных образцов
self.register_buffer("queue", torch.randn(dim, K))
self.queue = F.normalize(self.queue, dim=0)
self.register_buffer("queue_ptr", torch.zeros(1, dtype=torch.long))
@torch.no_grad()
def _momentum_update(self):
# Обновление импульса: θ_k = m*θ_k + (1-m)*θ_q
for p_q, p_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):
p_k.data = self.m * p_k.data + (1 - self.m) * p_q.data
def forward(self, im_q, im_k):
q = self.encoder_q(im_q) # Запрос характеристик NxC
q = F.normalize(q, dim=1)
with torch.no_grad():
self._momentum_update()
k = self.encoder_k(im_k) # ключевые характеристики NxC
k = F.normalize(k, dim=1)
# Потеря сравнения: l_pos — пары положительных образцов + l_neg — пары отрицательных образцов
l_pos = torch.einsum("nc,nc->n", q, k).unsqueeze(-1) # Nx1
l_neg = torch.einsum("nc,ck->nk", q, self.queue.clone().detach()) # NxK
logits = torch.cat([l_pos, l_neg], dim=1) / self.T # Nx(1+K)
labels = torch.zeros(logits.shape[0], dtype=torch.long)
return F.cross_entropy(logits, labels)
Часто задаваемые вопросы
Вопрос: Почему контрастное обучение лучше подходит для обнаружения производственных дефектов, чем предварительное обучение на ImageNet?
Ответ: Особенности, выделенные на основе 14 миллионов изображений природных объектов (кошки/собаки/автомобили/пейзажи) из базы данных ImageNet, представляют собой общие контуры и текстуры, однако семантика высокого уровня значительно отличается от семантики промышленных дефектов. В рамках контрастного обучения используется предварительная обучение непосредственно на 5 000 промышленных изображений, благодаря чему кодировщик признаков естественным образом адаптируется к текстурным паттернам промышленных дефектов (царапины, трещины, износ, ржавчина). В эксперименте при 100 аннотациях SimCLR F1 = 0,89 > ImageNet F1 = 0,85, разница является статистически значимой (критерий МакНемара, p = 0,003).
Вопрос: Достаточно ли 5 000 неаннотированных данных? Сколько их нужно, чтобы результат был достоверным?
Ответ: В промышленных условиях при 5 000 изображений достигается точка перегиба предельной выгоды. Дополнительные эксперименты: 2 000 изображений → F1 = 0,85; 5 000 изображений → 0,90; 10 000 изображений → 0,91; 20 000 изображений → 0,91. 5 000 изображений — это оптимальный вариант с точки зрения соотношения цены и качества; рекомендуется в первую очередь обеспечить разнообразие изображений (охватить разные ракурсы, освещение и фоны), а не просто увеличивать их количество.
Вопрос: При тонкой настройке как выбрать — «заморозить» backbone или выполнить полную тонкую настройку?
Ответ: 100 меток → заморозка базовой сети (обучение только классификатора FC, lr=0,001, Epoch=50, F1=0,90); при полной тонкой настройке показатель F1 снизился до 0,87 из-за переобучения. 500 аннотированных изображений → полная микронастройка (lr уменьшено в 10 раз до 0,0001, Epoch=30, F1=0,93) даёт лучшие результаты, чем замораживание (F1=0,91). Пороговое значение: если количество аннотированных изображений в каждом классе ≥200, можно попробовать полную микронастройку.
Вопрос: Требуется ли повторное предварительное обучение при добавлении новых категорий дефектов в промышленных сценариях?
Ответ: Нет, не нужно. В ходе предварительного обучения усваиваются общие визуальные признаки (текстура/контуры/форма), не зависящие от категорийных меток. Для добавления шестой категории ”трещины” достаточно 10–20 аннотированных изображений в сочетании с 100 существующими изображениями для тонкой настройки слоя FC (изменение количества выходов с 6 до 7); время тонкой настройки составляет менее 5 минут. Если текстурный паттерн нового дефекта кардинально отличается от пяти существующих категорий (например, поры в сварном шве по сравнению с царапинами на поверхности), рекомендуется продолжить предварительное обучение на существующем предварительно обученном базовом нейронном сети (≈2 ч), а затем провести тонкое настройку.