Stellen Sie sich einen Datenwissenschaftler vor, der das Verhalten von Wildtieren untersucht und Hunderte Stunden Videomaterial von Kameras in einem abgelegenen Wald analysiert. Oder einen Sporttrainer, der aus den Spielen einer ganzen Saison Schlüsselszenen identifizieren muss, um neue Strategien zu entwickeln. Oder stellen Sie sich einen Filmemacher vor, der in einer riesigen Videogalerie nach bestimmten Szenen sucht, um daraus einen Dokumentarfilm zusammenzustellen.
Traditionell stehen alle diese Experten vor der zeitaufwändigen, fehleranfälligen und überwältigenden Herausforderung, stundenlanges Filmmaterial manuell zu sortieren.
Fortschritte bei künstlicher Intelligenz und maschinellem Lernen haben jedoch die Videosuchanwendungen dramatisch verändert. Diese Technologien ermöglichen es uns nun, mit unglaublicher Raffinesse in umfangreichen Videodatensätzen nach bestimmten Objekten und Ereignissen zu suchen. Datenwissenschaftler und Forscher können relevante Videosegmente mit außergewöhnlicher Präzision und Effizienz herausfiltern.
Das Ziel bestand darin, den Rechercheprozess durch die Bereitstellung erweiterter Suchfunktionen zu vereinfachen, sodass Benutzer in extrem großen Videodatensätzen problemlos Filmmaterial mit bestimmten Inhalten oder Eigenschaften finden können.
Durch die Verwendung ausgefeilter Suchalgorithmen und einer benutzerfreundlichen Oberfläche wollte OpenOrigins die Plattform zu einem wichtigen Tool für diese Community machen.
OpenOrigins hat zwei technologische Ansätze zum Aufbau dieses Videosuchangebots in Betracht gezogen: Frame-Suche mithilfe von Bildeinbettungen und multimodale Einbettungen. Sehen wir uns die beiden Optionen einmal an.
Um die semantische Suche nach Videos zu ermöglichen und so komplexe Fragen zu beantworten, wie etwa „Wie viele Minuten Videoinhalte gibt es, die Hirsche in ihrem natürlichen Lebensraum zeigen?“, sind ausgefeilte Suchfunktionen erforderlich, die den Inhalt der Videos über die einfache Übereinstimmung von Schlüsselwort-Metadaten hinaus verstehen und interpretieren können. Der Schlüssel dazu? Multimodale Einbettungen.
Multimodale Einbettungsmodelle und multimodale Large Language Models (LLMs) können als ähnliche Lösungen angesehen werden. Modelle wie CLIP und Google Multimodal Embeddings generieren Einbettungen für Datentypen wie Text, Bilder und Videos und erstellen hochdimensionale Vektoren, die semantische Bedeutung erfassen. Dies ermöglicht Anwendungen wie semantische Suche, Inhaltsabruf und Ähnlichkeitserkennung.
Andererseits sind multimodale LLMs wie GPT-4 (mit multimodalen Fähigkeiten), Flamingo und Gemini darauf ausgelegt, Inhalte über verschiedene Datentypen hinweg zu verstehen und zu generieren.
Diese Modelle eignen sich gut für komplexe Aufgaben wie Konversations-KI und Inhaltsgenerierung, indem sie multimodale Eingaben (beispielsweise Text und Bilder) verwenden und multimodale Ausgaben generieren, was zu aussagekräftigen und kontextreichen Antworten führt.
Während Einbettungsmodelle auf effizientes Suchen und Abrufen ausgerichtet sind, eignen sich multimodale LLMs zum Generieren und Verstehen unterschiedlicher Inhalte und sind daher ideal für Chatbots, interaktive Assistenten und multimodale Interaktionen.
| Multimodale Einbettungsmodelle | Multimodale große Sprachmodelle (LLMs) |
---|---|---|
Hauptzweck | Ermöglichen Sie die Suche und Abfrage in verschiedenen Datenmodalitäten wie Text und Bild | Generieren und verstehen Sie Inhalte über mehrere Modalitäten hinweg |
Kernanwendungsfall | Semantische Suche, Inhaltsabruf und Ähnlichkeit | Konversations-KI, Inhaltsgenerierung und Dialogsysteme |
Beispielmodelle | CLIP, Google Multimodal Embedding Model | GPT-4 (mit multimodalen Fähigkeiten), Llava, Gemini, Flamingo, LaMDA |
Suchen und Abrufen | Optimiert für schnelle, genaue Suche und Ähnlichkeit | Optimiert für umfassendes Verständnis und Generierung über verschiedene Datentypen hinweg. |
Anwendungen | Inhaltsmoderation, Empfehlungssysteme, semantische Suche | Konversationsagenten, Inhaltserstellung, multimodale Interaktionen |
Die erste Methode, die OpenOrigins untersuchte, umfasste die Einzelbildanalyse von Videos mithilfe von Bildeinbettungen. Bei diesem Ansatz wird das Video in einzelne Einzelbilder zerlegt, die jeweils mithilfe von
Durch das Studium von Millionen von Webbildern und deren Beschreibungen versteht CLIP visuelle Konzepte auf eine Weise, die der Wahrnehmung und Beschreibung der Welt durch Menschen ähnelt. Sein Training umfasst „kontrastives Lernen“, bei dem es lernt, Bilder mit den richtigen Beschreibungen zu verbinden. Dadurch erhält es die einzigartige Fähigkeit, verschiedene Aufgaben zu bewältigen, indem es die Verbindung zwischen dem, was wir sehen, und den Wörtern, die wir verwenden, versteht.
Dadurch ist CLIP äußerst anpassungsfähig und nützlich für Anwendungen, die ein tiefes Verständnis der gleichzeitigen Verwendung von Bildern und Sprache erfordern.
Diese Einbettungen werden in einer Vektordatenbank gespeichert, die schnelle und genaue Suchvorgänge ermöglicht, indem Text mit Text, Text mit Bild oder Bild mit Bild auf der Grundlage semantischer Ähnlichkeit abgeglichen wird.
Bei der Frame-Extraktion werden Videos in festgelegten Intervallen in Frames zerlegt. Jeder Frame wird durch ein Bildeinbettungsmodell verarbeitet, um eine hochdimensionale Vektordarstellung zu erzeugen. Diese Vektoren werden in einem Vektorspeicher wie DataStax Astra DB gespeichert, was effiziente Ähnlichkeitssuchen ermöglicht.
Diese Methode bietet eine hohe Genauigkeit bei der multimodalen semantischen Suche und eignet sich gut für die Suche nach bestimmten Objekten oder Szenen. Sie ist jedoch rechenintensiv, insbesondere bei langen Videos, und es kann vorkommen, dass zeitliche Zusammenhänge oder Änderungen zwischen den Einzelbildern übersehen werden.
Der zweite Ansatz nutzt die neueste generative KI-Technologie mit multimodalen Einbettungen, insbesondere unter Verwendung von Googles
Durch die numerische Darstellung von Videos ermöglichen diese Einbettungen erweiterte Aufgaben des maschinellen Lernens und erleichtern so die Suche, Analyse und Kategorisierung von Videoinhalten.
Die Integration dieser Einbettungen mit
Die multimodalen Einbettungen von Google und die CLIP-Methode betten multimodale Daten jeweils in einen gemeinsamen Einbettungsraum ein. Der Hauptunterschied besteht darin, dass die multimodalen Einbettungen von Google Video unterstützen, während dies bei CLIP nicht der Fall ist.
Wir haben die folgenden Repositorien zusammengestellt, um Beispiele sowohl für die Frame-Search-Videoanalyse als auch für multimodale Einbettungen zu veranschaulichen und anzuwenden. Diese Beispiele bieten praktische Demonstrationen und detaillierte Anweisungen, die dabei helfen, jeden Ansatz effektiv zu implementieren und zu bewerten.
In diesem Ansatz führen wir ein
Die Funktion get_single_frame_from_scene
berechnet die Frame-ID, setzt die Videoaufnahme auf dieses Frame und liest es:
def get_single_frame_from_scene(scene, video_capture): frame_id = (scene[1] - scene[0]).frame_num // 2 + scene[0].frame_num video_capture.set(cv2.CAP_PROP_POS_FRAMES, frame_id) _, frame = video_capture.read() return Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
Die Funktion get_frames_from_video
verarbeitet ein Video, erkennt Szenen mit dem AdaptiveDetector und extrahiert durch Aufrufen von get_single_frame_from_scene ein einzelnes Bild aus jeder Szene und speichert diese Bilder in einer Liste:
def get_frames_from_video(video_path): res = [] video_capture = cv2.VideoCapture(video_path) content_list = detect(video_path, AdaptiveDetector()) for scene in content_list: res.append(get_single_frame_from_scene(scene, video_capture)) return res
Die Funktion get_image_embedding verwendet eine
def get_image_embedding(image): inputs = clip_processor(images=image, return_tensors="pt") image_embeddings = model.get_image_features(**inputs) return list(image_embeddings[0].detach().numpy().astype(float))
Dieser Code stellt eine Verbindung zu einer Astra DB-Datenbank her, erstellt eine Sammlung von JSON-Objekten mit Vektoreinbettungen und fügt diese Objekte in die „Video“-Sammlung in der Datenbank ein:
import json from astrapy import DataAPIClient client = DataAPIClient(ASTRA_DB_TOKEN) database = client.get_database(ASTRA_DB_API_ENDPOINT) collectiondb = database.video json_embedding = [ {"id": f"{i+1}", "$vector": values} for i, values in enumerate(image_embeddings) ] response = collectiondb.insert_many(json_embedding)
Suchen Sie nach einem bestimmten Text mithilfe von OpenAI Clip-Einbettungen:
query_text = "men with white hair" query_embedding = get_text_embedding(query_text) result = collectiondb.find_one({}, vector=query_embedding)
Hier erfahren Sie, wie Sie Videoeinbettungen mit dem multimodalen Einbettungsmodell von Google erstellen und in Astra DB speichern, einschließlich Metadateninformationen wie start_offset_sec und end_offset_sec (siehe
import vertexai from vertexai.vision_models import MultiModalEmbeddingModel, Video from astrapy import DataAPIClient import streamlit as st # Initialize Vertex AI vertexai.init(project=st.secrets['PROJECT'], location=st.secrets['REGION']) # Initialize the client client = DataAPIClient(st.secrets['ASTRA_TOKEN']) database = client.get_database(st.secrets['ASTRA_API_ENDPOINT']) my_collection = database.create_collection( "videosearch", dimension=1408, metric=astrapy.constants.VectorMetric.COSINE, ) collectiondb = database.videosearch # Load the pre-trained model and video model = MultiModalEmbeddingModel.from_pretrained("multimodalembedding") video = Video.load_from_file(st.secrets['PATH']) # Get embeddings with the specified contextual text embeddings = model.get_embeddings( video=video, contextual_text="Mixed Content", dimension=1408, ) # Video Embeddings are segmented based on the video_segment_config. for video_embedding in embeddings.video_embeddings: # Check if embedding is a numpy array or a tensor and convert accordingly if isinstance(video_embedding.embedding, (list, tuple)): embedding_list = video_embedding.embedding else: embedding_list = video_embedding.embedding.tolist() embedding_data = { "metadata": { "start_offset_sec": video_embedding.start_offset_sec, "end_offset_sec": video_embedding.end_offset_sec }, "$vector": embedding_list # Ensure embedding is in list format } response = collectiondb.insert_one(embedding_data)
Hier richten wir die
import vertexai from vertexai.vision_models import MultiModalEmbeddingModel, Video from vertexai.vision_models import Image as img from astrapy import DataAPIClient import streamlit as st from PIL import Image st.title("Video Search App") user_input_placeholder = st.empty() user_input = user_input_placeholder.text_input( "Describe the content you're looking for:", key="user_input" ) uploaded_file = st.file_uploader("Choose an image file that is similar you're looking for", type="png") if uploaded_file is not None: image = Image.open(uploaded_file) image_path = st.secrets['IMAGE_PATH'] image.save(image_path) saved_image = Image.open(image_path) st.image(saved_image, caption='', use_column_width=True) # Initialize Vertex AI vertexai.init(project=st.secrets['PROJECT'], location=st.secrets['REGION']) # Initialize the client client = DataAPIClient(st.secrets['ASTRA_TOKEN']) database = client.get_database(st.secrets['ASTRA_API_ENDPOINT']) collectiondb = database.videosearch # Load the pre-trained model and video model = MultiModalEmbeddingModel.from_pretrained("multimodalembedding") video = Video.load_from_file(st.secrets['PATH']) # Search action trigger if st.button("Search"): if user_input: embeddings = model.get_embeddings( contextual_text=user_input ) result = collectiondb.find_one({}, vector=embeddings.text_embedding) start_offset_value = result['metadata']['start_offset_sec'] end_offset_value = result['metadata']['end_offset_sec'] st.write("Text input result found between: " + str(start_offset_value) + "-" + str(end_offset_value)) video_file = open(st.secrets['PATH'], 'rb') video_bytes = video_file.read() st.video(video_bytes, start_time=start_offset_value) if uploaded_file is not None: embimage = img.load_from_file(image_path) embeddingsimg = model.get_embeddings( image=embimage ) imgresult = collectiondb.find_one({}, vector=embeddingsimg.image_embedding) start_offset_value = imgresult['metadata']['start_offset_sec'] end_offset_value = imgresult['metadata']['end_offset_sec'] st.write("Image input result found between: " + str(start_offset_value) + "-" + str(end_offset_value)) video_file = open(st.secrets['PATH'], 'rb') video_bytes = video_file.read() st.video(video_bytes, start_time=start_offset_value)
So sehen die Ergebnisse aus:
Die Untersuchung dieser beiden Ansätze unterstreicht das erhebliche Potenzial moderner KI-Techniken in Videosuchanwendungen. Während die Frame-Suche mit Bildeinbettungen eine hohe Genauigkeit für bestimmte visuelle Suchen bietet, sind multimodale Einbettungen aufgrund ihrer Flexibilität und Leistungsfähigkeit die bessere Wahl für komplexe, multimodale Suchanforderungen.
Durch die Verwendung von Astra DB kann eine Videosuchplattform den Benutzern erweiterte Suchfunktionen bieten, die ein präzises und effizientes Abrufen bestimmter Videoinhalte aus großen Datensätzen ermöglichen. Dies verbessert die Fähigkeit zur Analyse und Interpretation von Videodaten erheblich und führt zu schnelleren und genaueren Erkenntnissen.
Die Zukunft der Videosuche sieht dank fortlaufender Forschung und Entwicklung rosig aus. Fortschritte in der künstlichen Intelligenz und im maschinellen Lernen werden diese Techniken weiter verbessern und sie zugänglicher und effizienter machen. Die Integration mit anderen neuen Technologien wie Augmented Reality und Echtzeit-Videoanalyse wird ihre Möglichkeiten noch weiter ausbauen.
Von Matthew Pendlebury , technischer Leiter bei OpenOrigins, und Betul O'Reilly , Lösungsarchitektin bei DataStax