赞
踩
背景
水果分类在水果产业和社会经济发展中具有重要意义。目前,水果分类主要依赖人工分类,但这种方法浪费大量人力物力且效率低。随着人工智能和机器视觉的发展,基于深度学习的水果分类方法具有重要意义和广泛的应用价值。
数据准备:
数据集创建:
数据加载与划分:
模型构建:
模型训练:
模型测试:
- # 查看当前挂载的数据集目录, 该目录下的变更重启环境后会自动还原
- # View dataset directory.
- # This directory will be recovered automatically after resetting environment.
- !ls /home/aistudio/data
- # 查看工作区文件, 该目录下的变更将会持久保存. 请及时清理不必要的文件, 避免加载过慢.
- # View personal work directory.
- # All changes under this directory will be kept even after reset.
- # Please clean unnecessary files in time to speed up environment loading.
- !ls /home/aistudio/work
- # 如果需要进行持久化安装, 需要使用持久化路径, 如下方代码示例:
- # If a persistence installation is required,
- # you need to use the persistence path as the following:
- !mkdir /home/aistudio/external-libraries
- !pip install beautifulsoup4 -t /home/aistudio/external-libraries
- # 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:
- # Also add the following code,
- # so that every time the environment (kernel) starts,
- # just run the following code:
- import sys
- sys.path.append('/home/aistudio/external-libraries')
- import paddle
- print(sys.version)
对应关系: torch.nn--paddle.nn torchvision.transforms--paddle.vision.transforms torchvision.datasets--paddle.vision.datasets torch.utils.data--paddle.io.DataLoader
- import paddle.nn as nn
- import paddle.vision.transforms as transforms
- import paddle.vision.datasets as datasets
- import paddle.io as DataLoader
- from matplotlib import pyplot as plt
- batch_size=64#批处理数量
- num_epochs=100#训练周期
- num_classes=3#标签种类数
- lr=0.001#学习率
- trans=transforms.Compose([
- transforms.ToTensor(),
- transforms.Resize(size=28),
- transforms.CenterCrop(28),
- transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
- ])
- %cd /home/aistudio/
- !unzip /home/aistudio/data/data154561/shuiguo.zip
- import os
- all_file_dir = 'shuiguo'
-
- img_list = []
- label_list = []
-
- label_id = 0
-
- class_list = [c for c in os.listdir(all_file_dir) if os.path.isdir(os.path.join(all_file_dir, c))]
-
- for class_dir in class_list:
- image_path_pre = os.path.join(all_file_dir, class_dir)
- for img in os.listdir(image_path_pre):
- img_list.append(os.path.join(image_path_pre, img))
- label_list.append(label_id)#标签值
- label_id += 1
- import pandas as pd
- import numpy as np
- img_df = pd.DataFrame(img_list)
- label_df = pd.DataFrame(label_list)
-
- img_df.columns = ['images']
- label_df.columns = ['label']
-
- df = pd.concat([img_df, label_df], axis=1)
- df = df.reindex(np.random.permutation(df.index))
- df.to_csv('food_data.csv', index=0)
- df = pd.read_csv('food_data.csv')#读取csv文件
- image_path_list = df['images'].values
- label_list = df['label'].values
-
- all_size = len(image_path_list)
- train_size = int(all_size * 0.8)
-
- #训练集
- train_image_path_list = image_path_list[:train_size]
- train_label_list = label_list[:train_size]
-
- #测试集
- val_image_path_list = image_path_list[train_size:]
- val_label_list = label_list[train_size:]
- import numpy as np
- from PIL import Image
- from paddle.io import Dataset
- import paddle.vision.transforms as T
- import paddle as pd
-
- class MyDataset(Dataset):
- """
- 步骤一:继承paddle.io.Dataset类
- """
- def __init__(self, image, label, transform=None):
- """
- 步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集
- """
- super(MyDataset, self).__init__()
- imgs = image
- labels = label
-
- self.labels = labels
- self.imgs = imgs
- self.transform = transform
- # self.loader = loader
- def __getitem__(self, index): # 这个方法是必须要有的,用于按照索引读取每个元素的具体内容
- fn = self.imgs
- label = self.labels
- # fn是图片path #fn和label分别获得imgs[index]也即是刚才每行中word[0]和word[1]的信息
- for im,la in zip(fn, label):
- img = Image.open(im)
- img = img.convert("RGB")
- img = np.array(img)
- label = np.array([la]).astype(dtype='int64')
- # 按照路径读取图片
- if self.transform is not None:
- img = self.transform(img)
- # 数据标签转换为Tensor
- return img, label
- # return回哪些内容,那么我们在训练时循环读取每个batch时,就能获得哪些内容
-
- def __len__(self):
- # 这个函数也必须要写,它返回的是数据集的长度,也就是多少张图片,要和loader的长度作区分
- return len(self.imgs)
-
- import paddle
- from paddle.metric import Accuracy
- from paddle.vision.models import resnet18
-
- import warnings
- warnings.filterwarnings("ignore")
- import warnings
- warnings.filterwarnings("ignore")
-
- #训练集
- train_dataset = MyDataset(image=train_image_path_list, label=train_label_list ,transform=trans)#转化成一个dataset子类实例
- train_loader = paddle.io.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
- #测试集
- test_dataset = MyDataset(image=val_image_path_list,label=val_label_list,transform=trans)
- test_loader = paddle.io.DataLoader(test_dataset, batch_size=batch_size, shuffle=True)
- images,lables=next(iter(train_loader))
- imgs=images[0].numpy().transpose(1,2,0)
- plt.imshow(imgs)
- plt.title(lables[0])
- plt.show()
- print("一共{}个样本".format(len(train_loader.dataset)))
- images,lables=next(iter(test_loader))
- imgs=images[0].numpy().transpose(1,2,0)
- plt.imshow(imgs)
- plt.title(lables[0])
- plt.show()
- print("一共{}个样本".format(len(test_loader.dataset)))
定义卷积神经网络过程基本相同,和pytorch不同的是,Tensor维度的变化: paddle里面没有view这个函数,使用paddle.reshape代替。 新张量=paddle.reshape(张量,维度)
- import paddle.fluid as fluid
- import paddle.nn.functional as F##torch.nn.functional
- depth=[32,64,128,256]
- class CNN(fluid.dygraph.Layer):##torch.nn.Module
- def __init__(self):
- super(CNN,self).__init__()
- self.conv1=nn.Conv2D(in_channels=3,out_channels=depth[0],kernel_size=5,stride=1,padding=2)
- self.pool=nn.MaxPool2D(2,2)
- self.conv2=nn.Conv2D(in_channels=depth[0],out_channels=depth[1],kernel_size=5,stride=1,padding=2)
- self.fc1=nn.Linear(28//4*28//4*depth[1],512)
- self.fc2=nn.Linear(512,num_classes)
-
- ##前向传播
- def forward(self,x):
- x=F.relu(self.conv1(x))
- x=self.pool(x)
- x=F.relu(self.conv2(x))
- x=self.pool(x)
- x=paddle.reshape(x,[-1,28//4*28//4*depth[1]])#####有所不同
- x=F.relu(self.fc1(x))
- x=F.dropout(x,training=self.training)
- x=self.fc2(x)
- x=F.dropout(x,training=self.training)
- return x
cnn_model=CNN()
训练数据,和pytorch也有很大不同。比pytorch里面的训练方式方便。模型封装,函数配置,启动训练。
- model = paddle.Model(cnn_model) # 模型封装
-
- # 配置优化器、损失函数、评估指标
- model.prepare(paddle.optimizer.Adam(learning_rate=0.0001, parameters=model.parameters()),
- paddle.nn.CrossEntropyLoss(),
- paddle.metric.Accuracy())
-
-
- # 启动模型全流程训练
- model.fit(train_loader, # 训练数据集
- test_loader, # 评估数据集
- epochs=5, # 训练的总轮次
- batch_size=2, # 训练使用的批大小
- verbose=1)
model.save('work/model1')#保存模型
- import paddle
- _model=paddle.Model(cnn_model)
- _model.load('work/model1')#加载模型
- import os
- trans=transforms.Compose([
- transforms.ToTensor(),
- transforms.Resize(size=28),
- transforms.CenterCrop(28),
- transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
- ])
-
-
- all_file_dir = 'test1'
-
- img_list = []
- label_list = []
-
- label_id = 0
-
- class_list = [c for c in os.listdir(all_file_dir) if os.path.isdir(os.path.join(all_file_dir, c))]
-
- for class_dir in class_list:
- image_path_pre = os.path.join(all_file_dir, class_dir)
- for img in os.listdir(image_path_pre):
- img_list.append(os.path.join(image_path_pre, img))
- label_list.append(label_id)#标签值
- label_id += 1
- import pandas as pd
- import numpy as np
- img_df = pd.DataFrame(img_list)
- label_df = pd.DataFrame(label_list)
-
- img_df.columns = ['images']
- label_df.columns = ['label']
-
- df = pd.concat([img_df, label_df], axis=1)
- df = df.reindex(np.random.permutation(df.index))
- df.to_csv('test1.csv', index=0)
- ##存为csv文件
- df = pd.read_csv('test1.csv')
- image_path_list = df['images'].values
- label_list = df['label'].values
-
- input_dataset = MyDataset(image=image_path_list, label=label_list ,transform=trans)#转化成一个dataset子类实例
- input_loader = paddle.io.DataLoader(input_dataset, batch_size=1, shuffle=True)
- images,lables=next(iter(input_loader))
- imgs=images[0].numpy().transpose(1,2,0)
- plt.imshow(imgs)
- plt.title(lables[0])
- plt.show()
- print("一共{}个样本".format(len(input_loader.dataset)))
- classes=['orange','apple','banana']
- test_result=model.predict(input_loader)
- pred_label = test_result[0][0].argmax()
- print("预测结果为:{}".format(classes[pred_label]))
本项目实现了一个水果分类程序,基于深度学习技术。通过合理的数据预处理、自定义数据集类、CNN模型构建和训练,我们成功实现了水果图像的分类任务。这个项目对于自动化水果分类在农业和食品工业中具有重要的应用前景,可以提高分类准确度和效率。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。