訂閱
糾錯(cuò)
加入自媒體

構(gòu)建一個(gè)計(jì)算機(jī)視覺(jué)項(xiàng)目

你想創(chuàng)建一個(gè)應(yīng)用程序來(lái)檢測(cè)一些東西嗎?貓和狗,檢測(cè)水果的成熟程度,在圖片中找到品牌?

如果你的答案是需要,那么這篇文章就是為你準(zhǔn)備的!

將向你展示如何為你的探測(cè)器創(chuàng)建一個(gè)應(yīng)用程序,并把它放到互聯(lián)網(wǎng)上,讓每個(gè)人都能看到。

你將能夠上傳一個(gè)測(cè)試圖像,模型將返回預(yù)測(cè)框和標(biāo)簽。

免責(zé)聲明:你需要在你的電腦中安裝git才能將文件上傳到HuggingFace Spaces。如果你沒(méi)有,不要擔(dān)心!安裝起來(lái)很容易。

這將是項(xiàng)目的工作流程:

首先,你必須為你的項(xiàng)目收集圖像。你想從長(zhǎng)頸鹿中發(fā)現(xiàn)斑馬嗎?首先需要獲取這兩種動(dòng)物的圖像。無(wú)論你想檢測(cè)什么,你都需要它的圖像。這個(gè)點(diǎn)在工作流程中是白色的,這意味著你必須在你的計(jì)算機(jī)中完成工作。

標(biāo)簽圖像在工作流中顯示為藍(lán)色,這是因?yàn)槟銓⑹褂肈atature的標(biāo)簽工具。Datature是一家專門(mén)為數(shù)據(jù)標(biāo)簽和模型訓(xùn)練構(gòu)建用戶友好工具的公司。

你還將使用Datature來(lái)訓(xùn)練模型。

一旦模型訓(xùn)練好了,你就把它下載到你的電腦上,把所有的文件放在一起(這些文件我會(huì)提供給你)

當(dāng)所有文件放在一起時(shí),你將把它們上傳到HuggingFace Spaces,你的模型就可以使用了!

1.找到圖片

計(jì)算機(jī)視覺(jué)項(xiàng)目中,我們需要做的第一件事是收集圖像。如果我們想要訓(xùn)練一個(gè)深度神經(jīng)網(wǎng)絡(luò),我們需要成千上萬(wàn)張圖像。

幸運(yùn)的是,Datature使用非常先進(jìn)的模型,而且可能是預(yù)訓(xùn)練的,這意味著如果我們從頭開(kāi)始訓(xùn)練模型,我們只需要需要的一小部分圖像。

每個(gè)類大約有100個(gè)圖像就足夠了。例如,如果你想要檢測(cè)t恤和褲子,你將需要100個(gè)t恤和100個(gè)褲子的圖像。當(dāng)然,這個(gè)例子也適用于其他情況。例如,你可以有100張貓和狗的圖片,所以你可以有100張貓的例子,也可以有100張狗的例子。

如果有類不平衡是可以的,例如如果你的項(xiàng)目檢測(cè)晴天和陰天,你可以有120張晴天的圖片和100張陰天的圖片。大約100張就足夠了。

收集所有的圖像并存儲(chǔ)在你的計(jì)算機(jī)的一個(gè)文件夾中。

2.標(biāo)記圖像

在Datature中創(chuàng)建一個(gè)帳戶,并為你的用例創(chuàng)建一個(gè)項(xiàng)目。

這篇博文詳細(xì)介紹了如何:

創(chuàng)建Datature Nexus賬戶(免費(fèi)試用)

創(chuàng)建一個(gè)項(xiàng)目

上傳圖片

創(chuàng)建類

注釋圖片

在圖像中創(chuàng)建矩形框

為每個(gè)框分配一個(gè)類

對(duì)于每個(gè)圖像,你將注釋一個(gè)框(對(duì)象在哪里?)和一個(gè)類(對(duì)象是什么?)

只閱讀標(biāo)簽部分,之后,在項(xiàng)目概述中,你應(yīng)該看到你的圖像統(tǒng)計(jì),標(biāo)簽分布等。例如,項(xiàng)目概述應(yīng)該是這樣的:

在這個(gè)例子中,我有一個(gè)名為香蕉的項(xiàng)目,我標(biāo)記了16張圖片,我有3類:成熟的、可食用的和無(wú)效的。這只是一個(gè)示例,所以請(qǐng)確保每個(gè)類至少有100個(gè)示例!

3.訓(xùn)練模型

一旦我們有了圖像,我們就可以訓(xùn)練我們的模型了!我們將不得不在Nexus中創(chuàng)建一個(gè)“工作流”。

構(gòu)建訓(xùn)練工作流程:選擇訓(xùn)練-測(cè)試分割比,選擇增強(qiáng),選擇模型設(shè)置

訓(xùn)練模型

監(jiān)控模型:損失、精度、召回

導(dǎo)出模型

模型將需要大約1小時(shí)來(lái)訓(xùn)練,之后你應(yīng)該看到這個(gè)

進(jìn)入Artifacts并下載TensorFlow模型

當(dāng)計(jì)算機(jī)中導(dǎo)出了一個(gè).zip文件時(shí),這一部分就完成了。

4.創(chuàng)建一個(gè)HuggingFace帳戶

模型是經(jīng)過(guò)訓(xùn)練的,我們把它以.zip的形式下載到我們的電腦上。但我們?nèi)绾闻c它交互呢?

我們可以通過(guò)上傳照片到HuggingFace Spaces與它交互。我們還需要一些網(wǎng)站前端的代碼。

Huggingface Spaces是Huggingface旗下的一個(gè)網(wǎng)站,人們可以在這里展示自己的模型,并與他們交互。

這些是創(chuàng)建步驟

1.創(chuàng)建Huggingface帳戶

2.創(chuàng)建一個(gè)Space

3.為Space寫(xiě)一個(gè)名字。記住,這個(gè)網(wǎng)站將是公開(kāi)的,所以選擇一個(gè)與應(yīng)用程序相匹配的名字!例如:香蕉分析或類似的東西

4.選擇Streamlit作為空間SDK

5.選擇public

6.Space使用完成后,將存儲(chǔ)庫(kù)克隆到本地計(jì)算機(jī)中的一個(gè)文件夾中

7.可選的README.md

5.收集所有文件并上傳至HuggingFace空間

現(xiàn)在,我們的計(jì)算機(jī)中有了屬于Space的文件夾。我們必須復(fù)制所有文件,并使用git將所有文件上傳到Space。

首先,復(fù)制模型文件(saved_model/ folder, label_map.pbtxt)到文件夾

然后,在這個(gè)https://gist.github.com/anebz/2f62caeab1f24aabb9f5d1a60a4c2d25文件夾中創(chuàng)建3個(gè)文件

app.py

此文件包含用于上傳圖像、加載模型、進(jìn)行預(yù)處理和從模型獲得預(yù)測(cè)的代碼。

注意那些帶有#TODO的行,你必須修改它們!

特別是color_map,它們是每個(gè)類的方框的顏色。打開(kāi)文件label_map.pbtxt查看給每個(gè)類分配了什么label_id,并使用這個(gè)label_id為顏色分配RGB值。

在這個(gè)例子中,我只有2個(gè)類,因此只有2種顏色。如果你有更多的類,按照示例的格式添加更多行:

1: [255, 0, 0],

記住,除了最后一行以外,每一行的末尾都應(yīng)該有一個(gè)逗號(hào)!

import cv2
      import numpy as np
      from PIL import Image
      import streamlit as st
      import tensorflow as tf
      from tensorflow.keras.models import load_model
      # most of this code has been obtained from Datature's prediction script
      # https://github.com/datature/resources/blob/main/scripts/bounding_box/prediction.py
      st.set_option('deprecation.showfileUploaderEncoding', False)
      @st.cache(allow_output_mutation=True)
      def load_model():
         return tf.saved_model.load('./saved_model')
      def load_label_map(label_map_path):
        """
         Reads label map in the format of .pbtxt and parse into dictionary
         Args:
             label_map_path: the file path to the label_map
         Returns:
             dictionary with the format of {label_index: {'id': label_index, 'name': label_name}}
         """
          label_map = {}
         
          with open(label_map_path, "r") as label_file:
               for line in label_file:
                    if "id" in line:
                          label_index = int(line.split(":")[-1])
               
                          label_name = next(label_file).split(":")[-1].strip().strip('"')
               
                          label_map[label_index] = {"id": label_index, "name": label_name}
          return label_map

      def predict_class(image, model):
        image = tf.cast(image, tf.float32)
   
        image = tf.image.resize(image, [150, 150])
   
        image = np.expand_dims(image, axis = 0)
   
        return model.predict(image)
      def plot_boxes_on_img(color_map, classes, bboxes, image_origi, origi_shape):
        for idx, each_bbox in enumerate(bboxes):
          color = color_map[classes[idx]]
      ## Draw bounding box
       cv2.rectangle(
           image_origi,
         (int(each_bbox[1] * origi_shape[1]),
           int(each_bbox[0] * origi_shape[0]),),
        (int(each_bbox[3] * origi_shape[1]),
          int(each_bbox[2] * origi_shape[0]),),
          color,
          2,
      )
       
     ## Draw label background
      cv2.rectangle(
         image_origi,
       (int(each_bbox[1] * origi_shape[1]),
         int(each_bbox[2] * origi_shape[0]),),
       (int(each_bbox[3] * origi_shape[1]),
         int(each_bbox[2] * origi_shape[0] + 15),),
         color,
         -1,
       )
       
      ## Insert label class & score
      cv2.putText(
          image_origi,
         "Class: {}, Score: {}".format(
          str(category_index[classes[idx]]["name"]),
          str(round(scores[idx], 2)),
          ),
       (int(each_bbox[1] * origi_shape[1]),
          int(each_bbox[2] * origi_shape[0] + 10),),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.3,
      (0, 0, 0),
        1,
        cv2.LINE_AA,
      )
     return image_origi
    # Webpage code starts here
    #TODO change this
     st.title('YOUR PROJECT NAME')
     st.text('made by XXX')
     st.markdown('## Description about your project')
     with st.spinner('Model is being loaded...'):
        model = load_model()
    # ask user to upload an image
     file = st.file_uploader("Upload image", type=["jpg", "png"])
    if file is None:
    st.text('Waiting for upload...')
   
    else:
      st.text('Running inference...')
   
    # open image
   
     test_image = Image.open(file).convert("RGB")
   
     origi_shape = np.a(chǎn)sarray(test_image).shape
   
     # resize image to default shape
   
     default_shape = 320
   
     image_resized = np.a(chǎn)rray(test_image.resize((default_shape, default_shape)))
     ## Load color map
   
     category_index = load_label_map("./label_map.pbtxt")
     # TODO Add more colors if there are more classes
         # color of each label. check label_map.pbtxt to check the index for each class
      color_map = {
         1: [255, 0, 0], # bad -> red
         2: [0, 255, 0] # good -> green
       }
      ## The model input needs to be a tensor
   
      input_tensor = tf.convert_to_tensor(image_resized)
   
      ## The model expects a batch of images, so add an axis with `tf.newaxis`.
   
      input_tensor = input_tensor[tf.newaxis, ...]
      ## Feed image into model and obtain output
   
      detections_output = model(input_tensor)
   
      num_detections = int(detections_output.pop("num_detections"))
   
      detections = {key: value[0, :num_detections].numpy() for key, value in detections_output.items()}
   
      detections["num_detections"] = num_detections
      ## Filter out predictions below threshold
      # if threshold is higher, there will be fewer predictions
      # TODO change this number to see how the predictions change
       confidence_threshold = 0.8
   
      indexes = np.where(detections["detection_scores"] > confidence_threshold)
      ## Extract predicted bounding boxes
   
       bboxes = detections["detection_boxes"][indexes]
   
      # there are no predicted boxes
      if len(bboxes) == 0:
          st.error('No boxes predicted')
       
      # there are predicted boxes
      else:
          st.success('Boxes predicted')
       
          classes = detections["detection_classes"][indexes].a(chǎn)stype(np.int64)
       
          scores = detections["detection_scores"][indexes]
 
          # plot boxes and labels on image
           image_origi = np.a(chǎn)rray(Image.fromarray(image_resized).resize((origi_shape[1], origi_shape[0])))
       
           image_origi = plot_boxes_on_img(color_map, classes, bboxes, image_origi, origi_shape)
          # show image in web page
          st.image(Image.fromarray(image_origi), caption="Image with predictions", width=400)
       
          st.markdown("### Predicted boxes")
       
          for idx in range(len((bboxes))):
              st.markdown(f"* Class: {str(category_index[classes[idx]]['name'])}, confidence score: {str(round(scores[idx], 2))}")

packages.txt:

ffmpeg
      libsm6
      libxext6

requirements.txt:

numpy==1.18.5
      opencv-python-h(huán)eadless
      Pillow==7.2.0
      streamlit
      tensorflow==2.3.0

packages.txt和requirements.txt是將安裝在Space中的庫(kù)。這些文件非常重要,沒(méi)有它們,代碼將無(wú)法運(yùn)行。

最后,文件夾應(yīng)該像這樣

saved_model/是你先前從Datature下載的.zip文件中的文件夾

label_map.pbtxt存在于.zip文件

.gitattributes

README.md

app.py是用我在本文前面編寫(xiě)的代碼創(chuàng)建的文件

requirements.txt在前面的代碼中提供

packages.txt在前面的代碼中提供

一旦我們需要的所有文件都在文件夾中,我們可以將其推送到Space。打開(kāi)Git Bash,依次粘貼以下命令:

git add .

git commit -m “Added files”

git push

app上傳文件需要一些時(shí)間,尤其是模型文件。git推送完成后,Space將花費(fèi)幾分鐘來(lái)構(gòu)建應(yīng)用程序,并在Space中顯示我們的應(yīng)用程序。

最后,你的應(yīng)用會(huì)顯示如下:https://huggingface.co/spaces/anebz/test

你可以上傳一張圖片,模型需要幾秒鐘來(lái)加載,然后你就可以看到預(yù)測(cè)結(jié)果了。項(xiàng)目完成了!

結(jié)論

你的項(xiàng)目完成了,祝賀你。∧憧梢詮牧汩_(kāi)始快速創(chuàng)建一個(gè)應(yīng)用程序。你只需要在你的電腦上安裝Git,不需要Python或者不需要編寫(xiě)任何代碼。

       原文標(biāo)題 : 構(gòu)建一個(gè)計(jì)算機(jī)視覺(jué)項(xiàng)目

聲明: 本文由入駐維科號(hào)的作者撰寫(xiě),觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問(wèn)題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過(guò)于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無(wú)評(píng)論

暫無(wú)評(píng)論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號(hào)
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號(hào)