Python中的快速特征工程
“在任何一種數(shù)據(jù)豐富的環(huán)境中都很容易找到模式。關(guān)鍵在于確定模式是代表噪聲還是信號(hào)。”―奈特·西爾弗本文將介紹將圖像處理作為機(jī)器學(xué)習(xí)工作流程的一部分時(shí)要遵循的一些最佳實(shí)踐。庫(kù)import random
from PIL import Image
import cv2
import numpy as np
from matplotlib import pyplot as plt
import json
import albumentations as A
import torch
import torchvision.models as models
import torchvision.transforms as transforms
import torch.nn as nn
from tqdm import tqdm_notebook
from torch.utils.data import DataLoader
from torchvision.datasets import CIFAR10
調(diào)整圖像大。s放圖像調(diào)整大小是該領(lǐng)域深度學(xué)習(xí)實(shí)踐者所做的最基本的改變。這樣做的主要原因是確保我們的深度學(xué)習(xí)系統(tǒng)收到的輸入是一致的。調(diào)整大小的另一個(gè)原因是減少模型中的參數(shù)數(shù)量。更小的維數(shù)意味著更小的神經(jīng)網(wǎng)絡(luò),從而節(jié)省了我們訓(xùn)練模型所需的時(shí)間和計(jì)算能力。信息丟失怎么辦?從較大的圖像向下調(diào)整大小時(shí),確實(shí)會(huì)丟失一些信息。但是,根據(jù)你的任務(wù),你可以選擇愿意為訓(xùn)練時(shí)間和計(jì)算資源犧牲多少信息。例如,對(duì)象檢測(cè)任務(wù)將要求你保持圖像的縱橫比,因?yàn)槟繕?biāo)是檢測(cè)對(duì)象的準(zhǔn)確位置。相反,圖像分類任務(wù)可能需要將所有圖像的大小調(diào)整為指定的大。224x224是一個(gè)很好的經(jīng)驗(yàn)法則)。
img = Image.open("goldendoodle-1234760_960_720.jpeg")
img_resized = Image.Image.resize(img, size=(224, 224))
調(diào)整圖像大小后,圖像如下所示:
為什么要執(zhí)行圖像縮放?與表格數(shù)據(jù)類似,用于分類任務(wù)的縮放圖像可以幫助我們的深度學(xué)習(xí)模型的學(xué)習(xí)率更好地收斂到最小值?s放可確保特定維度不會(huì)主導(dǎo)其他維度。在StackExchange上找到了一個(gè)非常好的答案。一種特征縮放是標(biāo)準(zhǔn)化像素值的過程。我們通過從每個(gè)通道的像素值中減去每個(gè)通道的平均值,然后除以標(biāo)準(zhǔn)差。在為分類任務(wù)訓(xùn)練模型時(shí),這是一種常用的特征工程選擇。mean = np.mean(img_resized, axis=(1,2), keepdims=True)
std = np.std(img_resized, axis=(1,2), keepdims=True)
img_std = (img_resized - mean) / std
注意:與調(diào)整大小一樣,在執(zhí)行對(duì)象檢測(cè)和圖像生成任務(wù)時(shí),可能不希望進(jìn)行圖像縮放。上面的示例代碼演示了通過標(biāo)準(zhǔn)化縮放圖像的過程。還有其他形式的縮放,例如居中和標(biāo)準(zhǔn)化。擴(kuò)充(分類)增強(qiáng)圖像背后的主要?jiǎng)訖C(jī)是由于計(jì)算機(jī)視覺任務(wù)的可觀數(shù)據(jù)需求。通常,由于多種原因,獲取足夠的圖像進(jìn)行訓(xùn)練是一項(xiàng)挑戰(zhàn)。圖像增強(qiáng)使我們能夠通過稍微修改原始樣本來創(chuàng)建新的訓(xùn)練樣本。在本例中,我們將研究如何將普通的增強(qiáng)應(yīng)用于分類任務(wù)。我們可以使用Albumentations庫(kù)來實(shí)現(xiàn)這一點(diǎn):img_cropped = Image.fromarray(A.RandomCrop(width=225, height=225)(image=np.a(chǎn)rray(img))['image'])
img_gau_blur = Image.fromarray(A.GaussianBlur(p=0.8)(image=np.a(chǎn)rray(img_resized))['image'])
img_flip = Image.fromarray(A.Flip(0.8)(image=np.a(chǎn)rray(img_resized))['image'])
高斯模糊、隨機(jī)裁剪、翻轉(zhuǎn):
通過應(yīng)用圖像增強(qiáng),我們的深度學(xué)習(xí)模型可以更好地概括任務(wù)(避免過擬合),從而提高其對(duì)未知數(shù)據(jù)的預(yù)測(cè)能力。增強(qiáng)(目標(biāo)檢測(cè))Albumentations庫(kù)還可用于為其他任務(wù)(如對(duì)象檢測(cè))創(chuàng)建增強(qiáng)。對(duì)象檢測(cè)要求我們?cè)诟信d趣的對(duì)象周圍創(chuàng)建邊界框。當(dāng)試圖用邊界框的坐標(biāo)注釋圖像時(shí),使用原始數(shù)據(jù)可能是一項(xiàng)挑戰(zhàn)。幸運(yùn)的是,有許多公開和免費(fèi)可用的數(shù)據(jù)集,我們可以用來創(chuàng)建用于對(duì)象檢測(cè)的增強(qiáng)管道。其中一個(gè)數(shù)據(jù)集就是國(guó)際象棋數(shù)據(jù)集。該數(shù)據(jù)集包含棋盤上的606張棋子圖像。除了這些圖像,還提供了一個(gè)JSON文件,其中包含與單個(gè)圖像中每個(gè)棋子的邊界框相關(guān)的所有信息。通過編寫一個(gè)簡(jiǎn)單的函數(shù),我們可以在應(yīng)用擴(kuò)展后可視化數(shù)據(jù):
with open("_annotations.coco.json") as f:
json_file = json.load(f)
x_min, y_min, w, h = json_file['annotations'][0]['bbox']
x_min, x_max, y_min, y_max = int(x_min), int(x_min + w), int(y_min), int(y_min + h)
def visualize_bbox(img, bbox, class_name, color=(0, 255, 0), thickness=2):
x_min, y_min, w, h = bbox
x_min, x_max, y_min, y_max = int(x_min), int(x_min + w), int(y_min), int(y_min + h)
cv2.rectangle(img, (x_min, y_min), (x_max, y_max), color=color, thickness=thickness)
((text_width, text_h(yuǎn)eight), _) = cv2.getTextSize(class_name, cv2.FONT_HERSHEY_SIMPLEX, 0.35, 1)
cv2.rectangle(img, (x_min, y_min - int(1.3 * text_h(yuǎn)eight)), (x_min + text_width, y_min), BOX_COLOR, -1)
cv2.putText(
img,
text=class_name,
org=(x_min, y_min - int(0.3 * text_h(yuǎn)eight)),
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=0.35,
color=(255, 255, 255),
lineType=cv2.LINE_AA,
)
return img
bbox_img = visualize_bbox(np.a(chǎn)rray(img),
json_file['annotations'][0]['bbox'],
class_name=j(luò)son_file['categories'][0]['name'])
Image.fromarray(bbox_img)
現(xiàn)在,讓我們嘗試使用Albumentations創(chuàng)建一個(gè)增強(qiáng)管道。包含注釋信息的JSON文件具有以下鍵:dict_keys([‘info’, ‘licenses’, ‘categories’, ‘images’, ‘a(chǎn)nnotations’])
圖像包含有關(guān)圖像文件的信息,而注釋包含有關(guān)圖像中每個(gè)對(duì)象的邊界框的信息。最后,類別包含映射到圖像中棋子類型的鍵。image_list = json_file.get('images')
anno_list = json_file.get('annotations')
cat_list = json_file.get('categories')
image_list:[{'id': 0,
'license': 1,
'file_name': 'IMG_0317_JPG.rf.00207d2fe8c0a0f20715333d49d22b4f.jpg',
'height': 416,
'width': 416,
'date_captured': '2021-02-23T17:32:58+00:00'},
{'id': 1,
'license': 1,
'file_name': '5a8433ec79c881f84ef19a07dc73665d_jpg.rf.00544a8110f323e0d7721b3acf2a9e1e.jpg',
'height': 416,
'width': 416,
'date_captured': '2021-02-23T17:32:58+00:00'},
{'id': 2,
'license': 1,
'file_name': '675619f2c8078824cfd182cec2eeba95_jpg.rf.0130e3c26b1bf275bf240894ba73ed7c.jpg'
'height': 416,
'width': 416,
'date_captured': '2021-02-23T17:32:58+00:00'},
anno_list:[{'id': 0,
'image_id': 0,
'category_id': 7,
'bbox': [220, 14, 18, 46.023746508293286],
'area': 828.4274371492792,
'segmentation': [],
'iscrowd': 0},
{'id': 1,
'image_id': 1,
'category_id': 8,
'bbox': [187, 103, 22.686527154676014, 59.127992255841036],
'area': 1341.4088019136107,
'segmentation': [],
'iscrowd': 0},
{'id': 2,
'image_id': 2,
'category_id': 10,
'bbox': [203, 24, 24.26037020843023, 60.5],
'area': 1467.752397610029,
'segmentation': [],
'iscrowd': 0},
cat_list:[{'id': 0, 'name': 'pieces', 'supercategory': 'none'},
{'id': 1, 'name': 'bishop', 'supercategory': 'pieces'},
{'id': 2, 'name': 'black-bishop', 'supercategory': 'pieces'},
{'id': 3, 'name': 'black-king', 'supercategory': 'pieces'},
{'id': 4, 'name': 'black-knight', 'supercategory': 'pieces'},
{'id': 5, 'name': 'black-pawn', 'supercategory': 'pieces'},
{'id': 6, 'name': 'black-queen', 'supercategory': 'pieces'},
{'id': 7, 'name': 'black-rook', 'supercategory': 'pieces'},
{'id': 8, 'name': 'white-bishop', 'supercategory': 'pieces'},
{'id': 9, 'name': 'white-king', 'supercategory': 'pieces'},
{'id': 10, 'name': 'white-knight', 'supercategory': 'pieces'},
{'id': 11, 'name': 'white-pawn', 'supercategory': 'pieces'},
{'id': 12, 'name': 'white-queen', 'supercategory': 'pieces'},
{'id': 13, 'name': 'white-rook', 'supercategory': 'pieces'}]
我們必須改變這些列表的結(jié)構(gòu),以創(chuàng)建高效的管道:new_anno_dict = {}
new_cat_dict = {}
for item in cat_list:
new_cat_dict[item['id']] = item['name']
for item in anno_list:
img_id = item.get('image_id')
if img_id not in new_anno_dict:
temp_list = []
temp_list.a(chǎn)ppend(item)
new_anno_dict[img_id] = temp_list
else:
new_anno_dict.get(img_id).a(chǎn)ppend(item)
現(xiàn)在,讓我們創(chuàng)建一個(gè)簡(jiǎn)單的增強(qiáng)管道,水平翻轉(zhuǎn)圖像,并為邊界框添加一個(gè)參數(shù):transform = A.Compose(
[A.HorizontalFlip(p=0.5)],
bbox_params=A.BboxParams(format='coco', label_fields=['category_ids']),
)
最后,我們將創(chuàng)建一個(gè)類似于Pytorch dataset類的dataset。為此,我們需要定義一個(gè)實(shí)現(xiàn)方法__len__和__getitem_。class ImageDataset:
def __init__(self, path, img_list, anno_dict, cat_dict, albumentations=None):
self.path = path
self.img_list = img_list
self.a(chǎn)nno_dict = anno_dict
self.cat_dict = cat_dict
self.a(chǎn)lbumentations = albumentations
def __len__(self):
return len(self.img_list)
def __getitem__(self, idx):
# 每個(gè)圖像可能有多個(gè)對(duì)象,因此有多個(gè)盒子
bboxes = [item['bbox'] for item in self.a(chǎn)nno_dict[int(idx)]]
cat_ids = [item['category_id'] for item in self.a(chǎn)nno_dict[int(idx)]]
categories = [self.cat_dict[idx] for idx in cat_ids]
image = self.img_list[idx]
img = Image.open(f"{self.path}{image.get('file_name')}")
img = img.convert("RGB")
img = np.a(chǎn)rray(img)
if self.a(chǎn)lbumentations is not None:
augmented = self.a(chǎn)lbumentations(image=img, bboxes=bboxes, category_ids=cat_ids)
img = augmented["image"]
return {
"image": img,
"category_ids": augmented["category_ids"],
"category": categories
}
# path是json_file和images的路徑
dataset = ImageDataset(path, image_list, new_anno_dict, new_cat_dict, transform)
以下是在自定義數(shù)據(jù)集上迭代時(shí)的一些結(jié)果:
因此,我們現(xiàn)在可以輕松地將此自定義數(shù)據(jù)集傳遞給數(shù)據(jù)加載器以訓(xùn)練我們的模型。特征提取你可能聽說過預(yù)訓(xùn)練模型用于訓(xùn)練圖像分類器和其他有監(jiān)督的學(xué)習(xí)任務(wù)。但是,你知道嗎,你也可以使用預(yù)訓(xùn)練的模型來提取圖像的特征?簡(jiǎn)言之,特征提取是一種降維形式,其中大量像素被降維為更有效的表示。這主要適用于無監(jiān)督機(jī)器學(xué)習(xí)任務(wù)。讓我們嘗試使用Pytorch預(yù)先訓(xùn)練的模型從圖像中提取特征。為此,我們必須首先定義我們的特征提取器類:class ResnetFeatureExtractor(nn.Module):
def __init__(self, model):
super(ResnetFeatureExtractor, self).__init__()
self.model = nn.Sequential(*model.children())[:-1]
def forward(self, x):
return self.model(x)
請(qǐng)注意,在第4行中,創(chuàng)建了一個(gè)新模型,將原始模型的所有層保存為最后一層。你會(huì)記得,神經(jīng)網(wǎng)絡(luò)中的最后一層是用于預(yù)測(cè)輸出的密集層。然而,由于我們只對(duì)提取特征感興趣,所以我們不需要最后一層,因此它被排除在外。然后,我們將torchvision預(yù)訓(xùn)練的resnet34模型傳遞給ResnetFeatureExtractor構(gòu)造函數(shù),從而利用該模型。讓我們使用著名的CIFAR10數(shù)據(jù)集(50000張圖像),并在其上循環(huán)以提取特征。CIFAR10數(shù)據(jù)集(源)
cifar_dataset = CIFAR10("./", transform=transforms.ToTensor(), download=True)
cifar_dataloader = DataLoader(cifar_dataset, batch_size=1, shuffle=True)
feature_extractor.eval()
feature_list = []
for _, data in enumerate(tqdm_notebook(cifar_dataloader)):
inputs, labels = data
with torch.no_grad():
extracted_features = feature_extractor(inputs)
extracted_features = torch.flatten(extracted_features)
feature_list.a(chǎn)ppend(extracted_features)
我們現(xiàn)在有一個(gè)50000個(gè)圖像特征向量的列表,每個(gè)特征向量的大小為512(原始resnet模型倒數(shù)第二層的輸出大小)。print(fNumber of feature vectors: {len(feature_list)}") #50000
print(f"Number of feature vectors: {len(feature_list[0])}") #512
因此,該特征向量列表現(xiàn)在可由統(tǒng)計(jì)學(xué)習(xí)模型(如KNN)用于搜索類似圖像。
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
10月31日立即下載>> 【限時(shí)免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場(chǎng)仿真助跑新能源汽車
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國(guó)智造CIO在線峰會(huì)
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
推薦專題
- 1 【一周車話】沒有方向盤和踏板的車,你敢坐嗎?
- 2 特斯拉發(fā)布無人駕駛車,還未迎來“Chatgpt時(shí)刻”
- 3 特斯拉股價(jià)大跌15%:Robotaxi離落地還差一個(gè)蘿卜快跑
- 4 馬斯克給的“驚喜”夠嗎?
- 5 大模型“新星”開啟變現(xiàn)競(jìng)速
- 6 海信給AI電視打樣,12大AI智能體全面升級(jí)大屏體驗(yàn)
- 7 打完“價(jià)格戰(zhàn)”,大模型還要比什么?
- 8 馬斯克致敬“國(guó)產(chǎn)蘿卜”?
- 9 神經(jīng)網(wǎng)絡(luò),誰是盈利最強(qiáng)企業(yè)?
- 10 比蘋果偉大100倍!真正改寫人類歷史的智能產(chǎn)品降臨
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市