构建简单的推荐系统

在电子商务网站中,推荐系统是一种常见的工具,它能够根据用户对某个商品的兴趣,推荐相似的商品。本文将探讨如何构建一个简单的推荐系统,该系统能够根据给定的商品推荐外观相似的商品。将使用最新的预训练模型和迁移学习技术来实现这一目标。

图像的数字表示

图像由红、绿、蓝三种基本颜色组成,可以通过一个二维矩阵来表示。例如,一个3x3大小的图像,每个颜色通道都有一个3x3的矩阵,每个单元格包含像素值,这些像素值表示颜色的饱和度(或亮度)。对于红色,有一个每个单元格值在0到255之间的矩阵,每个值代表不同的红色色调。因此,对于一个3x3大小的图像,有:

Red color having a matrix of size = 3 x 3 = 9 pixels Green color having a matrix of size = 3 x 3 = 9 pixels Blue color having a matrix of size = 3 x 3 = 9 pixels So the entire image will be represented by a matrix of width X height X Components = 3 x 3 x 3 = 27 pixels.

然而,在现实世界中,图像的大小通常不会这么小。例如,一个1080p的图像大小为1920x1080,因此整个1080p图像需要1920x1080x3=6,220,800个像素。以下是获取这些像素的代码示例:

# import the necessary packages import cv2 import imutils import numpy as np from matplotlib import pyplot as plt # img_path = ‘food101/images/image_pizza_1.jpeg’ img_path = 'pizza.png' im = cv2.imread(img_path) plt.axis('off') plt.imshow(im[:,:,::-1]) plt.title('Original Image') plt.show() row,col,plane = im.shape # ... (省略其他代码)

什么是图像嵌入?

如上所述,对于一个1080p的图像,需要存储1920x1080x3=6,220,800个像素。这些像素是信息的视觉表示,如人物、物体等。由于正在尝试构建一个图像推荐系统,使用约600万像素来识别相似性将非常耗费计算资源。是否有更简单的方法来表示图像?答案是肯定的。

可以使用图像嵌入,而不是使用图像像素。图像嵌入可以被看作是图像的向量表示。它将图像特征和信息捕获到向量格式中。让通过一个预训练模型来了解如何派生图像嵌入。

ResNet50架构是一个例子,它接受一个图像并使用多个隐藏的神经网络层进行多次变换。通过这些变换,它预测图像属于哪个类别。模型通过卷积机制从图像中接收像素和邻域数据。这些卷积对图像数据执行多次变换,并创建一个最终向量。输出层使用这个最终向量将图像分类为1000个类别。

不使用最后一层,而是使用ResNet50架构的倒数第二层。它包含一个大小为2048的向量,这是图像的表示。这将是图像嵌入。因此,现在可以使用图像嵌入而不是像素来表示图像特征。

from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions from tensorflow.keras.preprocessing import image import numpy as np import pandas as pd import cv2 from tqdm.auto import tqdm import os from matplotlib import pyplot as plt def return_image_embedding(model, img_path): 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) preds = model.predict(x) curr_df = pd.DataFrame(preds[0]).T return curr_df model = ResNet50(include_top=False, weights='imagenet', pooling='avg') img_path = 'food101/images/image_french_fries_692.jpeg' return_image_embedding(model, img_path)

如何找到相似的图像?

将使用余弦距离来确定相似性。余弦相似度衡量两个向量之间的距离。如果两个向量对齐,它们之间的夹角将为0,cos 0 = 1。因此,从数学上讲,这种距离度量将被用来找到最相似的图像。

逻辑是:对于给定的图像,使用嵌入之间的余弦相似度来识别最相似的图像。这个想法是使用KNN(K最近邻)模型衍生出来的。

from sklearn.metrics.pairwise import cosine_distances, pairwise_distances, cosine_similarity cosine_similarity_df = pd.DataFrame(cosine_similarity(embedding_df.drop('image',axis=1)))

让看看模型的表现如何。在此之前,创建一个显示图像的函数。

def show_img(image_name, title=image_name): img_path = 'food101/images/'+str(image_name) im = cv2.imread(img_path) im = cv2.resize(im, (960, 540)) plt.axis('off') plt.imshow(im[:,:,::-1]) plt.title(title) plt.show() def fetch_most_similar_products(image_name, n_similar=7): print("-----------------------------------------------------------------------") print("Original Product:") show_img(image_name, image_name) curr_index = embedding_df[embedding_df['image']==image_name].index[0] closest_image = pd.DataFrame(cosine_similarity_df.iloc[ curr_index].nlargest(n_similar+1)[1:]) print("-----------------------------------------------------------------------") print("Recommended Product") for index, imgs in closest_image.iterrows(): similar_image_name = embedding_df.iloc[index]['image'] similarity = np.round(imgs.iloc[0], 3) show_img(similar_image_name, str(similar_image_name)+' Similarity : '+str(similarity))
  • 信息和图像特征可以被捕获在一个向量中(或图像嵌入)。
  • 可以使用最新的模型通过迁移学习来派生图像嵌入。
  • 这种嵌入非常有用,可以用于各种任务——比如图像相似性、图像注释等。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485