图片Embeddings

图片嵌入(Image Embeddings)技术是将图像数据转换为一个固定长度的向量表示的技术。这种向量能够捕捉图像的语义信息,方便机器学习模型理解、比较和处理图像。这种技术在计算机视觉(Computer Vision)和多模态任务中有广泛的应用。

应用场景有图像检索,用户上传图片,系统计算嵌入向量,并在数据库中匹配相似图片。如 Google 图片搜索、电子商务网站的视觉搜索功能。

python代码

我们将使用 python代码基本以下图片来计算cat.png的embedding:

cat

然后计算其他三张图片的embedding(分别为1,2,3):

1

2

3

根据这三个图片的embedding,分别计算它跟第一张图片的cosine值,从而得到最相似的图片。

下载图片并解压到python代码的目录:

https://pingfan.s3.amazonaws.com/files/embedding-images.zip

文件结构如下:

├── image_embedding.py
└── images
    ├── 1.png
    ├── 2.png
    ├── 3.png
    └── cat.png

image_embedding.py代码:

import boto3
import json
import base64

def dotProduct(embedding1: list, embedding2: list):
    return sum([embedding1[i] * embedding2[i] for i in range(len(embedding1))])

def cosineSimilarity(embedding1: list, embedding2: list):
    dotProductValue = dotProduct(embedding1, embedding2)
    magnitude1 = dotProduct(embedding1, embedding1) ** 0.5
    magnitude2 = dotProduct(embedding2, embedding2) ** 0.5
    return dotProductValue / (magnitude1 * magnitude2)


client = boto3.client(service_name='bedrock-runtime', region_name="us-west-2")

images = [
    'images/1.png',
    'images/2.png',
    'images/3.png',
]

def getImagesEmbedding(imagePath: str):
    with open(imagePath, "rb") as f:
        base_image = base64.b64encode(f.read()).decode("utf-8")

    response = client.invoke_model(
        body=json.dumps({
            "inputImage": base_image,
        }),
        modelId='amazon.titan-embed-image-v1',
        accept='application/json',
        contentType='application/json')

    response_body = json.loads(response.get('body').read())
    return response_body.get('embedding')

imagesWithEmbeddings = []

for image in images:
    imagesWithEmbeddings.append({
        'path': image,
        'embedding': getImagesEmbedding(image)
    })

test_image = 'images/cat.png'

test_image_embedding = getImagesEmbedding(test_image)

similarities = []

for image in imagesWithEmbeddings:
    similarities.append({
        'path': image['path'],
        'similarity': cosineSimilarity(image['embedding'], test_image_embedding)
    })

similarities.sort(key=lambda x: x['similarity'], reverse=True)

print(f"Similarities of '{test_image}' with:")
for similarity in similarities:
    print(f"  '{similarity['path']}': {similarity['similarity']:.2f}")

运行结果:

image-20241130215232511

cat.png跟第一张相似性最高,因为它们都是猫的图片。