基于人工智能的苹果成熟度检测

慈云数据 2024-03-12 技术支持 133 0

一、选题的背景

苹果在采摘期被采摘后,需要工人进行手工对苹果的成熟度进行分类,这耗费了大量的人力与物力,而且相近成熟度难以区分,存在分类颗粒度过粗,分类过程存在较为强烈的主观因素等问题。

在这里,我们提出了基于深度学习的苹果成熟度识别方案,这是一种用于帮助农民和采摘工人判断苹果成熟度的人工智能系统。它能够从图像中快速、准确地判断苹果的成熟度,判断苹果是否已经成熟,从而为农民和采摘工人提供帮助。

二、数据集的来源

数据一共有A -F一共六种不同成熟度的苹果,一共包括6161张照片。

AppleD文件夹: 网上搜索苹果成熟前5个月,此时苹果还很青涩

AppleF文件夹: 网上搜索苹果成熟前4个月

AppleE文件夹: 网上搜索苹果前成熟3个月

AppleC文件夹: 网上搜索苹果成熟前2个月

AppleA文件夹: 网上搜索苹果成熟前1个月

AppleB文件夹: 网上搜索苹果成熟时,此时苹果成熟

三、采用的机器学习框架描述

采用keras框架搭建分类模型,完成模型训练、预测和分类任务。

采用tensorflow.image API与tensorflow.data API完成图片的增强与数据集的制作。

采用sklearn,完成训练集和测试集的划分,并且固定随机数种子,防止信息泄露。

四、涉及到的技术难点与解决思路

tf.data可以把python写的代码编译到C++后端高效执行,因此也存在较大的限制。对模型张量存在要求,使用上也有限制。

数据集并不算十分充裕,因此引入预训练模型就十分必要了。这里采用的是ResNet50在imageNet上预训练的模型,有很强的泛化能力。

五、数据的预处理

为了利用在ResNet在ImageNet上预训练的权重,因此我们要使用与预训练相同的数据预处理方式,使数据保证在同一份分布上。

网络输入尺寸设置为224 * 224 * 3的RGB全彩图像,为了迎合各种尺寸的实际图像,需要把数据集中的图像按比例缩放,保证图像不会走形,影响模型的性能。将图片进行居中对齐,然后对每个维度缺失部分填0补充,反映到图像上,及为图像增加黑边。

在这里我们采用图片放大然后随机裁剪的方式对数据集进行扩充。

在实际中,我们缩放后的图片并非为实际网络输入尺寸,而是输入尺寸的1.4倍,然后再随机裁剪出需要尺寸。

最后对图片进行随机镜像,随机旋转进行数据增强,提高模型性能。

六、模型选择:

模型采用ResNet50,并加载imageNet数据集上训练的权重,降低训练压力,提高训练效果。

七、训练参数:

优化器: 采用Adam优化器学习率设置为2*1e-4,并训练10个epoch

损失函数: 采用SparseCategoryEntropy,及交叉熵作为分类损失。

衡量指标: 采用正确率和计算损失作为衡量指标

八、开始训练:

这里我训练了6个epoch,但是由图可知只有前3个epoch是有效训练。

训练集和测试集按照6:4比例划分,分类模型在测试集上实现了99.4%的分类精度

九、模型测试:

我们加载一张图片对苹果进行分类演示:

模型预测苹果为D类,实现了正确分类。

十、总结

通过这次的实验,我学会更好的使用python,利用python做好更多的事情,只要一些简单的代码,就能让电脑学会分辨苹果的成熟度,很是方便,自己也可以利用这个程序检验生活中苹果的成熟度。

十一、代码

import tensorflow as tf

from keras.applications import resnet

from keras.losses import SparseCategoricalCrossentropy

from keras.layers import *

from keras.applications.resnet import preprocess_input

from keras import Model

from keras.optimizers import Adam

import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

from keras.callbacks import ModelCheckpoint

import os

pretained = True

image_size = 224

expand_rate = 1.1

expand_size = int(expand_rate * image_size)

batch_size = 32

learning_rate = 1*1e-5

#classes = [‘Apple’,‘Carambola’,‘Kiwi’,‘Orange’,‘Pear’,‘Pitaya’,‘Pomegranate’,‘muskmelon’,

‘Banana’,‘Guava’,‘Mango’,‘Peach’,‘Persimmon’,‘Plum’,‘Tomatoes’]

#data_dir = r"D:\datasets\水果分类"

classes = [‘Apple A’, ‘Apple B’, ‘Apple C’, ‘Apple D’, ‘Apple E’, ‘Apple F’]

data_dir = r"D:/苹果成熟度分类\Apple"

weights_file = “苹果分类ResNet50.h5”

def build_resnet50_model(input_size,num_classes,is_pretrained):

_input = Input((input_size,input_size,3))
_body = resnet.ResNet50(include_top=False,weights= 'imagenet' if is_pretrained else None,pooling='avg')(_input)
_output = Dense(num_classes,activation='softmax')(_body)
model = Model(inputs=_input,outputs=_output)
model.compile(optimizer=Adam(learning_rate= learning_rate),loss=SparseCategoricalCrossentropy(from_logits=False),metrics='accuracy')
return model

model = build_resnet50_model(image_size,len(classes),True)

model.summary()

def process_image(filepath,label_idx,show_image=False):

binary = tf.io.read_file(filepath)
image = tf.image.decode_image(binary,expand_animations=False,dtype=tf.float32)
image_height,image_width = tf.shape(image)[0],tf.shape(image)[1]#获取图片的高,获取图片的宽
#接下来对图片进行等比例缩放.
#宽与高较大的者的缩放后的尺寸会直接设置为目标图片大小
#通过上述确定的先后图片边的尺寸,进而确定比例尺
#通过确定的比例尺对图片另一条边进行缩放
if image_height > image_width:
    new_height = expand_size
    new_ratio = tf.cast(expand_size,tf.float32) / tf.cast(image_height,tf.float32)
    new_width = tf.clip_by_value(tf.cast(tf.cast(image_width,tf.float32)* new_ratio,tf.int32),0,expand_size)
else:
    new_width = expand_size
    new_ratio = tf.cast(expand_size,tf.float32) / tf.cast(image_width,tf.float32)
    new_height = tf.clip_by_value(tf.cast(tf.cast(image_height,tf.float32)* new_ratio,tf.int32),0,expand_size)
image_big = tf.image.resize(image,[new_height,new_width])#对图片按照计算出的高于宽进行调整
image_expand = tf.pad(image_big,[[(expand_size - new_height)//2,expand_size-(new_height+(expand_size - new_height)//2)],
                             [(expand_size - new_width)//2,expand_size-(new_width+(expand_size - new_width)//2)],[0,0]])
image_crop = tf.image.random_crop(image_expand,[image_size,image_size,3])
image_flip = tf.image.random_flip_left_right(image_crop)
image_output = tf.image.random_flip_up_down(image_flip)
#image_output = tf.image.transpose(image_flip,tf.gather([0,90,270],tf.random.uniform((),minval=0,maxval=3,dtype=tf.int32)))
if not show_image:
    image_output = preprocess_input(image_output * 255.)
return image_output,label_idx

test_image,_ = process_image(r"D:/苹果成熟度分类\Apple\Apple03.jpg",‘’,show_image=True)

print(tf.reduce_mean(test_image))

print(tf.reduce_max(test_image))

import matplotlib.pyplot as plt

plt.imshow(test_image)

def load_dataset(data_dir):

filepaths = []
label_idices = []
for label_idx,current_dir in enumerate(classes):
    for filename in os.listdir(os.path.join(data_dir,current_dir)):
        filepath = os.path.join(data_dir,current_dir,filename)
        filepaths.append(filepath)
        label_idices.append(label_idx)
return filepaths,label_idices

x_train,x_test,y_train,y_test = train_test_split(*load_dataset(data_dir),shuffle=True,random_state=1234)

train_dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train)).shuffle(2048,seed=1234).map(process_image,num_parallel_calls=32).prefetch(tf.data.AUTOTUNE).batch(batch_size)

test_dataset = tf.data.Dataset.from_tensor_slices((x_test,y_test)).shuffle(2048,seed=1234).map(process_image,num_parallel_calls=32).prefetch(tf.data.AUTOTUNE).batch(batch_size)

model.compile(optimizer=Adam(learning_rate=2*1e-4),loss=SparseCategoricalCrossentropy(from_logits=False),metrics=‘accuracy’)

if os.path.exists(weights_file):

model.load_weights(weights_file)

else:

model.fit(train_dataset,validation_data=test_dataset,epochs=10)

def predict_image(imagepath):

input_image = tf.expand_dims(process_image(imagepath,'')[0],axis=0)
output_probs = model(input_image)
image_label_idx = tf.argmax(output_probs,axis=-1)[0]
image_label = tf.gather(classes,image_label_idx).numpy()
image_label = image_label.decode("UTF-8")
return image_label

label = predict_image(r"D:/苹果成熟度分类\Apple\Apple03.jpg")

print("预测的分类为: ",label)

最后

为了帮助大家更好的学习人工智能,这里给大家准备了一份人工智能入门/进阶学习资料,里面的内容都是适合学习的笔记和资料,不懂编程也能听懂、看懂,所有资料朋友们如果有需要全套人工智能入门+进阶学习资源包,可以在评论区或扫.码领取哦)~

在线教程

  • 麻省理工学院人工智能视频教程 – 麻省理工人工智能课程
  • 人工智能入门 – 人工智能基础学习。Peter Norvig举办的课程
  • EdX 人工智能 – 此课程讲授人工智能计算机系统设计的基本概念和技术。
  • 人工智能中的计划 – 计划是人工智能系统的基础部分之一。在这个课程中,你将会学习到让机器人执行一系列动作所需要的基本算法。
  • 机器人人工智能 – 这个课程将会教授你实现人工智能的基本方法,包括:概率推算,计划和搜索,本地化,跟踪和控制,全部都是围绕有关机器人设计。
  • 机器学习 – 有指导和无指导情况下的基本机器学习算法
  • 机器学习中的神经网络 – 智能神经网络上的算法和实践经验
  • 斯坦福统计学习

    😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

    请添加图片描述

    人工智能书籍

    • OpenCV(中文版).(布拉德斯基等)
    • OpenCV+3计算机视觉++Python语言实现+第二版
    • OpenCV3编程入门 毛星云编著
    • 数字图像处理_第三版
    • 人工智能:一种现代的方法
    • 深度学习面试宝典
    • 深度学习之PyTorch物体检测实战
    • 吴恩达DeepLearning.ai中文版笔记
    • 计算机视觉中的多视图几何
    • PyTorch-官方推荐教程-英文版
    • 《神经网络与深度学习》(邱锡鹏-20191121)
    • 在这里插入图片描述

      😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

      第一阶段:零基础入门(3-6个月)

      新手应首先通过少而精的学习,看到全景图,建立大局观。 通过完成小实验,建立信心,才能避免“从入门到放弃”的尴尬。因此,第一阶段只推荐4本最必要的书(而且这些书到了第二、三阶段也能继续用),入门以后,在后续学习中再“哪里不会补哪里”即可。

      第二阶段:基础进阶(3-6个月)

      熟读《机器学习算法的数学解析与Python实现》并动手实践后,你已经对机器学习有了基本的了解,不再是小白了。这时可以开始触类旁通,学习热门技术,加强实践水平。在深入学习的同时,也可以探索自己感兴趣的方向,为求职面试打好基础。

      第三阶段:工作应用

      这一阶段你已经不再需要引导,只需要一些推荐书目。如果你从入门时就确认了未来的工作方向,可以在第二阶段就提前阅读相关入门书籍(对应“商业落地五大方向”中的前两本),然后再“哪里不会补哪里”。

      在这里插入图片描述

      😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon