欢迎光临
我们一直在努力

【Clustering】Deep Image Clustering with TensorFlow

在这里插入图片描述

使用 Python+OpenCV+TensorFlow 实现图像聚类:无需标注数据的深度学习方案

摘要:本文介绍如何在不创建训练数据集、不训练神经网络的情况下,利用预训练 CNN(ResNet50)作为特征提取器,结合层次聚类算法对图像进行无监督分类。我们将以 Kaggle 上的 Keep Babies Safe 数据集为例,完成从特征提取到聚类可视化的完整流程。


1. 引言

在这里插入图片描述

在计算机视觉的众多任务中,图像分类 是最基础也最常见的需求。传统方法需要我们:

  • 收集大量标注数据
  • 设计或选择网络结构
  • 在数据集上训练模型
  • 用训练好的模型进行推理
  • 但现实往往更复杂——很多场景下我们根本没有标注数据。比如参加一个深度学习竞赛时,官方只给了测试集,没有训练标签,怎么办?

    答案就是:将预训练 CNN 作为特征提取器,直接对测试集进行无监督聚类。

    这就是本文的核心内容。我们不需要训练任何模型,只需要一个在 ImageNet 上预训练好的 CNN,就能把视觉上相似的图像自动聚到一起。


    2. 核心原理

    在这里插入图片描述

    2.1 CNN 如何"看懂"图像?

    卷积神经网络(CNN)的卷积层本质上是一系列特征检测器。浅层卷积层倾向于检测边缘、颜色、纹理等低级特征,深层卷积层则能检测更高级的语义特征(如眼睛、鼻子、轮子等物体组成部分)。

    以一个预训练好的 VGG16 为例,可视化其第一层卷积层看到的特征图:

    在这里插入图片描述

    图:VGG16 第一个卷积层的特征图可视化。不同通道关注不同的视觉模式——有的关注边缘轮廓,有的关注纹理细节。

    2.2 迁移学习作为特征提取器

    既然 CNN 已经学会了提取有意义的视觉特征,我们完全可以直接用它来处理新图像——这就是 迁移学习 (Transfer Learning) 的思路:

  • 加载在 ImageNet 上预训练的 CNN(如 ResNet50)
  • 移除最后的分类头(include_top=False)
  • 添加全局平均池化层(pooling='avg'),将任意尺寸的特征图压缩为固定长度的向量
  • 将图像输入模型,取倒数第二层的输出作为特征向量
  • 对于 ResNet50,每张图像会被映射为一个 2048 维的特征向量。这个向量已经编码了图像的语义信息,可以直接用于聚类。

    2.3 整体流程

    原始图像 → ResNet50(无分类头) → 2048–d 特征向量 → 标准化 → 聚类算法 → 簇标签 → 可视化


    3. 数据集

    在这里插入图片描述

    本文使用 Kaggle 上的 Keep Babies Safe 数据集。

    在这里插入图片描述

    该数据集包含 1131 张图像,分为两大类:

    • 玩具(Toys):毛绒玩具、积木、玩偶等
    • 消费品(Consumer Products):日用品、包装盒等

    数据集位于 /dataset/images/ 目录下,附带一个 test.csv 文件(包含图像名和类别列,但标签为空——这正是我们需要聚类的原因)。

    让我们先看看数据集中的一些样本图像:

    在这里插入图片描述


    4. 代码实现

    在这里插入图片描述

    下面逐步解析核心实现。

    在这里插入图片描述

    4.1 环境依赖

    pip install numpy opencv-python tensorflow scikit-learn matplotlib seaborn pandas

    4.2 CNN 特征提取器

    import numpy as np
    import cv2
    import tensorflow as tf

    class CNNFeatureExtractor:
    def __init__(self, model_name="resnet50", input_size=(224, 224)):
    if model_name == "resnet50":
    self.base_model = tf.keras.applications.ResNet50(
    include_top=False, # 移除分类头
    weights="imagenet", # 使用 ImageNet 预训练权重
    pooling="avg", # 全局平均池化 → 2048-d 向量
    )
    self.base_model.trainable = False # 冻结权重

    def extract(self, img):
    img = cv2.resize(img, self.input_size)
    img = np.expand_dims(img, axis=0)
    img = tf.keras.applications.resnet50.preprocess_input(img)
    features = self.base_model.predict(img, verbose=0)
    return features.flatten() # 返回 2048 维特征向量

    关键点解释:

    参数含义
    include_top=False 丢弃 ResNet50 最后的全连接分类层(原本输出 1000 个 ImageNet 类别)
    pooling='avg' 对最后一个卷积层输出的 7×7×2048 特征图做全局平均池化,输出 1×1×2048
    trainable=False 不更新任何权重,纯前向推理模式

    4.3 图像聚类器

    from sklearn.cluster import AgglomerativeClustering
    from sklearn.preprocessing import StandardScaler

    class ImageClusterer:
    def __init__(self, n_clusters=2, method="agglomerative"):
    self.model = AgglomerativeClustering(n_clusters=n_clusters)
    self.scaler = StandardScaler()

    def fit(self, feature_matrix):
    scaled = self.scaler.fit_transform(feature_matrix)
    self.labels_ = self.model.fit_predict(scaled)
    return self.labels_

    为什么选择层次聚类?

    • 不需要预设聚类中心:不像 K-Means 需要随机初始化
    • 对特征分布不敏感:层次聚类通过计算样本间距离逐步合并,更稳定
    • 可解释性强:可以生成树状图(dendrogram)展示聚类层次

    4.4 可视化

    import seaborn as sns
    import matplotlib.pyplot as plt
    from sklearn.decomposition import PCA

    def plot_cluster_scatter(features, labels, image_names):
    # PCA 降维到 2D
    reduced = PCA(n_components=2).fit_transform(features)

    df = pd.DataFrame({
    "V1": reduced[:, 0],
    "V2": reduced[:, 1],
    "Category": [f"Cluster {l}" for l in labels],
    })

    sns.scatterplot(data=df, x="V1", y="V2", hue="Category", palette="Set2")
    plt.title("Image Clustering Results")
    plt.show()

    4.5 完整运行

    python main.py \\
    –data_dir ./dataset/dataset/images/ \\
    –n_clusters 2 \\
    –method agglomerative \\
    –output_dir ./output/


    5. 实验结果

    在这里插入图片描述

    5.1 聚类分布

    在 1131 张图像上运行层次聚类(n_clusters=2):

    簇编号图像数量占比
    Cluster 0 624 55.2%
    Cluster 1 507 44.8%

    在这里插入图片描述

    5.2 PCA 降维可视化

    将 2048 维特征向量用 PCA 降维到 2D 后可视化:

    在这里插入图片描述

    从上图可以看出,两个簇在特征空间中有明显的分离边界。这说明 ResNet50 提取的视觉特征确实能够捕捉到"玩具"和"消费品"之间的视觉差异。

    5.3 性能数据

    指标数值
    图像总数 1131
    单张图像特征提取时间 ~0.2s
    总特征提取时间 ~208s
    特征向量维度 2048
    聚类方法 Agglomerative Clustering
    簇数量 2

    6. 进阶探索

    6.1 尝试不同的特征提取器

    # 使用 VGG16 替代 ResNet50(特征维度从 2048 降为 512)
    python main.py –model vgg16 –n_clusters 2 –data_dir ./dataset/dataset/images/

    在这里插入图片描述

    和 resnet50 比起来还是差一些,特征都没有怎么拉开

    6.2 尝试不同聚类算法

    # K-Means
    python main.py –method kmeans –n_clusters 2 –data_dir ./dataset/dataset/images/

    在这里插入图片描述

    k-means 感觉效果更好一点,特别是分界处的最上面部分

    # DBSCAN(适用于未知类别数量的场景)
    python main.py –method dbscan –data_dir ./dataset/dataset/images/

    在这里插入图片描述

    不指定,聚成 1 个类别了

    6.3 使用 t-SNE 替代 PCA

    t-SNE 能更好地保留局部结构,适合可视化高维特征:

    python main.py –reduction tsne –data_dir ./dataset/dataset/images/

    在这里插入图片描述

    6.4 结合 OCR 文本特征

    原文中还提到可以使用 Tesseract OCR 提取图像中的文字信息,作为额外的特征维度:

    import pytesseract

    text = pytesseract.image_to_string(img, config='–oem 2')
    # 将文本特征与视觉特征拼接,可能进一步提升聚类质量


    7. 总结

    本文展示了一个实用的技巧:当没有标注数据时,如何利用预训练 CNN + 无监督聚类来解决图像分类问题。

    核心要点:

  • 预训练 CNN = 通用视觉特征提取器:在 ImageNet 上训练好的 ResNet50/VGG16 可以提取高质量的图像特征,无需在自己的数据上重新训练
  • 特征向量 + 聚类 = 无监督分类:将 CNN 倒数第二层的输出作为特征,输入到聚类算法中,即可实现图像的自动分组
  • 灵活可扩展:可以轻松替换特征提取器(ResNet→EfficientNet→ViT)或聚类算法(层次聚类→K-Means→DBSCAN→谱聚类)
  • 这种方法特别适用于以下场景:

    • 竞赛中的无标注测试集
    • 快速探索新数据集的结构
    • 数据清洗和去重
    • 作为半监督学习的第一步(先聚类,再人工标注几个样本)

    8. 完整代码

    feature_extractor.py

    """
    使用预训练 CNN (ResNet50 / VGG16) 作为图像特征提取器

    核心思路:
    – 不需要自己标注训练数据,直接使用 ImageNet 预训练权重
    – 移除分类头 (include_top=False),只保留卷积层 + 池化层
    – 每张图像 → 2048 维特征向量 (ResNet50 avg pooling)
    – 这个特征向量已经捕获了图像的语义信息(纹理、形状、边缘等)
    """

    import numpy as np
    import cv2
    import tensorflow as tf
    from typing import List, Tuple, Optional

    class CNNFeatureExtractor:
    """
    基于预训练 CNN 的图像特征提取器

    Parameters
    ———-
    model_name : str
    预训练模型名称,支持 'resnet50' 或 'vgg16'
    input_size : Tuple[int, int]
    模型输入尺寸,默认 (224, 224)
    """

    def __init__(
    self,
    model_name: str = "resnet50",
    input_size: Tuple[int, int] = (224, 224),
    ):
    self.model_name = model_name.lower()
    self.input_size = input_size

    if self.model_name == "resnet50":
    self.base_model = tf.keras.applications.ResNet50(
    include_top=False,
    weights="imagenet",
    pooling="avg", # 全局平均池化,输出 2048-d 向量
    )
    elif self.model_name == "vgg16":
    self.base_model = tf.keras.applications.VGG16(
    include_top=False,
    weights="imagenet",
    pooling="avg", # 输出 512-d 向量
    )
    else:
    raise ValueError(f"Unsupported model: {model_name}")

    # 冻结所有权重,只做前向推理
    self.base_model.trainable = False

    def preprocess(self, img: np.ndarray) –> np.ndarray:
    """
    预处理图像:resize → expand dims → 模型特定归一化

    Parameters
    ———-
    img : np.ndarray
    BGR 图像 (H, W, 3)

    Returns
    ——-
    np.ndarray
    预处理后的图像 (1, H, W, 3)
    """
    img = cv2.resize(img, self.input_size)
    img = np.expand_dims(img, axis=0)

    if self.model_name == "resnet50":
    img = tf.keras.applications.resnet50.preprocess_input(img)
    elif self.model_name == "vgg16":
    img = tf.keras.applications.vgg16.preprocess_input(img)

    return img

    def extract(self, img: np.ndarray) –> np.ndarray:
    """
    从单张图像提取特征向量

    Parameters
    ———-
    img : np.ndarray
    BGR 图像 (H, W, 3)

    Returns
    ——-
    np.ndarray
    特征向量,形状 (feature_dim,)
    """
    preprocessed = self.preprocess(img)
    features = self.base_model.predict(preprocessed, verbose=0)
    return features.flatten()

    def extract_batch(self, images: List[np.ndarray]) –> np.ndarray:
    """
    批量提取特征向量

    Parameters
    ———-
    images : List[np.ndarray]
    BGR 图像列表

    Returns
    ——-
    np.ndarray
    特征向量矩阵,形状 (N, feature_dim)
    """
    features_list = []
    for img in images:
    feats = self.extract(img)
    features_list.append(feats)
    return np.array(features_list, dtype=np.float64)

    def get_feature_map_model(self, layer_idx: int):
    """
    获取指定卷积层的输出模型(用于可视化特征图)

    Parameters
    ———-
    layer_idx : int
    目标卷积层的索引

    Returns
    ——-
    tf.keras.Model
    截断模型,输出为指定层的特征图
    """
    inputs = self.base_model.inputs
    outputs = self.base_model.layers[layer_idx].output
    return tf.keras.Model(inputs=inputs, outputs=outputs)

    def visualize_feature_maps(
    self, img: np.ndarray, layer_idx: int, max_maps: int = 64
    ) –> np.ndarray:
    """
    可视化指定层的特征图

    Parameters
    ———-
    img : np.ndarray
    输入图像
    layer_idx : int
    卷积层索引
    max_maps : int
    最多显示的特征图数量

    Returns
    ——-
    np.ndarray
    可视化的特征图网格图像
    """
    import matplotlib.pyplot as plt

    preprocessed = self.preprocess(img)
    fm_model = self.get_feature_map_model(layer_idx)
    feature_maps = fm_model.predict(preprocessed, verbose=0)

    # 取第一个样本
    if feature_maps.ndim == 4:
    feature_maps = feature_maps[0]

    n_maps = min(feature_maps.shape[–1], max_maps)
    grid_size = int(np.ceil(np.sqrt(n_maps)))

    fig, axes = plt.subplots(grid_size, grid_size, figsize=(12, 12))
    for i in range(grid_size * grid_size):
    row, col = i // grid_size, i % grid_size
    if i < n_maps:
    axes[row, col].imshow(
    feature_maps[:, :, i], cmap="viridis"
    )
    axes[row, col].axis("off")

    plt.tight_layout()
    return fig

    def load_images_from_folder(
    folder_path: str, input_size: Tuple[int, int] = (224, 224)
    ) –> Tuple[List[str], List[np.ndarray]]:
    """
    从文件夹加载所有图像

    Parameters
    ———-
    folder_path : str
    图像文件夹路径
    input_size : Tuple[int, int]
    统一的图像尺寸

    Returns
    ——-
    Tuple[List[str], List[np.ndarray]]
    (文件名列表, 图像数组列表)
    """
    import os

    valid_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp"}
    image_names = []
    images = []

    for filename in sorted(os.listdir(folder_path)):
    ext = os.path.splitext(filename)[1].lower()
    if ext not in valid_extensions:
    continue

    filepath = os.path.join(folder_path, filename)
    img = cv2.imread(filepath)
    if img is None:
    print(f"Warning: Failed to load {filepath}")
    continue

    image_names.append(filename)
    images.append(img)

    print(f"Loaded {len(images)} images from {folder_path}")
    return image_names, images

    clustering.py

    """
    图像聚类模块

    使用 CNN 提取的特征向量进行无监督聚类。
    支持多种聚类算法:
    – 层次聚类 (Agglomerative Clustering) — 文章推荐方法
    – K-Means
    – DBSCAN(适用于未知类别数量的场景)
    """

    import numpy as np
    import pandas as pd
    from typing import Dict, List, Tuple, Optional
    from sklearn.cluster import (
    AgglomerativeClustering,
    KMeans,
    DBSCAN,
    )
    from sklearn.preprocessing import StandardScaler
    from sklearn.decomposition import PCA
    from sklearn.manifold import TSNE

    class ImageClusterer:
    """
    图像聚类器

    Parameters
    ———-
    n_clusters : int
    聚类数量
    method : str
    聚类算法: 'agglomerative', 'kmeans', 'dbscan'
    random_state : int
    随机种子(保证可复现性)
    """

    def __init__(
    self,
    n_clusters: int = 2,
    method: str = "agglomerative",
    random_state: int = 42,
    ):
    self.n_clusters = n_clusters
    self.method = method.lower()
    self.random_state = random_state

    if self.method == "agglomerative":
    self.model = AgglomerativeClustering(n_clusters=n_clusters)
    elif self.method == "kmeans":
    self.model = KMeans(
    n_clusters=n_clusters,
    random_state=random_state,
    n_init=10,
    )
    elif self.method == "dbscan":
    self.model = DBSCAN(eps=0.5, min_samples=5)
    else:
    raise ValueError(f"Unsupported clustering method: {method}")

    self.scaler = StandardScaler()
    self.labels_: Optional[np.ndarray] = None
    self.feature_matrix_: Optional[np.ndarray] = None

    def fit(self, feature_matrix: np.ndarray) –> np.ndarray:
    """
    对特征矩阵进行聚类

    Parameters
    ———-
    feature_matrix : np.ndarray
    特征向量矩阵,形状 (N, D)

    Returns
    ——-
    np.ndarray
    聚类标签,形状 (N,)
    """
    # 标准化特征
    self.feature_matrix_ = feature_matrix
    scaled_features = self.scaler.fit_transform(feature_matrix)
    self.labels_ = self.model.fit_predict(scaled_features)
    return self.labels_

    def get_cluster_stats(self) –> Dict[int, int]:
    """
    获取每个簇的样本数量

    Returns
    ——-
    Dict[int, int]
    {cluster_id: count}
    """
    if self.labels_ is None:
    raise RuntimeError("Please call fit() first.")
    unique, counts = np.unique(self.labels_, return_counts=True)
    return dict(zip(unique.tolist(), counts.tolist()))

    def reduce_dimensions(
    feature_matrix: np.ndarray,
    method: str = "pca",
    n_components: int = 2,
    random_state: int = 42,
    ) –> np.ndarray:
    """
    降维到 2D/3D 用于可视化

    Parameters
    ———-
    feature_matrix : np.ndarray
    特征向量矩阵
    method : str
    降维方法: 'pca' 或 'tsne'
    n_components : int
    目标维度
    random_state : int
    随机种子

    Returns
    ——-
    np.ndarray
    降维后的矩阵,形状 (N, n_components)
    """
    if method.lower() == "pca":
    reducer = PCA(n_components=n_components, random_state=random_state)
    elif method.lower() == "tsne":
    reducer = TSNE(
    n_components=n_components,
    random_state=random_state,
    perplexity=min(30, len(feature_matrix) – 1),
    )
    else:
    raise ValueError(f"Unknown reduction method: {method}")

    return reducer.fit_transform(feature_matrix)

    def create_results_dataframe(
    image_names: List[str],
    feature_matrix: np.ndarray,
    labels: np.ndarray,
    ) –> pd.DataFrame:
    """
    创建结果 DataFrame,包含图像名、特征向量和聚类标签

    Parameters
    ———-
    image_names : List[str]
    图像文件名列表
    feature_matrix : np.ndarray
    特征向量矩阵
    labels : np.ndarray
    聚类标签

    Returns
    ——-
    pd.DataFrame
    """
    df = pd.DataFrame(
    {
    "photo_name": image_names,
    "cluster_label": labels,
    }
    )

    # 添加特征向量列
    for i in range(feature_matrix.shape[1]):
    df[f"feature_{i}"] = feature_matrix[:, i]

    return df

    main.py

    #!/usr/bin/env python3
    """
    使用 Python+OpenCV+Tensorflow 实现图像聚类

    基于预训练 CNN (ResNet50) 提取图像特征,无需标注数据即可进行无监督图像聚类。

    数据集: Keep Babies Safe (Kaggle)
    将图像分为"玩具"和"消费品"两类

    核心流程:
    1. 加载图像 → ResNet50 提取特征向量 (2048-d)
    2. 标准化特征 → 层次聚类 (Agglomerative Clustering)
    3. PCA/TSNE 降维 → 2D 散点图可视化
    4. 按簇展示样本图像

    Usage:
    # 下载数据集到 ./dataset/ 文件夹后运行:
    python main.py –data_dir ./dataset/keep-babies-safe/ –n_clusters 2

    # 也可用其他图像文件夹测试:
    python main.py –data_dir ./my_images/ –n_clusters 3
    """

    import os
    import sys
    import argparse
    import time
    import numpy as np

    # 添加当前目录到路径
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

    from feature_extractor import CNNFeatureExtractor, load_images_from_folder
    from clustering import (
    ImageClusterer,
    reduce_dimensions,
    create_results_dataframe,
    )
    from visualize import (
    plot_cluster_scatter,
    plot_sample_images,
    plot_cluster_distribution,
    )

    def main(args):
    # ============================================================
    # Step 1: 加载图像
    # ============================================================
    print("=" * 60)
    print("Step 1/5: Loading images…")
    print("=" * 60)

    image_names, images = load_images_from_folder(args.data_dir)

    if len(images) < 2:
    print(f"Error: Need at least 2 images, got {len(images)}")
    print("请先从 Kaggle 下载数据集到 ./dataset/ 目录:")
    print(" https://www.kaggle.com/akash14/keep-babies-safe")
    sys.exit(1)

    print(f" ✓ Loaded {len(images)} images")

    # ============================================================
    # Step 2: 提取 CNN 特征
    # ============================================================
    print("=" * 60)
    print("Step 2/5: Extracting features with ResNet50…")
    print("=" * 60)

    extractor = CNNFeatureExtractor(
    model_name=args.model,
    input_size=(args.img_size, args.img_size),
    )

    t0 = time.time()
    feature_matrix = extractor.extract_batch(images)
    elapsed = time.time() – t0

    print(f" ✓ Feature shape: {feature_matrix.shape}")
    print(f" ✓ Time elapsed: {elapsed:.1f}s ({elapsed/len(images):.1f}s per image)")

    # ============================================================
    # Step 3: 聚类
    # ============================================================
    print("=" * 60)
    print(f"Step 3/5: Clustering with {args.method}…")
    print("=" * 60)

    clusterer = ImageClusterer(
    n_clusters=args.n_clusters,
    method=args.method,
    )
    labels = clusterer.fit(feature_matrix)
    stats = clusterer.get_cluster_stats()

    print(f" ✓ Cluster distribution: {stats}")

    # ============================================================
    # Step 4: 降维 + 可视化
    # ============================================================
    print("=" * 60)
    print("Step 4/5: Reducing dimensions & visualizing…")
    print("=" * 60)

    # PCA 降维到 2D
    reduced = reduce_dimensions(
    feature_matrix,
    method=args.reduction,
    n_components=2,
    )

    os.makedirs(args.output_dir, exist_ok=True)

    # 散点图
    scatter_path = os.path.join(args.output_dir, "cluster_scatter.png")
    fig_scatter = plot_cluster_scatter(
    reduced,
    labels,
    image_names=image_names,
    title=f"Image Clustering Results ({args.method}, {args.n_clusters} clusters)",
    save_path=scatter_path,
    )
    print(f" ✓ Saved scatter plot to: {scatter_path}")

    # 分布图
    dist_path = os.path.join(args.output_dir, "cluster_distribution.png")
    fig_dist = plot_cluster_distribution(
    labels,
    title=f"Cluster Distribution ({len(images)} images)",
    save_path=dist_path,
    )
    print(f" ✓ Saved distribution plot to: {dist_path}")

    # 样本图
    sample_path = os.path.join(args.output_dir, "cluster_samples.png")
    fig_samples = plot_sample_images(
    images,
    image_names,
    labels,
    n_per_cluster=min(args.show_n, 8),
    save_path=sample_path,
    )
    print(f" ✓ Saved sample images to: {sample_path}")

    # ============================================================
    # Step 5: 保存结果
    # ============================================================
    print("=" * 60)
    print("Step 5/5: Saving results…")
    print("=" * 60)

    df = create_results_dataframe(image_names, feature_matrix, labels)
    csv_path = os.path.join(args.output_dir, "clustering_results.csv")
    df.to_csv(csv_path, index=False)
    print(f" ✓ Saved results to: {csv_path}")

    # 打印每个簇的前 N 个图像
    print("\\n" + "=" * 60)
    print("Clustering Summary")
    print("=" * 60)
    for label in sorted(stats.keys()):
    members = [image_names[i] for i in range(len(labels)) if labels[i] == label]
    print(f"\\n Cluster {label} ({stats[label]} images):")
    for m in members[:10]:
    print(f" – {m}")
    if len(members) > 10:
    print(f" … and {len(members) – 10} more")

    print("\\nDone! All outputs saved to:", args.output_dir)

    if __name__ == "__main__":
    parser = argparse.ArgumentParser(
    description="Image Clustering with Pre-trained CNN Features"
    )
    parser.add_argument(
    "–data_dir",
    type=str,
    default="./dataset/",
    help="Path to image directory",
    )
    parser.add_argument(
    "–n_clusters",
    type=int,
    default=2,
    help="Number of clusters (default: 2)",
    )
    parser.add_argument(
    "–method",
    type=str,
    default="agglomerative",
    choices=["agglomerative", "kmeans", "dbscan"],
    help="Clustering method (default: agglomerative)",
    )
    parser.add_argument(
    "–model",
    type=str,
    default="resnet50",
    choices=["resnet50", "vgg16"],
    help="CNN feature extractor (default: resnet50)",
    )
    parser.add_argument(
    "–img_size",
    type=int,
    default=224,
    help="Input image size (default: 224)",
    )
    parser.add_argument(
    "–reduction",
    type=str,
    default="pca",
    choices=["pca", "tsne"],
    help="Dimensionality reduction method (default: pca)",
    )
    parser.add_argument(
    "–output_dir",
    type=str,
    default="./output/",
    help="Output directory for results (default: ./output/)",
    )
    parser.add_argument(
    "–show_n",
    type=int,
    default=5,
    help="Number of sample images per cluster (default: 5)",
    )

    args = parser.parse_args()
    main(args)

    9. 参考资源

    • 原文链接
    • Keep Babies Safe 数据集
    • ResNet 论文
    • VGG16 论文
    • Scikit-learn 聚类算法对比
    赞(0)
    未经允许不得转载:171主机测评 » 【Clustering】Deep Image Clustering with TensorFlow
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址