설명의 입력 및 출력 이해

설명을 요청하기 전에 설명 메타데이터 파일을 제출하여 설명 요청을 구성해야 합니다. 이 메타데이터 파일에는 모델의 입력과 출력이 포함되어야 합니다. 또한 이미지 데이터의 입력 기준 및 시각화 설정과 같은 선택적 설정도 포함됩니다.

모델의 입력과 출력을 지정하면 모델을 변경하지 않고도 설명 요청에 원하는 특성을 선택할 수 있습니다. 새 모델을 빌드할 때 Explainable AI SDK를 사용하여 이 작업을 자동으로 수행할 수 있습니다. Explainable AI SDK를 사용하지 않는 경우 입력 및 출력을 수동으로 식별해야 합니다.

이 가이드에서는 설명 메타데이터 파일을 준비하는 데 도움이 되도록 입력 및 출력 텐서를 수동으로 식별하는 방법을 주로 설명합니다.

설명 메타데이터의 입력 및 출력

설명 메타데이터를 준비하려면 explanation_metadata.json 파일에 모델의 입력과 출력을 지정해야 합니다.

{
  "inputs": {
    string <input feature key>: {
      "input_tensor_name": string,
  },
  "outputs": {
    string <output value key>:  {
      "output_tensor_name": string
    },
  },
  "framework": "tensorflow"
}

파일의 inputsoutputs 객체에서 설명 요청에 입력 및 출력 텐서의 이름을 제공해야 합니다.

  • 각 입력 및 출력의 키(앞의 예시에서 '입력 특성 키'와 '출력 값 키')를 통해 각 텐서에 의미 있는 이름을 지정할 수 있습니다. 아래 샘플에서 입력 특성 키는 degrees_celsius이며, 출력 값 키는 probabilities입니다.
  • 각 메타데이터 inputoutput의 값에서 텐서의 실제 이름을 input_tensor_name 또는 output_tensor_name으로 제공해야 합니다. 아래 샘플에서 input_tensor_namex:0이고 output_tensor_namedense/Softmax:0입니다.
{
    "inputs": {
      "degrees_celsius": {
        "input_tensor_name": "x:0",
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
}

실제 텐서 이름은 name:index 형식입니다.

입력 및 출력 텐서 찾기

TensorFlow 모델을 학습시킨 후 저장된 모델로 내보냅니다. TensorFlow 저장된 모델에는 학습된 TensorFlow 모델과 함께 그래프를 실행하는 데 필요한 직렬화된 서명, 변수, 기타 애셋이 포함되어 있습니다. 각 SignatureDef는 그래프에서 텐서 입력을 허용하고 텐서 출력을 생성하는 함수를 식별합니다. 마찬가지로 설명 메타데이터 파일은 AI Explanations에 특성 기여 분석 요청을 하는 데 사용할 그래프의 입력과 출력을 정의합니다.

설명 메타데이터 파일에 지정하는 입력 및 출력 텐서는 모델을 저장할 때 정의한 서명과 정확히 일치하는 경우가 많습니다. 이런 경우에는 입력 및 출력 텐서 이름을 더욱 쉽게 찾을 수 있습니다. 하지만 경우에 따라 설명하려는 입력 또는 출력이 모델을 저장할 때 정의한 입력 또는 출력과 다를 수도 있습니다.

설명의 입력과 출력은 다음의 경우 SignatureDef 제공 시 설정한 입력과 출력과 동일합니다.

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

위의 경우 모델을 빌드할 때 입력 및 출력 텐서의 이름을 가져올 수 있습니다. 또는 저장된 모델 CLI를 사용하여 저장된 모델의 SignatureDef를 검사하여 입력 및 출력 텐서의 이름을 찾을 수도 있습니다.

앞의 기준에 맞지 않는 경우에는 다른 방법으로 올바른 입력 및 출력 텐서를 찾을 수 있습니다.

학습 중에 텐서 이름 가져오기

학습 중에 입력 및 출력 텐서 이름에 액세스하는 것이 가장 쉬운 방법입니다. 모델을 빌드할 때 설정한 변수를 프로그램 또는 환경에서 계속 액세스할 수 있는 경우 이들 값을 설명 메타데이터 파일에 저장할 수 있습니다. 다음 예시에서 Keras 레이어의 name 필드는 설명 메타데이터에 필요한 기본 텐서 이름을 생성합니다.

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 = keras.Model(inputs=bow_inputs, outputs=predictions)
print('input_tensor_name:', bow_inputs.name)
print('output_tensor_name:', predictions.name)
input_tensor_name: input_1:0
output_tensor_name: dense_1/Sigmoid:0

전체 예시를 보려면 예시 메모장을 참조하세요.

서명 정의에서 텐서 이름 가져오기

SignatureDef와 설명 메타데이터 모두 텐서 입력 및 출력을 식별한다고 가정하면 SignatureDef를 사용하여 설명 메타데이터 파일을 준비할 수 있습니다(단, 앞에서 언급된 기준을 충족하는 경우).

다음 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라는 출력 텐서가 있습니다. 두 텐서에는 각각 my_numpy_inputprobabilities라는 의미 있는 이름이 있습니다. my_numpy_input 관련 probabilities에 대한 설명을 요청하려면 다음과 같이 설명 메타데이터 파일을 만들면 됩니다.

{
    "inputs": {
      "my_numpy_input": {
        "input_tensor_name": "x:0",
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
}

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

입력 및 출력 불일치 처리

설명 메타데이터의 입력 및 출력 텐서가 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 모델에서는 이러한 상황이 발생하지 않습니다. 하지만 발생할 경우 텐서보드 또는 기타 그래프 시각화 도구를 사용하여 올바른 출력 텐서 이름을 찾을 수 있습니다.

통합된 경사에 대한 추가 고려사항

AI Explanations에서는 샘플링된 Shapley와 통합된 경사 등 두 가지 특성 기여 분석 방법을 제공합니다. 통합된 경사 방법을 사용하려면 출력을 기준으로 입력을 미분할 수 있어야 하므로 설명 메타데이터를 준비할 때 이 점을 염두에 둬야 합니다. 샘플링된 Shapley 특성 기여 분석 방법을 사용할 경우에는 입력을 미분할 필요가 없습니다. AI Explanations에서 지원되는 특성 기여 분석 방법에 대해 자세히 알아보세요.

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

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

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

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

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

설명 요청에서 두 입력 텐서의 데이터를 사용하려면 메타데이터 inputs를 다음과 같이 설정합니다.

  • 입력 특성 키를 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"
      }
    },
  "framework": "tensorflow"
}

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

인코딩

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

인코딩 특성은 기여 분석에 필요한 프로세스를 인코딩된 데이터에서 입력 데이터로 되돌리는 데 유용하므로 반환된 기여 분석 결과를 수동으로 후처리할 필요가 없습니다. 현재 AI Explanations에서는 combined_embedding을 지원하며 가변 길이 특성은 삽입에 결합됩니다. 이 combined_embedding과 일치하는 예시 작업은 tf.nn.embedding_lookup_sparse입니다.

combined_embedding의 경우:

입력 텐서가 1D 배열로 인코딩됩니다. 예를 들면 다음과 같습니다.

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

다음 단계