<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          分享 | 基于圖像分類網(wǎng)絡(luò)ResNet50_vd實(shí)現(xiàn)桃子分類

          共 6938字,需瀏覽 14分鐘

           ·

          2021-12-23 19:23

          點(diǎn)擊下方卡片,關(guān)注“新機(jī)器視覺”公眾號(hào)

          視覺/圖像重磅干貨,第一時(shí)間送達(dá)

          隨著時(shí)代的快速發(fā)展,人工智能已經(jīng)融入我們生活的方方面面。中國(guó)的農(nóng)業(yè)也因人工智能而受益進(jìn)入高速發(fā)展階段?,F(xiàn)今,看莊稼長(zhǎng)勢(shì)有衛(wèi)星遙感技術(shù),水果分揀有智能分揀系統(tǒng),灌溉施肥有自動(dòng)化機(jī)械……

          來源:知乎
          作者:快速實(shí)現(xiàn)AI想法

          具體以水果分揀場(chǎng)景為例,大型的水果種植園每到豐收的季節(jié),都會(huì)雇傭大量的分揀工人來分揀水果,這是一件人力成本很高的事情。另外,人工分揀水平層次不一還可能使得農(nóng)場(chǎng)主收益受到很大影響。然而,如今智能水果分揀系統(tǒng)的出現(xiàn),可以自動(dòng)根據(jù)設(shè)置的水果等農(nóng)作物的品級(jí)進(jìn)行分揀,降低人力成本,提高處理效率,提升分揀的準(zhǔn)確性,那么問題來了。

          如何搭建一套完整的智能水果分揀系統(tǒng)?巧了,PaddleHub正好可以幫你搞定完整的系統(tǒng)建立!

          今天我們帶大家利用PaddleHub搭建ResNet50_vd網(wǎng)絡(luò),實(shí)現(xiàn)桃子分類,讓大家親自感受圖像分類的魅力。

          本實(shí)踐旨在通過桃子分類來讓大家對(duì)圖像分類問題有一個(gè)初步了解,同時(shí)理解和掌握如何使用PaddleHub搭建一個(gè)經(jīng)典的卷積神經(jīng)網(wǎng)絡(luò)。

          如果您覺得本案例對(duì)您有幫助,歡迎Star收藏一下,不易走丟哦~,鏈接指路:https://github.com/PaddlePaddle/awesome-DeepLearning。


          方案設(shè)計(jì)


          本教程的設(shè)計(jì)方案如圖2所示。對(duì)于一幅輸入的桃子圖像,首先使用ResNet50_vd網(wǎng)絡(luò)提取特征,獲取特征表示;然后使用分類器獲取屬于每個(gè)桃子類別的概率值。在訓(xùn)練階段,通過模型輸出的概率值與樣本的真實(shí)標(biāo)簽構(gòu)建損失函數(shù),從而進(jìn)行模型訓(xùn)練;在推理階段,選出概率最大的類別作為最終的輸出。



          環(huán)境搭建與準(zhǔn)備



          安裝PaddlePaddle:參考快速安裝,aistudio已經(jīng)預(yù)先安裝好了PaddlePaddle。

          安裝PaddleHub:為了保證最新版本穩(wěn)定,建議執(zhí)行以下命令安裝。

          !pip install paddlehub==2.0.4 -i https://pypi.tuna.tsinghua.edu.cn/simple


          數(shù)據(jù)處理


          在本教程提供的數(shù)據(jù)文件中,已經(jīng)提供了分割好的訓(xùn)練集、驗(yàn)證集、測(cè)試集的索引和標(biāo)注文件。如果用戶利用PaddleHub遷移CV類任務(wù)使用自定義數(shù)據(jù),則需要自行切分?jǐn)?shù)據(jù)集,將數(shù)據(jù)集切分為訓(xùn)練集、驗(yàn)證集和測(cè)試集。需要三個(gè)文本文件來記錄對(duì)應(yīng)的圖片路徑和標(biāo)簽,此外還需要一個(gè)標(biāo)簽文件用于記錄標(biāo)簽的名稱。相關(guān)方法可參考自定義數(shù)據(jù)集。該桃子分揀系統(tǒng)按照桃子品相分為4個(gè)等級(jí)。


          其中:R0為最好:顏色鮮紅且果實(shí)較大;B1為次優(yōu):果實(shí)較大,顏色較紅;M2為中等:果實(shí)中等;S3為較差:果實(shí)個(gè)頭比較小。

          數(shù)據(jù)分為訓(xùn)練集、驗(yàn)證集和測(cè)試集,訓(xùn)練集為每種桃子各1500張,驗(yàn)證集每種桃子各100張,測(cè)試集每種桃子為15張。

          ├─data: 數(shù)據(jù)目錄
          ├─train_list.txt:訓(xùn)練集數(shù)據(jù)列表
          ├─test_list.txt:測(cè)試集數(shù)據(jù)列表
          ├─validate_list.txt:驗(yàn)證集數(shù)據(jù)列表
          ├─label_list.txt:標(biāo)簽列表
          └─……

          訓(xùn)練集、驗(yàn)證集和測(cè)試集的數(shù)據(jù)列表文件的格式如下,列與列之間以空格鍵分隔。

          圖片1路徑 圖片1標(biāo)簽
          圖片2路徑 圖片2標(biāo)簽
          ...

          label_list.txt的格式如下:

          分類1名稱
          分類2名稱
          ...

          隨后進(jìn)行數(shù)據(jù)集的解壓:

          !unzip -q -o ./data/data67225/peach.zip -d ./work

          準(zhǔn)備好數(shù)據(jù)后即可使用PaddleHub完成數(shù)據(jù)讀取器的構(gòu)建,實(shí)現(xiàn)方法如下所示:構(gòu)建數(shù)據(jù)讀取Python類,并繼承paddle.io.Dataset這個(gè)類完成數(shù)據(jù)讀取器構(gòu)建。在定義數(shù)據(jù)集時(shí),需要預(yù)先定義好對(duì)數(shù)據(jù)集的預(yù)處理操作,并且設(shè)置好數(shù)據(jù)模式。在數(shù)據(jù)集定義中,需要重新定義__init____getitem____len__三個(gè)部分。示例如下:

          #coding:utf-8
          import os

          import paddle
          import paddlehub as hub


          class DemoDataset(paddle.io.Dataset):
          def __init__(self, transforms, num_classes=4, mode='train'):
          # 數(shù)據(jù)集存放位置
          self.dataset_dir = "./work/peach-classification" #dataset_dir為數(shù)據(jù)集實(shí)際路徑,需要填寫全路徑
          self.transforms = transforms
          self.num_classes = num_classes
          self.mode = mode

          if self.mode == 'train':
          self.file = 'train_list.txt'
          elif self.mode == 'test':
          self.file = 'test_list.txt'
          else:
          self.file = 'validate_list.txt'

          self.file = os.path.join(self.dataset_dir , self.file)
          self.data = []

          with open(self.file, 'r') as f:
          for line in f.readlines():
          line = line.strip()
          if line != '':
          self.data.append(line)

          def __getitem__(self, idx):
          img_path, grt = self.data[idx].split(' ')
          img_path = os.path.join(self.dataset_dir, img_path)
          im = self.transforms(img_path)
          return im, int(grt)


          def __len__(self):
          return len(self.data)

          將訓(xùn)練數(shù)據(jù)輸入模型之前,我們通常還需要對(duì)原始數(shù)據(jù)做一些數(shù)據(jù)處理的工作,比如數(shù)據(jù)格式的規(guī)范化處理,或增加一些數(shù)據(jù)增強(qiáng)策略。

          構(gòu)建圖像分類模型的數(shù)據(jù)讀取器,負(fù)責(zé)將桃子dataset的數(shù)據(jù)進(jìn)行預(yù)處理,以特定格式組織并輸入給模型進(jìn)行訓(xùn)練。

          如下數(shù)據(jù)處理策略,只做了三種操作:
          1.指定輸入圖片的尺寸,并將所有樣本數(shù)據(jù)統(tǒng)一處理成該尺寸。
          2.對(duì)輸入圖像進(jìn)行裁剪,并且保持圖片中心點(diǎn)不變。
          3.對(duì)所有輸入圖片數(shù)據(jù)進(jìn)行歸一化處理。

          對(duì)數(shù)據(jù)預(yù)處理及加載數(shù)據(jù)集的示例如下:

          import paddlehub.vision.transforms as T

          transforms = T.Compose(
          [T.Resize((256, 256)),
          T.CenterCrop(224),
          T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])],
          to_rgb=True)

          peach_train = DemoDataset(transforms)
          peach_validate = DemoDataset(transforms, mode='val')
          peach_test = DemoDataset(transforms, mode='test')

          PaddleHub提供了豐富的數(shù)據(jù)預(yù)處理方式,具體可以參見預(yù)處理。


          模型構(gòu)建


          我們要在PaddleHub中選擇合適的預(yù)訓(xùn)練模型來Fine-tune,由于桃子分類是一個(gè)圖像分類任務(wù),這里采用Resnet50模型,并且是采用ImageNet數(shù)據(jù)集預(yù)訓(xùn)練過的版本。這個(gè)預(yù)訓(xùn)練模型是在圖像任務(wù)中的一個(gè)“萬金油”模型,Resnet是目前較為有效的處理圖像的網(wǎng)絡(luò)結(jié)構(gòu),50層是一個(gè)精度和性能兼顧的選擇,而ImageNet又是計(jì)算機(jī)視覺領(lǐng)域公開的最大的分類數(shù)據(jù)集。所以,在不清楚選擇什么模型好的時(shí)候,可以優(yōu)先以這個(gè)模型作為baseline。

          使用PaddleHub加載ResNet50模型,十分簡(jiǎn)單,只需一行代碼即可實(shí)現(xiàn)。關(guān)于更多預(yù)訓(xùn)練模型信息參見PaddleHub模型介紹。

          #安裝預(yù)訓(xùn)練模型
          !hub install resnet50_vd_imagenet_ssld==1.1.0
          # 加載模型

          import paddlehub as hub

          model = hub.Module(name='resnet50_vd_imagenet_ssld', label_list=["R0", "B1", "M2", "S3"])


          模型訓(xùn)練


          本案例中,我們使用Adam優(yōu)化器,2014年12月,Kingma和Lei Ba提出了Adam優(yōu)化器。該優(yōu)化器對(duì)梯度的均值,即一階矩估計(jì)(First Moment Estimation)和梯度的未中心化的方差,即二階矩估計(jì)(Second Moment Estimation)進(jìn)行綜合計(jì)算,獲得更新步長(zhǎng)。Adam優(yōu)化器實(shí)現(xiàn)起來較為簡(jiǎn)單,且計(jì)算效率高,需要的內(nèi)存更少,梯度的伸縮變換不會(huì)影響更新梯度的過程, 超參數(shù)的可解釋性強(qiáng),且通常超參數(shù)無需調(diào)整或僅需微調(diào)等優(yōu)點(diǎn)。我們將學(xué)習(xí)率設(shè)置為0.001,訓(xùn)練10個(gè)epochs。

          from paddlehub.finetune.trainer import Trainer

          import paddle

          optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
          trainer = Trainer(model, optimizer, checkpoint_dir='img_classification_ckpt', use_gpu=True)
          trainer.train(peach_train, epochs=10, batch_size=16, eval_dataset=peach_validate, save_interval=1)

          其中?paddle.optimizer.Adam:
          • learning_rate:全局學(xué)習(xí)率。默認(rèn)為1e-3;
          • parameters:待優(yōu)化模型參數(shù)。

          運(yùn)行配置


          Trainer?主要控制Fine-tune的訓(xùn)練,包含以下可控制的參數(shù):
          • model:被優(yōu)化模型;
          • optimizer:優(yōu)化器選擇;
          • use_vdl:是否使用vdl可視化訓(xùn)練過程;
          • checkpoint_dir:保存模型參數(shù)的地址;
          • compare_metrics:保存最優(yōu)模型的衡量指標(biāo);

          trainer.train?主要控制具體的訓(xùn)練過程,包含以下可控制的參數(shù):
          • train_dataset:訓(xùn)練時(shí)所用的數(shù)據(jù)集;
          • epochs:訓(xùn)練輪數(shù);
          • batch_size:訓(xùn)練的批大小,如果使用GPU,請(qǐng)根據(jù)實(shí)際情況調(diào)整batch_size;
          • num_workers:works的數(shù)量,默認(rèn)為0;
          • eval_dataset:驗(yàn)證集;
          • log_interval:打印日志的間隔, 單位為執(zhí)行批訓(xùn)練的次數(shù)。
          • save_interval:保存模型的間隔頻次,單位為執(zhí)行訓(xùn)練的輪數(shù)。

          當(dāng)Fine-tune完成后,我們使用模型來進(jìn)行預(yù)測(cè),實(shí)現(xiàn)如下:


          模型評(píng)估


          這里我們使用測(cè)試集來評(píng)估訓(xùn)練完成的模型。

          # 模型評(píng)估
          trainer.evaluate(peach_test, 16)


          模型推理


          這里我們使用訓(xùn)練完成的模型來預(yù)測(cè)測(cè)試集中的一張圖片,觀察預(yù)測(cè)結(jié)果與真實(shí)結(jié)果是否一致。

          import paddle
          import paddlehub as hub
          from PIL import Image
          import matplotlib.pyplot as plt

          img_path = './work/test.jpg'
          img = Image.open(img_path)
          plt.imshow(img)
          plt.axis('off')
          plt.show()
          result = model.predict([img_path])
          print("桃子的類別被預(yù)測(cè)為:{}".format(result))

          以上為加載模型后實(shí)際預(yù)測(cè)結(jié)果(這里只測(cè)試了一張圖片),返回的是預(yù)測(cè)的實(shí)際效果,可以看到我們傳入待預(yù)測(cè)的是M2類別的桃子照片,經(jīng)過Fine-tune之后的模型預(yù)測(cè)的效果也是M2,由此成功完成了桃子分類的遷移學(xué)習(xí)。


          模型部署


          由于AIStudio不支持ip訪問,以下代碼僅做示例,如有需要,請(qǐng)?jiān)诒镜貦C(jī)器運(yùn)行。

          想用我們自己訓(xùn)練的分揀桃子的網(wǎng)絡(luò)參數(shù),先配置config.json文件:

          {
          "modules_info": {
          "resnet50_vd_imagenet_ssld": {
          "init_args": {
          "version": "1.1.0",
          "label_list":["R0", "B1", "M2", "S3"],
          "load_checkpoint": "img_classification_ckpt/best_model/model.pdparams"
          },
          "predict_args": {
          "batch_size": 1
          }

          }
          },
          "port": 8866,
          "gpu": "0"
          }

          借助?PaddleHub,服務(wù)器端的部署也非常簡(jiǎn)單,直接用一條命令行在服務(wù)器啟動(dòng)resnet50分類模型就行了:

          $ hub serving start --config config.json

          是的,在服務(wù)器端這就完全沒問題了。相比手動(dòng)配置各種參數(shù)或者調(diào)用各種框架,PaddleHub 部署服務(wù)器實(shí)在是太好用了。

          NOTE:?如使用GPU預(yù)測(cè),則需要在啟動(dòng)服務(wù)之前,請(qǐng)?jiān)O(shè)置CUDA_VISIBLE_DEVICES環(huán)境變量,否則不用設(shè)置。

          在服務(wù)端發(fā)送請(qǐng)求,請(qǐng)求腳本如下:

          import requests
          import json
          import cv2
          import base64

          import numpy as np


          def cv2_to_base64(image):
          data = cv2.imencode('.jpg', image)[1]
          return base64.b64encode(data.tostring()).decode('utf8')

          def base64_to_cv2(b64str):
          data = base64.b64decode(b64str.encode('utf8'))
          data = np.fromstring(data, np.uint8)
          data = cv2.imdecode(data, cv2.IMREAD_COLOR)
          return data

          # 發(fā)送HTTP請(qǐng)求
          org_im = cv2.imread('/PATH/TO/IMAGE')

          data = {'images':[cv2_to_base64(org_im)], 'top_k':1}
          headers = {"Content-type": "application/json"}
          url = "http://127.0.0.1:8866/predict/resnet50_vd_imagenet_ssld"
          r = requests.post(url=url, headers=headers, data=json.dumps(data))
          data =r.json()["results"]['data']

          相信只要有一些 Python 基礎(chǔ),在本地預(yù)測(cè)、以及部署到服務(wù)器端都是沒問題的,飛槳的 PaddleHub 已經(jīng)幫我們做好了各種處理過程。

          數(shù)據(jù)來源:https://aistudio.baidu.com/aistudio/datasetdetail/67225
          本文僅做學(xué)術(shù)分享,如有侵權(quán),請(qǐng)聯(lián)系刪文。
          —THE END—
          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色中文娱乐网 | 亚洲V国产v欧美v久久久久久 | 亚洲日韩小电影 | 青春草视频免费观看 | 国产 亚洲 无码 激情 |