cqu 数据挖掘 图片标签识别

一、实验目的

1. 熟悉数据标注的流程,熟悉相关的函数;

2. 学习运用Python对手写数字图片进行数据标注,实现数据预处理;

3. 学习KNN,SVN,CNN三种网络模型分别对MNIST手写数据集以及手写数字图片数据集进行识别并计算预测准确率。

二、使用仪器、材料

环境:Python 3.12.4 (Anaconda3)

开发工具:Visual Studio Code

三、实验过程原始记录及实验结果分析

3.1处理MNIST手写数据集

3.1.1 KNN(K-近邻算法)

~~~
python代码:
import struct
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import os
import joblib # 用于保存和加载模型
# 设置中文字体以支持中文标签
# 请确保系统中安装了相应的中文字体,例如SimHei或SimSun
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示为方块的问题
# 定义读取IDX文件的函数
def read_idx_images(filename):
with open(filename, 'rb') as f:
magic, num, rows, cols = struct.unpack('>IIII', f.read(16))
if magic != 2051:
raise ValueError(f'无效的魔数 {magic} 在图像文件: {filename}')
images = np.frombuffer(f.read(), dtype=np.uint8).reshape(num, rows, cols)
return images
def read_idx_labels(filename):
with open(filename, 'rb') as f:
magic, num = struct.unpack('>II', f.read(8))
if magic != 2049:
raise ValueError(f'无效的魔数 {magic} 在标签文件: {filename}')
labels = np.frombuffer(f.read(), dtype=np.uint8)
return labels
# 配置文件路径
train_images_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\train-images.idx3-ubyte'
train_labels_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\train-labels.idx1-ubyte'
test_images_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-images.idx3-ubyte'
test_labels_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-labels.idx1-ubyte'
# 检查文件是否存在
for path in [train_images_path, train_labels_path, test_images_path, test_labels_path]:
if not os.path.exists(path):
raise FileNotFoundError(f'文件未找到: {path}')
# 读取数据
print("正在读取训练图像...")
train_images = read_idx_images(train_images_path)
print("正在读取训练标签...")
train_labels = read_idx_labels(train_labels_path)
print("正在读取测试图像...")
test_images = read_idx_images(test_images_path)
print("正在读取测试标签...")
test_labels = read_idx_labels(test_labels_path)
print(f"训练图像数量: {train_images.shape[0]}")
print(f"测试图像数量: {test_images.shape[0]}")
# 数据预处理
# 归一化图像数据到 [0, 1]
train_images = train_images.astype('float32') / 255.0
test_images = test_images.astype('float32') / 255.0
# KNN需要二维的输入,因此将28x28的图像展平为784维的向量
train_images_flat = train_images.reshape(train_images.shape[0], -1) # 形状: (60000, 784)
test_images_flat = test_images.reshape(test_images.shape[0], -1) # 形状: (10000, 784)
# 查看一张图像
plt.imshow(train_images[0], cmap='gray')
plt.title(f"标签: {train_labels[0]}", fontproperties='SimHei')
plt.axis('off')
plt.show()
# 构建KNN模型
knn = KNeighborsClassifier(n_neighbors=3, n_jobs=-1) # 使用3个邻居,n_jobs=-1使用所有CPU核心
# 训练模型
print("正在训练KNN模型...")
knn.fit(train_images_flat, train_labels)
print("KNN模型训练完成。")
# 评估模型
print("正在评估KNN模型...")
test_predictions = knn.predict(test_images_flat)
test_accuracy = accuracy_score(test_labels, test_predictions)
print(f"\n测试准确率: {test_accuracy}")
# 打印分类报告
print("\n分类报告:")
print(classification_report(test_labels, test_predictions, target_names=[str(i) for i in range(10)]))
# 混淆矩阵
cm = confusion_matrix(test_labels, test_predictions)
plt.figure(figsize=(10, 8))
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.title('混淆矩阵', fontproperties='SimHei')
plt.colorbar()
tick_marks = np.arange(10)
plt.xticks(tick_marks, [str(i) for i in range(10)], rotation=45, fontproperties='SimHei')
plt.yticks(tick_marks, [str(i) for i in range(10)], fontproperties='SimHei')
# 在每个单元格上显示数字
thresh = cm.max() / 2.
for i in range(cm.shape[0]):
for j in range(cm.shape[1]):
plt.text(j, i, format(cm[i, j], 'd'),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black",
fontproperties='SimHei')
plt.ylabel('真实标签', fontproperties='SimHei')
plt.xlabel('预测标签', fontproperties='SimHei')
plt.tight_layout()
plt.show()
# 保存KNN模型
model_save_path = 'mnist_knn_model.joblib'
joblib.dump(knn, model_save_path)
print(f"模型已保存为 {model_save_path}")
# 加载并使用保存的KNN模型(示例)
# loaded_knn = joblib.load(model_save_path)
# example_image = test_images_flat[0].reshape(1, -1)
# example_prediction = loaded_knn.predict(example_image)
# print(f"加载的模型预测结果: {example_prediction[0]}, 真实标签: {test_labels[0]}")
~~~

运行结果:

终端输出:

PS E:\CODE\DataMining\teamWork\model> & E:/software/Anaconda3/python.exe e:/CODE/DataMining/teamWork/model/mnistKNN.py

正在读取训练图像…

正在读取训练标签…

正在读取测试图像…

正在读取测试标签…

训练图像数量: 60000

测试图像数量: 10000

正在训练KNN模型…

KNN模型训练完成。

正在评估KNN模型…

测试准确率: 0.9705

分类报告:

              precision    recall  f1-score   support

           0       0.97      0.99      0.98       980

           1       0.96      1.00      0.98      1135

           2       0.98      0.97      0.97      1032

           3       0.96      0.97      0.96      1010

           4       0.98      0.97      0.97       982

           5       0.97      0.96      0.96       892

           6       0.98      0.99      0.98       958

           7       0.96      0.96      0.96      1028

           8       0.99      0.94      0.96       974

           9       0.96      0.96      0.96      1009

    accuracy                           0.97     10000

   macro avg       0.97      0.97      0.97     10000

weighted avg       0.97      0.97      0.97     10000

3.1.2 CNN(卷积神经网络)

~~~
python代码:
import struct
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.utils import to_categorical
import os
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示为方块的问题
# 定义读取IDX文件的函数
def read_idx_images(filename):
with open(filename, 'rb') as f:
magic, num, rows, cols = struct.unpack('>IIII', f.read(16))
if magic != 2051:
raise ValueError(f'无效的魔数 {magic} 在图像文件: {filename}')
images = np.frombuffer(f.read(), dtype=np.uint8).reshape(num, rows, cols)
return images
def read_idx_labels(filename):
with open(filename, 'rb') as f:
magic, num = struct.unpack('>II', f.read(8))
if magic != 2049:
raise ValueError(f'无效的魔数 {magic} 在标签文件: {filename}')
labels = np.frombuffer(f.read(), dtype=np.uint8)
return labels
# 配置文件路径
train_images_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-images.idx3-ubyte'
train_labels_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-labels.idx1-ubyte'
test_images_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-images.idx3-ubyte'
test_labels_path = r'E:\CODE\DataMining\teamWork\dataset\mnist\t10k-labels.idx1-ubyte'
# 检查文件是否存在
for path in [train_images_path, train_labels_path, test_images_path, test_labels_path]:
if not os.path.exists(path):
raise FileNotFoundError(f'文件未找到: {path}')
# 读取数据
print("正在读取训练图像...")
train_images = read_idx_images(train_images_path)
print("正在读取训练标签...")
train_labels = read_idx_labels(train_labels_path)
print("正在读取测试图像...")
test_images = read_idx_images(test_images_path)
print("正在读取测试标签...")
test_labels = read_idx_labels(test_labels_path)
print(f"训练图像数量: {train_images.shape[0]}")
print(f"测试图像数量: {test_images.shape[0]}")
# 数据预处理
# 归一化图像数据到 [0, 1]
train_images = train_images.astype('float32') / 255.0
test_images = test_images.astype('float32') / 255.0
# 添加通道维度(因为CNN需要4D输入)
train_images = np.expand_dims(train_images, -1) # 形状: (60000, 28, 28, 1)
test_images = np.expand_dims(test_images, -1) # 形状: (10000, 28, 28, 1)
# 转换标签为独热编码
train_labels_categorical = to_categorical(train_labels, num_classes=10)
test_labels_categorical = to_categorical(test_labels, num_classes=10)
# 查看一张图像
plt.imshow(train_images[0].squeeze(), cmap='gray')
plt.title(f"标签: {train_labels[0]}")
plt.axis('off')
plt.show()
# 构建CNN模型
model = Sequential([
Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)),
MaxPooling2D(pool_size=(2, 2)),
Conv2D(64, kernel_size=(3, 3), activation='relu'),
MaxPooling2D(pool_size=(2, 2)),
Flatten(),
Dense(128, activation='relu'),
Dense(10, activation='softmax') # 10个类别
])
# 编译模型
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 显示模型摘要
model.summary()
# 训练模型
history = model.fit(train_images, train_labels_categorical,
epochs=10,
batch_size=128,
validation_split=0.1)
# 评估模型
test_loss, test_acc = model.evaluate(test_images, test_labels_categorical, verbose=2)
print(f"\n测试准确率: {test_acc}")
# 可视化训练过程
# 准确率曲线
plt.plot(history.history['accuracy'], label='训练准确率')
plt.plot(history.history['val_accuracy'], label='验证准确率')
plt.xlabel('Epoch')
plt.ylabel('准确率')
plt.legend()
plt.title('训练与验证准确率')
plt.show()
# 损失曲线
plt.plot(history.history['loss'], label='训练损失')
plt.plot(history.history['val_loss'], label='验证损失')
plt.xlabel('Epoch')
plt.ylabel('损失')
plt.legend()
plt.title('训练与验证损失')
plt.show()
# 使用模型进行预测
predictions = model.predict(test_images)
# 显示测试集中的第一张图像及其预测结果
predicted_label = np.argmax(predictions[0])
true_label = test_labels[0]
plt.imshow(test_images[0].squeeze(), cmap='gray')
plt.title(f"预测: {predicted_label}, 真实: {true_label}")
plt.axis('off')
plt.show()
# 保存模型
model.save('mnist_cnn_model.h5')
print("模型已保存为 mnist_cnn_model.h5")
~~~

运行结果:

终端输出:

PS E:\CODE\DataMining\teamWork\model> & E:/software/Anaconda3/python.exe e:/CODE/DataMining/teamWork/model/mnistCNN.py

正在读取训练图像…

正在读取训练标签…

正在读取测试图像…

正在读取测试标签…

训练图像数量: 10000

测试图像数量: 10000

Model: “sequential”

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓

┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃

┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩

│ conv2d (Conv2D)                      │ (None, 26, 26, 32)          │             320 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ max_pooling2d (MaxPooling2D)         │ (None, 13, 13, 32)          │               0 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ conv2d_1 (Conv2D)                    │ (None, 11, 11, 64)          │          18,496 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ max_pooling2d_1 (MaxPooling2D)       │ (None, 5, 5, 64)            │               0 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ flatten (Flatten)                    │ (None, 1600)                │               0 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ dense (Dense)                        │ (None, 128)                 │         204,928 │

├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤

│ dense_1 (Dense)                      │ (None, 10)                  │           1,290 │

└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘

 Total params: 225,034 (879.04 KB)

 Trainable params: 225,034 (879.04 KB)

 Non-trainable params: 0 (0.00 B)

Epoch 1/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 3s 15ms/step – accuracy: 0.6003 – loss: 1.2923 – val_accuracy: 0.9300 – val_loss: 0.2432

Epoch 2/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step – accuracy: 0.9467 – loss: 0.1809 – val_accuracy: 0.9580 – val_loss: 0.1479

Epoch 3/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step – accuracy: 0.9686 – loss: 0.1038 – val_accuracy: 0.9690 – val_loss: 0.1111

Epoch 4/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step – accuracy: 0.9704 – loss: 0.0910 – val_accuracy: 0.9620 – val_loss: 0.1114

Epoch 5/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step – accuracy: 0.9830 – loss: 0.0572 – val_accuracy: 0.9620 – val_loss: 0.1164

Epoch 6/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step – accuracy: 0.9842 – loss: 0.0529 – val_accuracy: 0.9730 – val_loss: 0.0847

Epoch 7/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step – accuracy: 0.9901 – loss: 0.0332 – val_accuracy: 0.9760 – val_loss: 0.0885

Epoch 8/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step – accuracy: 0.9896 – loss: 0.0292 – val_accuracy: 0.9730 – val_loss: 0.0860

Epoch 9/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step – accuracy: 0.9945 – loss: 0.0205 – val_accuracy: 0.9790 – val_loss: 0.0853

Epoch 10/10

71/71 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step – accuracy: 0.9946 – loss: 0.0173 – val_accuracy: 0.9830 – val_loss: 0.0791

313/313 – 0s – 1ms/step – accuracy: 0.9978 – loss: 0.0144

测试准确率: 0.9977999925613403

313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step 

3.1.3 SVM(支持向量机)

~~~

python代码:

import struct

import numpy as np

import matplotlib.pyplot as plt

import matplotlib

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

from sklearn.preprocessing import StandardScaler

import os

import joblib  # 用于保存和加载模型

# 设置中文字体以支持中文标签

# 请确保系统中安装了相应的中文字体,例如SimHeiSimSun

matplotlib.rcParams[‘font.sans-serif’] = [‘SimHei’]  # 设置中文字体为黑体

matplotlib.rcParams[‘axes.unicode_minus’] = False    # 解决负号显示为方块的问题

# 定义读取IDX文件的函数

def read_idx_images(filename):

    with open(filename, ‘rb’) as f:

        magic, num, rows, cols = struct.unpack(‘>IIII’, f.read(16))

        if magic != 2051:

            raise ValueError(f’无效的魔数 {magic} 在图像文件: {filename}’)

        images = np.frombuffer(f.read(), dtype=np.uint8).reshape(num, rows, cols)

    return images

def read_idx_labels(filename):

    with open(filename, ‘rb’) as f:

        magic, num = struct.unpack(‘>II’, f.read(8))

        if magic != 2049:

            raise ValueError(f’无效的魔数 {magic} 在标签文件: {filename}’)

        labels = np.frombuffer(f.read(), dtype=np.uint8)

    return labels

# 配置文件路径

train_images_path = r’E:\CODE\DataMining\teamWork\dataset\mnist\train-images.idx3-ubyte’

train_labels_path = r’E:\CODE\DataMining\teamWork\dataset\mnist\train-labels.idx1-ubyte’

test_images_path = r’E:\CODE\DataMining\teamWork\dataset\mnist\t10k-images.idx3-ubyte’

test_labels_path = r’E:\CODE\DataMining\teamWork\dataset\mnist\t10k-labels.idx1-ubyte’

# 检查文件是否存在

for path in [train_images_path, train_labels_path, test_images_path, test_labels_path]:

    if not os.path.exists(path):

        raise FileNotFoundError(f’文件未找到: {path}’)

# 读取数据

print(“正在读取训练图像…”)

train_images = read_idx_images(train_images_path)

print(“正在读取训练标签…”)

train_labels = read_idx_labels(train_labels_path)

print(“正在读取测试图像…”)

test_images = read_idx_images(test_images_path)

print(“正在读取测试标签…”)

test_labels = read_idx_labels(test_labels_path)

print(f”训练图像数量: {train_images.shape[0]}”)

print(f”测试图像数量: {test_images.shape[0]}”)

# 数据预处理

# 归一化图像数据到 [0, 1]

train_images = train_images.astype(‘float32’) / 255.0

test_images = test_images.astype(‘float32’) / 255.0

# KNN需要二维的输入,SVM同样需要,将28×28的图像展平为784维的向量

train_images_flat = train_images.reshape(train_images.shape[0], -1)  # 形状: (60000, 784)

test_images_flat = test_images.reshape(test_images.shape[0], -1)     # 形状: (10000, 784)

# 标准化特征

scaler = StandardScaler()

train_images_flat = scaler.fit_transform(train_images_flat)

test_images_flat = scaler.transform(test_images_flat)

# 查看一张图像

plt.imshow(train_images[0], cmap=’gray’)

plt.title(f”标签: {train_labels[0]}”, fontproperties=’SimHei’)

plt.axis(‘off’)

plt.show()

# 构建SVM模型

# 由于MNIST数据集较大,训练时间可能较长。可以考虑使用线性核或调整C参数。

svm = SVC(kernel=’rbf’, C=1.0, gamma=’scale’, verbose=True)  # 使用径向基核函数

# 训练模型

print(“正在训练SVM模型…”)

svm.fit(train_images_flat, train_labels)

print(“SVM模型训练完成。”)

# 评估模型

print(“正在评估SVM模型…”)

test_predictions = svm.predict(test_images_flat)

test_accuracy = accuracy_score(test_labels, test_predictions)

print(f”\n测试准确率: {test_accuracy}”)

# 打印分类报告

print(“\n分类报告:”)

print(classification_report(test_labels, test_predictions, target_names=[str(i) for i in range(10)]))

# 混淆矩阵

cm = confusion_matrix(test_labels, test_predictions)

plt.figure(figsize=(10, 8))

plt.imshow(cm, interpolation=’nearest’, cmap=plt.cm.Blues)

plt.title(‘混淆矩阵’, fontproperties=’SimHei’)

plt.colorbar()

tick_marks = np.arange(10)

plt.xticks(tick_marks, [str(i) for i in range(10)], rotation=45, fontproperties=’SimHei’)

plt.yticks(tick_marks, [str(i) for i in range(10)], fontproperties=’SimHei’)

# 在每个单元格上显示数字

thresh = cm.max() / 2.

for i in range(cm.shape[0]):

    for j in range(cm.shape[1]):

        plt.text(j, i, format(cm[i, j], ‘d’),

                 horizontalalignment=”center”,

                 color=”white” if cm[i, j] > thresh else “black”,

                 fontproperties=’SimHei’)

plt.ylabel(‘真实标签’, fontproperties=’SimHei’)

plt.xlabel(‘预测标签’, fontproperties=’SimHei’)

plt.tight_layout()

plt.show()

# 保存SVM模型

model_save_path = ‘mnist_svm_model.joblib’

joblib.dump(svm, model_save_path)

print(f”模型已保存为 {model_save_path}”)

# 加载并使用保存的SVM模型(示例)

# loaded_svm = joblib.load(model_save_path)

# example_image = test_images_flat[0].reshape(1, -1)

# example_prediction = loaded_svm.predict(example_image)

# print(f”加载的模型预测结果: {example_prediction[0]}, 真实标签: {test_labels[0]}”)

~~~

运行结果:

3.2处理手写数字图片数据集

3.2.1 预处理数据集(数据标注)

先将所有图片切片后数据清洗并打标记,剔除不符合规范的图片

3.2.2 KNN(K-近邻算法)

~~~
python代码:
import os
import re
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from PIL import Image
# 定义符合要求的文件名模式
pattern = re.compile(r"^\d{8}_\d{2}_\d{3}_[0-9]\.(jpg|png)$")
# 指定要搜索的文件目录
directory = r"E:\CODE\DataMining\teamWork\dataset\passdata"
# 创建数据集列表
images = []
labels = []
# 遍历文件列表
for file in os.listdir(directory):
    if pattern.match(file):
        file_path = os.path.join(directory, file)
        # 读取图像并转换为numpy数组
        image = Image.open(file_path).convert("L")  # 转换为灰度图
        image = image.resize((28, 28))  # 调整图像大小
        image = np.array(image).flatten()  # 展平图像
        images.append(image)
        # 提取标签
        label = int(file.split("_")[-1].split(".")[0])
        labels.append(label)
# 转换为numpy数组
images = np.array(images)
labels = np.array(labels)
# 归一化图像数据
images = images / 255.0
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    images, labels, test_size=0.2, random_state=42
)
# 构建KNN模型
knn = KNeighborsClassifier(n_neighbors=3)
# 训练模型
knn.fit(X_train, y_train)
# 预测测试集
y_pred = knn.predict(X_test)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f"测试集准确率: {accuracy * 100:.2f}%")
~~~

运行结果:

PS E:\CODE\DataMining\teamWork> & E:/software/Anaconda3/python.exe e:/CODE/DataMining/teamWork/model/datasetKNN.py

测试集准确率: 81.36%

3.2.3 CNN(卷积神经网络)

~~~
python代码:
import os
import re
import shutil
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import to_categorical
from PIL import Image
# 定义符合要求的文件名模式
pattern = re.compile(r"^\d{8}_\d{2}_\d{3}_[0-9]\.(jpg|png)$")
# 指定要搜索的文件目录
directory = r"E:\CODE\DataMining\teamWork\dataset\passdata"
# 创建数据集列表
images = []
labels = []
# 遍历文件列表
for file in os.listdir(directory):
    if pattern.match(file):
        file_path = os.path.join(directory, file)
        # 读取图像并转换为numpy数组
        image = Image.open(file_path).convert("L")  # 转换为灰度图
        image = image.resize((28, 28))  # 调整图像大小
        image = np.array(image)
        images.append(image)
        # 提取标签
        label = int(file.split("_")[-1].split(".")[0])
        labels.append(label)
# 转换为numpy数组
images = np.array(images)
labels = np.array(labels)
# 归一化图像数据
images = images / 255.0
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    images, labels, test_size=0.2, random_state=42
)
# 将标签转换为one-hot编码
y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)
# 构建CNN模型
model = Sequential(
    [
        Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)),
        MaxPooling2D((2, 2)),
        Conv2D(64, (3, 3), activation="relu"),
        MaxPooling2D((2, 2)),
        Flatten(),
        Dense(128, activation="relu"),
        Dense(10, activation="softmax"),
    ]
)
# 编译模型
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])
# 训练模型
model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test))
# 评估模型
loss, accuracy = model.evaluate(X_test, y_test)
print(f"测试集准确率: {accuracy * 100:.2f}%")
~~~

运行结果:

PS E:\CODE\DataMining\teamWork> & E:/software/Anaconda3/python.exe e:/CODE/DataMining/teamWork/model/datasetCNN.py

2024-11-28 17:45:35.358463: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.

2024-11-28 17:45:37.022833: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.

C:\Users\yanyifan\AppData\Roaming\Python\Python312\site-packages\keras\src\layers\convolutional\base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.

  super().__init__(activity_regularizer=activity_regularizer, **kwargs)

2024-11-28 17:46:23.334702: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.

To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.

Epoch 1/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 9s 5ms/step – accuracy: 0.5946 – loss: 1.2190 – val_accuracy: 0.9090 – val_loss: 0.3386

Epoch 2/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9334 – loss: 0.2623 – val_accuracy: 0.9507 – val_loss: 0.2004

Epoch 3/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9534 – loss: 0.1836 – val_accuracy: 0.9564 – val_loss: 0.1807

Epoch 4/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9638 – loss: 0.1413 – val_accuracy: 0.9597 – val_loss: 0.1630

Epoch 5/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9700 – loss: 0.1135 – val_accuracy: 0.9641 – val_loss: 0.1381

Epoch 6/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9743 – loss: 0.0976 – val_accuracy: 0.9601 – val_loss: 0.1460

Epoch 7/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9783 – loss: 0.0786 – val_accuracy: 0.9640 – val_loss: 0.1399

Epoch 8/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9817 – loss: 0.0673 – val_accuracy: 0.9652 – val_loss: 0.1413

Epoch 9/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step – accuracy: 0.9837 – loss: 0.0531 – val_accuracy: 0.9653 – val_loss: 0.1404

Epoch 10/10

1569/1569 ━━━━━━━━━━━━━━━━━━━━ 6s 4ms/step – accuracy: 0.9850 – loss: 0.0490 – val_accuracy: 0.9650 – val_loss: 0.1370

393/393 ━━━━━━━━━━━━━━━━━━━━ 1s 1ms/step – accuracy: 0.9639 – loss: 0.1392

测试集准确率: 96.50%

3.2.4 SVM(支持向量机)

~~~
python代码:
import os
import re
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from PIL import Image
# 定义符合要求的文件名模式
pattern = re.compile(r"^\d{8}_\d{2}_\d{3}_[0-9]\.(jpg|png)$")
# 指定要搜索的文件目录
directory = r"E:\CODE\DataMining\teamWork\dataset\passdata"
# 创建数据集列表
images = []
labels = []
# 遍历文件列表
for file in os.listdir(directory):
    if pattern.match(file):
        file_path = os.path.join(directory, file)
        # 读取图像并转换为numpy数组
        image = Image.open(file_path).convert("L")  # 转换为灰度图
        image = image.resize((28, 28))  # 调整图像大小
        image = np.array(image).flatten()  # 展平图像
        images.append(image)
        # 提取标签
        label = int(file.split("_")[-1].split(".")[0])
        labels.append(label)
# 转换为numpy数组
images = np.array(images)
labels = np.array(labels)
# 归一化图像数据
images = images / 255.0
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    images, labels, test_size=0.2, random_state=42
)
# 构建SVM模型
svm = SVC(kernel="linear")
# 训练模型
svm.fit(X_train, y_train)
# 预测测试集
y_pred = svm.predict(X_test)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f"测试集准确率: {accuracy * 100:.2f}%")
~~~

运行结果:

PS E:\CODE\DataMining\teamWork> & E:/software/Anaconda3/python.exe e:/CODE/DataMining/teamWork/model/datasetSVM.py

加载图像: 100%|████████████████████████████████████████████████████████| 62722/62722 [00:40<00:00, 1556.75it/s]

开始训练模型…

模型训练完成 测试集准确率: 61.73%

本技术内容仅供学习和交流使用,如有疑问请联系qq2014160588并注明来意。请确保在使用过程中遵守相关法律法规。任何因使用本技术内容而导致的直接或间接损失,作者概不负责。用户需自行承担因使用本技术内容而产生的所有风险和责任。请勿将本技术内容用于任何非法用途。
上一篇
下一篇