基于Fruits-360数据集构建CNN进行水果识别实验

2023-11-19

基于Fruits-360数据集的水果识别项目

前段时间导师要求做一个神经网络可视化的项目,要将水果数据集进行训练得到模型,用于TensorSpace可视化。前前后后捣鼓了很久,现在回过头总结一下整个项目过程,写下这篇博客记录遇到的问题,有任何问题欢迎在评论区留言。

  • 1.实验数据集

  • (1)实验用的数据集是最常见的Fruits-360水果数据集,截至写博客为止这个数据集最新版本是2020.05.18.0
  • (2)该数据集有131种水果分类(分的特别细致,比方说苹果(不同品种:深红色雪,金黄色,金红色,史密斯奶奶,粉红色淑女,红色,红色美味)):Apples (different varieties: Crimson Snow, Golden, Golden-Red, Granny Smith, Pink Lady, Red, Red Delicious), Apricot, Avocado, Avocado ripe, Banana (Yellow, Red, Lady Finger), Beetroot Red, Blueberry, Cactus fruit, Cantaloupe (2 varieties), Carambula, Cauliflower, Cherry (different varieties, Rainier), Cherry Wax (Yellow, Red, Black), Chestnut, Clementine, Cocos, Corn (with husk), Cucumber (ripened), Dates, Eggplant, Fig, Ginger Root, Granadilla, Grape (Blue, Pink, White (different varieties)), Grapefruit (Pink, White), Guava, Hazelnut, Huckleberry, Kiwi, Kaki, Kohlrabi, Kumsquats, Lemon (normal, Meyer), Lime, Lychee, Mandarine, Mango (Green, Red), Mangostan, Maracuja, Melon Piel de Sapo, Mulberry, Nectarine (Regular, Flat), Nut (Forest, Pecan), Onion (Red, White), Orange, Papaya, Passion fruit, Peach (different varieties), Pepino, Pear (different varieties, Abate, Forelle, Kaiser, Monster, Red, Stone, Williams), Pepper (Red, Green, Orange, Yellow), Physalis (normal, with Husk), Pineapple (normal, Mini), Pitahaya Red, Plum (different varieties), Pomegranate, Pomelo Sweetie, Potato (Red, Sweet, White), Quince, Rambutan, Raspberry, Redcurrant, Salak, Strawberry (normal, Wedge), Tamarillo, Tangelo, Tomato (different varieties, Maroon, Cherry Red, Yellow, not ripened, Heart), Walnut, Watermelon.
  • (3)数据集属性
    • 图片总数:90483。
    • 训练集大小:67692张图像(每张图像一个水果)
    • 测试集大小:22688张图像(每张图像一个水果)
    • 种类数:131(水果)
    • 图片尺寸:100 x 100像素。
    • 文件名格式:图像索引_100.jpg(例如32_100.jpg)或r_图像索引_100.jpg(例如r_32_100.jpg)或r2_图像索引_100.jpg或r3_图像索引_100.jpg。“ r”代表旋转的水果。“ r2”表示水果绕第三轴旋转。“100”来自图像尺寸(100x100像素)。
    • 同一水果(例如苹果)的不同品种被存储为属于不同类别。
  • (4)数据集下载链接:Fruits-360.
  • 2.导包

实验用到了以下包:

// 导包
import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt 
import glob 
import cv2 
import tensorflow as tf
import keras
import os
print(os.listdir("../dataset/Training"))
['Apple Braeburn', 'Apple Crimson Snow', 'Apple Golden 1', 'Apple Golden 2', 'Apple Golden 3', 'Apple Granny Smith', 'Apple Pink Lady', 'Apple Red 1', 'Apple Red 2', 'Apple Red 3', 'Apple Red Delicious', 'Apple Red Yellow 1', 'Apple Red Yellow 2', 'Apricot', 'Avocado', 'Avocado ripe', 'Banana', 'Banana Lady Finger', 'Banana Red', 'Beetroot', 'Blueberry', 'Cactus fruit', 'Cantaloupe 1', 'Cantaloupe 2', 'Carambula', 'Cauliflower', 'Cherry 1', 'Cherry 2', 'Cherry Rainier', 'Cherry Wax Black', 'Cherry Wax Red', 'Cherry Wax Yellow', 'Chestnut', 'Clementine', 'Cocos', 'Corn', 'Corn Husk', 'Cucumber Ripe', 'Cucumber Ripe 2', 'Dates', 'Eggplant', 'Fig', 'Ginger Root', 'Granadilla', 'Grape Blue', 'Grape Pink', 'Grape White', 'Grape White 2', 'Grape White 3', 'Grape White 4', 'Grapefruit Pink', 'Grapefruit White', 'Guava', 'Hazelnut', 'Huckleberry', 'Kaki', 'Kiwi', 'Kohlrabi', 'Kumquats', 'Lemon', 'Lemon Meyer', 'Limes', 'Lychee', 'Mandarine', 'Mango', 'Mango Red', 'Mangostan', 'Maracuja', 'Melon Piel de Sapo', 'Mulberry', 'Nectarine', 'Nectarine Flat', 'Nut Forest', 'Nut Pecan', 'Onion Red', 'Onion Red Peeled', 'Onion White', 'Orange', 'Papaya', 'Passion Fruit', 'Peach', 'Peach 2', 'Peach Flat', 'Pear', 'Pear 2', 'Pear Abate', 'Pear Forelle', 'Pear Kaiser', 'Pear Monster', 'Pear Red', 'Pear Stone', 'Pear Williams', 'Pepino', 'Pepper Green', 'Pepper Orange', 'Pepper Red', 'Pepper Yellow', 'Physalis', 'Physalis with Husk', 'Pineapple', 'Pineapple Mini', 'Pitahaya Red', 'Plum', 'Plum 2', 'Plum 3', 'Pomegranate', 'Pomelo Sweetie', 'Potato Red', 'Potato Red Washed', 'Potato Sweet', 'Potato White', 'Quince', 'Rambutan', 'Raspberry', 'Redcurrant', 'Salak', 'Strawberry', 'Strawberry Wedge', 'Tamarillo', 'Tangelo', 'Tomato 1', 'Tomato 2', 'Tomato 3', 'Tomato 4', 'Tomato Cherry Red', 'Tomato Heart', 'Tomato Maroon', 'Tomato not Ripened', 'Tomato Yellow', 'Walnut', 'Watermelon']
  • 3.数据预处理

  • (1)训练集处理

// 训练集处理
training_fruit_img = []
training_label = []
for dir_path in glob.glob("../dataset/Training/*"):
    img_label = dir_path.split("/")[-1]
    for img_path in glob.glob(os.path.join(dir_path, "*.jpg")):
        img = cv2.imread(img_path)
        img = cv2.resize(img, (64, 64))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        training_fruit_img.append(img)
        training_label.append(img_label)
training_fruit_img = np.array(training_fruit_img)
training_label = np.array(training_label)
print(len(np.unique(training_label)))
131
  • (2)测试集处理

// 测试集处理
test_fruit_img = []
test_label = []
for dir_path in glob.glob("../dataset/Test/*"):
    img_label = dir_path.split("/")[-1]
    for img_path in glob.glob(os.path.join(dir_path, "*.jpg")):
        img = cv2.imread(img_path)
        img = cv2.resize(img, (64, 64))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        test_fruit_img.append(img)
        test_label.append(img_label)
test_fruit_img = np.array(test_fruit_img)
test_label = np.array(test_label)
print(len(np.unique(test_label)))
131
  • (3)测试集(混合水果图像)处理

// 测试集(混合水果图像)处理
test_fruits_img = []
tests_label = []
for img_path in glob.glob(os.path.join("../dataset/test-multiple_fruits", "*.jpg")):
     img_label = img_path.split("/")[-1]
     img = cv2.imread(img_path)
     img = cv2.resize(img, (64, 64))
     img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
     test_fruits_img.append(img)
     tests_label.append(img_label)
test_fruits_img = np.array(test_fruits_img)
tests_label = np.array(tests_label)
len(np.unique(tests_label))
103
  • (4)训练集标签和id互相转化

trainging_label_to_id = {v : k for k, v in enumerate(np.unique(training_label))}
training_id_to_label = {v : k for k, v in trainging_label_to_id.items()}
training_label_id = np.array([trainging_label_to_id[i] for i in training_label])
print(training_label_id)
array([  0,   0,   0, ..., 130, 130, 130])
  • (5)测试集标签和id互相转化

  • 这部分同训练集,也是使用enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,即将测试集标签去重后组合为一个索引序列,并进行键值对对换,再转化为NumPy数组。
  • (6)像素值缩放

  • 这里我将训练集图像和测试集图像乘以1/255进行缩放,将像素值缩放至[0, 1]区间。
  • 然后使用matplotlib.pyplot将图像显示出来(实验中我以训练集第10001个图像为例)
    训练集第10001个图像
  • 4.Keras模型构建

  • 我实验中的搭建的模型结构如下:
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 64, 64, 16)        448       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 32, 32, 16)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 32, 32, 32)        4640      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 16, 16, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 16, 16, 32)        9248      
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 8, 8, 32)          0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 8, 8, 64)          18496     
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 4, 4, 64)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 1024)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               262400    
_________________________________________________________________
dense_2 (Dense)              (None, 131)               33667     
=================================================================
Total params: 328,899
Trainable params: 328,899
Non-trainable params: 0
_________________________________________________________________
  • 5.模型编译和训练

  • 我实验中使用的是交叉熵损失函数sparse_categorical_crossentropy,优化器使用的是Adamaxbatch_size设置为128,epochs设置为10,并且使用TensorBoard将训练过程可视化。
Train on 67692 samples
Epoch 1/10
67692/67692 [==============================] - 145s 2ms/sample - loss: 1.6539 - accuracy: 0.5947
Epoch 2/10
67692/67692 [==============================] - 156s 2ms/sample - loss: 0.2184 - accuracy: 0.9370
Epoch 3/10
67692/67692 [==============================] - 179s 3ms/sample - loss: 0.0812 - accuracy: 0.9764
Epoch 4/10
67692/67692 [==============================] - 264s 4ms/sample - loss: 0.0466 - accuracy: 0.9864
Epoch 5/10
67692/67692 [==============================] - 272s 4ms/sample - loss: 0.0257 - accuracy: 0.9932
Epoch 6/10
67692/67692 [==============================] - 257s 4ms/sample - loss: 0.0160 - accuracy: 0.9958
Epoch 7/10
67692/67692 [==============================] - 301s 4ms/sample - loss: 0.0164 - accuracy: 0.9956
Epoch 8/10
67692/67692 [==============================] - 289s 4ms/sample - loss: 0.0094 - accuracy: 0.9976
Epoch 9/10
67692/67692 [==============================] - 252s 4ms/sample - loss: 0.0113 - accuracy: 0.9967
Epoch 10/10
67692/67692 [==============================] - 245s 4ms/sample - loss: 0.0062 - accuracy: 0.9982
  • 6.在测试集上评估模型

22688/22688 [==============================] - 30s 1ms/step


Loss: 0.25497715034207047
Accuracy: 0.9393512010574341
  • 可以看到该模型精确率达到93.94%,效果相对来说还算是不错的。
  • 7.保存模型

  • 将训练完成的模型进行保存,得到一个.h5文件,这个文件也是后续TensorSpace项目所需要用到的核心文件。
model.save("../model/model_demo.h5")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Fruits-360数据集构建CNN进行水果识别实验 的相关文章

随机推荐

  • css ol 序列样式:数字带圆圈、括号

    有序ol基本的网上都有 在这里就不介绍了 1 数字带登号 如标题的这种 2 通过上面的例子可以扩展一下 1 只要修改成下面的代码 其余不变 ol li before content counter sectioncounter counte
  • K8S存储之volume

    K8S存储之volume 容器磁盘上的文件的生命周期是短暂的 这就使得在容器中运行重要应用时会出现一些问题 首先 当容器崩溃时 kubelet会重启它 但是容器中的文件将丢失一一容器以干净的状态 镜像最初的状态 重新启动 其次 在Pod中同
  • 【Python】Jupyter Notebook无法运行代码,不可重命名且提示error和自动保存失败时如何操作?

    Python Jupyter Notebook无法运行代码 且提示error和自动保存失败时如何操作 Anaconda的Jupyter Notebook作为优秀的网页编辑器 非常适用于编写Python程序 但往往可能因安装版本不兼容等原因而
  • Flutter中的依赖注入——get_it

    Flutter社区的一个library get it 视频介绍 Flutter Dependency Injection For Beginners Complete Guide 视频对应的博文 Dependency Injection i
  • JavaWeb开发中出现DataSource读取不到怎么办呢?(详细,适合初入门的程序员)

    这样的问题是怎么产生的呢 其实啊也不难 来吧 跟我走一遍 目录 前言 二 使用步骤 1 基本的JavaWeb项目的结构 1 1 创建一个JavaWeb项目 1 2 配置文件的配置 1 3 重点来了 2 DBUtil的代码内容 3 测试 总结
  • 树的广度优先遍历与深度优先遍历算法

    1 树的广度优先遍历算法 广度优先遍历算法 又叫宽度优先遍历 或横向优先遍历 是从根节点开始 沿着树的宽度遍历树的节点 如果所有节点均被访问 则算法中止 如上图所示的二叉树 A 是第一个访问的 然后顺序是 B C 然后再是 D E F G
  • 数据库实体关系图(ERD)

    数据库是软件系统中不可或缺的一个组成部分 若能在数据库工程中好好利用 ER 图 便能让您生成高质量的数据库设计 用于数据库创建 管理和维护 也为人员间的交流提供了有意义的基础 今天 我们将为你深入介绍 ER 图表 通过阅读本ERD指南 您将
  • Gikee 大数据

    据Gikee数据显示 今日13 58分 地址 1MAhRt279uYmVC1dUxKR6dWwEULBJT34Nh 向地址 1Fc4QQu6nEc4snAe4HAb4Kryd8koH89pYk 转了34010个BTC 价值约2 17亿美元
  • stm32USB之模拟U盘

    STMF0 W25Q32模拟U盘 1 第一次写博客 如有错误 请及时指正 如有表达不通顺的地方 敬请谅解 2 本篇文章主要描述如何使用STM32cube配置USB 使用的主控为STM32F072 Flash为W25Q32 使用的主控RAM只
  • scrapy爬虫错误一:无法爬到期望的数据

    最近在开始学习scrapy爬虫 遇到了一处很坑的地方 在屏幕上输出的debug信息总是没有任何结果就直接提示 scrapy statscollectors INFO Dumping Scrapy stats scrapy core engi
  • 2023算法面试题1

    1 介绍SAM模型 2 大语言模型的微调方法 3 yolov8与yolov5的区别 4 介绍LoRA和QLoRA微调技术 5 negative prompt怎么做的 6 stable diffusion的结构与原理
  • tc 流控脚本

    系统平台 RedHat AS4 root bridgenet software uname a Linux bridgenet 2 6 9 42 ELsmp 1 SMP Wed Jul 12 23 27 17 EDT 2006 i686 i
  • upf仿真例子

    原文链接 关于什么是UPF以及电源域等等概念赛宝龙在这里就不多说了 有兴趣的可以查阅IEEE1801 2013标准 先上低功耗要求 即power intent 顶层模块为TOP 而TOP中例化了一个子模块 其例化名为instA1 具体的代码
  • 危化安全生产信息化平台在煤化领域的应用

    一 背景介绍 煤化工行业是一个集煤炭 石油 化工等多种产业于一体的综合性行业 其特点是工艺流程复杂 设备繁多 安全隐患大 近年来 随着煤化工行业的快速发展 安全生产问题日益凸显 为了有效提高危化安全生产水平 某煤化工企业引入了信息化技术 搭
  • Springboot+Websocket中@Autowired注入service为null的解决方法

    使用工具类用于从Spring的上下文中去获取到类的实例 ServerEndpoint websocket userId Component 关键点1 public class WebSocket private static UserSer
  • 高效程序员的40个好习惯和行为方式

    每一个好的习惯 开头都会相应有一个唱反调的句子哦 1 做事 出了问题 第一重要的是确定元凶 找到那个人 一旦证实了是他的错误 就可以保证这样的问题永远也不会再发生了 指责不会修复bug 把矛头对准问题的解决办法 而不是人 这是真正有用处的正
  • Modbus​协议​深入​讲解_NI

    from https www ni com zh cn innovations white papers 14 the modbus protocol in depth html 已 更新 Mar 5 2019
  • hutool的json工具完成list和json转换

    将json和list相互转换 import cn hutool json JSONArray import cn hutool json JSONUtil List转Json maps是List类型的参数 String json JSONU
  • 因果系列文章(10)—— 因果关系发现

    如何从纷繁复杂的数据中发现其中隐含因果关系 就是因果关系发现 casual discovery 要做的工作 本节简要总结这方面的工作 主要材料来源于 Elements of Causal Inference Foundations and
  • 基于Fruits-360数据集构建CNN进行水果识别实验

    基于Fruits 360数据集的水果识别项目 前段时间导师要求做一个神经网络可视化的项目 要将水果数据集进行训练得到模型 用于TensorSpace可视化 前前后后捣鼓了很久 现在回过头总结一下整个项目过程 写下这篇博客记录遇到的问题 有任