浅谈人工智能之基于VGG16与Kmeans进行图像分类

浅谈人工智能之基于VGG16与Kmeans进行图像分类

摘要

随着深度学习技术的快速发展,卷积神经网络(CNN)在图像识别领域取得了显著的成就。VGG16作为经典的CNN模型之一,因其结构简单、性能稳定而被广泛应用于各种图像分类任务中。本文将详细介绍如何使用VGG16模型进行图像分类,包括模型的结构、训练过程、优化技巧以及实际应用案例。

VGG16模型简介

VGG16是由牛津大学的Visual Geometry Group (VGG)提出的一种深度卷积神经网络模型。该模型在2014年的ImageNet竞赛中取得了优异的成绩。VGG16的主要特点包括:
● 深度:模型包含16个可训练的层(13个卷积层和3个全连接层)。
● 结构简单:所有卷积层均使用3x3的小卷积核,步长为1,填充为1,使得输出的特征图大小与输入相同。
● 池化层:每个卷积层组后接一个2x2的最大池化层,步长为2,用于降低特征图的尺寸。

实战应用

我们为了简化操作实验步骤,我们通过两张图片经过数据增强生成多张图片进行训练,并且利用另外两张图片作为测试数据进行验证。
训练图片数据如下:
在这里插入图片描述
测试图片数据如下:
在这里插入图片描述

开发搭建

我们的开发环境如下:
python:Python 3.8.10
依赖环境如下:

pip install keras
pip install pandas
pip install tensorflow
pip install sklearn

如果提示还需要安装其他赖,则在提示下进行安装。

数据增强

我们分别将训练图片的两张图片,分别生成100张和20张图片。
第一步:在root目录下新建文件夹vgg,并且在此文件夹下从创建另外一个文件夹。

mkdir vgg
cd vgg
mkdir enhance

因此我们整体的目录的绝对类路径是:/root/vgg/enhance
第二步:将训练图片中的其中一张图片放到enhance目录下,代码如下

import os
from keras.preprocessing.image import ImageDataGenerator

# 定义路径
path = '/root/vgg'
dst_path = '/root/enhance_data'

# 检查路径是否存在,如果不存在则创建
os.makedirs(dst_path, exist_ok=True)

# 定义数据增强参数
datagen = ImageDataGenerator(
    rotation_range=10,          # 旋转范围,角度值
    width_shift_range=0.1,      # 水平平移范围
    height_shift_range=0.02,    # 垂直平移范围
    horizontal_flip=True,       # 水平翻转
    vertical_flip=True          # 垂直翻转
)

# 生成数据
gen = datagen.flow_from_directory(
    path,
    target_size=(224, 224),    # 图像大小
    batch_size=2,              # 批量大小
    save_to_dir=dst_path,      # 保存生成的图像路径
    save_prefix='gen',        # 保存图像的前缀
    save_format='jpg'          # 保存图像的格式
)

# 生成并保存图像
for i in range(100):
    try:
        gen.next()
    except Exception as e:
        print(f"Error generating image: {e}")

第三步:在root下新建另外一个文件夹train_data
第四步:将刚刚生成的图片剪切到train_data文件夹下,然后重复第二个步骤,把另外的20张生成的图片放到train_data中。

单张图片数据加载和特征提取

我们首先尝试对单个数据进行加载和特征提取。
第一步:加载图片

from keras.preprocessing.image import load_img, img_to_array

img_path = 'baby.png'
img = load_img(img_path,target_size=(224,224))
print(type(img))
第二步:可视化图片并且进行展示
from matplotlib import pyplot as p

figOne = p.figure()
p.imshow(img)

结果如下:
在这里插入图片描述
第三步:格式转换

img = img_to_array(img)
print(type(img))
print(img.shape)

打印的结果如下:

<class ‘numpy.ndarray’>
(1, 224, 224, 3)

第四步:数据的维度转化和预处理

from keras.applications.vgg16 import preprocess_input
import numpy as npy

img_to_do = npy.expand_dims(img,axis=0)
print(img_to_do.shape)
img_to_do = preprocess_input(img_to_do)

第五步:特征提取

from keras.applications.vgg16 import VGG16

m_vgg16 = VGG16(weights='imagenet',include_top=False)
featuresForImg = m_vgg16.predict(img_to_do)
print(featuresForImg.shape,featuresForImg)

第六步:特征展开

featuresForImg = featuresForImg.reshape(1,7*7*512)
print(featuresForImg.shape)

打印的结果如下:

(1, 25088)

多张图片数据加载和特征提取

当我们可以获取单张实现特征提取时,我们可以批量对图片进行操作
第一步:获取所有图片路径

import os

# 定义文件夹路径
folder = '/root/train_data'

# 获取文件夹中的所有文件名
files_name = os.listdir(folder)

# 用于存储图片路径的列表
img_path = []

# 遍历文件名,筛选出.jpg文件并构建完整路径
for file_name in files_name:
    if os.path.splitext(file_name)[1].lower() == '.jpg':
        img_path.append(os.path.join(folder, file_name))

# 打印图片路径
print(img_path)
第二步:根据单张特征提取的方法,我们写一个vgg16的特征提取的方法
def modelProcess(img_path, model):
    try:
        # 加载图像并调整大小
        img = image.load_img(img_path, target_size=(224, 224))  
        # 将图像转换为数组
        img_array = image.img_to_array(img)
        # 增加一个维度以匹配模型输入要求
        img_array = npy.expand_dims(img_array, axis=0)
        # 预处理图像
        img_array = preprocess_input(img_array)
        # 使用模型进行预测
        features = model.predict(img_array)
        # 重塑特征向量
        features = features.reshape(1, 7 * 7 * 512)
        return features
    except Exception as e:
        print(f"Error processing image {img_path}: {e}")
        return None

第三步:批量提取特征

features_train = npy.zeros([len(img_path),7*7*512])
for i in range(len(img_path)):
    features_temp = modelProcess(img_path[i],model_vgg16)
    features_train[i] = features_temp
    print('preprocess:',img_path[i])

执行以后我们可以看到如下信息
在这里插入图片描述
第四步:打印样本梳理和特征数

print(features_train.shape)
#赋值
X = features_train
print(X.shape)

第五步:使用kemeans进行聚类分析训练

from sklearn.cluster import KMeans

vgg_kmeans = KMeans(n_clusters=2,max_iter=3000)
#训练
vgg_kmeans.fit(X)

第六步:结果预测和打印

y_predict_km = vgg_kmeans.predict(X)
print(y_predict_km)

结果显示如下:
在这里插入图片描述
第七步:统计结果分布

import pandas as pd

print(pd.value_counts(y_predict_km))

结果显示如下:
在这里插入图片描述
第八步:图形化展示

# 设置有婴儿头像的标签为0
baby_id = 0

# 创建图形
figTwo = plt.figure(figsize=(10, 40))

# 遍历图像并绘制
for i in range(30):
    for j in range(4):
        index = i * 4 + j
        if index < len(img_path):
            img = image.load_img(img_path[index], target_size=(224, 224))
            plt.subplot(30, 4, index + 1)
            plt.title('baby' if y_predict_km[index] == baby_id else 'swim')
            plt.imshow(img)
            plt.axis('off')
        else:
            break  # 如果图像路径列表不足120张,提前退出循环

plt.tight_layout()
plt.show()

显示结果如下
在这里插入图片描述

测试数据集

训练的数据集预测以后,我们针对测试数据集进行预测,这里就不再累赘,直接上代码:

import os

# 定义文件夹路径
folder = '/root/test_data'

# 获取文件夹中的所有文件名
files_name = os.listdir(folder)

# 用于存储图片路径的列表
img_path = []

# 遍历文件名,筛选出.jpg文件并构建完整路径
for file_name in files_name:
    if os.path.splitext(file_name)[1].lower() == '.jpg':
        img_path.append(os.path.join(folder, file_name))

# 打印图片路径
print(img_path)

#批量提取图片特征
features_test = np.zeros([len(img_path),7*7*512])

for i in range(len(img_path)):
    features_temp = modelProcess(img_path[i],model_vgg16)
    features_test[i] = features_temp
    print('preprocess:',img_path[i])


# 创建图形
figThree = plt.figure(figsize=(10, 40))

# 遍历图像并绘制
for i in range(2):
    for j in range(1):
        index = i * 4 + j
        if index < len(img_path):
            img = image.load_img(img_path[index], target_size=(224, 224))
            plt.subplot(2, 1, index + 1)
            plt.title('baby' if y_predict_km_test[index] == baby_id else 'swim')
            plt.imshow(img)
            plt.axis('off')
        else:
            break  # 如果图像路径列表不足120张,提前退出循环

plt.tight_layout()
plt.show()
#X_test
X_test = features_test
print(X_test.shape)

#测试数据预测
y_predict_km_test = vgg_kmeans.predict(X_test)
print(y_predict_km_test)

结果如下:
在这里插入图片描述

上一篇:C#基础31-35


下一篇:【Vue3】【Naive UI】<n-message>标签