草庐IT

【计算机视觉(CV)】基于全连接网络实现宝石分类

灵彧universe 2023-03-28 原文

【计算机视觉(CV)】基于全连接网络实现宝石分类


作者简介:在校大学生一枚,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践资源建设专家委员会(TIPCC)志愿者,以及编程爱好者,期待和大家一起学习,一起进步~ . 博客主页ぃ灵彧が的学习日志 . 本文专栏人工智能 . 专栏寄语:若你决定灿烂,山无遮,海无拦 .

(文章目录)


前言

(一)、任务描述

本次实践是一个多分类任务,需要将照片中的宝石分别进行识别,完成宝石的识别 实践平台:百度AI实训平台-AI Studio、PaddlePaddle2.0.0 动态图


(二)、环境配置

本实践代码运行的环境配置如下:Python版本为3.7,PaddlePaddle版本为2.0.0,操作平台为AI Studio。大部分深度学习项目都要经过以下几个过程:数据准备、模型配置、模型训练、模型评估。

import paddle import numpy as np import matplotlib.pyplot as plt print(paddle.__version__) # cpu/gpu环境选择,在 paddle.set_device() 输入对应运行设备。 # device = paddle.set_device('gpu')

一、方案设计

(一)、深度神经网络(DNN)

深度神经网络(Deep Neural Networks,简称DNN)是深度学习的基础,其结构为input、hidden(可有多层)、output,每层均为全连接。


二、数据集介绍

  • 数据集文件名为archive_train.zip,archive_test.zip。
  • 该数据集包含25个类别不同宝石的图像。
  • 这些类别已经分为训练和测试数据。
  • 图像大小不一,格式为.jpeg。 ​ ​
请勿将本数据集用于商务用途。


三、数据集预处理

本案例主要分以下几个步骤进行数据预处理:

(1)解压原始数据集

(2)按照比例划分训练集与验证集

(3)乱序,生成数据列表

(4)定义数据读取器,转换图片


(一)、导入相关包

首先我们引入本案例需要的所有模块

#导入需要的包 import os import zipfile import random import json import cv2 import numpy as np from PIL import Image import paddle import matplotlib.pyplot as plt from paddle.io import Dataset

(二)、参数配置

''' 参数配置 ''' train_parameters = { "input_size": [3, 224, 224], #输入图片的shape "class_dim": 25, #分类数 "src_path":"data/data55032/archive_train.zip", #原始数据集路径 "target_path":"/home/aistudio/data/dataset", #要解压的路径 "train_list_path": "./train.txt", #train_data.txt路径 "eval_list_path": "./eval.txt", #eval_data.txt路径 "label_dict":{}, #标签字典 "readme_path": "/home/aistudio/data/readme.json", #readme.json路径 "num_epochs": 40, #训练轮数 "train_batch_size": 32, #批次的大小 "learning_strategy": { #优化函数相关的配置 "lr": 0.0001 #超参数学习率 } }

(三)、解压数据集

def unzip_data(src_path,target_path): ''' 解压原始数据集,将src_path路径下的zip包解压至data/dataset目录下 ''' if(not os.path.isdir(target_path)): z = zipfile.ZipFile(src_path, 'r') z.extractall(path=target_path) z.close() else: print("文件已解压")

(四)、生成数据列表

def get_data_list(target_path,train_list_path,eval_list_path): ''' 生成数据列表 ''' #存放所有类别的信息 class_detail = [] #获取所有类别保存的文件夹名称 data_list_path=target_path class_dirs = os.listdir(data_list_path) if '__MACOSX' in class_dirs: class_dirs.remove('__MACOSX') # #总的图像数量 all_class_images = 0 # #存放类别标签 class_label=0 # #存放类别数目 class_dim = 0 # #存储要写进eval.txt和train.txt中的内容 trainer_list=[] eval_list=[] #读取每个类别 for class_dir in class_dirs: if class_dir != ".DS_Store": class_dim += 1 #每个类别的信息 class_detail_list = {} eval_sum = 0 trainer_sum = 0 #统计每个类别有多少张图片 class_sum = 0 #获取类别路径 path = os.path.join(data_list_path,class_dir) # 获取所有图片 img_paths = os.listdir(path) for img_path in img_paths: # 遍历文件夹下的每个图片 if img_path =='.DS_Store': continue name_path = os.path.join(path,img_path) # 每张图片的路径 if class_sum % 15 == 0: # 每10张图片取一个做验证数据 eval_sum += 1 # eval_sum为测试数据的数目 eval_list.append(name_path + "\t%d" % class_label + "\n") else: trainer_sum += 1 trainer_list.append(name_path + "\t%d" % class_label + "\n")#trainer_sum测试数据的数目 class_sum += 1 #每类图片的数目 all_class_images += 1 #所有类图片的数目 # 说明的json文件的class_detail数据 class_detail_list['class_name'] = class_dir #类别名称 class_detail_list['class_label'] = class_label #类别标签 class_detail_list['class_eval_images'] = eval_sum #该类数据的测试集数目 class_detail_list['class_trainer_images'] = trainer_sum #该类数据的训练集数目 class_detail.append(class_detail_list) #初始化标签列表 train_parameters['label_dict'][str(class_label)] = class_dir class_label += 1 #初始化分类数 train_parameters['class_dim'] = class_dim print(train_parameters) #乱序 random.shuffle(eval_list) with open(eval_list_path, 'a') as f: for eval_image in eval_list: f.write(eval_image) #乱序 random.shuffle(trainer_list) with open(train_list_path, 'a') as f2: for train_image in trainer_list: f2.write(train_image) # 说明的json文件信息 readjson = {} readjson['all_class_name'] = data_list_path #文件父目录 readjson['all_class_images'] = all_class_images readjson['class_detail'] = class_detail jsons = json.dumps(readjson, sort_keys=True, indent=4, separators=(',', ': ')) with open(train_parameters['readme_path'],'w') as f: f.write(jsons) print ('生成数据列表完成!')

(五)、参数初始化

''' 参数初始化 ''' src_path=train_parameters['src_path'] target_path=train_parameters['target_path'] train_list_path=train_parameters['train_list_path'] eval_list_path=train_parameters['eval_list_path'] batch_size=train_parameters['train_batch_size'] ''' 解压原始数据到指定路径 ''' unzip_data(src_path,target_path) ''' 划分训练集与验证集,乱序,生成数据列表 ''' #每次生成数据列表前,首先清空train.txt和eval.txt with open(train_list_path, 'w') as f: f.seek(0) f.truncate() with open(eval_list_path, 'w') as f: f.seek(0) f.truncate() #生成数据列表 get_data_list(target_path,train_list_path,eval_list_path) 输出结果如下图1所示:


(六)、定义数据读取器

class Reader(Dataset): def __init__(self, data_path, mode='train'): """ 数据读取器 :param data_path: 数据集所在路径 :param mode: train or eval """ super().__init__() self.data_path = data_path self.img_paths = [] self.labels = [] if mode == 'train': with open(os.path.join(self.data_path, "train.txt"), "r", encoding="utf-8") as f: self.info = f.readlines() for img_info in self.info: img_path, label = img_info.strip().split('\t') self.img_paths.append(img_path) self.labels.append(int(label)) else: with open(os.path.join(self.data_path, "eval.txt"), "r", encoding="utf-8") as f: self.info = f.readlines() for img_info in self.info: img_path, label = img_info.strip().split('\t') self.img_paths.append(img_path) self.labels.append(int(label)) def __getitem__(self, index): """ 获取一组数据 :param index: 文件索引号 :return: """ # 第一步打开图像文件并获取label值 img_path = self.img_paths[index] img = Image.open(img_path) if img.mode != 'RGB': img = img.convert('RGB') img = img.resize((224, 224), Image.BILINEAR) img = np.array(img).astype('float32') img = img.transpose((2, 0, 1)) / 255 label = self.labels[index] label = np.array([label], dtype="int64") return img, label def print_sample(self, index: int = 0): print("文件名", self.img_paths[index], "\t标签值", self.labels[index]) def __len__(self): return len(self.img_paths)

三、定义模型

#定义DNN网络 class MyDNN(paddle.nn.Layer): def __init__(self): super(MyDNN,self).__init__() self.linear1 = paddle.nn.Linear(in_features=3*224*224, out_features=1024) self.relu1 = paddle.nn.ReLU() self.linear2 = paddle.nn.Linear(in_features=1024, out_features=512) self.relu2 = paddle.nn.ReLU() self.linear3 = paddle.nn.Linear(in_features=512, out_features=128) self.relu3 = paddle.nn.ReLU() self.linear4 = paddle.nn.Linear(in_features=128, out_features=25) def forward(self,input): # forward 定义执行实际运行时网络的执行逻辑 # input.shape (16, 3, 224, 224) x = paddle.reshape(input, shape=[-1,3*224*224]) #-1 表示这个维度的值是从x的元素总数和剩余维度推断出来的,有且只能有一个维度设置为-1 # print(x.shape) x = self.linear1(x) x = self.relu1(x) # print('1', x.shape) x = self.linear2(x) x = self.relu2(x) # print('2',x.shape) x = self.linear3(x) x = self.relu3(x) # print('3',x.shape) y = self.linear4(x) # print('4',y.shape) return y Batch=0 Batchs=[] all_train_accs=[] def draw_train_acc(Batchs, train_accs): title="training accs" plt.title(title, fontsize=24) plt.xlabel("batch", fontsize=14) plt.ylabel("acc", fontsize=14) plt.plot(Batchs, train_accs, color='green', label='training accs') plt.legend() plt.grid() plt.show() all_train_loss=[] def draw_train_loss(Batchs, train_loss): title="training loss" plt.title(title, fontsize=24) plt.xlabel("batch", fontsize=14) plt.ylabel("loss", fontsize=14) plt.plot(Batchs, train_loss, color='red', label='training loss') plt.legend() plt.grid() plt.show()

四、模型训练

model=MyDNN() #模型实例化 model.train() #训练模式 cross_entropy = paddle.nn.CrossEntropyLoss() opt=paddle.optimizer.SGD(learning_rate=0.001, parameters=model.parameters()) epochs_num=train_parameters['num_epochs'] #迭代次数 for pass_num in range(train_parameters['num_epochs']): for batch_id,data in enumerate(train_loader()): image = data[0] label = data[1] predict=model(image) #数据传入model loss=cross_entropy(predict,label) acc=paddle.metric.accuracy(predict,label)#计算精度 if batch_id!=0 and batch_id%5==0: Batch = Batch+5 Batchs.append(Batch) all_train_loss.append(loss.numpy()[0]) all_train_accs.append(acc.numpy()[0]) print("train_pass:{},batch_id:{},train_loss:{},train_acc:{}".format(pass_num,batch_id,loss.numpy(),acc.numpy())) loss.backward() opt.step() opt.clear_grad() #opt.clear_grad()来重置梯度 paddle.save(model.state_dict(),'MyDNN')#保存模型 draw_train_acc(Batchs,all_train_accs) draw_train_loss(Batchs,all_train_loss) 输出结果如下图2、3、4所示:



五、模型评估

#模型评估 para_state_dict = paddle.load("MyDNN") model = MyDNN() model.set_state_dict(para_state_dict) #加载模型参数 model.eval() #验证模式 accs = [] for batch_id,data in enumerate(eval_loader()):#测试集 image=data[0] label=data[1] predict=model(image) acc=paddle.metric.accuracy(predict,label) accs.append(acc.numpy()[0]) avg_acc = np.mean(accs) print("当前模型在验证集上的准确率为:",avg_acc) 输出结果如下图5所示:


六、模型预测


总结

本系列文章内容为根据清华社出版的《自然语言处理实践》所作的相关笔记和感悟,其中代码均为基于百度飞桨开发,若有任何侵权和不妥之处,请私信于我,定积极配合处理,看到必回!!!

最后,引用本次活动的一句话,来作为文章的结语~( ̄▽ ̄~)~:

【**学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。**】

有关【计算机视觉(CV)】基于全连接网络实现宝石分类的更多相关文章

  1. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  5. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby - 使用 Ruby,计算 n x m 数组的每一列中有多少个 true 的简单方法是什么? - 2

    给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in

  8. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  9. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  10. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

随机推荐