使用 Python 对本地图片进行图像分类
Python 图像分类入门
在完成图像分类的入门学习后,若要利用本地图片开展分类任务,需针对数据处理与模型应用流程进行专门调整。下面将详细阐述从数据准备到模型预测,使用本地图片进行图像分类的具体方法。
一、数据准备
(一)规整数据目录结构
首要任务是将本地图片按类别分别存放在不同文件夹中,文件夹名称即为图像所属类别。分别用于存放猫和狗的图片。这种清晰的目录结构能极大便利后续数据读取,并实现标签的自动生成。如图
(二)读取图片数据及标签
运用os
和PIL
(Python Imaging Library,安装Pillow
库即可使用)库来读取图片数据及其对应的标签。代码如下:
# 定义图片尺寸和类别列表
img_size = (32, 32)class_names = os.listdir('G:\img') # 请将此处路径替换为本地图片根目录路径
data = []
labels = []
# Load images, resize them, convert to numpy arrays, and store in data list
# Store corresponding labels in labels list
for class_name in class_names:class_path = os.path.join('G:\img', class_name) # 请将此处路径替换为本地图片根目录路径#打印print(f"Processing class: {class_name}")for img_name in os.listdir(class_path):img_path = os.path.join(class_path, img_name)img = Image.open(img_path).convert('RGB').resize(img_size) # Convert image to RGBimg = np.array(img)data.append(img)labels.append(class_names.index(class_name))
# Convert the data list to a NumPy array
data = np.array(data)
在上述代码中,程序会遍历每个类别文件夹下的所有图片,将其尺寸调整为统一大小,再转换为数组形式并存入data
列表;同时,依据类别文件夹顺序生成对应的标签,存入labels
列表,最终将这两个列表转换为 NumPy 数组,方便后续处理。
(三)数据预处理操作
与之前处理 CIFAR - 10 数据集类似,需要对本地图片数据执行归一化和标签编码操作:
# 数据预处理
data = data.astype('float32') / 255.0
# 使用 to_categorical 函数将标签转换为 one-hot 编码形式,
# 方便在分类任务中计算损失和评估模型
labels = to_categorical(labels, len(class_names))
归一化操作将图片像素值从 0 - 255 范围缩放到 0 - 1,有助于提升模型训练效率与收敛速度;标签编码则将类别标签转换为 one - hot 编码形式,适配多分类模型的输入要求。
二、模型构建与训练流程
(一)搭建模型架构
既可以沿用之前教程中构建的 CNN 模型结构,也能依据实际情况灵活调整模型复杂度,以更好地适配本地图片数据特点。
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(img_size[0], img_size[1], 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.25))model.add(Conv2D(64, (3, 3), activation='relu'))model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(img_size[0], img_size[1], 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.25))model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.25))model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(class_names), activation='softmax'))
该模型结构中,卷积层(Conv2D)负责通过卷积核滑动提取图片的局部特征;池化层(MaxPooling2D)利用最大池化操作对特征图进行下采样,有效减少特征图尺寸,降低计算量;Flatten 层将多维特征图转换为一维向量,以便输入全连接层(Dense)进行分类;Dropout 层则在训练过程中随机丢弃部分神经元,防止模型过拟合,确保模型具有良好的泛化能力。
(二)编译模型参数
同样要精心选择合适的优化器、损失函数和评估指标,对模型进行编译:
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
这里选用adam
优化器,它是一种自适应学习率的优化算法,能在训练进程中自动调整学习率,加快模型收敛速度;对于多分类问题,采用categorical_crossentropy
交叉熵损失函数,精准衡量模型预测结果与真实标签间的差异;同时,将accuracy
准确率作为评估指标,便于在训练和测试阶段实时监控模型性能表现。
(三)划分数据集并启动训练
为全面评估模型性能,必须将数据划分为训练集和测试集。此处借助sklearn
库的train_test_split
函数来完成划分:
#划分数据集并启动训练
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)
history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=64, verbose=2)
train_test_split
函数将数据集按 80% 训练集、20% 测试集的比例进行划分,确保训练集用于模型训练,测试集用于评估模型在未见过数据上的表现。model.fit
函数启动模型训练,指定训练轮数为 20 次,每次训练使用 64 张图片作为一个批次,verbose=2
表示训练过程中打印较为简洁的训练信息,方便用户监控训练进度。
三、模型评估与预测步骤
(一)开展模型评估
模型训练完成后,需在测试集上全面评估其性能:
test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)
print(f'\nTest accuracy: {test_acc}')
#绘制训练和验证的损失曲线
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss')
plt.xlabel('Epoch')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Accuracy')
plt.xlabel('Epoch')
plt.legend()
plt.show()
model.evaluate
函数返回模型在测试集上的损失值和准确率。通过分析这些评估结果,能够精准了解模型在未知数据上的泛化能力,判断模型是否达到预期效果。通过图形显示指标
(二)进行模型预测
保存训练结果模型
model_path = 'meter_model/img_meter_model.keras'
model.save(model_path)
对新的本地图片进行预测,其步骤与之前类似:
img_path = r'XXXXXXXXX.jpg'
# Use a raw string for the file path
try:# Use the imported load_img functionimg = load_img(img_path, target_size=img_size)img = img_to_array(img)img = np.expand_dims(img, axis = 0)img = img / 255.0# 预测# 加载模型(请将此处路径替换为实际模型路径)# Change file extension to .kerasmodel_path = 'meter_model/img_meter_model.keras'# Bug fix: Import the correct load_model functionfrom tensorflow.keras.models import load_modeltry:# 加载已保存的模型model = load_model(model_path)print("模型加载成功")predictions = model.predict(img)predicted_index = np.argmax(predictions)predicted_class = class_names[predicted_index]print('Predicted class:', predicted_class)except FileNotFoundError:print(f"Error: The model file {model_path} was not found. Please check the file path.")
首先,加载新图片并将其尺寸调整为与训练数据一致,转换为数组形式后进行归一化处理;接着,使用训练好的模型对图片进行预测,model.predict
函数返回一个概率数组,数组中每个元素代表图片属于对应类别的概率;最后,利用np.argmax
函数获取概率最大的类别索引,从而确定图片的预测类别。
通过以上系统步骤,便能顺利使用 Python 对本地图片进行图像分类。在实际操作过程中,可依据图片数量的多寡、类别复杂程度等因素,进一步优化模型结构和数据处理方式。例如,引入数据增强技术,对训练数据进行旋转、翻转、裁剪等操作,扩充数据集的多样性,显著提升模型的泛化能力 。