快速掌握视频搜索技巧:仅需5分钟,利用内容识别,无须标签标记 - 特征抽取与向量导入步骤详解
最编程
2024-02-12 11:31:45
...
本文教学的「视频检索」系统主要包含数据插入和检索两个部分。首先,我们将视频库里的所有视频转换成一个向量并存入数据库(Milvus 集合)中。当数据库准备完成后,该系统就可以实现检索服务。检索过程会将查询语句转换成一个向量,然后在数据库中找到与其最相近的视频向量,最终通过视频向量的 id 返回其对应的实际视频。为了将视频与文本转换成向量,我们需要一个视频-文本跨模态的神经网络模型用于提取特征。Towhee 提供了一系列简单又好用的 API[12] ,以供我们可以更便捷地操作数据处理的算子和流水线。这里我们选用了 towhee clip4clip[13] 算子将视频库里的所有视频转换成向量,并插入事先准备好的 Milvus 集合中。该算子不仅提供了预训练的 CLIP4Clip[14] 提取特征,还包含了后处理工作(比如池化、维度处理、转数据格式),能够通过几行代码轻松提取向量。
为了加速算子与预训练模型的下载,在运行 clip4clip 算子之前,请确保你已经安装了 git[15] 和 git-lfs[16](如果已安装请跳过):
sudo apt-get install git & git-lfs
git lfs install
import os
import towhee
device = 'cuda:0'
# device = 'cpu'
# For the first time you run this line,
# it will take some time
# because towhee will download operator with weights on backend.
dc = (
towhee.read_csv(test_sample_csv_path).unstream()
.runas_op['video_id', 'id'](func=lambda x: int(x[-4:] "'video_id', 'id'"))
.video_decode.ffmpeg['video_path', 'frames'](sample_type='uniform_temporal_subsample', args={'num_samples': 12} "'video_path', 'frames'") \
.runas_op['frames', 'frames'](func=lambda x: [y for y in x] "'frames', 'frames'") \
.video_text_embedding.clip4clip['frames', 'vec'](model_name='clip_vit_b32', modality='video', device=device "'frames', 'vec'") \
.to_milvus['id', 'vec'](collection=collection, batch=30 "'id', 'vec'")
)
Wall time: 1min 19s
检查数据库集合可以看到共有 1000 条向量,通过 Towhee 提供的接口还可以查看各个数据之间的对应关系:
print('Total number of inserted data is {}.'.format(collection.num_entities))
dc.select['video_id', 'id', 'vec']( "'video_id', 'id', 'vec'").show()
Total number of inserted data is 1000.
我们在这里对上面的代码做一些接口说明:
-
towhee.read_csv(test_sample_csv_path)
:读取 csv 文件中的数据。 -
.runas_op['video_id', 'id'](func=lambda x: int(x[-4:] "'video_id', 'id'"))
:取每一行数据的 video_id 列最后 4 个数据作为 id 列的数据,并转换其数据类型为 int。 -
.video_decode.ffmpeg and runas_op
:统一对视频进行二次采样,然后得到一串视频图像列表,作为 clip4clip 模型的输入。 -
.video_text_embedding.clip4clip['frames', 'vec'](model_name='clip_vit_b32', modality='video' "'frames', 'vec'")
:从视频中采样的图像帧中提取 Embedding 特征向量,然后在时间维度上平均池化它们。 -
.to_milvus['id', 'vec'](collection=collection, batch=30 "'id', 'vec'")
:将向量 30 个一批插入 Milvus 集合中。