Transform TFX 管線元件會使用 SchemaGen 元件建立的資料結構描述,對 ExampleGen 元件發出的 tf.Examples 執行特徵工程,並發出 SavedModel,以及轉換前和轉換後資料的統計資料。執行時,SavedModel 會接受 ExampleGen 元件發出的 tf.Examples,並發出轉換後的特徵資料。
- 取用項目:來自 ExampleGen 元件的 tf.Examples,以及來自 SchemaGen 元件的資料結構描述。
- 發出項目:傳送至 Trainer 元件的 SavedModel、轉換前和轉換後統計資料。
設定 Transform 元件
一旦寫入 preprocessing_fn
,就必須在 Python 模組中定義,然後將該模組做為輸入提供給 Transform 元件。Transform 會載入這個模組,並找到名為 preprocessing_fn
的函式,然後由 Transform 使用來建構預先處理管線。
transform = Transform(
examples=example_gen.outputs['examples'],
schema=schema_gen.outputs['schema'],
module_file=os.path.abspath(_taxi_transform_module_file))
此外,您可能希望為以 TFDV 為基礎的轉換前或轉換後統計資料運算提供選項。若要這麼做,請在同一個模組中定義 stats_options_updater_fn
。
Transform 和 TensorFlow Transform
Transform 廣泛使用 TensorFlow Transform,針對您的資料集執行特徵工程。TensorFlow Transform 是轉換特徵資料的絕佳工具,可在特徵資料傳送到您的模型之前以及在訓練流程中轉換。常見的特徵轉換包括:
- 嵌入:透過尋找從高維空間到低維空間的有意義對應,將稀疏特徵 (例如詞彙表產生的整數 ID) 轉換為密集特徵。如需嵌入的簡介,請參閱機器學習速成課程中的嵌入單元。
- 詞彙表產生:藉由建立將每個唯一值對應到 ID 號碼的詞彙表,將字串或其他非數值特徵轉換為整數。
- 正規化值:轉換數值特徵,讓它們全部落在相似的範圍內。
- 分桶化:藉由將值指派給離散值組,將連續值特徵轉換為類別特徵。
- 豐富文字特徵:從原始資料 (例如符記、n-gram、實體、情感等) 產生特徵,以豐富特徵集。
TensorFlow Transform 支援這些轉換和許多其他種類的轉換
從您的最新資料自動產生詞彙表。
在將資料傳送到模型之前,對資料執行任意轉換。TensorFlow Transform 會將轉換建置到模型的 TensorFlow 圖表中,以便在訓練和推論時執行相同的轉換。您可以定義參照資料全域屬性的轉換,例如所有訓練例項中特徵的最大值。
您可以在執行 TFX 之前,隨意轉換您的資料。但是,如果您在 TensorFlow Transform 中執行轉換,轉換就會變成 TensorFlow 圖表的一部分。這種方法有助於避免訓練/服務偏差。
模型建構程式碼內部的轉換會使用 FeatureColumns。使用 FeatureColumns,您可以定義分桶化、使用預先定義詞彙表的整數化,或任何其他可在不查看資料的情況下定義的轉換。
相較之下,TensorFlow Transform 專為需要完整傳遞資料以運算事先未知的值的轉換而設計。例如,詞彙表產生需要完整傳遞資料。
除了使用 Apache Beam 運算值之外,TensorFlow Transform 也允許使用者將這些值嵌入到 TensorFlow 圖表中,然後可以將該圖表載入到訓練圖表中。例如,在正規化特徵時,tft.scale_to_z_score
函式將運算特徵的平均值和標準差,以及 TensorFlow 圖表中減去平均值並除以標準差的函式表示法。TensorFlow Transform 藉由發出 TensorFlow 圖表 (而不只是統計資料),簡化了撰寫預先處理管線的流程。
由於預先處理表示為圖表,因此可以在伺服器上進行,並保證在訓練和服務之間保持一致。這種一致性消除了訓練/服務偏差的一個來源。
TensorFlow Transform 允許使用者使用 TensorFlow 程式碼指定其預先處理管線。這表示管線的建構方式與 TensorFlow 圖表相同。如果這個圖表中僅使用 TensorFlow 運算元,則管線會是純粹的對應,接受輸入批次並傳回輸出批次。當使用 tf.Estimator
API 時,這類管線相當於將此圖表放在您的 input_fn
內。為了指定完整傳遞運算 (例如運算分位數),TensorFlow Transform 提供稱為 analyzers
的特殊函式,這些函式看起來像 TensorFlow 運算元,但實際上指定了將由 Apache Beam 完成的延遲運算,並且輸出會做為常數插入圖表中。雖然一般的 TensorFlow 運算元會將單一批次做為其輸入、僅對該批次執行一些運算並發出批次,但 analyzer
會對所有批次執行全域縮減 (在 Apache Beam 中實作) 並傳回結果。
藉由結合一般的 TensorFlow 運算元和 TensorFlow Transform analyzers,使用者可以建立複雜的管線來預先處理其資料。例如,tft.scale_to_z_score
函式會採用輸入張量,並傳回正規化為平均值 0
和變異數 1
的張量。它藉由在底層呼叫 mean
和 var
analyzers 來完成此操作,這實際上會在圖表中產生等於輸入張量的平均值和變異數的常數。然後,它會使用 TensorFlow 運算元來減去平均值並除以標準差。
TensorFlow Transform preprocessing_fn
TFX Transform 元件藉由處理與讀取和寫入資料相關的 API 呼叫,以及將輸出 SavedModel 寫入磁碟,簡化了 Transform 的使用。身為 TFX 使用者,您只需要定義一個名為 preprocessing_fn
的函式即可。preprocessing_fn
中,您定義了一系列函式,這些函式會操縱張量的輸入字典,以產生張量的輸出字典。您可以找到輔助函式,例如 scale_to_0_1 和 compute_and_apply_vocabulary (TensorFlow Transform API TensorFlow Transform API),或使用下方顯示的一般 TensorFlow 函式。
def preprocessing_fn(inputs):
"""tf.transform's callback function for preprocessing inputs.
Args:
inputs: map from feature keys to raw not-yet-transformed features.
Returns:
Map from string feature key to transformed feature operations.
"""
outputs = {}
for key in _DENSE_FLOAT_FEATURE_KEYS:
# If sparse make it dense, setting nan's to 0 or '', and apply zscore.
outputs[_transformed_name(key)] = transform.scale_to_z_score(
_fill_in_missing(inputs[key]))
for key in _VOCAB_FEATURE_KEYS:
# Build a vocabulary for this feature.
outputs[_transformed_name(
key)] = transform.compute_and_apply_vocabulary(
_fill_in_missing(inputs[key]),
top_k=_VOCAB_SIZE,
num_oov_buckets=_OOV_SIZE)
for key in _BUCKET_FEATURE_KEYS:
outputs[_transformed_name(key)] = transform.bucketize(
_fill_in_missing(inputs[key]), _FEATURE_BUCKET_COUNT)
for key in _CATEGORICAL_FEATURE_KEYS:
outputs[_transformed_name(key)] = _fill_in_missing(inputs[key])
# Was this passenger a big tipper?
taxi_fare = _fill_in_missing(inputs[_FARE_KEY])
tips = _fill_in_missing(inputs[_LABEL_KEY])
outputs[_transformed_name(_LABEL_KEY)] = tf.where(
tf.is_nan(taxi_fare),
tf.cast(tf.zeros_like(taxi_fare), tf.int64),
# Test if the tip was > 20% of the fare.
tf.cast(
tf.greater(tips, tf.multiply(taxi_fare, tf.constant(0.2))), tf.int64))
return outputs
瞭解 preprocessing_fn 的輸入
preprocessing_fn
描述了一系列張量 (也就是 Tensor
、SparseTensor
或 RaggedTensor
) 的運算。為了正確定義 preprocessing_fn
,必須瞭解資料如何表示為張量。preprocessing_fn
的輸入由結構描述決定。Schema
proto 最終會轉換為「特徵規格」(有時稱為「剖析規格」),用於資料剖析,如需轉換邏輯的更多詳細資訊,請參閱這裡。
使用 TensorFlow Transform 處理字串標籤
通常,人們會想要使用 TensorFlow Transform 來產生詞彙表,並套用該詞彙表來將字串轉換為整數。當遵循這個工作流程時,在模型中建構的 input_fn
將輸出整數化的字串。但是,標籤是例外情況,因為為了讓模型能夠將輸出 (整數) 標籤對應回字串,模型需要 input_fn
輸出字串標籤,以及標籤可能值的清單。例如,如果標籤是 cat
和 dog
,則 input_fn
的輸出應該是這些原始字串,且金鑰 ["cat", "dog"]
需要做為參數傳遞到估算器中 (請參閱下方的詳細資訊)。
為了處理字串標籤到整數的對應,您應該使用 TensorFlow Transform 來產生詞彙表。我們在下方的程式碼片段中示範了這一點
def _preprocessing_fn(inputs):
"""Preprocess input features into transformed features."""
...
education = inputs[features.RAW_LABEL_KEY]
_ = tft.vocabulary(education, vocab_filename=features.RAW_LABEL_KEY)
...
上方的預先處理函式會採用原始輸入特徵 (也會做為預先處理函式的輸出部分傳回),並對其呼叫 tft.vocabulary
。這會導致為 education
產生可在模型中存取的詞彙表。
範例也示範如何轉換標籤,然後為轉換後的標籤產生詞彙表。特別是,它採用原始標籤 education
,並將頻率排名前 5 名以外的所有標籤轉換為 UNKNOWN
,而不會將標籤轉換為整數。
在模型程式碼中,分類器必須取得 tft.vocabulary
產生的詞彙表做為 label_vocabulary
引數。這會先藉由使用輔助函式將此詞彙表讀取為清單來完成。下方片段中顯示了這一點。請注意,範例程式碼使用上方討論的轉換後標籤,但這裡我們顯示使用原始標籤的程式碼。
def create_estimator(pipeline_inputs, hparams):
...
tf_transform_output = trainer_util.TFTransformOutput(
pipeline_inputs.transform_dir)
# vocabulary_by_name() returns a Python list.
label_vocabulary = tf_transform_output.vocabulary_by_name(
features.RAW_LABEL_KEY)
return tf.contrib.learn.DNNLinearCombinedClassifier(
...
n_classes=len(label_vocab),
label_vocabulary=label_vocab,
...)
設定轉換前和轉換後統計資料
如上方所述,Transform 元件會叫用 TFDV 來運算轉換前和轉換後統計資料。TFDV 採用選用的 StatsOptions 物件做為輸入。使用者可能希望設定這個物件,以啟用某些額外的統計資料 (例如 NLP 統計資料) 或設定要驗證的門檻 (例如最小/最大符記頻率)。若要這麼做,請在模組檔案中定義 stats_options_updater_fn
。
def stats_options_updater_fn(stats_type, stats_options):
...
if stats_type == stats_options_util.StatsType.PRE_TRANSFORM:
# Update stats_options to modify pre-transform statistics computation.
# Most constraints are specified in the schema which can be accessed
# via stats_options.schema.
if stats_type == stats_options_util.StatsType.POST_TRANSFORM
# Update stats_options to modify post-transform statistics computation.
# Most constraints are specified in the schema which can be accessed
# via stats_options.schema.
return stats_options
轉換後統計資料通常受益於瞭解用於預先處理特徵的詞彙表。詞彙表名稱到路徑的對應會針對每個 TFT 產生的詞彙表提供給 StatsOptions (以及 TFDV)。此外,可以使用下列任一種方法新增外部建立詞彙表的對應:(i) 直接修改 StatsOptions 內的 vocab_paths
字典,或 (ii) 使用 tft.annotate_asset
。