Пуста полиця в ритейлі — втрата 15% продажів категорії. Ручна перевірка планограм раз на тиждень запізнюється: порушення фіксується через 7 днів, коли втрачена виручка вже невідновна. Втрати від невідповідності можуть сягати значних сум на мережу з 50 магазинів. Ми впроваджуємо CV-системи на основі YOLOv8 і CLIP, які детектують порушення за хвилини після зйомки. Система обробляє фото з будь-яких IP-камер роздільною здатністю від 1080p і видає звіт із зазначенням кожного невідповідності. AI-система виявляє порушення в 4 рази швидше ручної перевірки, при цьому точність детекції сягає 95% проти 80% у людини.
Затримка в кілька днів перетворюється на мільйонні збитки, особливо в категоріях з високим оборотом. Автоматизація контролю полиць за допомогою AI — це не просто заміна ручної праці, а новий рівень точності та швидкості реакції. Наші клієнти після впровадження фіксують зниження out-of-stock на 30% та суттєву економію на мережу з 20 магазинів. Гарантуємо mAP детектора не нижче 0.92 на ваших даних.
Проблеми, які вирішує AI-контроль планограм
- Затримка реакції: від порушення до фіксації проходить 7 днів — за цей час втрачаються продажі. AI-система видає звіт одразу після зйомки.
- Людська помилка: мерчандайзер пропускає до 20% невідповідностей, особливо при великому асортименті. Детектор знаходить >95% порушень.
- Складність масштабування: ручна перевірка сотень магазинів потребує штату. AI-система обробляє 10 000+ фото на день без додаткових ресурсів.
Як YOLOv8 і CLIP детектують порушення?
Основний пайплайн складається з трьох кроків: детекція продуктів на полиці → ідентифікація кожного продукту → порівняння з еталонною планограмою.
from ultralytics import YOLO
import numpy as np
from PIL import Image
import torch
import torch.nn.functional as F
class PlanogramComplianceChecker:
"""
Крок 1: YOLOv8 детектує всі товари на полиці (bbox + клас)
Крок 2: CLIP/ViT ідентифікує конкретний SKU по cropу
Крок 3: Порівняння з планограмою
"""
def __init__(
self,
detector_path: str, # fine-tuned YOLO на полицях
sku_embeddings_path: str, # CLIP embeddings всіх SKU
planogram: dict # {position: sku_id}
):
self.detector = YOLO(detector_path)
sku_data = np.load(sku_embeddings_path)
self.sku_embeddings = torch.from_numpy(
sku_data['embeddings']
).float() # (N_SKU, embedding_dim)
self.sku_ids = sku_data['sku_ids'].tolist()
self.planogram = planogram
# CLIP для ідентифікації SKU
from transformers import CLIPProcessor, CLIPModel
self.clip_model = CLIPModel.from_pretrained(
'openai/clip-vit-large-patch14'
).eval().cuda()
self.clip_processor = CLIPProcessor.from_pretrained(
'openai/clip-vit-large-patch14'
)
def analyze_shelf(
self,
shelf_image: Image.Image,
confidence_threshold: float = 0.5
) -> dict:
img_array = np.array(shelf_image)
# Крок 1: детекція
detections = self.detector.predict(
img_array, conf=confidence_threshold, verbose=False
)[0]
shelf_products = []
for box in detections.boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
crop = shelf_image.crop((x1, y1, x2, y2))
# Крок 2: ідентифікація SKU через CLIP
sku_id, similarity = self._identify_sku(crop)
shelf_products.append({
'bbox': [x1, y1, x2, y2],
'sku_id': sku_id,
'confidence': float(box.conf),
'sku_similarity': float(similarity),
'position': self._get_shelf_position(
[x1, y1, x2, y2], img_array.shape
)
})
# Крок 3: порівняння з планограмою
compliance = self._check_compliance(shelf_products)
return compliance
@torch.no_grad()
def _identify_sku(
self, crop: Image.Image
) -> tuple[str, float]:
inputs = self.clip_processor(
images=crop, return_tensors='pt'
).to('cuda')
features = self.clip_model.get_image_features(**inputs)
features = F.normalize(features, dim=-1).cpu()
# Cosine similarity зі всіма SKU embeddings
similarities = (features @ self.sku_embeddings.T).squeeze()
best_idx = similarities.argmax().item()
return self.sku_ids[best_idx], float(similarities[best_idx])
def _get_shelf_position(
self, bbox: list, img_shape: tuple
) -> dict:
"""Горизонтальна позиція + ряд полиці"""
h, w = img_shape[:2]
cx = (bbox[0] + bbox[2]) / 2
cy = (bbox[1] + bbox[3]) / 2
return {
'col': int(cx / w * 10), # 0-9 — десять колонок
'row': int(cy / h * 5) # 0-4 — п'ять рядів
}
def _check_compliance(self, shelf_products: list) -> dict:
violations = []
actual_positions = {
f"{p['position']['row']}_{p['position']['col']}": p['sku_id']
for p in shelf_products
}
for position_key, expected_sku in self.planogram.items():
actual_sku = actual_positions.get(position_key)
if actual_sku is None:
violations.append({
'type': 'out_of_stock',
'position': position_key,
'expected_sku': expected_sku
})
elif actual_sku != expected_sku:
violations.append({
'type': 'wrong_product',
'position': position_key,
'expected_sku': expected_sku,
'actual_sku': actual_sku
})
compliance_score = 1.0 - len(violations) / max(len(self.planogram), 1)
return {
'compliance_score': round(compliance_score, 3),
'violations': violations,
'total_positions': len(self.planogram),
'violations_count': len(violations),
'detected_products': len(shelf_products)
}
Переваги CLIP перед класифікатором
Класифікатор потребує ретрайну при кожному додаванні товару. CLIP працює на embedding-схожості: додали фото нового SKU в індекс — система готова. Це знижує витрати на підтримку при асортименті >500 одиниць. За даними дослідження ECR Retail, автоматизація контролю полиць скорочує out-of-stock на 30%.
Роль MLOps у ритейлі
MLOps забезпечує безперервне оновлення моделей при зміні асортименту. Ми використовуємо Kubeflow для оркестрації пайплайнів і MLflow для відстеження експериментів. Це дозволяє автоматично переучувати детектор і перебудовувати CLIP-індекс без участі розробника. Без MLOps кожне додавання нового SKU потребувало б ручного ретрайну — при асортименті в 2000+ одиниць це стає вузьким місцем.
Як швидко окупається впровадження AI-контролю?
Типовий проект окупається за 6–8 місяців за рахунок скорочення out-of-stock і зменшення ручної праці. Для мережі з 50 магазинів пряма економія може бути суттєвою. Додатковий ефект — підвищення лояльності покупців через постійну наявність товарів. AI-система в 4 рази швидше виявляє порушення порівняно з ручною перевіркою.
Етапи впровадження AI-системи
- Аудит схеми контролю та збір даних — аналіз поточних процесів, зйомка полиць (не менше 2000 зображень).
- Fine-tuning YOLOv8 — розмітка зображень, навчання детектора товарів до mAP ≥0.92.
- Побудова CLIP-індексу SKU — збір фотографій товарів, генерація embeddings.
- Розробка пайплайну порівняння з планограмою — реалізація логіки детекції порушень.
- Інтеграція з ERP — REST API для автоматичного вивантаження звітів.
- Тестування та навчання команди — 2 дні on-site + запис вебінарів.
- Супровід — 3 місяці підтримки, донавчання при зміні асортименту.
Індексація SKU через CLIP embeddings
from transformers import CLIPProcessor, CLIPModel
import torch
import numpy as np
from pathlib import Path
def build_sku_index(
product_images_dir: str, # директорія: {sku_id}/{image1.jpg, ...}
output_path: str,
model_name: str = 'openai/clip-vit-large-patch14',
images_per_sku: int = 5 # усереднюємо embedding по кількох фото
) -> None:
"""
Будуємо CLIP-індекс всіх SKU.
Кілька фото на товар → усереднений embedding стабільніший.
"""
model = CLIPModel.from_pretrained(model_name).eval().cuda()
processor = CLIPProcessor.from_pretrained(model_name)
sku_embeddings = []
sku_ids = []
for sku_dir in sorted(Path(product_images_dir).iterdir()):
if not sku_dir.is_dir():
continue
sku_id = sku_dir.name
image_files = list(sku_dir.glob('*.{jpg,jpeg,png}'))[:images_per_sku]
if not image_files:
continue
batch_embeddings = []
for img_path in image_files:
image = Image.open(img_path).convert('RGB')
inputs = processor(images=image, return_tensors='pt').to('cuda')
with torch.no_grad():
emb = model.get_image_features(**inputs)
emb = F.normalize(emb, dim=-1).cpu().numpy()
batch_embeddings.append(emb)
mean_emb = np.mean(batch_embeddings, axis=0)
mean_emb = mean_emb / np.linalg.norm(mean_emb)
sku_embeddings.append(mean_emb.squeeze())
sku_ids.append(sku_id)
np.savez(
output_path,
embeddings=np.array(sku_embeddings),
sku_ids=np.array(sku_ids)
)
print(f'Indexed {len(sku_ids)} SKUs')
Що входить в роботу?
- Документація: опис архітектури, специфікація API, інструкція з експлуатації.
- Fine-tuning детектора YOLOv8 на ваших полицях (збір і розмітка ~2000 зображень).
- Побудова CLIP-індексу SKU за каталогом товарів.
- Інтеграція з ERP (1С, SAP, Oracle) через REST API — автоматичне вивантаження звітів.
- Навчання команди: 2 дні on-site + запис вебінарів.
- Технічна підтримка: 3 місяці після здачі — виправлення багів, донавчання при зміні асортименту.
Строки
| Задача | Строк |
|---|---|
| Детектор продуктів на полиці (fine-tuning YOLO) | 3–5 тижнів |
| Повна система (детекція + ідентифікація + планограма) | 7–12 тижнів |
| Інтеграція з ERP / мобільний застосунок для мерчандайзерів | 10–16 тижнів |
Порівняння підходів: AI vs ручна перевірка
| Критерій | Ручна перевірка | AI-система |
|---|---|---|
| Час реакції на порушення | до 7 днів | хвилини (після фото) |
| Пропуск порушень | 15–20% | <5% |
| Масштабування на 100 магазинів | 10+ мерчандайзерів | без збільшення штату |
Впровадження AI-системи окупається за 6–8 місяців за рахунок скорочення out-of-stock і зменшення ручної праці. Зв'яжіться з нами для пілотного проекту — ми безкоштовно проаналізуємо вашу поточну схему та назвемо строки. Отримайте консультацію щодо впровадження AI-контролю планограм вже сьогодні. Додаткову інформацію про комп'ютерний зір можна знайти у відповідній статті.







