共用方式為


BrainScript 和 Python:瞭解和擴充讀者

從 1.5 版開始,CNTK 會從整合型讀取器設計移出更可撰寫的模型,讓您指定和撰寫不同格式的輸入資料。

之前,每個和每個讀取器都負責資料讀取的不同層面,包括但不限於:

  • 將資料從外部儲存體還原序列化為記憶體內部標記法
  • 隨機化整個主體
  • 輸入序列/樣本的不同轉換 (,也就是裁剪或調整影像)
  • 針對不同模式建立迷你batches (,例如框架、序列或截斷的 BPTT) ,以及 GPU 可取用的配置
  • 預先擷取 minibatches 和 IO 區塊層級

在 1.5 版中,上述功能的主要部分是分解並移至核心 CNTK,以便在不同的讀取器之間共用。 此版本也引進了兩個主要抽象概念,可擴充以支援新的資料格式:

  • 還原序列化程式 - 負責將外部儲存體輸入還原序列化為記憶體內部序列
  • transform - 它會將輸入序列轉換成輸出序列

在下一節中,我們會更詳細地討論這些抽象概念。

在 Python 中設定讀取器 (迷你batch 來源)

本節提供數個範例,說明複合讀取器 (如何在 Python 中設定 MinibatchSource) 。

下列範例是從 AlexNet_ImageNet_Distributed.py調整而來,它會顯示 Python 相當於 Transforms 區段的 AlexNet 讀取器。

import cntk.io

mean_file = ...
map_file = ...

# model dimensions
image_height = 227
image_width  = 227
num_channels = 3  # RGB
num_classes  = 1000

transforms = [
     ImageDeserializer.crop(crop_type='randomside', 
                            side_ratio=0.88671875, 
                            jitter_type='uniratio'),
     ImageDeserializer.scale(width=image_width, 
                            height=image_height, 
                            channels=num_channels, 
                            interpolations='linear'),
     ImageDeserializer.mean(mean_file)
]

reader = MinibatchSource(
    ImageDeserializer(map_file, StreamDefs(
        # first column in map file is referred to as 'image'
        features = StreamDef(field='image', transforms=transforms),
        # and second as 'label' 
        labels   = StreamDef(field='label', shape=num_classes)))) 

下列範例 (從 A2_RunCntk_py3.py 調整) 示範如何結合數個還原序列化器。

n_rois = 100
n_classes = 17
rois_dim = 4 * n_rois
label_dim = n_classes * n_rois

map_file = ...
roi_file = ...
label_file = ...

# read images
scale = ImageDeserializer.scale(width=1000, 
                                height=1000, 
                                channels=3,
                                scale_mode="pad", 
                                pad_value=114, 
                                interpolations='linear')
image_source = ImageDeserializer(map_file)
image_source.ignore_labels()
image_source.map_features('features', [scale])

# read rois and labels
roi_source = CTFDeserializer(roi_file)
roi_source.map_input('rois', dim=rois_dim, format="dense")
label_source = CTFDeserializer(label_file)
label_source.map_input('roiLabels', dim=label_dim, format="dense")

# define a composite reader
reader = MinibatchSource([image_source, roi_source, label_source])

...

# define mapping from reader streams to network inputs
input_map = {
    image_input: reader.streams.features,
    roi_input: reader.streams.rois,
    label_input: reader.streams.roiLabels
}

BrainScript

還原序列化程式

讓我們從端對端LSTM/FullUtterance測試查看HTKMLFReader的下列組態片段, (此處的完整設定) :

...
# Old reader config. For illustration only.
reader = [
    readerType = "HTKMLFReader"
    readMethod = "blockRandomize"
    nbruttsineachrecurrentiter = 32
    randomize = "auto"
    verbosity = 0

    features = [
        dim = 363
        type = "real"
        scpFile = "$DataDir$/glob_0000.scp"
    ]

    labels = [
        mlfFile = "$DataDir$/glob_0000.mlf"
        labelMappingFile = "$DataDir$/state.list"

        labelDim = 132
        labelType = "category"
    ]
]

此組態片段會宣告讀取器,此讀取器會產生具有名稱和 "features""labels" 的兩個數據流。 它會接受輸入兩種類型的檔案:

  • HTK剖析中已知為 scp 檔案 (「script」 檔案的功能檔案清單)
  • 稱為 mlf 檔案 (「主要標籤檔案」的標籤檔案)

在上述組態片段中,沒有明確實體會定義還原序列化或 scpmlf 格式的方式。 所有專案都封裝在 HTKMLFReader 設定中。 因此,如果您需要與 和 mlf 一起 scp 公開另一個不同資料格式的輸入資料流程,您必須變更HTKMLFReader,並在該處新增支援。

為了增加可撰寫性和重複使用性,相同輸入 的新 組態會明確定義還原序列化器和它們所產生的輸入資料流程:

reader = [
    verbosity = 0
    randomize = true

    # A list of deserializers the reader uses.
    deserializers = (
        [
            # Type of deserializer, in this case the one that knows
            # how to deserialize HTK feature files.
            type = "HTKFeatureDeserializer"
            # Module (.dll or .so) where this deserializer is implemented
            module = "HTKDeserializers"

            # Description of input streams the deserializer provides,
            # can be one or many, depending on a particular
            # deserializer implementation
            # For HTKFeatureDeserializer, just one stream can be described.
            input = [
                # Description of input stream to feed the Input node named "features"
                features = [
                    dim = 363
                    scpFile = "$DataDir$/glob_0000.scp"
                ]
            ]
        ]:
        [
            # Type of deserializer, in this case the one
            # that knows how to deserialize mlf files.
            type = "HTKMLFDeserializer"
            module = "HTKDeserializers"
            # Description of input streams the deserializer provides,
            # For HTKMLFDeserializer, just one stream can be described.
            input = [
                # Description of input stream to feed the Input node named "labels"
                labels = [
                    dim = 132
                    mlfFile = "$DataDir$/glob_0000.mlf"
                    labelMappingFile = "$DataDir$/state.list"
                    # whether phone boundary information should be encoded
                    # set to true in CTC-type training
                    phoneBoundaries=false
                ]
            ]
        ]
    )
]

htk 還原序列化器所產生的 mlf 序列會根據其邏輯索引鍵 (結合在一起,這是唯一識別語音語句的字串,而且同時存在於 scpmlf 檔案中) 。 當您需要另一個不同格式的資料流程時,只要將對應的還原序列化程式新增至組態 (現在無法使用 HTK 功能和 HTK MLF 還原序列化器來公開每個) 的多個輸入資料流程。

注意

目前支援舊和新的讀取器組態。 當讀取器組態中使用 「deserializers」 索引鍵時,讀取器類型會隱含地設定為 「CompositeDataReader」。 若要確定可以在 Windows 上載入 CompositeDataReader 模組, Cntk.Composite.dll 應該位於與 CNTK 可執行檔相同的目錄中。 在 Linux Cntk.Composite.so 上,應該位在 lib 包含 CNTK 可執行檔的資料夾並存 bin 資料夾中。

目前 CNTK 支援下列還原序列化程式:

還原序列化程式類型 模組 Description
HTKFeatureDeserializer HTKDeserializers HTK 功能檔案的還原序列化程式
HTKMLFDeserializer HTKDeserializers HTK MLF 檔案的還原序列化程式
ImageDeserializer ImageReader 還原序列化程式,用於編碼為純文字檔案或 zip 封存中的影像。
Base64ImageDeserializer ImageReader 對應檔中編碼為 base64 字串之影像的還原序列化程式。
CNTKTextFormatDeserializer CNTKTextFormatReader CNTK 文字檔的還原序列化程式
CNTKBinaryFormatDeserializer CNTKBinaryReader CNTK 二進位格式檔案的還原序列化程式

如需組態參數的完整描述,請參閱 下表

轉換

轉換是一個簡單的抽象概念,會採用序列作為輸入、在序列中執行一些樣本轉換,並傳回輸出序列。 轉換的一般範例是影像的不同轉換,例如裁剪、縮放或轉置。 每個輸入都可以設定轉換。

讓我們看看如何將轉換套用至輸入, (設定取自 Test/EndToEndTests/Image/AlexNet 測試) :

deserializers = ([
    type = "ImageDeserializer"
    module = "ImageReader"

    # Map file which maps images to labels
    file = "$ConfigDir$/train_map.txt"

    # Description of input streams
    input = [
            # Description of input stream to feed the Input node named "features"
            features = [
                transforms = (
                    [
                        type = "Crop"
                        # Possible values: Center, RandomSide, RandomArea, Multiview10. Default: Center
                        cropType = "RandomSide"
                        # Crop scale side ratio.
                        sideRatio = 0.875
                        # Crop scale ratio jitter type
                        jitterType = "UniRatio"
                    ]:[
                        type = "Scale"
                        width = 224
                        height = 224
                        channels = 3
                        # Interpolation to use when scaling image to width x height size.
                        interpolations = "linear"
                    ]:[
                        type = "Mean"
                        # Stores mean values for each pixel in OpenCV matrix XML format.
                        meanFile = "$ConfigDir$/ImageNet1K_mean.xml"
                    ]:[
                        # Changes the image layout from HWC to CHW
                        type = "Transpose"
                    ]
                )
            ]
            # Description of input stream to feed the Input node named "labels"
            labels = [
                labelDim = 1000
            ]
        ]
    ]
])

在此組態中,會將四個轉換套用至輸入資料流程 features 。 一開始,影像資料還原序列化程式會產生由 HWC 表示中的單一影像所組成的序列。 之後,已排序的轉換清單會套用至影像:第一個 是裁剪 轉換,後面接著 ScaleMean。 最後一個轉換是 Transpose ,會將影像配置從 HWC 變更為 CHW。

目前已實作下列轉換。 如需其詳細描述,請參閱 ImageReader

轉換類型 模組
Crop ImageReader
調整 ImageReader
色彩 ImageReader
平均數 ImageReader
轉置 ImageReader

新的讀取器設定格式描述

撰寫數個數據還原序列化器的讀取器組態區段如下所示:

reader = [
    randomize = true|false
    verbosity = 0|1|2
    ...

    deserializers = (
        [<deserializerConfiguration1>]:
        [<deserializerConfiguration2>]:
        ...
        [<deserializerConfigurationN>]
    )
]

每個還原序列化程式組態都會指定為:

[
    module = "<readerModuleName>"   # Name of the external module (.dll or .so) where this particular deserializer is implemented
    type = "<deserializerType>"     # The type of the deserializer

    # There could be more deserializer-specific options in this section

    # Date deserializer input - describes a set of streams this deserializer produces.
    # It can be one (as in HTK) or many (as in CNTKTextFormat)
    input = [
        # Replace 'InputNameN' by the name of the corresponding input node in the network.
        InputName1 = [<inputConfiguration>]
        InputName2 = [<inputConfiguration>]
        ...
    ]
]

輸入組態包含輸入特定選項,並選擇性地列出應該套用至輸入的已排序轉換清單:

[
    # Per-input data deserializer-specific options

    # Optionally a pipeline of transformations, to be implemented by data deserializer's reader module:
    transforms = (
       [<transformationConfiguration1>]:
       [<transformationConfiguration2>]:
       ...
       [<transformationConfigurationN>]
    )
]

轉換組態會識別轉換類型和任何轉換特定選項:

[
    type = "<transformName>"
    # Transform-specific options
]

設定選項

一般讀取器設定

參數 Description
verbosity 詳細資訊層級 (01 、) 2 ,控制隨機化程式、還原序列化程式、配套程式 ) 等不同 (元件的診斷 輸出,預設0
randomize 指定輸入是否應該隨機化 ( truefalse) 。 隨機化方法與 HTKMLFReader 的 blockRandomize 相同。 選擇性,預設為 true
randomizationSeed 初始隨機化種子值 (在輸入資料重新隨機化) 時遞增每個掃掠。 選擇性,預設為 0
randomizationWindow 指定隨機化視窗的大小 (正整數) (,也就是隨機化範圍) 。 此參數會影響資料集需要一次位於記憶體中的數量。 選擇性,預設為樣本或區塊中 整個資料集 的大小 (,視 sampleBasedRandomizationWindow 值) 而定。 不過,如果其中一個還原序列化程式是 CNTKTextFormatDeserializersampleBasedRandomizationWindow 明確設定為 truerandomizationWindow 則預設會 128 (大約是 4 GB 的磁碟空間,) 。 當 為 falserandomize ,會忽略此參數。
sampleBasedRandomizationWindow 如果 true 為 ,則隨機視窗的大小會解譯為特定數目的樣本,否則會解譯為數個區塊。 選擇性,如果 CNTKTextFormatDeserializer 不存在於還原序列化程式清單中,則預設為 ,否則會預設 truefalse 。 與 randomizationWindow 類似,當 為 falserandomize ,會忽略此參數。
truncationLength 指定 BPTT (正整數) 樣本中的截斷長度。 只有在 為 truetruncated才需要,否則會忽略 。
multiThreadedDeserialization 指定從還原序列化程式收集迷你批次的序列時,是否應該使用多個執行緒, (true) false選擇項
frameMode 指定資料是否應該隨機化,並在畫面格或序列層級傳回。 當 為 時 true ,輸入序列會分割成框架。 選擇項frameModetruncated 不能同時設定為 true
truncated 當 為 時 true ,會啟用透過時間截斷的反向傳播, (BPTT) 。 選擇項frameModetruncated 不能同時設定為 true
useNumericSequenceKeys 時序索引鍵可用來相互關聯不同還原序列化程式之間的序列。 對於某些還原序列化程式 (亦即 HTK 和 MLF) 順序索引鍵是任一字元串。 儲存它們需要大量記憶體在大型主體上。 如果您確定順序索引鍵是數值,請將此參數設定為 true,在此情況下,所有字串索引鍵都會轉換成整數,降低記憶體壓力。 選擇性,預設 false
hashSequenceKeys 基於上述的記憶體原因,字串索引鍵也可以藉由將此參數設定為 true 來雜湊。 請只針對支援字串序列索引鍵的還原序列化程式使用, (HTK、MLF) 。 選擇性,預設 false
cacheIndex 指定在前置處理階段期間建置的中繼資料是否應該寫出到磁片,並在有可用 (truefalse 從磁片載入 ,) 。 選擇性,預設為 false 。 如需詳細資訊,請參閱下面的一節。 CNTK 2.1 版的新功能。
索引快取

注意

CNTK 2.1 版的新功能。

索引快取可大幅 (2-3x) 減少啟動時間,特別是在處理大型輸入檔案時。 cacheIndex將 旗標設定為 true 會向讀取器發出訊號,以將索引中繼資料寫入磁片 (與輸入檔相同的目錄,) 如果快取檔案無法使用,或快取檔案過時 (早于輸入檔) 。 撰寫是最好的工作,而且會在個別的執行緒上執行,以免影響讀取器效能。 如果快取檔案存在且為最新狀態,讀取器將不再流覽輸入檔以建置索引,而是會從快取檔案載入索引。 請注意,某些讀取器組態參數會對索引編制 (產生直接的影響,例如,不同的 值 frameMode 可能會導致具有不同序列數目的索引) 。 基於這個理由,讀取器可能會忽略快取檔案,其設定不同于產生快取的組態。 若要查看快取的完整優點,後續重新執行時不應修改組態。

cacheIndex 對 ImageDeserializer 和 CNTKBinaryFormatDeserializer 沒有任何作用,因為前者不會為輸入資料編制索引,而稍後的索引資訊會內嵌在格式本身。

一般還原序列化程式設定

參數 Description
module 指定實作資料還原序列化程式的讀取器模組名稱。 必要
type 指定指定讀取器模組所公開的資料還原序列化程式名稱。 必要

一般轉換組態

參數 Description
type 指定由實作資料還原序列化程式之讀取器模組公開的轉換名稱。 必要

HTKFeatureDeserializer 選項

參數 Description
scpFile 要處理的 SCP 檔案路徑清單。 這些檔案應該是 HTK 相容的檔案,而且必須以「封存」格式指定。 使用封存的詳細資料會在 HTKMLF 讀取器中說明。 必要
dim 整數,指定具有所需內容視窗的完整特徵向量維度。1必要
contextWindow 可以指定為一對正整數或單一正整數 (在此情況下,它會解譯為重複重複兩次相同數位的配對) 。 指定範例中內容視窗) 第一個和第二個整數的左右大小 (。 選擇性,預設為 1
prefixPathInSCP 要套用至 SCP 檔案內指定之路徑的前置詞字串。 選擇項

1 例如,如果您有 72 維特徵 (24 維篩選銀行特徵加上差異和差異差異係數) ,而網路的設計目的是要處理 11 個畫面格的內容視窗,則指定的維度應該是 792。

HTKMLFDeserializer 選項

參數 Description
mlfFile HTK 樣式 mlf 檔案的路徑,其中包含檔案中指定的 scp 所有語句標籤, (s) 。 如果未指定 , mlfFileList則為必要項。
mlfFileList HTK 樣式 mlf 檔案的路徑陣列, (s) ,其中包含檔案中指定的 scp 所有語句標籤 (s) 。 如果未指定 , mlfFile則為必要項。
dim 標籤集的總基數 (正整數) 。 必要
labelMappingFile 檔案的路徑,其中列出檔案中看到 mlf 的所有標籤,每行一個。 必要

labelDim 可作為 dim 的同義字。

CNTKTextFormatDeserializer 選項

可以搭配CNTKTextFormatReader使用的相同選項

ImageDeserializer 選項

  • file:簡單的文字檔,其中每一行都包含邏輯順序索引鍵、影像檔 (例如 JPEG、PNG 等) 和 0 型標籤之間的定位字元分隔對應。

如需詳細資訊,請參閱 ImageReader

Base64ImageDeserializer 選項

此還原序列化程式支援可與 ImageDeserializer 搭配使用的相同選項。 唯一的差異在於對應檔的格式:

  • file:一個簡單的文字檔,其中每一行都包含邏輯順序索引鍵之間的定位字元分隔對應, (選擇性,可以省略) 、以 0 為基礎的類別標籤和基底 64 編碼影像檔 (例如 JPEG、PNG 等) 。

組態和測試的範例

您會在 CNTK 存放庫中找到完整的網路定義和對應的資料集範例。 您也可以在該處找到使用還原序列化器的單元和端對端測試,亦即