代码拉取完成,页面将自动刷新
同步操作将从 mynameisi/faiss_dog_cat_question 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
import cv2 # 导入cv2模块,用于读取和处理图像
import numpy as np # 导入numpy模块,主要用于数值计算
import os # 导入os模块,用于处理文件和目录
from os.path import exists # 从os.path模块导入exists函数,用于检测文件或目录是否存在
from imutils import paths # 导入imutils中的paths工具,用于获取文件路径
import pickle # 导入pickle模块,用于序列化和反序列化Python对象结构
from tqdm import tqdm # 导入tqdm模块,用于在循环中添加进度条
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input # 从tensorflow.keras.applications导入VGG16模型及预处理函数
from tensorflow.keras.preprocessing import image # 从tensorflow.keras.preprocessing导入image工具,用于处理图像
import logging # 用于记录日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # 配置logging
# 定义函数get_size,获取文件大小,返回文件大小的兆字节的浮点数表示
def get_size(file):
"""
获取指定文件的大小(以MB为单位)
参数:
file (str): 文件的路径
返回:
float: 文件大小(MB)
"""
# TODO 填上函数的内容
size = os.path.getsize(file)
size = size / (1024 * 1024)
return size
# 定义函数createXY,用于从图像创建特征(X)和标签(y)
def createXY(train_folder, dest_folder, method='vgg', batch_size=64):
x_file_path = os.path.join(dest_folder, "X.pkl") # 设置X文件的路径,用于保存特征数据
y_file_path = os.path.join(dest_folder, "y.pkl") # 设置y文件的路径,用于保存标签数据
# 如果 X 和 y 已经存在,则直接读取,不再重新构建
if os.path.exists(x_file_path) and os.path.exists(y_file_path):
logging.info("X和y已经存在,直接读取") # 提示用户X和y文件已经存在
logging.info(f"X文件大小:{get_size(x_file_path):.2f}MB") # 打印X文件的大小
logging.info(f"y文件大小:{get_size(y_file_path):.2f}MB") # 打印y文件的大小
# TODO: 用 pickle 读取X和y文件
with open(x_file_path, 'rb') as x_file:
X = pickle.load(x_file)
with open(y_file_path, 'rb') as y_file:
y = pickle.load(y_file)
return X,y
logging.info("读取所有图像,生成X和y") # 提示用户开始读取图像并生成X和y
image_paths = list(paths.list_images(train_folder)) # 获取训练文件夹中所有图像的路径
X = [] # 初始化X列表,用于存储特征
y = [] # 初始化y列表,用于存储标签
# 根据传入的方法选择不同的模型
if method == 'vgg':
model = VGG16(weights='imagenet', include_top=False, pooling="max") # 加载VGG16模型,不包括顶层,使用最大池化
logging.info("完成构建 VGG16 模型") # 提示用户VGG16模型构建完成
elif method == 'flat':
model = None # 如果方法为'flat',不使用任何预训练模型
# 计算需要的批次数
num_batches = len(image_paths) // batch_size + (1 if len(image_paths) % batch_size else 0)
# 使用进度条对批次进行循环处理
for idx in tqdm(range(num_batches), desc="读取图像"):
batch_images = [] # 初始化存储批次图像的列表
batch_labels = [] # 初始化存储批次标签的列表
start = idx * batch_size # 计算批次开始的索引
end = min((idx + 1) * batch_size, len(image_paths)) # 计算批次结束的索引
# 对于每个批次中的图像
for i in range(start, end):
image_path = image_paths[i] # 获取图像路径
if method == 'vgg':
img = image.load_img(image_path, target_size=(224, 224)) # 加载图像并调整大小到224x224
img = image.img_to_array(img) # 将图像转换为数组
elif method == 'flat':
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 以灰度模式读取图像
img = cv2.resize(img, (32, 32)) # 调整图像大小到32x32
batch_images.append(img) # 将图像数组添加到批次图像列表
label = os.path.basename(image_path).split(".")[0] # 从文件名中解析出字符串标签
label = 1 if label == 'dog' else 0 # 如果标签是'dog'则为1,否则为0
batch_labels.extend([label]) # 将标签添加到批次标签列表
batch_images = np.array(batch_images) # 将批次图像列表转换为numpy数组
if method == 'vgg':
batch_images = preprocess_input(batch_images) # 对批次图像进行预处理
batch_pixels = model.predict(batch_images, verbose=0) # 使用VGG16模型进行预测
else:
batch_pixels = batch_images.reshape(batch_images.shape[0], -1) # 将 batch_images 展平,注意,要站平的不只是一张图像
X.extend(batch_pixels) # 将处理后的图像特征添加到X列表
y.extend(batch_labels) # 将标签添加到y列表
logging.info(f"X.shape: {np.shape(X)}") # 打印X的形状
logging.info(f"y.shape: {np.shape(y)}") # 打印y的形状
# 将X和y分别序列化到文件
# TODO: 用 pickle 保存X和y文件
with open(x_file_path, 'wb') as x_file:
pickle.dump(X, x_file)
with open(y_file_path, 'wb') as y_file:
pickle.dump(y, y_file)
return X, y # 返回构建的X和y
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。