要使用 AI 筛选本地图片(尤其是根据个人喜好筛选美女图片),并利用本地显卡进行高效处理,你可以参考以下现成的、易于部署的方案。这些方案通常基于深度学习模型,支持通过“喜好反馈”训练模型,从而自动筛选符合你口味的图片。
原理:
步骤:
pip install torch torchvision ftfy regex tqdm git+https://github.com/openai/CLIP.git
liked/
disliked/
.npy
scikit-learn
优点:
参考项目:
LAION-Aesthetics
pip install label-studio lightly
PhotoPrism
Digikam
Immich
如果你有 Python 基础,可以参考以下流程:
torchvision.models
SGDClassifier
XGBoost
示例代码:
from sklearn.linear_model import SGDClassifier import numpy as np from PIL import Image import clip # 加载 CLIP 模型 device = "cuda" if torch.cuda.is_available() else "cpu" model, preprocess = clip.load("ViT-B/32", device=device) # 提取图片特征 def get_image_features(image_path): image = preprocess(Image.open(image_path)).unsqueeze(0).to(device) with torch.no_grad(): features = model.encode_image(image) return features.cpu().numpy() # 训练分类器 X = [] # 所有图片的特征向量 y = [] # 标签(1=喜欢,0=不喜欢) for path, label in zip(liked_images, [1]*len(liked_images)): X.append(get_image_features(path)) y.append(label) for path, label in zip(disliked_images, [0]*len(disliked_images)): X.append(get_image_features(path)) y.append(label) clf = SGDClassifier() clf.fit(X, y) # 筛选新图片 new_features = get_image_features("new_image.jpg") prediction = clf.predict([new_features])
nvidia-smi
好的!以下是基于 CLIP 的图片筛选方案的详细步骤,适合在本地 GPU 上运行,通过“喜好反馈”自动筛选你喜欢的图片。整个过程分为环境准备、数据标记、特征提取、模型训练、筛选预测五个阶段,每一步都有具体的代码和操作说明。
确保你的机器已安装:
python -m venv clip_env source clip_env/bin/activate # Linux/Mac # 或 clip_env\Scripts\activate # Windows
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
pip install ftfy regex tqdm git+https://github.com/openai/CLIP.git scikit-learn pillow numpy
将你的图片分为两个文件夹:
示例结构:
your_project/ ├── liked/ │ ├── img1.jpg │ ├── img2.jpg │ └── ... ├── disliked/ │ ├── img101.jpg │ ├── img102.jpg │ └── ... └── unsorted/ # 待筛选的图片
注意:
使用 CLIP 模型将每张图片转换为向量特征,并保存到 .npy 文件。
代码: 创建 extract_features.py:
extract_features.py
import os import torch import clip import numpy as np from PIL import Image from tqdm import tqdm # 加载 CLIP 模型 device = "cuda" if torch.cuda.is_available() else "cpu" model, preprocess = clip.load("ViT-B/32", device=device) def extract_features_from_folder(folder_path, output_path): features = [] filenames = [] for filename in tqdm(os.listdir(folder_path)): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): try: image_path = os.path.join(folder_path, filename) image = preprocess(Image.open(image_path)).unsqueeze(0).to(device) with torch.no_grad(): feature = model.encode_image(image) features.append(feature.cpu().numpy()) filenames.append(filename) except Exception as e: print(f"Error processing {filename}: {e}") np.save(output_path, { "features": np.concatenate(features, axis=0), "filenames": filenames }) # 提取喜欢和不喜欢的图片特征 extract_features_from_folder("liked", "liked_features.npy") extract_features_from_folder("disliked", "disliked_features.npy")
运行:
python extract_features.py
输出:
liked_features.npy
disliked_features.npy
使用 scikit-learn 训练一个简单的分类器(如 SVM 或 Logistic Regression),学习你的喜好。
代码: 创建 train_classifier.py:
train_classifier.py
import numpy as np from sklearn.svm import SVC from sklearn.linear_model import LogisticRegression import joblib # 加载特征 liked_data = np.load("liked_features.npy", allow_pickle=True) disliked_data = np.load("disliked_features.npy", allow_pickle=True) X = np.concatenate([liked_data["features"], disliked_data["features"]], axis=0) y = np.concatenate([ np.ones(len(liked_data["features"])), # 1 = 喜欢 np.zeros(len(disliked_data["features"])) # 0 = 不喜欢 ], axis=0) # 训练分类器(可选 SVM 或 Logistic Regression) # clf = SVC(kernel='linear', probability=True) clf = LogisticRegression() clf.fit(X, y) # 保存模型 joblib.dump(clf, "preference_classifier.pkl")
python train_classifier.py
preference_classifier.pkl
加载训练好的模型,为 unsorted/ 文件夹中的图片打分,并输出“可能喜欢”的图片。
unsorted/
代码: 创建 filter_images.py:
filter_images.py
import os import torch import clip import numpy as np from PIL import Image from tqdm import tqdm import joblib # 加载 CLIP 模型和分类器 device = "cuda" if torch.cuda.is_available() else "cpu" model, preprocess = clip.load("ViT-B/32", device=device) clf = joblib.load("preference_classifier.pkl") def predict_folder(folder_path, output_dir="selected"): if not os.path.exists(output_dir): os.makedirs(output_dir) for filename in tqdm(os.listdir(folder_path)): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): try: image_path = os.path.join(folder_path, filename) image = preprocess(Image.open(image_path)).unsqueeze(0).to(device) with torch.no_grad(): feature = model.encode_image(image) prob = clf.predict_proba(feature.cpu().numpy())[0][1] # P(喜欢) if prob > 0.7: # 阈值可调(0.5~0.9) os.system(f"cp {image_path} {output_dir}/") print(f"Selected {filename} with probability {prob:.2f}") except Exception as e: print(f"Error processing {filename}: {e}") predict_folder("unsorted", "selected")
python filter_images.py
selected/
prob > 0.7
0.5
如果筛选结果不理想:
ViT-L/14
model, preprocess = clip.load("ViT-L/14", device=device)
batch_size
使用 Gradio 搭建简单的 Web UI,实时标记和筛选:
import gradio as gr import os import shutil def move_image(image_path, label): filename = os.path.basename(image_path) dest = "liked" if label == "Like" else "disliked" shutil.copy(image_path, f"{dest}/{filename}") return f"Moved to {dest}/" gr.Interface( fn=move_image, inputs=[gr.Textbox(label="Image Path"), gr.Radio(["Like", "Dislike"], label="Your Preference")], outputs="text", ).launch()
# 在 extract_features.py 中修改 batch_size = 8 # 根据显存调整
torch.no_grad()
del
del image, feature torch.cuda.empty_cache()
from multiprocessing import Pool
RandomForest
your_project/ ├── liked/ ├── disliked/ ├── unsorted/ ├── selected/ ├── extract_features.py ├── train_classifier.py ├── filter_images.py ├── liked_features.npy ├── disliked_features.npy └── preference_classifier.pkl
This is a shared conversation and may include unverified content that doesn't reflect Mistral AI's views. Login to resume chatting.
Vibe can make mistakes. Check answers. Learn more