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
檔案 (「主要標籤檔案」的標籤檔案)
在上述組態片段中,沒有明確實體會定義還原序列化或 scp
mlf
格式的方式。
所有專案都封裝在 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
序列會根據其邏輯索引鍵 (結合在一起,這是唯一識別語音語句的字串,而且同時存在於 scp
和 mlf
檔案中) 。
當您需要另一個不同格式的資料流程時,只要將對應的還原序列化程式新增至組態 (現在無法使用 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 表示中的單一影像所組成的序列。
之後,已排序的轉換清單會套用至影像:第一個 是裁剪 轉換,後面接著 Scale 和 Mean。
最後一個轉換是 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 |
詳細資訊層級 (0 、 1 、) 2 ,控制隨機化程式、還原序列化程式、配套程式 ) 等不同 (元件的診斷 輸出,預設為 0 。 |
randomize |
指定輸入是否應該隨機化 ( true 、 false ) 。 隨機化方法與 HTKMLFReader 的 blockRandomize 相同。 選擇性,預設為 true 。 |
randomizationSeed |
初始隨機化種子值 (在輸入資料重新隨機化) 時遞增每個掃掠。 選擇性,預設為 0 。 |
randomizationWindow |
指定隨機化視窗的大小 (正整數) (,也就是隨機化範圍) 。 此參數會影響資料集需要一次位於記憶體中的數量。 選擇性,預設為樣本或區塊中 整個資料集 的大小 (,視 sampleBasedRandomizationWindow 值) 而定。 不過,如果其中一個還原序列化程式是 CNTKTextFormatDeserializer 且 sampleBasedRandomizationWindow 未 明確設定為 true , randomizationWindow 則預設會 128 (大約是 4 GB 的磁碟空間,) 。 當 為 false 時 randomize ,會忽略此參數。 |
sampleBasedRandomizationWindow |
如果 true 為 ,則隨機視窗的大小會解譯為特定數目的樣本,否則會解譯為數個區塊。 選擇性,如果 CNTKTextFormatDeserializer 不存在於還原序列化程式清單中,則預設為 ,否則會預設 true 為 false 。 與 randomizationWindow 類似,當 為 false 時 randomize ,會忽略此參數。 |
truncationLength |
指定 BPTT (正整數) 樣本中的截斷長度。 只有在 為 true 時 truncated 才需要,否則會忽略 。 |
multiThreadedDeserialization |
指定從還原序列化程式收集迷你批次的序列時,是否應該使用多個執行緒, (true ) false 。 選擇項。 |
frameMode |
指定資料是否應該隨機化,並在畫面格或序列層級傳回。 當 為 時 true ,輸入序列會分割成框架。 選擇項。 frameMode 和 truncated 不能同時設定為 true 。 |
truncated |
當 為 時 true ,會啟用透過時間截斷的反向傳播, (BPTT) 。 選擇項。 frameMode 和 truncated 不能同時設定為 true 。 |
useNumericSequenceKeys |
時序索引鍵可用來相互關聯不同還原序列化程式之間的序列。 對於某些還原序列化程式 (亦即 HTK 和 MLF) 順序索引鍵是任一字元串。 儲存它們需要大量記憶體在大型主體上。 如果您確定順序索引鍵是數值,請將此參數設定為 true,在此情況下,所有字串索引鍵都會轉換成整數,降低記憶體壓力。 選擇性,預設 false 。 |
hashSequenceKeys |
基於上述的記憶體原因,字串索引鍵也可以藉由將此參數設定為 true 來雜湊。 請只針對支援字串序列索引鍵的還原序列化程式使用, (HTK、MLF) 。 選擇性,預設 false 。 |
cacheIndex |
指定在前置處理階段期間建置的中繼資料是否應該寫出到磁片,並在有可用 (true 時 false 從磁片載入 ,) 。 選擇性,預設為 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 存放庫中找到完整的網路定義和對應的資料集範例。 您也可以在該處找到使用還原序列化器的單元和端對端測試,亦即
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/EndToEndTests/Speech/HTKDeserializers/LSTM/FullUtterance
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/EndToEndTests/Image/AlexNet
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/UnitTests/ReaderTests/Config/ImageAndTextReaderSimple_Config.cntk
- https://github.com/Microsoft/CNTK/tree/release/latest/Tests/UnitTests/ReaderTests/Config/CNTKTextFormatReader/dense.cntk