日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

第二篇 FastAI数据准备「建议收藏」

發布時間:2023/12/19 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 第二篇 FastAI数据准备「建议收藏」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Fast AI代碼組織結構 (文檔鏈接)

Fast AI庫主要涉及神經網絡在如下四個領域的應用:collab(協同濾波問題)、tabular(結構化數據或者說表格數據處理)、text(自然語言處理)、vision(機器視覺)。對每一領域(除了collab),其下又會按照如下結構組織代碼:

  • (1) data:定義了模型所需的數據集類。
  • (2) transform:數據預處理(如對圖像數據的圖像增強,表格數據的數據清洗,文本數據的符號化以及數字化)
  • (3) models:定義了相應的網絡模型。
  • (4) learner:定義了將數據和模型關聯起來的類,并定義了一系列回調函數。

本系列博客所關注的vision包,同樣是按照如上結構進行組織的,同時也定義了專用于視覺處理的對象:

  • (1) vision.Image定義了Fast AIImage對象,以及對其進行操作的函數。
  • (2) vision.data定義了專用于視覺應用的ImageDataBunch數據集,以及可從DataBunch構建的用于視覺應用的函數。
  • (3) vision.transform定義了可用于數據增強的變換。
  • (4) vision.learner定義了可用于訓練網絡或遷移學習的一些函數。

若要使用vision包的功能,僅需如下語句進行導入相關定義:

from fastai.vision import *

二、 vision.Image數據類型(fastai/vision/image.py)

Fast AI用于圖像處理的基礎類型為Image,是在PIL.Image類型上構建的,并封裝了一些常用函數。

1. 構建Image對象

Fast AI提供了一個將圖像文件讀取為vision.Image對象的函數open_image(定義在fastai/vision/image.py文件中):

open_image( fn:PathOrStr,               # 文件路徑
            div:bool=True,              # 是否除以255
            convert_mode:str='RGB',     # 轉換方式,同PIL.Image
            cls:type=Image,             # 返回的類型
            after_open:Callable=None)   # 打開文件后的回調

上述函數以PIL.Image.open()方式打開fn指定的文件后,做after_open的處理,然后調用pil2tensor()函數將之轉換成float32型的tensor(會進行維度的交換調整,調整后變為C x H x W),依據div決定是否做歸一化操作(默認是做歸一化操作的),最后轉換為cls類型的變量。cls默認使用vision.Image類型。

所以,Image類型還可使用C x H x W形狀的float32型的tensor類直接進行初始化。

2. Image對象的一些通用屬性
  • Image.data: 圖像像素數據,以tensor形式存儲。
  • Image.shape: channels x height x width。
  • Image.size: height x width。
3. Image對象的一些通用函數
  • Image.show()函數,用于顯示圖像
    Image.show(
        ax:Axes=None,       # 指定用于顯示圖像的圖對象(由matplotlib的相關函數生成)
        figsize:tuple=(3, 3),   # 圖的大小
        title:Optional[str]=None,   # 圖的標題
        hide_axis:bool=True,    # 隱藏坐標軸
        cmap:str=None,          # color map, 與matplotlib中的cmap一致
        y:Any=None,         # 是否有額外的顯示,如定位框、圖像掩膜之類的
        **kwargs
    )
  • Image.rotate()函數,用于圖像旋轉,這是一個神奇的函數,在Image類及其父類ItemBase中,均找不到它的定義,不過應該和PIL.Image.rotate()函數類似。對于旋轉后需要擴充的像素,采用的是反射補全。
  • Image.resize()函數,用于圖像縮放,其參數為一個整數,或者HxW型的元組。
  • Image.apply_tfms()函數,用于圖像變換:
    apply_tfms(
          tfms:Union[Callable, Collection[Callable]],  # 變換列表
          do_resolve:bool=True,   # 是否重新設置隨機化參數。比如對于圖像分割,
                                  # 對image和mask需要做同樣的縮放或平移,
                                  # 此時即需要設置do_resolve=False
          xtra:Optional[Dict[Callable, dict]]=None, # 變換所需的額外的參數
          size:Union[int, TensorImageSize, NoneType]=None, # 輸出圖片的尺寸 
          resize_method:ResizeMethod=None, # 如何達到最終所要的尺寸 [crop, pad, squish]
          mult:int=None, # 保證最終所得圖像的尺寸是mult的倍數
          padding_mode:str='reflection', # 填充方法 ["zero", "border", "reflection"]
          mode:str='bilinear', remove_out:bool=True) → Tensor

除去vision.Image類外,Fast AI還定義了一些用于具體任務的類,如用于圖像分割的ImageSegment類,用于目標檢測的ImageBBox類,用于關鍵點定位的ImagePoints類等。這些將在相關應用場景下進行介紹。

三、 用于灌入網絡的數據裝配類型vision.ImageDataBunch類(fastai/vision/data.py)

由前一博客的示例,Fast AI會將訓練集、驗證集、測試集的數據迭代器組合成DataBunch對象。而對于視覺領域的應用,Fast AI提供了更為合適的數據裝配類型:ImageDataBunch類。

對于視覺任務而言,其數據一般有兩種組織方式:

  • ImageNet類的數據組織形式:每類的圖像位于各自的文件夾下:

      path\
      	train\ 
                  class1\     class2\ ...
      	valid\
                  class1\     class2\ ...
       	test\
    
  • csv文件給出圖像以及對應的label:

      path\
      	train\  test\   labels.csv
    

針對這些情形,Fast AI提供了用于構建ImageDataBunch的6種工廠類方法。這6種方法均是基于ImageDataBunch.create_from_ll()方法。由前所述,ImageDataBunch僅是整合了用于灌入網絡的數據加載器(即訓練集、驗證集和可選的測試集),因此,create_from_ll()方法也很簡單:指定訓練集、驗證集、測試集的文件列表,指定網絡每次讀取的數據的大小(batch size),指定對數據進行的變換等等。

@classmethod
def create_from_ll(cls, 
    lls:LabelLists, # 文件列表
    bs:int=64, val_bs:int=None, # batch size
    ds_tfms:Optional[TfmList]=None, # 對數據進行的變換
    num_workers:int=defaults.cpus, 
    dl_tfms:Optional[Collection[Callable]]=None, 
    device:torch.device=None,
    test:Optional[PathOrStr]=None, # 測試數據集的路徑
    collate_fn:Callable=data_collate, 
    size:int=None, # 圖像大小
    no_check:bool=False,
    resize_method:ResizeMethod=None, 
    mult:int=None, padding_mode:str='reflection',
    mode:str='bilinear', 
    tfm_y:bool=False # 是否對標簽數據進行變換,如在圖像分割任務中,是否對mask進行變換
)->'ImageDataBunch':

實際上很少直接調用這個看著很復雜的函數,而是調用6種工廠類函數。這些工廠類函數大同小異,僅是在如何提供數據標簽方面有所差別。下面以fastai.URLs.MNIST_SAMPLE數據為例演示其用法。

1. URLs.MNIST_SAMPLE數據說明
path = untar_data(URLs.MNIST_SAMPLE)

會將數據文件下載至~/.fastai/data目錄下。數據目錄結構為

mnist_sample\
    labels.csv
    train\(12396)
        3\(6131)  7\(6265)
    valid\(2038)
        3\(1010)  7\(1028)         

數據僅包含MNIST手寫數字集的37兩類,按照ImageNet數據的組織格式存儲,同時以labels.csv文件提供文件名與類別的對應關系。其中labels.csv中的每條記錄的格式為:(注意其中的labels不再是37,而變成了01)

圖 1. labels.csv記錄格式

2. 使用文件夾提供數據標簽:from_folder()工廠類方法

from_folder()的函數簽名如下:

@classmethod
def from_folder(cls,
    path:PathOrStr,  # 數據目錄,包含train、valid等分類。
    train:PathOrStr='train', # 訓練集的文件夾名稱,默認為train
    valid:PathOrStr='valid', # 驗證集的文件夾名稱,默認為valid
    valid_pct=None, seed:int=None, # 用于劃分train和valid數據集的比例參數,以及隨機種子
                    # 如果設置了valid_pct參數,則train、valid參數指定的文件夾不再起作用
    classes:Collection=None, # 可以指定選取哪些類
    **kwargs:Any)->'ImageDataBunch':

對于MNIST_SAMPLE數據:

data = ImageDataBunch.from_folder(path, size=24)
3. 使用panda.DataFrame對象提供數據標簽:from_df()工廠類方法

from_df()的函數簽名如下:

@classmethod
def from_df(cls,
    path:PathOrStr, # 數據目錄
    df:pd.DataFrame, # 存儲圖像文件及其對應標簽的DataFrame
    folder:PathOrStr=None,  # 相對于path的子路徑
    label_delim:str=None,
    valid_pct:float=0.2, seed:int=None, # 用于劃分train和valid數據集的比例參數,以及隨機種子
    fn_col:IntsOrStrs=0, label_col:IntsOrStrs=1, # 數據文件和標簽的列
    suffix:str='', # 文件ID是否需要添加后綴
    **kwargs:Any)->'ImageDataBunch'

對于MNIST_SAMPLE數據:

df = pd.read_csv(path/'labels.csv', header='infer')
data = ImageDataBunch.from_df(path, df=df)

其中labels.csv可能會包含表頭,所以會使用header='infer'來做自動處理。如果labels.csv中記錄的文件路徑和path之間仍有子路徑,則可通過folder參數進行設置。如果labels.csv中記錄的文件路徑沒有后綴,則可通過suffix參數指定。如:圖像數據以jpg格式存儲在/home/user/data/train/路徑下,設置path="/home/user/data",另外labels.csv中的文件路徑為:img_1img_2……,則可設置:folder="train"suffix=".jpg"。

4. 使用csv文件提供數據標簽:from_csv()工廠類方法

from_csv()是基于from_df()函數實現的,其函數簽名如下:

@classmethod
def from_csv(cls,
    path:PathOrStr, # 數據目錄
    folder:PathOrStr=None, 
    label_delim:str=None, 
    csv_labels:PathOrStr='labels.csv', # csv文件名
    valid_pct:float=0.2, seed:int=None,
    fn_col:int=0, label_col:int=1,
    suffix:str='', delimiter:str=None, 
    header:Optional[Union[int,str]]='infer',
    **kwargs:Any)->'ImageDataBunch'

其中csv文件應位于path路徑下,如果csv文件的名稱為labels.csv,則可省略csv參數;csv文件中指定的數據,應位于path/folder路徑下。

對于MNIST_SAMPLE數據:

data = ImageDataBunch.from_csv(path, size=24)
5. 使用文件名提取數據標簽:from_name_func()工廠類方法

from_name_func()函數的簽名如下:

@classmethod
def from_name_func(cls,
    path:PathOrStr,         # 數據文件路徑
    fnames:FilePathList,    # 數據文件列表
    label_func:Callable,    # 從文件名中提取標簽的函數
    valid_pct:float=0.2,
    seed:int=None,**kwargs)

注意,函數將依據fnames中存儲的文件路徑fname來查找文件,而不是以path/fname為路徑。
對于MNIST_SAMPLE數據,其數據文件路徑形為:

'/home/user/.fastai/data/mnist_sample/train/3/7463.png'
'/home/user/.fastai/data/mnist_sample/train/7/3087.png'

故可通過檢查\3\\7\是否在路徑中來判斷文件類別:

df = pd.read_csv(path/'labels.csv', header='infer')
fnames = [path/file for file in df["name"]]
def get_labels(file_path):
    return '3' if '/3/' in str(file_path) else '7'
data = ImageDataBunch.from_name_func(path, fnames, label_func=get_labels, size=24)
6. 使用正則表達式提取數據標簽:from_name_re()工廠類方法

from_name_re()是基于from_name_func()實現的,其函數簽名為:

def from_name_re(cls,
    path:PathOrStr,
    fnames:FilePathList,
    pat:str,                # 正則表達式
    valid_pct:float=0.2,
    **kwargs)

對于MNIST_SAMPLE數據,可通過提取數據文件所在的文件夾名稱(即"3"或者"7")來指定文件標簽:

pat = r"/(\d)/\d+\.png$"
data = ImageDataBunch.from_name_re(path, fn_paths, pat=pat, size=24)
7. 使用列表提供數據標簽:from_list()工廠類方法

from_list()的函數簽名為:

@classmethod
def from_lists(cls,
    path:PathOrStr,
    fnames:FilePathList,    # 文件名稱列表
    labels:Collection[str], # 標簽列表
    valid_pct:float=0.2, seed:int=None,
    item_cls:Callable=None, **kwargs)

對于MNIST_SAMPLE數據:

df = pd.read_csv(path/'labels.csv', header='infer')
fn_paths = [path/file for file in df["name"]]
def get_labels(file_path):
    return '3' if '/3/' in str(file_path) else '7'
labels_ls = list(map(get_labels, fn_paths))
data = data = ImageDataBunch.from_lists(path, fn_paths, labels=labels_ls, size=24)

Fast AI提供了一套整合數據文件與標簽文件的數據類型和API,上述6種工廠類方法均是在其基礎上進行構建的。而這些數據類型和API也提供了足夠的靈活性,可在這6種工廠類方法不能覆蓋的應用情景下(如想要通過文件夾區分訓練集和驗證集,而通過csv文件提供數據標簽),方便地構建出所需的數據集和標簽集。這部分內容將在下一博客中進行闡述。

一些有用的鏈接

  • Fast AI代碼組織結構文檔鏈接
  • fastai.vision概覽
  • fastai.vision.Image數據類型文檔
  • fastai.vision.data: ImageDataBunch類的文檔

總結

以上是生活随笔為你收集整理的第二篇 FastAI数据准备「建议收藏」的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。