Vertex Explainable AI에서 TensorFlow 사용

커스텀 학습 TensorFlow 모델을 사용할 때는 모델을 저장하고 설명을 구성하는 데 필요한 특정 정보가 있습니다.

AutoML 테이블 형식 모델에서 Vertex Explainable AI를 사용하려는 경우에는 구성을 수행할 필요가 없습니다. Vertex AI는 Vertex Explainable AI용 모델을 자동으로 구성합니다. 이 문서를 건너뛰고 설명 받기를 읽어보세요.

이 가이드는 Vertex Explainable AI에서 사용할 수 있도록 TensorFlow 모델을 학습시킬 때 필요한 정보를 제공합니다. 구체적으로 다음과 같은 주제를 다룹니다.

  • Vertex Explainable AI의 Model 리소스를 구성할 때 지정해야 하는 학습 중 입력 및 출력 텐서 이름 찾기. 여기에는 일반적인 Vertex Explainable AI 텐서가 작동하지 않는 특수한 경우, Vertex Explainable AI에 적합한 텐서를 만들고 찾는 방법이 포함됩니다.

  • TensorFlow 모델을 Vertex Explainable AI와 호환되는 TensorFlow SavedModel로 내보내기

  • 이미 내보낸 TensorFlow SavedModel에서 입력 및 출력 텐서 이름 찾기. 모델의 학습 코드에 액세스할 수 없는 경우에 유용할 수 있습니다.

학습 중에 입력 및 출력 텐서 이름 찾기

TensorFlow 사전 빌드 컨테이너를 사용하여 예측을 제공하는 경우 모델의 입력 텐서와 출력 텐서의 이름을 알아야 합니다. Vertex Explainable AI의 Model을 구성할 때 이 이름을 ExplanationMetadata 메시지의 일부로 지정합니다.

TensorFlow 모델이 다음 기준을 충족하면 다음 섹션에서 설명하는 '기본 방법'을 사용하여 학습 중에 이러한 텐서 이름을 결정할 수 있습니다.

  • 입력이 직렬화되지 않은 경우
  • 모델의 SignatureDef에 대한 각 입력에는 특성 값이 직접 포함됩니다(숫자 값 또는 문자열일 수 있음).
  • 출력이 숫자 데이터로 처리되는 숫자 값인 경우. 이때 범주형 데이터로 간주되는 클래스 ID는 제외됩니다.

모델이 이러한 기준을 충족하지 않는 경우 특수한 경우에 학습 코드 조정 및 텐서 이름 찾기 섹션을 참조하세요.

기본 메서드

학습 중에 모델의 입력 텐서와 출력 텐서의 name 속성을 출력합니다. 다음 예시에서 Keras 레이어의 name 필드는 ExplanationMetadata에 필요한 기본 텐서 이름을 생성합니다.

bow_inputs = tf.keras.layers.Input(shape=(2000,))
merged_layer = tf.keras.layers.Dense(256, activation="relu")(bow_inputs)
predictions = tf.keras.layers.Dense(10, activation="sigmoid")(merged_layer)
model = tf.keras.Model(inputs=bow_inputs, outputs=predictions)
print('input_tensor_name:', bow_inputs.name)
print('output_tensor_name:', predictions.name)

이 Python 코드를 실행하면 다음 출력이 출력됩니다.

input_tensor_name: input_1:0
output_tensor_name: dense_1/Sigmoid:0

그런 다음 설명에 Model을 구성할 때 input_1:0을 입력 텐서 이름으로, dense_1/Sigmod:0을 출력 텐서 이름으로 사용할 수 있습니다.

특수한 경우 학습 코드 조정 및 텐서 이름 찾기

일반적으로 ExplanationMetadata의 입력 및 출력 텐서가 SignatureDef의 입력 및 출력 텐서와 동일하지 않아야 합니다.

  • 입력이 직렬화된 경우
  • 그래프에 전처리 작업이 포함된 경우
  • 제공 출력이 확률, 로지트 또는 다른 유형의 부동 소수점 텐서가 아닌 경우

위의 경우 다른 방법으로 올바른 입력 및 출력 텐서를 찾아야 합니다. 전체적인 목표는 입력으로 설명하려는 특성 값과 관련된 텐서 그리고 로지트(활성화 전), 확률(활성화 후) 또는 기타 출력 표현과 관련된 텐서를 찾는 것입니다.

입력 텐서의 특수한 경우

직렬화된 입력을 사용하여 모델을 피드하거나 그래프에 전처리 작업이 포함된 경우 설명 메타데이터의 입력 값은 제공 SignatureDef의 입력 값과 다릅니다.

직렬화된 입력

TensorFlow 저장된 모델에서는 다음과 같은 여러 복잡한 입력을 허용할 수 있습니다.

  • 직렬화된 tf.Example 메시지
  • JSON 문자열
  • 인코딩된 Base64 문자열(이미지 데이터를 나타냄)

모델에서 이러한 직렬화된 입력을 허용하는 경우 이러한 텐서를 설명용 입력으로 직접 사용하면 작동하지 않거나 무의미한 결과가 생성될 수 있습니다. 대신 모델 내에서 특성 열에 피드되는 후속 입력 텐서를 찾는 것이 좋습니다.

모델을 내보낼 때 제공 입력 함수에서 파싱 함수를 호출하면 TensorFlow 그래프에 파싱 작업을 추가할 수 있습니다. 파싱 함수는 tf.io 모듈에 있습니다. 일반적으로 이러한 파싱 함수는 응답으로 텐서를 반환하며 이러한 텐서는 설명 메타데이터로 더 적합합니다.

예를 들어 모델을 내보낼 때 tf.parse_example()을 사용할 수 있습니다. 이 함수는 직렬화된 tf.Example 메시지를 가져와 특성 열에 피드되는 텐서 사전을 출력합니다. 이 출력을 사용하여 설명 메타데이터를 채울 수 있습니다. 이러한 출력 중 일부가 텐서 3개로 구성되고 이름이 지정된 튜플인 tf.SparseTensor이면 indices, values, dense_shape 텐서의 이름을 가져와 메타데이터의 해당 필드를 채워야 합니다.

다음 예시에서는 디코딩 작업 후 입력 텐서 이름을 가져오는 방법을 보여줍니다.

float_pixels = tf.map_fn(
    lambda img_string: tf.io.decode_image(
        img_string,
        channels=color_depth,
        dtype=tf.float32
    ),
    features,
    dtype=tf.float32,
    name='input_convert'
  )

print(float_pixels.name)
입력 전처리

모델 그래프에 전처리 작업이 일부 포함되어 있는 경우 전처리 단계 이후에 텐서에 대한 설명을 가져올 수 있습니다. 이 경우 tf.Tensor의 name 속성을 사용하여 이러한 텐서의 이름을 가져와 설명 메타데이터에 삽입할 수 있습니다.

item_one_hot = tf.one_hot(item_indices, depth,
    on_value=1.0, off_value=0.0,
    axis=-1, name="one_hot_items:0")
print(item_one_hot.name)

디코딩된 텐서 이름은 input_pixels:0입니다.

출력 텐서의 특수한 경우

대부분의 경우 제공 SignatureDef의 출력은 확률 또는 로지트입니다.

모델이 확률이지만 로지트 값을 대신 설명하려면 로지트에 해당하는 적절한 출력 텐서 이름을 찾아야 합니다.

제공 SignatureDef에 확률 또는 로지트가 아닌 출력이 있으면 학습 그래프의 확률 연산을 참조해야 합니다. Keras 모델에서는 이러한 상황이 발생하지 않습니다. 하지만 발생할 경우 텐서보드 또는 기타 그래프 시각화 도구를 사용하여 올바른 출력 텐서 이름을 찾을 수 있습니다.

통합 그래디언트에 대한 특별 고려사항

Vertex Explainable AI의 통합 그래디언트 특성 기여 분석 방법를 사용하려면 출력과 관련하여 입력을 미분할 수 있어야 합니다.

설명 메타데이터는 모델 특성을 입력에서 논리적으로 분리합니다. 출력 텐서를 기준으로 미분할 수 없는 입력 텐서와 함께 통합된 경사를 사용할 경우 특성의 인코딩된 (그리고 미분 가능한) 버전도 제공해야 합니다.

미분할 수 없는 입력 텐서가 있거나 그래프에 미분할 수 없는 작업이 있으면 다음 방법을 사용합니다.

  1. 미분할 수 없는 입력을 미분할 수 있는 입력으로 인코딩합니다.
  2. input_tensor_name을 미분할 수 없는 원래 입력 텐서의 이름으로 설정하고 encoded_tensor_name을 인코딩된 미분할 수 있는 버전의 이름으로 설정합니다.

인코딩이 포함된 설명 메타데이터 파일

예를 들어 입력 텐서가 zip_codes:0인 범주형 특성이 있는 모델을 살펴보겠습니다. 입력 데이터에 우편번호가 문자열로 포함되어 있으므로 입력 텐서 zip_codes:0를 미분할 수 없습니다. 하지만 모델에서 이 데이터를 전처리하여 우편번호를 원-핫 인코딩 표현으로 만든다면 전처리 후 입력 텐서를 미분할 수 있습니다. 원래 입력 텐서와 구분하도록 이름을 zip_codes_embedding:0으로 지정할 수 있습니다.

설명 요청에서 두 입력 텐서의 데이터를 사용하려면 설명에 Model을 구성할 때 ExplanationMetadata를 다음과 같이 설정합니다.

  • 입력 특성 키를 zip_codes와 같은 의미 있는 이름으로 설정합니다.
  • input_tensor_name을 원래 텐서의 이름인 zip_codes:0으로 설정합니다.
  • encoded_tensor_name을 원-핫 인코딩 후 텐서 이름인 zip_codes_embedding:0으로 설정합니다.
  • encodingCOMBINED_EMBEDDING로 설정합니다.
{
    "inputs": {
      "zip_codes": {
        "input_tensor_name": "zip_codes:0",
        "encoded_tensor_name": "zip_codes_embedding:0",
        "encoding": "COMBINED_EMBEDDING"
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    }
}

또는 input_tensor_name을 인코딩된 미분할 수 있는 입력 텐서의 이름으로 설정하고 미분할 수 없는 원래 텐서를 생략할 수 있습니다. 두 텐서를 제공할 때 이점은 원-핫 인코딩 표현이 아닌 개별 우편번호 값에 기여 분석을 수행할 수 있다는 점입니다. 이 예시에서는 원래 텐서(zip_codes:0)를 제외하고 input_tensor_namezip_codes_embedding:0으로 설정합니다. 이에 따른 특성 기여 분석은 추론하기 어려우므로 이 방식은 권장되지 않습니다.

인코딩

Model에 인코딩을 사용 설정하려면 앞의 예시와 같이 인코딩 설정을 지정합니다.

인코딩 특성은 기여 분석에 필요한 프로세스를 인코딩된 데이터에서 입력 데이터로 되돌리는 데 유용하므로 반환된 기여 분석 결과를 수동으로 후처리할 필요가 없습니다. Vertex Explainable AI가 지원하는 인코딩 목록을 참조하세요.

COMBINED_EMBEDDING 인코딩의 경우 입력 텐서는 1D 배열로 인코딩됩니다.

예를 들면 다음과 같습니다.

  • 입력: ["This", "is", "a", "test"]
  • 인코딩된 입력: [0.1, 0.2, 0.3, 0.4]

Vertex Explainable AI용 TensorFlow SavedModel 내보내기

TensorFlow 모델을 학습시킨 후 저장된 모델로 내보냅니다. TensorFlow 저장된 모델에는 학습된 TensorFlow 모델과 함께 그래프를 실행하는 데 필요한 직렬화된 서명, 변수, 기타 애셋이 포함되어 있습니다. SavedModel의 각 SignatureDef는 그래프에서 텐서 입력을 허용하고 텐서 출력을 생성하는 함수를 식별합니다.

SavedModel이 Vertex Explainable AI와 호환되도록 하려면 TensorFlow 2 또는 TensorFlow 1 중 무엇을 사용하는지에 따라 다음 섹션 중 하나의 안내를 따르세요.

TensorFlow 2

TensorFlow 2.x로 작업하는 경우 tf.saved_model.save를 사용하여 모델을 저장합니다. 모델을 저장할 때 입력 서명을 지정할 수 있습니다. 입력 서명이 1개 있는 경우 Vertex Explainable AI는 설명 요청에 기본 제공 함수를 사용합니다. 입력 서명이 두 개 이상인 경우 모델을 저장할 때 제공 기본 함수의 서명을 지정해야 합니다.

tf.saved_model.save(m, model_dir, signatures={
    'serving_default': serving_fn,
    'xai_model': model_fn # Required for XAI
    })

이 경우 Vertex Explainable AI는 설명 요청에 xai_model 키를 사용하여 저장한 모델 함수 서명을 사용합니다. 키에 정확한 문자열 xai_model를 사용합니다.

사전 처리 함수를 사용하는 경우 사전 처리 함수와 모델 함수의 서명도 지정해야 합니다. 정확한 문자열 xai_preprocessxai_model을 키로 사용해야 합니다.

tf.saved_model.save(m, model_dir, signatures={
    'serving_default': serving_fn,
    'xai_preprocess': preprocess_fn, # Required for XAI
    'xai_model': model_fn # Required for XAI
    })

이 경우 Vertex Explainable AI는 설명 요청에 사전 처리 함수와 모델 함수를 사용합니다. 사전 처리 함수의 출력이 모델 함수의 예상 입력과 일치하는지 확인합니다.

TensorFlow에서 제공 서명 지정에 대해 자세히 알아보세요.

TensorFlow 1.15

TensorFlow 1.15를 사용하는 경우 tf.saved_model.save를 사용하지 마세요. Vertex Explainable AI는 이 방법으로 저장된 TensorFlow 1 모델을 지원하지 않습니다.

Keras에서 모델을 빌드하고 학습시키려면 모델을 TensorFlow Estimator로 변환하고 저장된 모델로 내보내야 합니다. 이 섹션에서는 모델 저장에 중점을 둡니다.

Keras 모델을 빌드하고, 컴파일하고, 학습시킨 후 다음을 수행해야 합니다.

  • tf.keras.estimator.model_to_estimator를 사용하여 Keras 모델을 TensorFlow Estimator로 변환합니다.
  • tf.estimator.export.build_raw_serving_input_receiver_fn을 사용하여 서빙 입력 함수를 제공합니다.
  • tf.estimator.export_saved_model을 사용하여 모델을 저장된 모델로 내보냅니다.
# Build, compile, train, and evaluate your Keras model
model = tf.keras.Sequential(...)
model.compile(...)
model.fit(...)
model.predict(...)

## Convert your Keras model to an Estimator
keras_estimator = tf.keras.estimator.model_to_estimator(keras_model=model, model_dir='export')

## Define a serving input function appropriate for your model
def serving_input_receiver_fn():
  ...
  return tf.estimator.export.ServingInputReceiver(...)

## Export the SavedModel to Cloud Storage, using your serving input function
export_path = keras_estimator.export_saved_model(
  'gs://' + 'YOUR_BUCKET_NAME',
  serving_input_receiver_fn
).decode('utf-8')

print("Model exported to: ", export_path)

SavedModel의 SignatureDef에서 텐서 이름 가져오기

TensorFlow SavedModel의 SignatureDef이전 섹션에서 설명하는 '기본 방법'의 기준을 충족하는 경우, 이를 사용하여 설명 메타데이터를 준비할 수 있습니다. 모델을 만든 학습 코드에 액세스할 수 없는 경우에 유용할 수 있습니다.

저장된 모델 CLI를 사용하여 저장된 모델의 SignatureDef를 검사할 수 있습니다. 저장된 모델 CLI 사용 방법에 대해 자세히 알아보세요.

다음 SignatureDef 예시를 참조하세요.

The given SavedModel SignatureDef contains the following input(s):
  inputs['my_numpy_input'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: x:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['probabilities'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: dense/Softmax:0
Method name is: tensorflow/serving/predict

그래프에 x:0라는 입력 텐서와 dense/Softmax:0라는 출력 텐서가 있습니다. 설명에 Model을 구성할 때 ExplanationMetadata 메시지에서 x:0를 입력 텐서 이름으로, dense/Softmax:0를 출력 텐서 이름으로 사용합니다.

다음 단계