自己打包一個數(shù)據(jù)集代碼案例——使用Numpy計(jì)算框架自定義一個類似MINST的數(shù)據(jù)集 原創(chuàng)
“ 自定義數(shù)據(jù)集既是未來人工智能技術(shù)的重點(diǎn),也是人工智能技術(shù)的難點(diǎn) ”
在人工智能領(lǐng)域中,數(shù)據(jù)的重要性得到了充分的體現(xiàn);但很多人還不知道怎么打造一個數(shù)據(jù)集,所以今天我們就用一些圖片來模仿MINST數(shù)據(jù)集打造一個類MINST數(shù)據(jù)集,能夠直接被神經(jīng)網(wǎng)絡(luò)加載和使用。
當(dāng)然,為了簡單起見我們對數(shù)據(jù)就只進(jìn)行簡單的處理,如統(tǒng)一圖片大小,不會按照嚴(yán)格的數(shù)據(jù)處理方式;比如說圖片裁剪,增強(qiáng)等。
自定義數(shù)據(jù)集實(shí)現(xiàn)
以MINST數(shù)據(jù)集為例,其主要由四個壓縮文件組成;訓(xùn)練集的圖片和標(biāo)簽,以及測試集的圖片和標(biāo)簽。如下圖所示:
而我們今天就以訓(xùn)練圖片數(shù)據(jù)為例,使用一些圖片構(gòu)造一個訓(xùn)練集。
首先我們需要從網(wǎng)上或者其它地方找到一些特征數(shù)據(jù),放到一個目錄里面,作者這里使用的是一些螞蟻的圖片數(shù)據(jù)。如下圖所示:
由于找到的圖片格式不同,大小也不同,因此我們第一步就通過對圖片大小進(jìn)行變換以獲取同樣大小的圖片,如MINST數(shù)據(jù)集的圖片就是28*28統(tǒng)一大小的數(shù)據(jù)。統(tǒng)一圖片大小的好處是方便神經(jīng)網(wǎng)絡(luò)進(jìn)行處理。
首先我們需要讀取圖片數(shù)據(jù),并對圖片數(shù)據(jù)大小進(jìn)行統(tǒng)一處理,如下所示,可以明顯看到圖片的size參差不齊。
因此,我們需要對圖片大小進(jìn)行統(tǒng)一處理;函數(shù)如下:
# 圖片大小轉(zhuǎn)換函數(shù) 這種只是簡單的大小變換 會導(dǎo)致圖片變形只作為例子使用
def resize_image(img, target_size=(500, 500)): # img 是待處理圖片 target_size是目標(biāo)大小,如(500, 500)
return img.resize(target_size, Image.Resampling.LANCZOS)
如下圖所示,變換之后的圖片大小變成了統(tǒng)一的500*500;但這里只是舉個簡單的圖片處理例子,在實(shí)際的業(yè)務(wù)場景中,對圖片數(shù)據(jù)的處理會更復(fù)雜,更嚴(yán)格;比如對圖片進(jìn)行裁剪,統(tǒng)一通道,等比縮放等;而現(xiàn)在這種簡單的變形方式會導(dǎo)致圖片變形,因此只作為例子使用。
這里對圖片處理的工具使用的是Python經(jīng)典的圖片處理包PIL,當(dāng)然讀者也可以選擇自己喜歡的其它工具包,如OpenCV等??傊康木褪前褕D片處理成自己需要的格式。
在對圖片數(shù)據(jù)進(jìn)行初步處理之后,就可以使用Numpy把圖片轉(zhuǎn)換為向量格式,也就是多維矩陣。
img = np.array(img)
完整代碼如下所示:
import os
from PIL import Image
import numpy as np
import struct
"""自定義圖片數(shù)據(jù)集 缺少的包需要自己按照 pip(3) install 包名"""
# 圖片大小轉(zhuǎn)換函數(shù)
def resize_image(img, target_size=(500, 500)):
# img 是待處理圖片 target_size是目標(biāo)大小,如(500, 500)
return img.resize(target_size, Image.Resampling.LANCZOS)
# 把處理后的圖片打包成類似MINST的二進(jìn)制格式 數(shù)據(jù)集的前部分是數(shù)據(jù)集的描述內(nèi)容 因此需要添加文件頭 類似于MINST的真實(shí)圖片都是從16字節(jié)開始的
def save_images_as_minst(file_path, images):
""" 將圖像數(shù)據(jù)保存為 MNIST 格式 :param file_path: :param images: 圖像數(shù)據(jù),形狀為 (num_samples, height, width) :return: """
num_samples, height, width = images.shape
with open(file_path, 'wb') as f:
# 寫入文件頭
f.write(struct.pack('>IIII', 0x00000803, num_samples, height, width))
# 寫入圖像數(shù)據(jù)
f.write(images.tobytes())
# 自定義數(shù)據(jù)集函數(shù)
def custom_data(ants_path):
# 收集向量化的圖片列表
image_data = []
for path in os.listdir(ants_path):
ant_path = os.path.join(ants_path, path)
# 獲取圖片完整路徑
image = Image.open(ant_path)
# print(image) # 打印螞蟻圖片類型
img = resize_image(image) # 變換之后的圖片大小
# print(img)
# 在對圖片進(jìn)行向量化之前 也可以指定圖片對模式 L-灰度模式 RGB-彩色 PIL一共有九種模式 讀者可以自信百度
# 目前圖片的默認(rèn)模式是RGB模式 而MINST數(shù)據(jù)集是灰度模式 也就是L 表示黑白色 讀者可以根據(jù)自己的需求進(jìn)行處理 或采用默認(rèn)即可
img = img.convert('L') # 這里由于圖片格式不一致 導(dǎo)致其通道數(shù)不同 因此這里使用最簡單的灰度圖——L 來統(tǒng)一圖片 方便后續(xù)處理
img = np.array(img) # 把向量化的圖片放到一個列表中
image_data.append(img)
# print("image_data: ", image_data)
# 統(tǒng)一轉(zhuǎn)換成numpy 數(shù)組 方便使用二進(jìn)制存儲
data = np.array(image_data)
print("轉(zhuǎn)換后的圖片數(shù)組: ", data)
# 打包文件名 保存在當(dāng)前目錄下 data是待打包的數(shù)據(jù)
save_images_as_minst("custom_images_ants_ubyte", data)
ants_path = "./ants_image"
custom_data(ants_path)
# 讀取打包的文件
def read_image(file_path):
with open(file_path, 'rb') as f:
magic, num, rows, cols = struct.unpack('>IIII', f.read(16))
images = np.frombuffer(f.read(), dtype=np.uint8).reshape(num, rows, cols)
return images
for img in read_image("./custom_images_ants_ubyte"):
im = Image.fromarray(img)
print(im)
這里只是舉了一個簡單的處理和打包數(shù)據(jù)集的例子,在真實(shí)的場景中數(shù)據(jù)處理要遠(yuǎn)比這復(fù)雜的多。
而且這里主要針對的是圖片數(shù)據(jù),工具使用的主要是PIL圖片處理工具和Numpy科學(xué)計(jì)算工具。
如果是文本數(shù)據(jù),還會涉及到詞表的構(gòu)建等;總之,數(shù)據(jù)處理是作為人工智能從業(yè)者所必備的技能。
完整數(shù)據(jù)和代碼,也可以在公眾號回復(fù): 自定義MINST數(shù)據(jù)集 獲取
本文轉(zhuǎn)載自公眾號AI探索時(shí)代 作者:DFires
