当前位置:   article > 正文

水果分类程序:基于深度学习的水果识别_python cnn水果识别代码 csdn

python cnn水果识别代码 csdn

背景

水果分类在水果产业和社会经济发展中具有重要意义。目前,水果分类主要依赖人工分类,但这种方法浪费大量人力物力且效率低。随着人工智能和机器视觉的发展,基于深度学习的水果分类方法具有重要意义和广泛的应用价值。

流程

  1. 数据准备

    • 在这一部分,首先设置了一些参数,如批处理大小、训练周期、标签种类数和学习率。
    • 定义了数据预处理操作,包括将图像转换为张量,调整大小、中心裁剪和标准化。
  2. 数据集创建

    • 遍历了水果数据集目录,收集了图像路径和对应的标签。
    • 随机打乱数据集并将数据保存为CSV文件。
  3. 数据加载与划分

    • 读取了CSV文件,将数据加载到内存中。
    • 把数据集划分为训练集和验证集。
    • 创建了一个自定义数据集类,这个类包括了数据加载和转换操作。
  4. 模型构建

    • 在这一部分,定义了一个卷积神经网络(CNN)模型。这个模型包括了卷积层、池化层和全连接层。
    • 还创建了一个模型对象并配置了优化器、损失函数和评估指标。
  5. 模型训练

    • 为训练数据集和验证数据集创建了数据加载器。
    • 使用模型对象启动了完整的模型训练流程,包括多个训练周期。
    • 最后,保存了训练好的模型,以便后续的使用。
  6. 模型测试

    • 这部分准备了测试数据集。
    • 使用保存的模型进行图像分类预测,并输出了预测结果。

准备
 

  1. # 查看当前挂载的数据集目录, 该目录下的变更重启环境后会自动还原
  2. # View dataset directory.
  3. # This directory will be recovered automatically after resetting environment.
  4. !ls /home/aistudio/data
  1. # 查看工作区文件, 该目录下的变更将会持久保存. 请及时清理不必要的文件, 避免加载过慢.
  2. # View personal work directory.
  3. # All changes under this directory will be kept even after reset.
  4. # Please clean unnecessary files in time to speed up environment loading.
  5. !ls /home/aistudio/work
  1. # 如果需要进行持久化安装, 需要使用持久化路径, 如下方代码示例:
  2. # If a persistence installation is required,
  3. # you need to use the persistence path as the following:
  4. !mkdir /home/aistudio/external-libraries
  5. !pip install beautifulsoup4 -t /home/aistudio/external-libraries
  1. # 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:
  2. # Also add the following code,
  3. # so that every time the environment (kernel) starts,
  4. # just run the following code:
  5. import sys
  6. sys.path.append('/home/aistudio/external-libraries')
  1. import paddle
  2. print(sys.version)

 对应关系: torch.nn--paddle.nn torchvision.transforms--paddle.vision.transforms torchvision.datasets--paddle.vision.datasets torch.utils.data--paddle.io.DataLoader

 导入包

  1. import paddle.nn as nn
  2. import paddle.vision.transforms as transforms
  3. import paddle.vision.datasets as datasets
  4. import paddle.io as DataLoader
  5. from matplotlib import pyplot as plt

 数据预处理

  1. batch_size=64#批处理数量
  2. num_epochs=100#训练周期
  3. num_classes=3#标签种类数
  4. lr=0.001#学习率

 转换图片格式

  1. trans=transforms.Compose([
  2. transforms.ToTensor(),
  3. transforms.Resize(size=28),
  4. transforms.CenterCrop(28),
  5. transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
  6. ])

 解压数据集

  1. %cd /home/aistudio/
  2. !unzip /home/aistudio/data/data154561/shuiguo.zip

 

创建数据集 

  1. import os
  2. all_file_dir = 'shuiguo'
  3. img_list = []
  4. label_list = []
  5. label_id = 0
  6. class_list = [c for c in os.listdir(all_file_dir) if os.path.isdir(os.path.join(all_file_dir, c))]
  7. for class_dir in class_list:
  8. image_path_pre = os.path.join(all_file_dir, class_dir)
  9. for img in os.listdir(image_path_pre):
  10. img_list.append(os.path.join(image_path_pre, img))
  11. label_list.append(label_id)#标签值
  12. label_id += 1

 存为csv文件

  1. import pandas as pd
  2. import numpy as np
  3. img_df = pd.DataFrame(img_list)
  4. label_df = pd.DataFrame(label_list)
  5. img_df.columns = ['images']
  6. label_df.columns = ['label']
  7. df = pd.concat([img_df, label_df], axis=1)
  8. df = df.reindex(np.random.permutation(df.index))
  9. df.to_csv('food_data.csv', index=0)

 读取数据并划分数据集

  1. df = pd.read_csv('food_data.csv')#读取csv文件
  2. image_path_list = df['images'].values
  3. label_list = df['label'].values
  4. all_size = len(image_path_list)
  5. train_size = int(all_size * 0.8)
  6. #训练集
  7. train_image_path_list = image_path_list[:train_size]
  8. train_label_list = label_list[:train_size]
  9. #测试集
  10. val_image_path_list = image_path_list[train_size:]
  11. val_label_list = label_list[train_size:]
  1. import numpy as np
  2. from PIL import Image
  3. from paddle.io import Dataset
  4. import paddle.vision.transforms as T
  5. import paddle as pd
  6. class MyDataset(Dataset):
  7. """
  8. 步骤一:继承paddle.io.Dataset类
  9. """
  10. def __init__(self, image, label, transform=None):
  11. """
  12. 步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集
  13. """
  14. super(MyDataset, self).__init__()
  15. imgs = image
  16. labels = label
  17. self.labels = labels
  18. self.imgs = imgs
  19. self.transform = transform
  20. # self.loader = loader
  21. def __getitem__(self, index): # 这个方法是必须要有的,用于按照索引读取每个元素的具体内容
  22. fn = self.imgs
  23. label = self.labels
  24. # fn是图片path #fn和label分别获得imgs[index]也即是刚才每行中word[0]和word[1]的信息
  25. for im,la in zip(fn, label):
  26. img = Image.open(im)
  27. img = img.convert("RGB")
  28. img = np.array(img)
  29. label = np.array([la]).astype(dtype='int64')
  30. # 按照路径读取图片
  31. if self.transform is not None:
  32. img = self.transform(img)
  33. # 数据标签转换为Tensor
  34. return img, label
  35. # return回哪些内容,那么我们在训练时循环读取每个batch时,就能获得哪些内容
  36. def __len__(self):
  37. # 这个函数也必须要写,它返回的是数据集的长度,也就是多少张图片,要和loader的长度作区分
  38. return len(self.imgs)
  1. import paddle
  2. from paddle.metric import Accuracy
  3. from paddle.vision.models import resnet18
  4. import warnings
  5. warnings.filterwarnings("ignore")
  6. import warnings
  7. warnings.filterwarnings("ignore")
  8. #训练集
  9. train_dataset = MyDataset(image=train_image_path_list, label=train_label_list ,transform=trans)#转化成一个dataset子类实例
  10. train_loader = paddle.io.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
  11. #测试集
  12. test_dataset = MyDataset(image=val_image_path_list,label=val_label_list,transform=trans)
  13. test_loader = paddle.io.DataLoader(test_dataset, batch_size=batch_size, shuffle=True)

 训练集展示

  1. images,lables=next(iter(train_loader))
  2. imgs=images[0].numpy().transpose(1,2,0)
  3. plt.imshow(imgs)
  4. plt.title(lables[0])
  5. plt.show()
  6. print("一共{}个样本".format(len(train_loader.dataset)))

 

 测试集展示

  1. images,lables=next(iter(test_loader))
  2. imgs=images[0].numpy().transpose(1,2,0)
  3. plt.imshow(imgs)
  4. plt.title(lables[0])
  5. plt.show()
  6. print("一共{}个样本".format(len(test_loader.dataset)))

 

定义卷积神经网络过程基本相同,和pytorch不同的是,Tensor维度的变化: paddle里面没有view这个函数,使用paddle.reshape代替。 新张量=paddle.reshape(张量,维度) 

定义卷积神经网络 

  1. import paddle.fluid as fluid
  2. import paddle.nn.functional as F##torch.nn.functional
  3. depth=[32,64,128,256]
  4. class CNN(fluid.dygraph.Layer):##torch.nn.Module
  5. def __init__(self):
  6. super(CNN,self).__init__()
  7. self.conv1=nn.Conv2D(in_channels=3,out_channels=depth[0],kernel_size=5,stride=1,padding=2)
  8. self.pool=nn.MaxPool2D(2,2)
  9. self.conv2=nn.Conv2D(in_channels=depth[0],out_channels=depth[1],kernel_size=5,stride=1,padding=2)
  10. self.fc1=nn.Linear(28//4*28//4*depth[1],512)
  11. self.fc2=nn.Linear(512,num_classes)
  12. ##前向传播
  13. def forward(self,x):
  14. x=F.relu(self.conv1(x))
  15. x=self.pool(x)
  16. x=F.relu(self.conv2(x))
  17. x=self.pool(x)
  18. x=paddle.reshape(x,[-1,28//4*28//4*depth[1]])#####有所不同
  19. x=F.relu(self.fc1(x))
  20. x=F.dropout(x,training=self.training)
  21. x=self.fc2(x)
  22. x=F.dropout(x,training=self.training)
  23. return x
cnn_model=CNN()

训练数据,和pytorch也有很大不同。比pytorch里面的训练方式方便。模型封装,函数配置,启动训练。

  1. model = paddle.Model(cnn_model) # 模型封装
  2. # 配置优化器、损失函数、评估指标
  3. model.prepare(paddle.optimizer.Adam(learning_rate=0.0001, parameters=model.parameters()),
  4. paddle.nn.CrossEntropyLoss(),
  5. paddle.metric.Accuracy())
  6. # 启动模型全流程训练
  7. model.fit(train_loader, # 训练数据集
  8. test_loader, # 评估数据集
  9. epochs=5, # 训练的总轮次
  10. batch_size=2, # 训练使用的批大小
  11. verbose=1)

 

model.save('work/model1')#保存模型
  1. import paddle
  2. _model=paddle.Model(cnn_model)
  3. _model.load('work/model1')#加载模型

测试 

  1. import os
  2. trans=transforms.Compose([
  3. transforms.ToTensor(),
  4. transforms.Resize(size=28),
  5. transforms.CenterCrop(28),
  6. transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
  7. ])
  8. all_file_dir = 'test1'
  9. img_list = []
  10. label_list = []
  11. label_id = 0
  12. class_list = [c for c in os.listdir(all_file_dir) if os.path.isdir(os.path.join(all_file_dir, c))]
  13. for class_dir in class_list:
  14. image_path_pre = os.path.join(all_file_dir, class_dir)
  15. for img in os.listdir(image_path_pre):
  16. img_list.append(os.path.join(image_path_pre, img))
  17. label_list.append(label_id)#标签值
  18. label_id += 1
  1. import pandas as pd
  2. import numpy as np
  3. img_df = pd.DataFrame(img_list)
  4. label_df = pd.DataFrame(label_list)
  5. img_df.columns = ['images']
  6. label_df.columns = ['label']
  7. df = pd.concat([img_df, label_df], axis=1)
  8. df = df.reindex(np.random.permutation(df.index))
  9. df.to_csv('test1.csv', index=0)
  10. ##存为csv文件
  1. df = pd.read_csv('test1.csv')
  2. image_path_list = df['images'].values
  3. label_list = df['label'].values
  4. input_dataset = MyDataset(image=image_path_list, label=label_list ,transform=trans)#转化成一个dataset子类实例
  5. input_loader = paddle.io.DataLoader(input_dataset, batch_size=1, shuffle=True)
  1. images,lables=next(iter(input_loader))
  2. imgs=images[0].numpy().transpose(1,2,0)
  3. plt.imshow(imgs)
  4. plt.title(lables[0])
  5. plt.show()
  6. print("一共{}个样本".format(len(input_loader.dataset)))

 

 模型预测

  1. classes=['orange','apple','banana']
  2. test_result=model.predict(input_loader)
  3. pred_label = test_result[0][0].argmax()
  4. print("预测结果为:{}".format(classes[pred_label]))

 

结论

本项目实现了一个水果分类程序,基于深度学习技术。通过合理的数据预处理、自定义数据集类、CNN模型构建和训练,我们成功实现了水果图像的分类任务。这个项目对于自动化水果分类在农业和食品工业中具有重要的应用前景,可以提高分类准确度和效率。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/627887
推荐阅读
相关标签
  

闽ICP备14008679号