

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 調整您的 TensorFlow 訓練指令碼
<a name="debugger-modify-script-tensorflow"></a>

若要開始收集模型輸出張量和針對訓練問題偵錯，請對 TensorFlow 訓練指令碼進行下列修改。

**為 SageMaker AI 中的訓練任務建立勾點**

```
import smdebug.tensorflow as smd

hook=smd.get_hook(hook_type="keras", create_if_not_exists=True)
```

這會在您啟動 SageMaker 訓練任務時建立勾點。當您在 [使用 SageMaker Python SDK 搭配 Debugger 啟動訓練任務](debugger-configuration-for-debugging.md) 於您的估算器中使用任何一個 `DebuggerHookConfig`、`TensorBoardConfig` 或 `Rules` 啟動訓練任務時，SageMaker AI 會將 JSON 組態檔案新增至您的訓練執行個體，該檔案將由 `smd.get_hook` 方法選取。請注意，如果您沒有在估算器中包含任何組態 API，就不會有要尋找勾點的組態檔案，且函式會傳回 `None`。

**(選用) 為 SageMaker AI 以外的訓練工作建立勾點**

如果您以本機模式執行訓練任務，請直接在 SageMaker 筆記本執行個體、Amazon EC2 執行個體或您自己的本機裝置上執行訓練任務，並使用 `smd.Hook` 類別建立勾點。不過，這種方法只能儲存張量集合，且僅可用於 TensorBoard 視覺化。SageMaker Debugger 的內建規則不適用於本機模式。在這種情況下，`smd.get_hook` 方法也會傳回 `None`。

如果您想要建立手動勾點，請使用下列程式碼片段與邏輯來檢查勾點是否傳回 `None`，並使用 `smd.Hook` 類別建立手動勾點。

```
import smdebug.tensorflow as smd

hook=smd.get_hook(hook_type="keras", create_if_not_exists=True) 

if hook is None:
    hook=smd.KerasHook(
        out_dir='/path/to/your/local/output/',
        export_tensorboard=True
    )
```

新增勾點建立程式碼之後，請繼續 TensorFlow Keras 的下列主題。

**注意**  
SageMaker Debugger 目前僅支援 TensorFlow Keras。

## 在您的 TensorFlow Keras 訓練指令碼中註冊勾點
<a name="debugger-modify-script-tensorflow-keras"></a>

以下程序將逐步引導您使用勾點及其方法，從模型和最佳化工具收集輸出純量與張量。

1. 利用勾點的類別方法包裝您的 Keras 模型和最佳化工具。

   `hook.register_model()` 方法採用您的模型並逐一查看每一層，尋找與您透過 [使用 SageMaker Python SDK 搭配 Debugger 啟動訓練任務](debugger-configuration-for-debugging.md) 組態提供的規則表達式所符合的任何張量。透過此勾點方法的可收式張量為加權、誤差和啟用。

   ```
   model=tf.keras.Model(...)
   hook.register_model(model)
   ```

1. 透過 `hook.wrap_optimizer()` 方法包裝最佳化工具。

   ```
   optimizer=tf.keras.optimizers.Adam(...)
   optimizer=hook.wrap_optimizer(optimizer)
   ```

1. 在 TensorFlow 中以嚴格模式編譯模型。

   若要從模型收集張量 (例如每層的輸入和輸出張量)，您必須以嚴格模式執行訓練。否則，SageMaker AI Debugger 將無法收集張量。不過，系統可以收集其他張量，例如模型加權、誤差和損失，而無須在嚴格模式中明確執行。

   ```
   model.compile(
       loss="categorical_crossentropy", 
       optimizer=optimizer, 
       metrics=["accuracy"],
       # Required for collecting tensors of each layer
       run_eagerly=True
   )
   ```

1. 將勾點註冊到 [https://www.tensorflow.org/api_docs/python/tf/keras/Model#fit](https://www.tensorflow.org/api_docs/python/tf/keras/Model#fit) 方法。

   若要從您註冊的勾點收集張量，請將 `callbacks=[hook]` 新增至 Keras `model.fit()` 類別方法。這會把 `sagemaker-debugger` 勾點作為 Keras 回呼來傳遞。

   ```
   model.fit(
       X_train, Y_train,
       batch_size=batch_size,
       epochs=epoch,
       validation_data=(X_valid, Y_valid),
       shuffle=True, 
       callbacks=[hook]
   )
   ```

1. TensorFlow 2.x 僅提供符號漸層變數，而這些變數不提供本身值的存取。如要收集漸層，請按照 [https://sagemaker-debugger.readthedocs.io/en/website/hook-methods.html#tensorflow-specific-hook-api](https://sagemaker-debugger.readthedocs.io/en/website/hook-methods.html#tensorflow-specific-hook-api) 方法包裝 `tf.GradientTape`，這需要您編寫自己的訓練步驟，如下所示。

   ```
   def training_step(model, dataset):
       with hook.wrap_tape(tf.GradientTape()) as tape:
           pred=model(data)
           loss_value=loss_fn(labels, pred)
       grads=tape.gradient(loss_value, model.trainable_variables)
       optimizer.apply_gradients(zip(grads, model.trainable_variables))
   ```

   透過包裝磁帶，`sagemaker-debugger` 勾點可以識別輸出張量，例如建層、參數和損失。包裝磁帶可確保圍繞磁帶物件函式的 `hook.wrap_tape()` 方法 (例如 `push_tape()`、`pop_tape()`、`gradient()`) 將設定 SageMaker Debugger 的寫入器，並儲存提供做為輸入 `gradient()` (可訓練的變數及損失) 和 `gradient()` (漸層) 輸出的張量。
**注意**  
如要透過自訂訓練循環進行收集，請務必使用嚴格模式。否則，SageMaker Debugger 無法收集任何張量。

如需 `sagemaker-debugger` 勾點 API 提供用來建構勾點和儲存張量的完整動作清單，請參閱 *`sagemaker-debugger`Python SDK 文件*中的[勾點方法](https://sagemaker-debugger.readthedocs.io/en/website/hook-methods.html)。

完成訓練指令碼的調整後，請繼續前往[使用 SageMaker Python SDK 搭配 Debugger 啟動訓練任務](debugger-configuration-for-debugging.md)。