Der Weg zur Optimierung der Bildsuche im Milliardenmaßstab (2/2)
Dieser Artikel ist der zweite Teil von The Journey to Optimizing Billion-scale Image Search by UPYUN. Wenn Sie den ersten verpasst haben, klicken Sie hier.
Das Search-by-Image-System der zweiten Generation
Das Search-by-Image-System der zweiten Generation entscheidet sich technisch für die Lösung CNN + Milvus. Das System basiert auf Feature-Vektoren und bietet eine bessere technische Unterstützung.
Feature-Extraktion
Im Bereich Computer Vision ist der Einsatz künstlicher Intelligenz zum Mainstream geworden. Ebenso nutzt die Feature-Extraktion des Search-by-Image-Systems der zweiten Generation Convolutional Neural Network (CNN) als zugrunde liegende Technologie
Der Begriff CNN ist schwer zu verstehen. Hier konzentrieren wir uns darauf, zwei Fragen zu beantworten:
- Was kann CNN leisten?
- Warum kann ich CNN für eine Bildsuche verwenden?
Foto von memegenerator.net
Es gibt viele Wettbewerbe im KI-Bereich, und die Bildklassifizierung ist einer der wichtigsten. Die Aufgabe der Bildklassifizierung besteht darin zu bestimmen, ob der Inhalt des Bildes eine Katze, einen Hund, einen Apfel, eine Birne oder andere Arten von Objekten zeigt.
Was kann CNN leisten? Es kann Features extrahieren und Objekte erkennen. Es extrahiert Features aus mehreren Dimensionen und misst, wie nah die Features eines Bildes an den Features von Katzen oder Hunden liegen. Wir können die nächstliegenden als unser Identifikationsergebnis auswählen, das angibt, ob der Inhalt eines bestimmten Bildes eine Katze, einen Hund oder etwas anderes zeigt.
Was ist die Verbindung zwischen der Objektidentifikationsfunktion von CNN und der Suche per Bild? Was wir wollen, ist nicht das endgültige Identifikationsergebnis, sondern der aus mehreren Dimensionen extrahierte Feature-Vektor. Die Feature-Vektoren zweier Bilder mit ähnlichem Inhalt müssen nahe beieinander liegen.
Welches CNN-Modell sollte ich verwenden?
Die Antwort ist VGG16. Warum sollte man es wählen? Erstens verfügt VGG16 über eine gute Generalisierungsfähigkeit, das heißt, es ist sehr vielseitig. Zweitens haben die von VGG16 extrahierten Feature-Vektoren 512 Dimensionen. Wenn es sehr wenige Dimensionen gibt, kann die Genauigkeit beeinträchtigt werden. Wenn es zu viele Dimensionen gibt, sind die Kosten für Speicherung und Berechnung dieser Feature-Vektoren relativ hoch.
CNN zur Extraktion von Bild-Features zu verwenden, ist eine Mainstream-Lösung. Wir können VGG16 als Modell und Keras + TensorFlow für die technische Implementierung verwenden. Hier ist das offizielle Beispiel von Keras:
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np
model = VGG16(weights=’imagenet’, include_top=False)
img_path = ‘elephant.jpg’
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
features = model.predict(x)
Die hier extrahierten Features sind Feature-Vektoren.
1. Normalisierung
Um nachfolgende Operationen zu erleichtern, normalisieren wir Features häufig:
Was anschließend verwendet wird, ist ebenfalls das normalisierte norm_feat.
2. Bildbeschreibung
Das Bild wird mit der Methode image.load_img von keras.preprocessing geladen:
from keras.preprocessing import image
img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
Tatsächlich handelt es sich um die TensorFlow-Methode, die von Keras aufgerufen wird. Details finden Sie in der TensorFlow-Dokumentation. Das endgültige Bildobjekt ist tatsächlich eine PIL-Image-Instanz (das von TensorFlow verwendete PIL).
3. Bytes-Konvertierung
In der Praxis werden Bildinhalte häufig über das Netzwerk übertragen. Daher ziehen wir es vor, anstatt Bilder aus einem Pfad zu laden, Bytes-Daten direkt in Bildobjekte zu konvertieren, das heißt in PIL Images:
import io
from PIL import Image
# img_bytes: 图片内容 bytes
img = Image.open(io.BytesIO(img_bytes))
img = img.convert('RGB')
img = img.resize((224, 224), Image.NEAREST)
Das obige img ist dasselbe wie das Ergebnis, das mit der Methode image.load_img erhalten wird. Es gibt zwei Dinge, auf die zu achten ist:
- Sie müssen eine RGB-Konvertierung durchführen.
- Sie müssen die Größe ändern (resize ist der zweite Parameter der
load_img method).
4. Verarbeitung schwarzer Ränder
Bilder, wie etwa Screenshots, können gelegentlich ziemlich viele schwarze Ränder haben. Diese schwarzen Ränder haben keinen praktischen Wert und verursachen viel Störung. Aus diesem Grund ist das Entfernen schwarzer Ränder ebenfalls eine gängige Praxis.
Ein schwarzer Rand ist im Wesentlichen eine Zeile oder Spalte von Pixeln, bei der alle Pixel (0, 0, 0) sind (RGB-Bild). Den schwarzen Rand zu entfernen bedeutet, diese Zeilen oder Spalten zu finden und sie zu löschen. Dies ist tatsächlich eine 3-D-Matrixmultiplikation in NumPy.
Ein Beispiel zum Entfernen horizontaler schwarzer Ränder:
# -*- coding: utf-8 -*-
import numpy as np
from keras.preprocessing import image
def RemoveBlackEdge(img):
Args:
img: PIL image instance
Returns:
PIL image instance
"""
width = img.width
img = image.img_to_array(img)
img_without_black = img[~np.all(img == np.zeros((1, width, 3), np.uint8), axis=(1, 2))]
img = image.array_to_img(img_without_black)
return img
Das ist so ziemlich das, worüber ich sprechen wollte, wenn es darum geht, CNN zur Extraktion von Bildmerkmalen und zur Implementierung anderer Bildverarbeitung zu verwenden. Sehen wir uns nun Vektorsuchmaschinen an.
Vektorsuchmaschine
Das Problem der Extraktion von Merkmalsvektoren aus Bildern wurde gelöst. Die verbleibenden Probleme sind dann:
- Wie speichert man Merkmalsvektoren?
- Wie berechnet man die Ähnlichkeit von Merkmalsvektoren, das heißt, wie sucht man? Die Open-Source-Vektorsuchmaschine Milvus kann diese beiden Probleme lösen. Bis jetzt läuft sie in unserer Produktionsumgebung gut.
Milvus-Logo.
Milvus, die Vektorsuchmaschine
Die Extraktion von Merkmalsvektoren aus einem Bild ist bei weitem nicht genug. Wir müssen diese Merkmalsvektoren auch dynamisch verwalten (Hinzufügen, Löschen und Aktualisieren), die Ähnlichkeit der Vektoren berechnen und die Vektordaten im Bereich der nächsten Nachbarn zurückgeben. Die Open-Source-Vektorsuchmaschine Milvus erledigt diese Aufgaben ziemlich gut.
Der Rest dieses Artikels beschreibt konkrete Praktiken und zu beachtende Punkte.
1. Anforderungen an die CPU
Um Milvus zu verwenden, muss Ihre CPU den avx2-Befehlssatz unterstützen. Verwenden Sie bei Linux-Systemen den folgenden Befehl, um zu prüfen, welche Befehlssätze Ihre CPU unterstützt:
cat /proc/cpuinfo | grep flags</code?
Dann erhalten Sie etwa Folgendes:
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti intel_ppin tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc dtherm ida arat pln pts
Was auf flags folgt, sind die Befehlssätze, die Ihre CPU unterstützt. Natürlich sind das viel mehr, als ich brauche. Ich möchte nur sehen, ob ein bestimmter Befehlssatz, wie etwa avx2, unterstützt wird. Fügen Sie einfach ein grep hinzu, um danach zu filtern:
cat /proc/cpuinfo | grep flags | grep avx2
Wenn kein Ergebnis zurückgegeben wird, bedeutet das, dass dieser bestimmte Befehlssatz nicht unterstützt wird. Dann müssen Sie Ihre Maschine wechseln.
2. Kapazitätsplanung
Die Kapazitätsplanung ist unsere erste Überlegung, wenn wir ein System entwerfen. Wie viele Daten müssen wir speichern? Wie viel Arbeitsspeicher und Speicherplatz benötigt die Datenmenge?
Machen wir ein paar schnelle Berechnungen. Jede Dimension eines Vektors ist float32. Ein float32-Typ nimmt 4 Bytes ein. Dann benötigt ein Vektor mit 512 Dimensionen 2 KB Speicher. Nach demselben Prinzip:
- Eintausend 512-dimensionale Vektoren benötigen 2 MB Speicherplatz.
- Eine Million 512-dimensionale Vektoren benötigen 2 GB Speicherplatz.
- 10 Millionen 512-dimensionale Vektoren benötigen 20 GB Speicherplatz.
- 100 Millionen 512-dimensionale Vektoren benötigen 200 GB Speicherplatz.
- Eine Milliarde 512-dimensionale Vektoren benötigen 2 TB Speicherplatz.
Wenn wir alle Daten im Arbeitsspeicher speichern möchten, benötigt das System mindestens die entsprechende Speicherkapazität.
Es wird empfohlen, das offizielle Tool zur Größenberechnung zu verwenden: Milvus sizing tool.
Tatsächlich ist unser Arbeitsspeicher möglicherweise nicht so groß. (Es spielt eigentlich keine Rolle, wenn Sie nicht genügend Arbeitsspeicher haben. Milvus schreibt Daten automatisch auf die Festplatte.) Zusätzlich zu den ursprünglichen Vektordaten müssen wir auch die Speicherung anderer Daten wie Protokolle berücksichtigen.
3. Systemkonfiguration
Weitere Informationen zur Systemkonfiguration finden Sie in der Milvus-Dokumentation:
- Milvus-Serverkonfiguration: https://milvus.io/docs/v0.10.1/milvus_config.md
4. Datenbankdesign
Collection & Partition
- Collection ist auch als Tabelle bekannt.
- Partition bezieht sich auf die Partitionen innerhalb einer Collection.
Die zugrunde liegende Implementierung einer Partition ist tatsächlich dieselbe wie die einer Collection, außer dass eine Partition einer Collection untergeordnet ist. Mit Partitionen wird die Organisation der Daten jedoch flexibler. Wir können auch eine bestimmte Partition in einer Collection abfragen, um bessere Abfrageergebnisse zu erzielen.
Wie viele Collections und Partitionen können wir haben? Die grundlegenden Informationen zu Collection und Partition befinden sich in den Metadaten. Milvus verwendet entweder SQLite (interne Integration von Milvus) oder MySQL (erfordert eine externe Verbindung) für die interne Metadatenverwaltung. Wenn Sie standardmäßig SQLite zur Verwaltung der Metadaten verwenden, erleiden Sie erhebliche Leistungseinbußen, wenn die Anzahl der Collections und Partitionen zu groß ist. Daher sollte die Gesamtzahl der Collections und Partitionen 50.000 nicht überschreiten (Milvus 0.8.0 begrenzt diese Zahl auf 4.096). Wenn Sie eine größere Anzahl festlegen müssen, wird empfohlen, MySQL über eine externe Verbindung zu verwenden.
Die von Milvus’ Collection und Partition unterstützte Datenstruktur ist sehr einfach, nämlich ID + vector. Mit anderen Worten, es gibt nur zwei Spalten in der Tabelle: ID und Vektordaten.
Hinweis:
- ID sollte aus Ganzzahlen bestehen.
- Wir müssen sicherstellen, dass die ID innerhalb einer Collection eindeutig ist, nicht innerhalb einer Partition.
Bedingte Filterung
Wenn wir traditionelle Datenbanken verwenden, können wir Feldwerte als Filterbedingungen angeben. Obwohl Milvus nicht exakt auf dieselbe Weise filtert, können wir mithilfe von Collections und Partitionen eine einfache bedingte Filterung implementieren. Zum Beispiel haben wir eine große Menge an Bilddaten, und die Daten gehören bestimmten Benutzern. Dann können wir die Daten nach Benutzer in Partitionen aufteilen. Daher bedeutet die Verwendung des Benutzers als Filterbedingung tatsächlich, die Partition anzugeben.
Strukturierte Daten und Vektormapping
Milvus unterstützt nur die Datenstruktur ID + Vektor. In Geschäftsszenarien benötigen wir jedoch strukturierte Daten mit geschäftlicher Bedeutung. Mit anderen Worten, wir müssen strukturierte Daten über Vektoren finden. Dementsprechend müssen wir die Mapping-Beziehungen zwischen strukturierten Daten und Vektoren über die ID pflegen.
strukturierte Daten-ID <--> Mapping-Tabelle <--> Milvus-ID
Index auswählen
Sie können die folgenden Artikel heranziehen:
- Indextypen: https://www.milvus.io/docs/v0.10.1/index.md
- So wählen Sie einen Index aus: https://medium.com/@milvusio/how-to-choose-an-index-in-milvus-4f3d15259212
5. Verarbeitung von Suchergebnissen
Die Suchergebnisse von Milvus sind eine Sammlung aus ID + Distanz:
- ID: die ID in einer Collection.
- Distanz: Ein Distanzwert von 0 ~ 1 gibt den Ähnlichkeitsgrad an; je kleiner der Wert, desto ähnlicher sind die beiden Vektoren.
Daten filtern, deren ID -1 ist
Wenn die Anzahl der Collections zu klein ist, können die Suchergebnisse Daten enthalten, deren ID -1 ist. Wir müssen sie selbst herausfiltern.
Paginierung
Die Suche nach Vektoren ist ganz anders. Die Abfrageergebnisse werden in absteigender Reihenfolge der Ähnlichkeit sortiert, und die ähnlichsten (topK) Ergebnisse werden ausgewählt (topK wird vom Benutzer zum Zeitpunkt der Abfrage angegeben).
Milvus unterstützt keine Paginierung. Wir müssen die Paginierungsfunktion selbst implementieren, wenn wir sie für das Geschäft benötigen. Wenn wir zum Beispiel zehn Ergebnisse auf jeder Seite haben und nur die dritte Seite anzeigen möchten, müssen wir angeben, dass topK = 30 ist, und nur die letzten zehn Ergebnisse zurückgeben.
Ähnlichkeitsschwellenwert für das Geschäft
Der Abstand zwischen den Vektoren zweier Bilder liegt zwischen 0 und 1. Wenn wir entscheiden möchten, ob zwei Bilder in einem bestimmten Geschäftsszenario ähnlich sind, müssen wir einen Schwellenwert innerhalb dieses Bereichs angeben. Die beiden Bilder sind ähnlich, wenn der Abstand kleiner als der Schwellenwert ist, oder sie sind recht unterschiedlich voneinander, wenn der Abstand größer als der Schwellenwert ist. Sie müssen den Schwellenwert anpassen, um Ihre eigenen Geschäftsanforderungen zu erfüllen.
Dieser Artikel wurde von rifewang, Milvus-Benutzer und Softwareingenieur von UPYUN, verfasst. Wenn Ihnen dieser Artikel gefällt, kommen Sie gerne vorbei und sagen Sie Hallo @ https://github.com/rifewang.
Weiterlesen

Expanding Our Global Reach: Zilliz Cloud Launches in Azure Central India
Zilliz Cloud expands to Azure Central India. This new region helps customers meet compliance, reduce latency, and optimize cloud costs when building AI applications.

Zilliz Cloud BYOC Upgrades: Bring Enterprise-Grade Security, Networking Isolation, and More
Discover how Zilliz Cloud BYOC brings enterprise-grade security, networking isolation, and infrastructure automation to vector database deployments in AWS

Top 5 AI Search Engines to Know in 2025
Discover the top AI-powered search engines of 2025, including OpenAI, Google AI, Bing, Perplexity, and Arc Search. Compare features, strengths, and limitations.



