使用Python+OpenCV+Tensorflow实现图像聚类

article/2025/10/1 13:36:54

介绍

大家好,最近在参加深度学习竞赛时,遇到了一个有趣的问题,即如何将给定的图像集进行聚类,你可能会说,这不是一个简单的分类问题吗?使用卷积神经网络, 就实现,但关键在于没有合适训练数据提供训练。

在不想自己收集数据集的情况,我们如何解决这个问题呢?这就是本文的主要内容,即将深度学习直接应用于测试数据(此处为图像),而无需创建训练数据集并在该数据集上训练神经网络。

卷积神经网络作为特征提取器

首先我们需要讨论为什么需要特征提取器?以及如何使卷积神经网络(CNN)发挥作用。

图像数据的特征提取器:

假设算法需要像特征一样需要两只眼睛,一只鼻子和一张嘴来将图像分类为面部,但是在不同的图像中,这些特征存在于不同的像素位置,因此简单地将图像扁平化并将其提供给算法是不起作用的。

而解决这个问题刚好是CNN的卷积层发挥作用的地方。卷积层作为我们的特征提取器,并将图像分解为越来越精细的细节,我们来看一下下面的例子:

这是一只猫的图像,这是Vgg16的第一个卷积层看到它的样子

请注意不同的图像,这些是我们的CNN所学习的特征图,一些特征图着重于轮廓,一些特征着重于纹理,而某些特征则涉及更细微的细节(如耳和嘴),下一阶段的卷积层将这些特征分解得更细的细节。

上午我们知道了卷积层可以学习图像的特定功能,那么接下来我们将实现编码。

实现CNN的卷积层网络:

以下代码显示了如何使用预训练的CNN Vgg16获得以上结果:

MyModel = tf2.<a onclick="parent.postMessage({'referent':'.tensorflow.keras'}, '*')">keras.applications.VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None,pooling=None, classes=1000, classifier_activation='softmax'
)
MyModel.summary()
## lets Define a Function that can show Features learned by CNN's nth convolusion layer
def ShowMeWhatYouLearnt(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..Image'}, '*')">Image, <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..layer'}, '*')">layer, <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..MyModel'}, '*')">MyModel):
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img = img_to_array(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..Image'}, '*')">Image)
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img = np.<a onclick="parent.postMessage({'referent':'.numpy.expand_dims'}, '*')">expand_dims(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img, 0)### preprocessing for img for vgg16
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img = tf2.<a onclick="parent.postMessage({'referent':'.tensorflow.keras'}, '*')">keras.applications.vgg16.preprocess_input(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img)## Now lets define a model which will help us## see what vgg16 sees
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..inputs'}, '*')">inputs = <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..MyModel'}, '*')">MyModel.inputs
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..outputs'}, '*')">outputs = <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..MyModel'}, '*')">MyModel.layers[<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..layer'}, '*')">layer].output
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..model'}, '*')">model = Model(inputs=<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..inputs'}, '*')">inputs, outputs=<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..outputs'}, '*')">outputs)
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..model'}, '*')">model.summary()## let make predictions to see what the Cnn sees
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..featureMaps'}, '*')">featureMaps = <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..model'}, '*')">model.predict(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..img'}, '*')">img)## Plotting Featuresfor a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..maps'}, '*')">maps in <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..featureMaps'}, '*')">featureMaps:
plt.<a onclick="parent.postMessage({'referent':'.matplotlib.pyplot.figure'}, '*')">figure(figsize=(20,20))
<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..pltNum'}, '*')">pltNum = 1for <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..a'}, '*')">a in range(8):for <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..b'}, '*')">b in <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..range'}, '*')">range(8):
plt.<a onclick="parent.postMessage({'referent':'.matplotlib.pyplot.subplot'}, '*')">subplot(8, 8, <a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..pltNum'}, '*')">pltNum)
plt.<a onclick="parent.postMessage({'referent':'.matplotlib.pyplot.imshow'}, '*')">imshow(<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..maps'}, '*')">maps[: ,: ,<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..pltNum'}, '*')">pltNum - 1], cmap='gray')<a onclick="parent.postMessage({'referent':'.kaggle.usercode.12234793.44545592.ShowMeWhatYouLearnt..pltNum'}, '*')">pltNum += 1
plt.<a onclick="parent.postMessage({'referent':'.matplotlib.pyplot.show'}, '*')">show()

接下来我们将重点介绍如何来创建我们的聚类算法。

设计图像聚类算法

在本节中,我们使用Kaggle上的 keep-babies-safe 数据集。

  • https://www.kaggle.com/akash14/keep-babies-safe

首先,我们创建一个图像聚类模型,来将给定的图像分为两类,即玩具消费品,以下是来自该数据集的一些图像。

以下代码实现我们的聚类算法:

##################### Making Essential Imports ############################
import sklearn
import os
import sys
import matplotlib.pyplot as plt
import cv2
import pytesseract
import numpy as np
import pandas as pd
import tensorflow as tf
conf = r'-- oem 2'
#####################################
# Defining a skeleton for our       #
# DataFrame                         #
#####################################
DataFrame = {'photo_name' : [],'flattenPhoto' : [],'text' : [],}
#######################################################################################
#      The Approach is to apply transfer learning hence using Resnet50 as my          #
#      pretrained model                                                               #
#######################################################################################
MyModel = tf.keras.models.Sequential()
MyModel.add(tf.keras.applications.ResNet50(include_top = False, weights='imagenet',    pooling='avg',
))
# freezing weights for 1st layer
MyModel.layers[0].trainable = False
### Now defining dataloading Function
def LoadDataAndDoEssentials(path, h, w):img = cv2.imread(path)DataFrame['text'].append(pytesseract.image_to_string(img, config = conf))img = cv2.resize(img, (h, w))## Expanding image dims so this represents 1 sampleimg = img = np.expand_dims(img, 0)img = tf.keras.applications.resnet50.preprocess_input(img)extractedFeatures = MyModel.predict(img)extractedFeatures = np.array(extractedFeatures)DataFrame['flattenPhoto'].append(extractedFeatures.flatten())### with this all done lets write the iterrrative loop
def ReadAndStoreMyImages(path):list_ = os.listdir(path)for mem in list_:DataFrame['photo_name'].append(mem)imagePath = path + '/' + memLoadDataAndDoEssentials(imagePath, 224, 224)### lets give the address of our Parent directory and start
path = 'enter your data's path here'
ReadAndStoreMyImages(path)
######################################################
#        lets now do clustering                      #
######################################################
Training_Feature_vector = np.array(DataFrame['flattenPhoto'], dtype = 'float64')
from sklearn.cluster import AgglomerativeClustering
kmeans = AgglomerativeClustering(n_clusters = 2)
kmeans.fit(Training_Feature_vector)
A little explanation for the above code:

上面的代码使用Resnet50(一种经过预先训练的CNN)进行特征提取,我们只需移除其头部或用于预测类别的神经元的最后一层,然后将图像输入到CNN并获得特征向量作为输出,实际上,这是我们的CNN在Resnet50的倒数第二层学习到的所有特征图的扁平数组。

可以将此输出向量提供给进行图像聚类的任何聚类算法。让我向你展示通过这种方法创建的簇。

该可视化的代码如下

## lets make this a dataFrame
import seaborn as sb
import matplotlib.pyplot as plt
dimReducedDataFrame = pd.DataFrame(Training_Feature_vector)
dimReducedDataFrame = dimReducedDataFrame.rename(columns = { 0: 'V1', 1 : 'V2'})
dimReducedDataFrame['Category'] = list (df['Class_of_image'])
plt.figure(figsize = (10, 5))
sb.scatterplot(data = dimReducedDataFrame, x = 'V1', y = 'V2',hue = 'Category')
plt.grid(True)
plt.show()

结论

本文通过解释如何使用深度学习和聚类将视觉上相似的图像聚在一起形成簇,而无需创建数据集并在其上训练CNN。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓


http://chatgpt.dhexx.cn/article/sTllmKKr.shtml

相关文章

论文阅读笔记(15):Deep Subspace Clustering with Data Augmentation,深度子空间聚类+数据增强

论文阅读笔记&#xff08;15&#xff09;&#xff1a;Deep Subspace Clustering with Data Augmentation&#xff0c;深度子空间聚类数据增强 摘要1 介绍2 相关工作带增强的聚类方法具有一致性损失的自监督子空间聚类中的自表达模型 3 深度子空间聚类数据增强总结 4 寻找有效增…

【SaaS金羊毛】微信小程序We分析

微信前几天发布了通告https://mp.weixin.qq.com/cgi-bin/announce?actiongetannouncement&announce_id11652079103ziYFG&version&langzh_CN&token&#xff0c;小程序统计模块会升级为”We分析“这样一款独立的产品。实际上这也符合很多B端产品的趋势&#xff…

Python 如何确定K-Means聚类的簇数

背景 “人以类聚&#xff0c;物以群分”&#xff0c;在大千世界中总有那么一些人&#xff0c;性格爱好、行为习惯比较相近&#xff0c;我们就会把他们归为一类人&#xff0c;这就是我们人脑自动进行的一个聚类(归类)。 在数据分析中&#xff0c;我们也经常拿数据来进行K-Means聚…

【机器学习】聚类代码练习

本课程是中国大学慕课《机器学习》的“聚类”章节的课后代码。 课程地址&#xff1a; https://www.icourse163.org/course/WZU-1464096179 课程完整代码&#xff1a; https://github.com/fengdu78/WZU-machine-learning-course 代码修改并注释&#xff1a;黄海广&#xff0c;ha…

【聚类算法】10种Python聚类算法完整操作示例(建议收藏

点击上方&#xff0c;选择星标&#xff0c;每天给你送干货&#xff01; 来源&#xff1a;海豚数据科学实验室 著作权归作者所有&#xff0c;本文仅作学术分享&#xff0c;若侵权&#xff0c;请联系后台删文处理 聚类或聚类分析是无监督学习问题。它通常被用作数据分析技术&…

理论+实战,一文详解最常使用的10个聚类算法(附代码)

聚类或聚类分析是无监督学习问题。它通常被用作数据分析技术&#xff0c;用于发现数据中的有趣模式&#xff0c;例如基于其行为的客户群。有许多聚类算法可供选择&#xff0c;对于所有情况&#xff0c;没有单一的最佳聚类算法。 相反&#xff0c;最好探索一系列聚类算法以及每…

基于微信小程序的家校通系统-JAVA【数据库设计、源码、开题报告】

第一章 绪 论 1.1选题背景 随着网络时代的到来&#xff0c;互联网的优势和普及时刻影响并改变着人们的生活方式。在信息技术迅速发展的今天&#xff0c;计算机技术已经遍及全球&#xff0c;使社会发生了巨大的变革。 为了不受时间和地点的限制&#xff0c;智能手机用户可以通…

python新闻文本聚类_TextCluster:短文本聚类预处理模块 Short text cluster

推荐Github上一个NLP相关的项目&#xff1a; RandyPen/TextCluster 项目地址&#xff0c;阅读原文可以直达&#xff0c;欢迎参与和Star&#xff1a; https://github.com/RandyPen/TextCluster 这个项目的作者是AINLP交流群里的昭鸣同学&#xff0c;该项目 开源了一个短文本聚…

【组队学习】十一月微信图文索引

十一月微信图文索引 一、组队学习相关 周报&#xff1a; Datawhale组队学习周报&#xff08;第037周&#xff09;Datawhale组队学习周报&#xff08;第038周&#xff09;Datawhale组队学习周报&#xff08;第039周&#xff09;Datawhale组队学习周报&#xff08;第040周&…

k-means聚类算法从入门到精通

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 k-means算法是非监督聚类最常用的一种方法&#xff0c;因其算法简单和很好的适用于大样本数据&#xff0c;广泛应用于不同领域&#xff0c;本文详细总结了k-means聚类算…

LaneAF | 利用Affinity Field聚类进行车道线实例分割

点击上方“计算机视觉工坊”&#xff0c;选择“星标” 干货第一时间送达 论文&#xff1a;https://arxiv.org/abs/2103.12040 开源代码&#xff1a;https://github.com/sel118/LaneAF 0 动机 车道线检测对于辅助驾驶、自动驾驶至关重要。全球范围内多种多样的车道线以及复杂的道…

机器学习 --- 聚类性能评估指标

第1关&#xff1a;外部指标 任务描述 本关任务:填写 python 代码&#xff0c;完成 calc_JC 函数、calc_FM 函数和 calc_Rand 函数分别实现计算 JC系数、FM 指数 和 Rand 指数 。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; JC 系数&#xff1b; FM 指数&…

如何用 DBSCAN 聚类算法做数据分析?

DBSCAN属于无监督学习算法&#xff0c;无监督算法的内涵是观察无标签数据集自动发现隐藏结构和层次&#xff0c;在无标签数据中寻找隐藏规律。 聚类模型在数据分析当中的应用&#xff1a;既可以作为一个单独过程&#xff0c;用于寻找数据内在规律&#xff0c;也可以作为分类等…

激光点云的物体聚类

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 文章导读 本文针对自动驾驶中三维点云的道路目标聚类进行讲解&#xff0c;从聚类算法的原理出发&#xff0c;介绍几种常用的点云障碍物聚类算法&#xff0c;并对比分析算…

K-means聚类算法

实训目标 本实训项目介绍无监督学习中&#xff0c;使用最广泛的 K-means 聚类算法。 先修知识 本实训项目假设&#xff0c;你已经掌握了初步的 Python 程序设计的基础知识。学习者若有一些 numpy 的使用经验&#xff0c;则可更快速地通过实训。 实训知识点 欧几里得距离 估算簇…

一文详解激光点云的物体聚类

点击上方“3D视觉工坊”&#xff0c;选择“星标” 干货第一时间送达 文章导读 本文针对自动驾驶中三维点云的道路目标聚类进行讲解&#xff0c;从聚类算法的原理出发&#xff0c;介绍几种常用的点云障碍物聚类算法&#xff0c;并对比分析算法的优劣和适用场景&#xff0c;从工程…

[计算机毕业设计]模糊聚类算法

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…

51nod-1548:欧姆诺姆和糖果

1548 欧姆诺姆和糖果 题目来源&#xff1a; CodeForces 基准时间限制&#xff1a;1 秒 空间限制&#xff1a;131072 KB 分值: 20 难度&#xff1a;3级算法题 收藏 关注 一天&#xff0c;欧姆诺诺姆来到了朋友家里&#xff0c;他发现了许多糖果。有蓝色和红色两种。他知道每颗…

android自动导入包快捷键,Android studio 自动导入(全部)包 import

http://blog.csdn.net/buaaroid/article/details/44979629 1 Android studio 只有import单个包的快捷键:Alt+Enter。没有Eclipse下的快速导入包的快捷键Ctrl+Shift+O。 2 但Android studio设置里有一项Auto Import自动导入功能。设置过程如下: Android studio --> File--&…

舍友打一把游戏的时间,我实现了一个selenium自动化测试并把数据保存到MySQL

文章目录 前言最终效果开发环境selenium元素定位方法页面分析思路分析实现步骤运行结果以下是全部代码 前言 很久没有玩selenium自动化测试了&#xff0c;近日在学习中都是在忙于学习新的知识点&#xff0c;所以呢今天就来写个selenium自动化测试的案例吧。有没有人疑惑&#…