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

使用簡(jiǎn)單方法在圖像中檢測(cè)血細(xì)胞

對(duì)象檢測(cè)問(wèn)題的基礎(chǔ)是數(shù)據(jù)的外觀,F(xiàn)在,本文將介紹可用于解決對(duì)象檢測(cè)問(wèn)題的不同深度學(xué)習(xí)架構(gòu)。讓我們首先討論我們將要處理的問(wèn)題陳述。

目錄

1. 了解問(wèn)題陳述:血細(xì)胞檢測(cè)

2. 數(shù)據(jù)集鏈接

3. 解決對(duì)象檢測(cè)問(wèn)題的簡(jiǎn)單方法

4. 實(shí)施簡(jiǎn)單方法的步驟

· 加載數(shù)據(jù)集

· 數(shù)據(jù)探索

· 為簡(jiǎn)單方法準(zhǔn)備數(shù)據(jù)集

· 創(chuàng)建訓(xùn)練和驗(yàn)證集

· 定義分類(lèi)模型架構(gòu)

· 訓(xùn)練模型

· 作出預(yù)測(cè)

5. 結(jié)論

了解問(wèn)題陳述血細(xì)胞檢測(cè)

問(wèn)題陳述

對(duì)于一組給定的血細(xì)胞圖像,我們必須檢測(cè)圖像中的白細(xì)胞。現(xiàn)在,這是來(lái)自數(shù)據(jù)集的示例圖像。如你所見(jiàn),你可以看到有一些紅色陰影區(qū)域和藍(lán)色或紫色區(qū)域。

在上圖中,紅色陰影區(qū)域是紅細(xì)胞(RBC),紫色陰影區(qū)域是白細(xì)胞(WBC),還有一些小的黑色突出部分是血小板。

正如你在此圖像中看到的那樣,我們有多個(gè)對(duì)象和多個(gè)類(lèi)。

為簡(jiǎn)單起見(jiàn),我們將其轉(zhuǎn)換為單類(lèi)單對(duì)象問(wèn)題。這意味著我們將只考慮白細(xì)胞。

因此,只有一個(gè)類(lèi),即白細(xì)胞,而忽略其余的類(lèi)。此外,我們將只保留具有單個(gè)白細(xì)胞的圖像。

因此,具有多個(gè)白細(xì)胞的圖像將從該數(shù)據(jù)集中刪除。

以下是我們將從該數(shù)據(jù)集中選擇圖像的方法。

因此,我們刪除了圖像 2 和圖像 5,因?yàn)閳D像 5 沒(méi)有白細(xì)胞,而圖像 2 有 2 個(gè)白細(xì)胞,其他圖像保留在數(shù)據(jù)集中。同樣,測(cè)試集也將只有一個(gè)白細(xì)胞。

現(xiàn)在,對(duì)于每個(gè)圖像,我們?cè)诎准?xì)胞周?chē)加幸粋(gè)邊界框。正如你在這張圖片中看到的,我們的文件名為 1.jpg,這些是白細(xì)胞周?chē)吔缈虻倪吔缈蜃鴺?biāo)。

在下一節(jié)中,我們將介紹解決此對(duì)象檢測(cè)問(wèn)題的簡(jiǎn)單方法。

解決對(duì)象檢測(cè)問(wèn)題的簡(jiǎn)單方法

在本節(jié)中,我們將討論一種解決對(duì)象檢測(cè)問(wèn)題的簡(jiǎn)單方法。所以讓我們首先了解任務(wù),我們必須在血細(xì)胞圖像中檢測(cè)白細(xì)胞,可以看到下圖。

現(xiàn)在,最簡(jiǎn)單的方法是將圖像劃分為多個(gè)塊,因此對(duì)于此圖像,將圖像劃分為四個(gè)塊。

我們對(duì)這些塊中的每一個(gè)進(jìn)行分類(lèi),因此第一個(gè)塊沒(méi)有白細(xì)胞,第二個(gè)塊有一個(gè)白細(xì)胞,同樣第三個(gè)和第四個(gè)沒(méi)有任何白細(xì)胞。

我們已經(jīng)熟悉分類(lèi)過(guò)程以及如何構(gòu)建分類(lèi)算法。因此,我們可以輕松地將這些單獨(dú)的塊中的每一個(gè)分類(lèi)為 yes 和 no,以表示白細(xì)胞。

現(xiàn)在,在下圖中,具有白細(xì)胞的塊(綠色框)可以表示為邊界框,因此在這種情況下,我們將取這個(gè)塊的坐標(biāo)值,并將其返回為白細(xì)胞的邊界框。

現(xiàn)在為了實(shí)施這種方法,我們首先需要準(zhǔn)備我們的訓(xùn)練數(shù)據(jù)。

現(xiàn)在可能有一個(gè)問(wèn)題,為什么我們需要準(zhǔn)備訓(xùn)練數(shù)據(jù)?我們已經(jīng)有了這些圖像和邊界框。

我們的訓(xùn)練數(shù)據(jù)采用以下格式,其中我們有白細(xì)胞邊界框和邊界框坐標(biāo)。

現(xiàn)在,請(qǐng)注意我們有完整圖像的這些邊界框坐標(biāo),但我們將把這個(gè)圖像分成四個(gè)塊。我們需要所有這四個(gè)塊的邊界框坐標(biāo)。下一個(gè)問(wèn)題是我們?nèi)绾巫龅竭@一點(diǎn)?

我們必須定義一個(gè)新的訓(xùn)練數(shù)據(jù),我們有文件名,如下圖所示。

我們有不同的塊,對(duì)于每個(gè)塊,我們有 Xmin、Xmax、Ymin 和 Ymax 值,它們表示這些塊的坐標(biāo),最后,我們的目標(biāo)變量是白細(xì)胞。圖像中是否存在白細(xì)胞?

現(xiàn)在在這種情況下,它將成為一個(gè)簡(jiǎn)單的分類(lèi)問(wèn)題。因此,對(duì)于每個(gè)圖像,我們將其劃分為四個(gè)不同的塊,并為每個(gè)塊創(chuàng)建邊界框坐標(biāo)。

現(xiàn)在下一個(gè)問(wèn)題是我們?nèi)绾蝿?chuàng)建這些邊界框坐標(biāo)?這真的很簡(jiǎn)單。

考慮到我們有一個(gè)大小為 (640*480) 的圖像。所以原點(diǎn)是(0,0)。上圖有 x 軸和 y 軸,這里我們的坐標(biāo)值為 (640, 480)。

現(xiàn)在,我們找出中點(diǎn),它是 (320,240)。一旦我們有了這些值,我們就可以很容易地找出每個(gè)塊的坐標(biāo)。所以對(duì)于第一個(gè)塊,我們的 Xmin 和 Ymin 將是 (0,0) ,而 Xmax, Ymax 將是 (320,240)。

同樣,我們可以在第二個(gè)、第三個(gè)和第四個(gè)塊中找到它。一旦我們有了這些塊中的每一個(gè)的坐標(biāo)值或邊界框值。下一個(gè)任務(wù)是確定此塊中是否存在白細(xì)胞。

在這里我們可以清楚地看到塊 2 有白細(xì)胞,而其他塊沒(méi)有,但是我們不能在數(shù)據(jù)集中的每個(gè)塊上對(duì)每個(gè)圖像都手動(dòng)標(biāo)注白細(xì)胞。

現(xiàn)在在下一節(jié)中,我們將實(shí)現(xiàn)簡(jiǎn)單的方法。

實(shí)施簡(jiǎn)單方法的步驟

在上一節(jié)中,我們討論了用于對(duì)象檢測(cè)的簡(jiǎn)單方法,F(xiàn)在讓我們定義在血細(xì)胞檢測(cè)問(wèn)題上實(shí)施這種方法的步驟。

這些是將要遵循的步驟:

1. 加載數(shù)據(jù)集

2. 數(shù)據(jù)探索

3. 為簡(jiǎn)單方法準(zhǔn)備數(shù)據(jù)集

4. 創(chuàng)建訓(xùn)練和驗(yàn)證集

5. 定義分類(lèi)模型架構(gòu)

6. 訓(xùn)練模型

7. 作出預(yù)測(cè)

讓我們進(jìn)入下一節(jié),實(shí)現(xiàn)上述步驟。

1.加載所需的庫(kù)和數(shù)據(jù)集

因此,讓我們首先從加載所需的庫(kù)開(kāi)始。numpy和pandas,matplotlib用來(lái)可視化數(shù)據(jù),我們已經(jīng)加載了一些庫(kù)來(lái)處理圖像并調(diào)整圖像大小,最后是torch庫(kù)。

# Importing Required Libraries

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

import os

from PIL import Image

from skimage.transform import resize

import torch

from torch import nn

現(xiàn)在我們將修復(fù)一個(gè)隨機(jī)種子值。

# Fixing a random seed values to stop potential randomness
seed = 42

rng = np.random.RandomState(seed)

在這里,我們將安裝驅(qū)動(dòng)器,因?yàn)閿?shù)據(jù)集存儲(chǔ)在驅(qū)動(dòng)器上。

# mount the drive

from google.colab import drive

drive.mount('/content/drive')

現(xiàn)在因?yàn)轵?qū)動(dòng)器上的數(shù)據(jù)以 zip 格式提供。我們必須解壓縮這些數(shù)據(jù),在這里我們將解壓縮數(shù)據(jù)。

所以我們可以看到所有的圖像都被加載并存儲(chǔ)在一個(gè)名為 images 的文件夾中。在這個(gè)文件夾的末尾,我們有一個(gè) CSV 文件,它是trained.csv。

# unzip the dataset from drive

!unzip /content/drive/My Drive/train_zedkk38.zip

2.?dāng)?shù)據(jù)探索

閱讀 CSV 文件并找出存儲(chǔ)在這個(gè)“train.csv”文件中的信息是什么。

## Reading target file

data = pd.read_csv('train.csv')

data.shape

打印 CSV 文件的前幾行,我們可以看到該文件具有 image_names 以及 cell_type,它將表示紅細(xì)胞或白細(xì)胞等等。最后是此特定圖像中此特定對(duì)象的邊界框坐標(biāo)。data.head()

因此,如果我們檢查紅細(xì)胞、白細(xì)胞和血小板的計(jì)數(shù)值。我們將看到紅細(xì)胞具有最大計(jì)數(shù)值,其次是白細(xì)胞和血小板。

data.cell_type.value_counts()

現(xiàn)在為簡(jiǎn)單起見(jiàn),我們將只考慮白細(xì)胞。因此,我們選擇了只有白細(xì)胞的數(shù)據(jù)。

現(xiàn)在我們針對(duì)這些圖像有 image_names和 cell_type WBC。還有邊界框坐標(biāo)。

(data.loc[data['cell_type'] =='WBC']).head()

讓我們看看原始數(shù)據(jù)集中的幾張圖像以及這些圖像的形狀。

我們可以看到這些圖像的形狀是(480,640,3)。這是一個(gè)具有三個(gè)通道的 RGB 圖像,這是數(shù)據(jù)集中的第一張圖像。

image = plt.imread('images/' + '1.jpg')

print(image.shape)

plt.imshow(image)

下一步是用這個(gè)圖像創(chuàng)建塊。我們要學(xué)習(xí)如何把這張圖片分成四個(gè)塊。現(xiàn)在我們知道圖像的形狀是 (640, 480)。因此這張圖片的中間點(diǎn)是 (320,240),中心是 (0, 0)。

因此,我們有圖像中所有這些塊的坐標(biāo),在這里我們將利用這些坐標(biāo)并創(chuàng)建塊。

這些坐標(biāo)的格式將是 Ymin、Ymax、Xmin 和 Xmax。這里我們的 (Ymin, Ymax) 是 (0, 240) 并且 (Xmin, Xmax) 是 (0,320)。這基本上表示第一個(gè)塊。

同樣,對(duì)于隨后的第二個(gè)第三個(gè)和第四個(gè)塊,我們有 image_2、image_3、image_4。這是一個(gè)我們可以從圖像創(chuàng)建塊的過(guò)程。

# creating 4 patches from the image

# format ymin, ymax, xmin, xmax

image_1 = image[0:240, 0:320, :]

image_2 = image[0:240, 320:640, :]

image_3 = image[240:480, 0:320, :]

image_4 = image[240:480, 320:640, :]

現(xiàn)在我們需要為這些塊分配一個(gè)目標(biāo)值。為了做到這一點(diǎn),我們計(jì)算并集的交集,我們必須找出交集區(qū)域和并集區(qū)域。

所以交集區(qū)域就是這個(gè)特定的矩形,要找出面積,我們需要找出這個(gè)矩形的 Xmin、Xmax 和 Ymin、Ymax 坐標(biāo)。

def iou(box1, box2):

   Irect_xmin, Irect_ymin = max(box1[0],box2[0]), max(box1[2],box2[2])

   Irect_xmax, Irect_ymax = min(box1[1],box2[1]), min(box1[3],box2[3])

   if Irect_xmax < Irect_xmin or Irect_ymax < Irect_ymin:

       target = inter_area = 0

   else:

     inter_area = np.a(chǎn)bs((Irect_xmax - Irect_xmin) * (Irect_ymax - Irect_ymin))

     box1_area = (box1[1]-box1[0])*(box1[3]-box1[2])

     box2_area = (box2[1]-box2[0])*(box2[3]-box2[2])

     union_area = box1_area+box2_area-inter_area

     iou = inter_area/union_area

     target = int(iou > 0.1)

   return target

我們有來(lái)自訓(xùn)練 CSV 文件的原始邊界框坐標(biāo)。當(dāng)我將這兩個(gè)值用作我們定義的“ iou”函數(shù)的輸入時(shí),目標(biāo)為 1。

你也可以嘗試使用不同的塊,也可以基于你將得到的目標(biāo)值。

box1= [320, 640, 0, 240]

box2= [93,    296, 1, 173]

iou(box1, box2)

輸出為 0,F(xiàn)在下一步是準(zhǔn)備數(shù)據(jù)集。

3.為簡(jiǎn)單方法準(zhǔn)備數(shù)據(jù)集

我們只考慮并探索了數(shù)據(jù)集中的單個(gè)圖像。因此,讓我們對(duì)數(shù)據(jù)集中的所有圖像執(zhí)行這些步驟。這里是我們擁有的完整數(shù)據(jù)。

data.head()

現(xiàn)在,我們正在轉(zhuǎn)換這些細(xì)胞類(lèi)型,紅細(xì)胞為0,白細(xì)胞為 1,血小板為 2。

data['cell_type'] = data['cell_type'].replace({'RBC': 0, 'WBC': 1, 'Platelets': 2})

現(xiàn)在我們必須選擇只有一個(gè)白細(xì)胞的圖像。

因此,首先我們創(chuàng)建數(shù)據(jù)集的副本,然后僅保留白細(xì)胞并刪除任何具有多個(gè)白細(xì)胞的圖像。

## keep only Single WBCs

data_wbc = data.loc[data.cell_type == 1].copy()

data_wbc = data_wbc.drop_duplicates(subset=['image_names', 'cell_type'], keep=False)

現(xiàn)在我們已經(jīng)選擇了圖像。我們將根據(jù)輸入圖像大小設(shè)置塊坐標(biāo)。

我們正在逐一讀取圖像并存儲(chǔ)該特定圖像的白細(xì)胞邊界框坐標(biāo),使用我們?cè)诖颂幎x的塊坐標(biāo)從該圖像中提取塊。

然后我們使用自定義的 IoU 函數(shù)找出每個(gè)塊的目標(biāo)值。最后,在這里我們將塊大小調(diào)整為標(biāo)準(zhǔn)大小 (224, 224, 3)。在這里,我們正在為每個(gè)塊創(chuàng)建最終輸入數(shù)據(jù)和目標(biāo)數(shù)據(jù)。

# create empty lists

X = []

Y = []

# set patch co-ordinates

patch_1_coordinates = [0, 320, 0, 240]

patch_2_coordinates = [320, 640, 0, 240]

patch_3_coordinates = [0, 320, 240, 480]

patch_4_coordinates = [320, 640, 240, 480]

for idx, row in data_wbc.iterrows():

   # read image

   image = plt.imread('images/' + row.image_names)

   bb_coordinates = [row.xmin, row.xmax, row.ymin, row.ymax]

   # extract patches

   patch_1 = image[patch_1_coordinates[2]:patch_1_coordinates[3],
                            patch_1_coordinates[0]:patch_1_coordinates[1], :]

   patch_2 = image[patch_2_coordinates[2]:patch_2_coordinates[3],
                              patch_2_coordinates[0]:patch_2_coordinates[1], :]

   patch_3 = image[patch_3_coordinates[2]:patch_3_coordinates[3],
                           patch_3_coordinates[0]:patch_3_coordinates[1], :]

   patch_4 = image[patch_4_coordinates[2]:patch_4_coordinates[3],
                           patch_4_coordinates[0]:patch_4_coordinates[1], :]

   # set default values

   target_1 = target_2 = target_3 = target_4 = inter_area = 0

   # figure out if the patch contains the object

   ## for patch_1

   target_1 = iou(patch_1_coordinates, bb_coordinates )

   ## for patch_2

   target_2 = iou(patch_2_coordinates, bb_coordinates)

   ## for patch_3

   target_3 = iou(patch_3_coordinates, bb_coordinates)

   ## for patch_4

   target_4 = iou(patch_4_coordinates, bb_coordinates)

   # resize the patches

   patch_1 = resize(patch_1, (224, 224, 3), preserve_range=True)

   patch_2 = resize(patch_2, (224, 224, 3), preserve_range=True)

   patch_3 = resize(patch_3, (224, 224, 3), preserve_range=True)

   patch_4 = resize(patch_4, (224, 224, 3), preserve_range=True)

   # create final input data

   X.extend([patch_1, patch_2, patch_3, patch_4])

   # create target data

   Y.extend([target_1, target_2, target_3, target_4])

# convert these lists to single numpy array

X = np.a(chǎn)rray(X)

Y = np.a(chǎn)rray(Y)

現(xiàn)在,讓我們打印原始數(shù)據(jù)和剛剛創(chuàng)建的新數(shù)據(jù)的形狀。我們可以看到我們最初有 240 張圖像。

現(xiàn)在我們將這些圖像分成四部分, 即(960,224,224,3)。這是圖像的形狀。

# 4 patches for every image

data_wbc.shape, X.shape, Y.shape

讓我們快速看一下我們剛剛創(chuàng)建的這些圖像之一。這是我們的原始圖像,這是原始圖像的最后一個(gè)塊或第四個(gè)塊。我們可以看到分配的目標(biāo)是1。

image = plt.imread('images/' + '1.jpg')

plt.imshow(image)

如果我們檢查任何其他塊,假設(shè)我要檢查此圖像的第一個(gè)塊,這里會(huì)將目標(biāo)設(shè)為0。你將獲得第一個(gè)塊。

同樣,你可以確保將所有圖像轉(zhuǎn)換為塊并相應(yīng)地分配目標(biāo)。

plt.imshow(X[0].a(chǎn)stype('uint8')), Y[0]

4.準(zhǔn)備訓(xùn)練和驗(yàn)證集

現(xiàn)在我們有了數(shù)據(jù)集。我們將準(zhǔn)備我們的訓(xùn)練和驗(yàn)證集,F(xiàn)在請(qǐng)注意,這里我們的圖像形狀為 (224,224,3)。

# 4 patches for every image

data_wbc.shape, X.shape, Y.shape

輸出是:

((240, 6), (960, 224, 224, 3), (960,))

在 PyTorch 中,我們首先需要擁有通道。因此,我們將移動(dòng)具有形狀 (3,224,224) 的軸。

X = np.moveaxis(X, -1, 1)

X.shape

輸出是:

(960, 3, 224, 224)

現(xiàn)在,我們對(duì)圖像像素值進(jìn)行歸一化。

X = X / X.max()

使用訓(xùn)練測(cè)試拆分功能,我們將創(chuàng)建一個(gè)訓(xùn)練集和驗(yàn)證集。

from sklearn.model_selection import train_test_split

X_train, X_valid, Y_train, Y_valid=train_test_split(X, Y, test_size=0.1,
                                           random_state=seed)

X_train.shape, X_valid.shape, Y_train.shape, Y_valid.shape

上述代碼的輸出是:

((864, 3, 224, 224), (96, 3, 224, 224), (864,), (96,))

現(xiàn)在,我們要將訓(xùn)練集和驗(yàn)證集都轉(zhuǎn)換為張量,因?yàn)樗鼈兪恰?numpy”數(shù)組。

X_train = torch.FloatTensor(X_train)

Y_train = torch.FloatTensor(Y_train)

X_valid = torch.FloatTensor(X_valid)

Y_valid = torch.FloatTensor(Y_valid)

5.模型構(gòu)建

現(xiàn)在,我們要構(gòu)建我們的模型,在這里我們安裝了一個(gè)庫(kù),它是 PyTorch 模型摘要。

!pip install pytorch-model-summary

這僅用于在 PyTorch 中打印模型摘要,F(xiàn)在我們從這里導(dǎo)入?yún)R總函數(shù)。

from pytorch_model_summary import summary

這是我們?yōu)榉椒ǘx的架構(gòu)。

我們定義了一個(gè)順序模型,其中有Conv2d 層,輸入通道數(shù)為 3,過(guò)濾器數(shù)量為 64,過(guò)濾器的大小為 5,步幅設(shè)置為 2。對(duì)于這個(gè) Conv2d 層有 ReLU 激活函數(shù)。一個(gè)池化層,窗口大小為 4,步幅為 2,然后是卷積層。

現(xiàn)在展平 Conv2d 層的輸出,最后是全連接層和 sigmoid 激活函數(shù)。

## model architecture

model = nn.Sequential(

       nn.Conv2d(in_channels=3, out_channels=64, kernel_size=5, stride=2),  

       nn.ReLU(),  

       nn.MaxPool2d(kernel_size=4,stride=2),  

       nn.Conv2d(in_channels=64, out_channels=64, kernel_size=5, stride=2),    

       nn.Flatten(),

       nn.Linear(40000, 1),

       nn.Sigmoid()

在這里打印模型,將是我們定義的模型架構(gòu)。

print(model)

使用summary函數(shù),我們可以查看模型摘要。因此,這將為我們返回每個(gè)層的輸出形狀,每個(gè)層的可訓(xùn)練參數(shù)的數(shù)量,F(xiàn)在我們的模型已經(jīng)準(zhǔn)備好了。

print(summary(model, X_train[:1]))

現(xiàn)在模型已經(jīng)準(zhǔn)備好訓(xùn)練了。

6.訓(xùn)練模型

讓我們訓(xùn)練這個(gè)模型。所以我們要定義我們的損失函數(shù)和優(yōu)化函數(shù)。我們將二元交叉熵定義為損失和Adam優(yōu)化器。然后我們將模型傳輸?shù)?GPU。

在這里,我們從輸入圖像中提取批次來(lái)訓(xùn)練這個(gè)模型。

## loss and optimizer

criterion = torch.nn.BCELoss()

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

## GPU device

if torch.cuda.is_available():

 model = model.cuda()

 criterion = criterion.cuda()

因此,我們從 x_train 中提取了批次并使用了這些批次。我們將對(duì)該模型進(jìn)行總共 15 個(gè) epoch 的訓(xùn)練。我們還設(shè)置了一個(gè) optimizer.Zero_grad() 并將輸出存儲(chǔ)在這里。

現(xiàn)在我們正在計(jì)算損失并存儲(chǔ)所有損失并執(zhí)行反向傳播和更新參數(shù)。此外,我們?cè)诿總(gè) epoch 之后打印損失。

在輸出中,我們可以看到每個(gè)時(shí)期的損失都在減少。所以這個(gè)模型的訓(xùn)練就完成了。

# batch size of the model

batch_size = 32

# defining the training phase

model.train()

for epoch in range(15):

   # setting initial loss as 0

   train_loss = 0.0        

   # to randomly pick the images without replacement in batches

   permutation = torch.randperm(X_train.size()[0])

   # to keep track of training loss

   training_loss = []

   # for loop for training on batches

   for i in range(0,X_train.size()[0], batch_size):

       # taking the indices from randomly generated values

       indices = permutation[i:i+batch_size]

      # getting the images and labels for a batch

       batch_x, batch_y = X_train[indices], Y_train[indices]

       if torch.cuda.is_available():

           batch_x, batch_y = batch_x.cuda().float(), batch_y.cuda().float()

       # clearing all the accumulated gradients

       optimizer.zero_grad()

       # mini batch computation

       outputs = model(batch_x)

       # calculating the loss for a mini batch

       loss = criterion(outputs.squeeze(),batch_y)

       # storing the loss for every mini batch

       training_loss.a(chǎn)ppend(loss.item())

       # calculating the gradients

       loss.backward()

       # updating the parameters

       optimizer.step()

   training_loss = np.a(chǎn)verage(training_loss)

   print('epoch: t', epoch, 't training loss: t', training_loss)

7.做出預(yù)測(cè)

現(xiàn)在讓我們使用這個(gè)模型來(lái)進(jìn)行預(yù)測(cè)。所以在這里我只從驗(yàn)證集中獲取前五個(gè)輸入并將它們傳輸?shù)?Cuda。

output = model(X_valid[:5].to('cuda')).cpu().detach().numpy()

這是我們拍攝的前五張圖像的輸出。現(xiàn)在我們可以看到前兩個(gè)的輸出是沒(méi)有白細(xì)胞或有白細(xì)胞。

output

這是輸出:

array([[0.00641595],

      [0.01172841],

      [0.99919134],

      [0.01065345],

      [0.00520921]], dtype=float32)

繪制圖像。我們可以看到這是第三張圖片,這里的模型說(shuō)有一個(gè)白細(xì)胞,我們可以看到這張圖片中有一個(gè)白細(xì)胞。

plt.imshow(np.transpose(X_valid[2]))

同樣,我們可以檢查另一張圖像,因此將獲取第一張圖像。

你可以看到輸出圖像,這個(gè)圖像是我們的輸入塊,這個(gè)塊中沒(méi)有白細(xì)胞。

plt.imshow(np.transpose(X_valid[1]))

這是一種非常簡(jiǎn)單的方法,可以進(jìn)行預(yù)測(cè)或識(shí)別具有白細(xì)胞的圖像的塊或部分。

結(jié)論

使用簡(jiǎn)單方法了解使用圖像數(shù)據(jù)集進(jìn)行血細(xì)胞檢測(cè)的實(shí)際實(shí)現(xiàn)。這是解決業(yè)務(wù)問(wèn)題和開(kāi)發(fā)模型的真正挑戰(zhàn)。

在處理圖像數(shù)據(jù)時(shí),你必須分析一些任務(wù),例如邊界框、計(jì)算 IoU 值、評(píng)估指標(biāo)。本文的下一個(gè)級(jí)別(未來(lái)任務(wù))是一個(gè)圖像可以有多個(gè)對(duì)象。任務(wù)是檢測(cè)每個(gè)圖像中的對(duì)象。希望這些文章能幫助你了解如何使用圖像數(shù)據(jù)檢測(cè)血細(xì)胞,如何建立檢測(cè)模型,我們將使用這種技術(shù),并將其應(yīng)用于醫(yī)學(xué)分析領(lǐng)域。

       原文標(biāo)題 : 使用簡(jiǎn)單方法在圖像中檢測(cè)血細(xì)胞

聲明: 本文由入駐維科號(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)