数据集
链接:https://pan.baidu.com/s/1qQglNzAIkBNxdrwND0NLNQ?pwd=data
提取码:data
1.目的
任务:根据original_data样本数据,建立模型,对test的图片进行普通/其他苹果判断
1.数据增强,扩充确认为普通苹果的样本数量
2.特征提取,使用VGG16模型提取特征
3.图片批量处理
4.Kmeans模型尝试普通、其他苹果聚类
5.基于标签数据矫正结果,并可视化
6.Meanshift模型提升模型表现
7.数据降维PCA处理,提升模型表现
2.模型训练
1.数据增强
为了缓解样本不平衡问题,特别是普通苹果样本数量的不足,我们采用了数据增强技术。通过随机旋转、缩放、平移、翻转等操作,我们成功扩充了普通苹果的样本集。这一步骤有效提升了模型的鲁棒性,使其能够更好地适应不同角度、光照条件下的苹果图像。
#数据增强
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
# 确保目标目录存在
if not os.path.exists(dst_path):
os.makedirs(dst_path)
# 修改文件路径分隔符
path = r'.\original_data' #图片加强的文件路径
dst_path = r'.\data\zengqiang' #图片加强后的文件路径
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): # 生成200张图片
next(gen)
2.数据预处理
为了高效地从苹果图像中提取有用信息,我们选择了预训练的VGG16模型进行特征提取。VGG16以其强大的特征学习能力在图像识别领域广受欢迎。通过移除VGG16模型的全连接层,我们保留了其卷积层和池化层,用于提取苹果图像的高级特征。这些特征不仅包含了图像的纹理、形状等基本信息,还蕴含了丰富的语义信息,为后续的分类任务奠定了坚实基础。
#列出数据的所有名称
import os
folder = r'.\data\train'
dirs = os.listdir(folder)
print(dirs)
#名称合并
img_path = []
for i in dirs:
if os.path.splitext(i)[1] == '.jpg':
img_path.append(i)
img_path = [folder + "\\" + i for i in img_path]
print(img_path)
#定义提取特征的方法
def modelPosses(img_path,model):
img = load_img(img_path, target_size=(224, 224))
img = img_to_array(img)
x = np.expand_dims(img, axis=0)
x = preprocess_input(x)
x_vgg = model.predict(x)
x_vgg = x_vgg.reshape(1, 7*7*512)
return x_vgg
运行结果
3.加载数据
为了高效处理大量测试图片,我们实现了图片批量处理流程。这一步骤包括图片加载、预处理(如大小调整、归一化等)、特征提取等环节。通过自动化处理,我们显著提高了模型评估的效率,为快速迭代优化提供了可能。
#加载数据
from keras.preprocessing.image import load_img, img_to_array
from keras.applications.vgg16 import VGG16, preprocess_input
import numpy as np
#图像批量处理
features_train = np.zeros([len(img_path), 7*7*512])
for i in range(len(img_path)):
features_i = modelPosses(img_path[i],model_vgg)
print('preprocessed:', img_path[i])
features_train[i] = features_i
运行结果
4.定义参数
#定义x;30>>10普通苹果》》+200普通苹果
x = features_train
5.构造模型并训练
#建立kmeans无监督模型
from sklearn.cluster import KMeans
cnn_kmeans = KMeans(n_clusters=2, max_iter=2000).fit(x)
3.模型评估与测试
1.预测训练集
#作出预测
y_predict_kmeans = cnn_kmeans.predict(x)
print(y_predict_kmeans)
from collections import Counter
print(Counter(y_predict_kmeans)) #预测结果统计
运行结果
2.将训练集预测结果可视化
normal_apple_id = 1
%matplotlib inline
import matplotlib.pyplot as plt
#将结果可视化
fig2 = plt.figure(figsize=(10, 40))
for i in range(45):
for j in range(5):
img = load_img(img_path[i*5+j]) #读取图片
plt.subplot(45,5,i*5+j+1)
plt.title('apple' if y_predict_kmeans[i*5+j]==normal_apple_id else 'other_apple')
plt.imshow(img)
plt.axis('off')
运行结果:这里展示部分结果
3.预测测试集
#列出数据的所有名称
import os
folder_test = r'.\data\test'
dirs_test = os.listdir(folder_test)
# print(dirs)
#名称合并
img_path_test = []
for i in dirs_test:
if os.path.splitext(i)[1] == '.jpg':
img_path_test.append(i)
img_path_test = [folder_test + "\\" + i for i in img_path_test]
print(img_path_test)
print(len(img_path_test))
#图像批量处理
features_test = np.zeros([len(img_path_test), 7*7*512])
for i in range(len(img_path_test)):
features_i = modelPosses(img_path_test[i],model_vgg)
print('preprocessed:', img_path_test[i])
features_test[i] = features_i
x_test = features_test
运行结果
下面是测试集的预测
y_predict_kmeans_test = cnn_kmeans.predict(x_test)
print(y_predict_kmeans_test)
运行结果
4.将测试集预测结果可视化
#将结果可视化
fig3 = plt.figure(figsize=(10, 10))
for i in range(3):
for j in range(4):
img = load_img(img_path_test[i*4+j]) #读取图片
plt.subplot(3,4,i*4+j+1)
plt.title('apple' if y_predict_kmeans_test[i*4+j]==normal_apple_id else 'other_apple')
plt.imshow(img)
plt.axis('off')
运行结果:可以看到结果不是特别好,说明我们构建的模型需要改进。
4.Kmeans模型尝试普通、其他苹果聚类
在获得足够的特征数据后,我们尝试使用Kmeans聚类算法对普通苹果和其他苹果进行初步分类。虽然Kmeans是一种无监督学习方法,但在一定程度上能够帮助我们理解数据分布,并为后续的有监督学习提供参考。通过调整聚类中心数(K值),我们观察了不同聚类结果对分类性能的影响。
1.构建一个Kmeans模型训练
#meanshift
from sklearn.cluster import MeanShift, estimate_bandwidth
#获得带宽
bw = estimate_bandwidth(x, n_samples=140)
print(bw)
#创建meanshift模型
cnn_ms = MeanShift(bandwidth=bw)
cnn_ms.fit(x)
运行结果
2.使用Kmeans预测结果
y_predict_ms = cnn_ms.predict(x)
print(y_predict_ms)
运行结果:说明这里只出现一次的类型也进行了分类,效果要比之前的好一些,下面看可视化的成果来评估
3.可视化评估训练集
normal_apple_id = 0
#将结果可视化
fig4 = plt.figure(figsize=(10, 40))
for i in range(45):
for j in range(5):
img = load_img(img_path[i*5+j]) #读取图片
plt.subplot(45,5,i*5+j+1)
plt.title('apple' if y_predict_ms[i*4+j]==normal_apple_id else 'other_apple')
plt.imshow(img)
plt.axis('off')
运行结果:这里也只展示部分数据,可以看到要比之前的结果好一些了。
4.可视化评估测试集
y_predict_ms_test = cnn_ms.predict(x_test)
print(y_predict_ms_test)
#将结果可视化
fig5 = plt.figure(figsize=(10, 10))
for i in range(3):
for j in range(4):
img = load_img(img_path_test[i*4+j]) #读取图片
plt.subplot(3,4,i*4+j+1)
plt.title('apple' if y_predict_ms_test[i*4+j]==normal_apple_id else 'other_apple')
plt.imshow(img)
plt.axis('off')
运行结果:这里结果其实已经比较靠近了,下面我们看一次进行PCA降维后处理的变化。
5.PCA降维处理
1.PCA降维
为了降低特征维度、减少计算复杂度并可能提升模型性能,我们采用了PCA(主成分分析)进行数据降维。通过保留数据中的主要变化方向(即主成分),我们有效减少了特征数量,同时尽量保留了原始数据的信息。这一步骤不仅简化了模型训练过程,还可能在一定程度上提升模型的泛化能力。
#PCA降维
from sklearn.preprocessing import StandardScaler
stds = StandardScaler()
x_norm = stds.fit_transform(x)
#PCA analysis
from sklearn.decomposition import PCA
pca = PCA(n_components=200)
x_pca = pca.fit_transform(x_norm)
2.创建meanshift模型
在Kmeans聚类的基础上,我们进一步尝试了Meanshift聚类算法。Meanshift算法能够自动确定聚类中心的数量,并在一定程度上缓解Kmeans对初始聚类中心敏感的问题。通过对比实验,我们发现Meanshift在某些情况下能够更准确地捕捉数据的内在结构,从而进一步提升分类模型的性能。
#meanshift
from sklearn.cluster import MeanShift, estimate_bandwidth
#获得带宽
bw = estimate_bandwidth(x_pca, n_samples=140)
print(bw)
#创建meanshift模型
cnn_pca_ms = MeanShift(bandwidth=bw)
cnn_pca_ms.fit(x_pca)
运行结果
3.进行预测和测试集结果可视化
#标准化处理
x_norm_test = stds.transform(x_test)
#数据降维
x_pca_test = pca.transform(x_norm_test)
y_predict_pca_ms_test = cnn_pca_ms.predict(x_pca_test)
print(y_predict_pca_ms_test)
#将结果可视化
fig7 = plt.figure(figsize=(10, 10))
for i in range(3):
for j in range(4):
img = load_img(img_path_test[i*4+j]) #读取图片
plt.subplot(3,4,i*4+j+1)
plt.title('apple' if y_predict_pca_ms_test[i*4+j]==normal_apple_id else 'other_apple')
plt.imshow(img)
plt.axis('off')
运行结果: 这里可以看到,预测结果只有两个不正确,说明这还是挺有效的提高了结果。并且因为降维了,所以处理的时间也少了的很多。
5.总结
在本次项目中,我们围绕original_data样本数据,构建了一个用于区分普通苹果与其他种类苹果的图像分类系统。通过一系列数据处理、特征提取、模型应用及优化步骤,我们不仅提升了模型的泛化能力,还通过可视化手段验证了模型的有效性。
通过本次项目,我们成功构建了一个基于VGG16特征提取与聚类优化的苹果分类系统。通过数据增强、特征提取、聚类分析、结果矫正及可视化等多个环节的紧密配合,我们实现了对普通苹果与其他种类苹果的准确分类。未来,我们可以进一步探索更先进的特征提取方法、聚类算法及分类模型,以不断提升系统的分类性能和泛化能力。同时,我们还可以尝试将系统应用于更广泛的农业场景中,为农业生产提供更加智能化的解决方案。
标签:predict,plt,apple,img,VGG16,test,聚类,特征提取,path From: https://blog.csdn.net/ge20040119/article/details/140349047