메인 콘텐츠로 건너뛰기
wandb.Table을(를) 사용하여 W&B에서 시각화하고 쿼리할 데이터를 로깅하세요. 이 가이드에서는 다음을 다룹니다:
  1. 테이블 생성
  2. 데이터 추가
  3. 데이터 가져오기
  4. 테이블 저장

테이블 생성

Table을 정의하려면 각 데이터 행(row)에 대해 확인하려는 열(컬럼)을 지정하면 됩니다. 각 행에는 트레이닝 데이터셋의 단일 항목, 트레이닝 중 특정 스텝이나 에포크, 테스트 항목에 대해 모델이 만든 예측값, 모델이 생성한 객체 등이 들어갈 수 있습니다. 각 열은 숫자, 텍스트, 불리언, 이미지, 비디오, 오디오 등과 같이 고정된 타입을 가집니다. 타입을 미리 명시할 필요는 없습니다. 각 열에 이름을 지정하고, 해당 열 인덱스에는 그 타입에 해당하는 데이터만 전달해야 합니다. 더 자세한 예시는 W&B Tables guide를 참고하십시오. wandb.Table 생성자는 두 가지 방식 중 하나로 사용할 수 있습니다:
  1. 행(Row) 목록: 이름이 지정된 열과 데이터 행을 로깅합니다. 예를 들어, 다음 코드 스니펫은 두 개의 행과 세 개의 열을 가진 테이블을 생성합니다:
    wandb.Table(columns=["a", "b", "c"], data=[["1a", "1b", "1c"], ["2a", "2b", "2c"]])
    
  2. Pandas DataFrame: wandb.Table(dataframe=my_df)를 사용해 DataFrame을 로깅합니다. 열 이름은 DataFrame에서 자동으로 추출됩니다.

기존 배열이나 데이터프레임에서

# 모델이 네 개의 이미지에 대한 예측을 반환했다고 가정합니다.
# 다음 필드를 사용할 수 있습니다:
# - 이미지 id
# - wandb.Image()로 래핑된 이미지 픽셀
# - 모델의 예측 레이블
# - 실제 정답 레이블
my_data = [
    [0, wandb.Image("img_0.jpg"), 0, 0],
    [1, wandb.Image("img_1.jpg"), 8, 0],
    [2, wandb.Image("img_2.jpg"), 7, 1],
    [3, wandb.Image("img_3.jpg"), 1, 1],
]

# 해당 열로 wandb.Table()을 생성합니다
columns = ["id", "image", "prediction", "truth"]
test_table = wandb.Table(data=my_data, columns=columns)

데이터 추가

테이블은 변경 가능합니다. 스크립트를 실행하는 동안 최대 200,000개의 행까지 테이블에 더 많은 데이터를 추가할 수 있습니다. 테이블에 데이터를 추가하는 방법은 두 가지입니다:
  1. 행 추가: table.add_data("3a", "3b", "3c"). 새 행은 리스트로 표현되지 않는다는 점에 유의하세요. 행이 리스트 형식이라면, 리스트를 위치 인자로 펼치기 위해 별표 표기법 *를 사용하세요: table.add_data(*my_row_list). 행에는 테이블의 열 개수와 동일한 수의 항목이 포함되어야 합니다.
  2. 열 추가: table.add_column(name="col_name", data=col_data). col_data의 길이는 테이블의 현재 행 수와 같아야 한다는 점에 유의하세요. 여기서 col_data는 리스트이거나 NumPy NDArray가 될 수 있습니다.

데이터를 점진적으로 추가하기

이 코드 예제는 W&B 테이블을 점진적으로 생성하고 채우는 방법을 보여줍니다. 가능한 모든 레이블에 대한 신뢰도 점수(confidence score)를 포함한 미리 정의된 열로 테이블을 정의한 다음, 추론(inference) 중에 행 단위로 데이터를 추가합니다. 또한 run을 다시 시작(resume)할 때 테이블에 데이터를 점진적으로 추가할 수도 있습니다.
# 테이블의 열을 정의합니다. 각 레이블에 대한 신뢰도 점수를 포함합니다
columns = ["id", "image", "guess", "truth"]
for digit in range(10):  # 각 숫자(0-9)에 대한 신뢰도 점수 열을 추가합니다
    columns.append(f"score_{digit}")

# 정의된 열로 테이블을 초기화합니다
test_table = wandb.Table(columns=columns)

# 테스트 데이터셋을 순회하며 테이블에 행 단위로 데이터를 추가합니다
# 각 행에는 이미지 ID, 이미지, 예측 레이블, 실제 레이블, 신뢰도 점수가 포함됩니다
for img_id, img in enumerate(mnist_test_data):
    true_label = mnist_test_data_labels[img_id]  # 실제 정답 레이블
    guess_label = my_model.predict(img)  # 예측 레이블
    test_table.add_data(
        img_id, wandb.Image(img), guess_label, true_label
    )  # 테이블에 행 데이터를 추가합니다

재개한 run에 데이터 추가하기

아티팩트에서 기존 테이블을 로드한 뒤 마지막 행의 데이터를 가져와 업데이트된 메트릭을 추가하면, 재개한 run에서 W&B 테이블을 순차적으로 업데이트할 수 있습니다. 그런 다음 호환성을 위해 테이블을 재초기화하고, 업데이트된 버전을 W&B에 다시 로그합니다.
import wandb

# run 초기화 
with wandb.init(project="my_project") as run:

    # 아티팩트에서 기존 테이블 로드
    best_checkpt_table = run.use_artifact(table_tag).get(table_name)

    # 재개를 위해 테이블의 마지막 행 데이터 가져오기
    best_iter, best_metric_max, best_metric_min = best_checkpt_table.data[-1]

    # 필요에 따라 최적 메트릭 업데이트

    # 업데이트된 데이터를 테이블에 추가
    best_checkpt_table.add_data(best_iter, best_metric_max, best_metric_min)

    # 호환성 확보를 위해 업데이트된 데이터로 테이블 재초기화
    best_checkpt_table = wandb.Table(
        columns=["col1", "col2", "col3"], data=best_checkpt_table.data
    )

    # Run 초기화
    with wandb.init() as run:

        # 업데이트된 테이블을 W&B에 로그
        run.log({table_name: best_checkpt_table})

데이터 가져오기

데이터가 Table 안에 들어가면 열 또는 행 단위로 접근할 수 있습니다:
  1. Row Iterator: 사용자는 for ndx, row in table.iterrows(): ... 와 같이 Table의 row iterator를 사용해 데이터의 각 행을 효율적으로 순회할 수 있습니다.
  2. 열 가져오기 (Get a Column): 사용자는 table.get_column("col_name") 을 사용해 특정 열의 데이터를 가져올 수 있습니다. 편의상 convert_to="numpy" 를 전달하여 해당 열을 NumPy 기본 자료형 NDArray로 변환할 수 있습니다. 이는 열에 wandb.Image 와 같은 미디어 타입이 들어 있어 그 내부 데이터를 직접 액세스해야 할 때 유용합니다.

테이블 저장

스크립트에서 데이터 테이블(예: 모델 예측값 테이블)을 생성한 후, 결과를 실시간으로 시각화할 수 있도록 테이블을 W&B에 저장합니다.

run에 테이블 기록하기

wandb.Run.log()을 사용해 다음과 같이 테이블을 run에 기록합니다:
with wandb.init() as run:
    my_table = wandb.Table(columns=["a", "b"], data=[["1a", "1b"], ["2a", "2b"]])
    run.log({"table_key": my_table})
같은 키에 테이블을 로깅할 때마다 테이블의 새로운 버전이 생성되어 백엔드에 저장됩니다. 이렇게 하면 동일한 테이블을 여러 트레이닝 스텝에 걸쳐 로깅하여 시간이 지남에 따라 모델 예측이 어떻게 개선되는지 확인하거나, 동일한 키로 로깅하는 한 서로 다른 run 간에 테이블을 비교할 수 있습니다. 최대 200,000개 행까지 로깅할 수 있습니다.
200,000개 행보다 더 많이 로깅하려면 다음과 같이 제한을 재정의할 수 있습니다:wandb.Table.MAX_ARTIFACT_ROWS = X그러나 이렇게 하면 UI에서 쿼리가 느려지는 등 성능 문제가 발생할 수 있습니다.

프로그래밍 방식으로 테이블에 액세스하기

백엔드에서는 Tables가 Artifacts 형태로 저장됩니다. 특정 버전에 액세스하려면 아티팩트 API를 사용할 수 있습니다:
with wandb.init() as run:
    my_table = run.use_artifact("run-<run-id>-<table-name>:<tag>").get("<table-name>")
Artifacts에 대한 자세한 내용은 Developer Guide의 Artifacts 장을 참조하세요.

테이블 시각화

이 방식으로 로깅한 모든 테이블은 Workspace의 Run 페이지와 Project 페이지에 표시됩니다. 자세한 내용은 테이블 시각화 및 분석을 참고하세요.

아티팩트 테이블

artifact.add()를 사용하여 테이블을 워크스페이스 대신 run의 Artifacts 섹션에 로깅하세요. 이는 데이터셋을 한 번만 로깅해 두고 이후 run에서 계속 참조하려는 경우에 유용합니다.
with wandb.init(project="my_project") as run:
    # 각 의미 있는 단계마다 wandb Artifact 생성
    test_predictions = wandb.Artifact("mnist_test_preds", type="predictions")

    # [위와 같이 예측 데이터를 구성합니다]
    test_table = wandb.Table(data=data, columns=columns)
    test_predictions.add(test_table, "my_test_key")
    run.log_artifact(test_predictions)
이미지 데이터와 함께 artifact.add()를 사용하는 자세한 예시는 이 Colab을 참고하고, Artifacts와 Tables를 사용해 테이블 형태 데이터를 버전 관리하고 중복을 제거하는 방법의 예시는 이 Report를 참고하세요.

Artifact 테이블 조인하기

로컬에서 생성한 Table이나 다른 아티팩트에서 가져온 Table을 wandb.JoinedTable(table_1, table_2, join_key)를 사용해 조인할 수 있습니다.
ArgsDescription
table_1(str, wandb.Table, ArtifactEntry) 아티팩트 안의 wandb.Table 경로, Table 객체, 또는 ArtifactEntry
table_2(str, wandb.Table, ArtifactEntry) 아티팩트 안의 wandb.Table 경로, Table 객체, 또는 ArtifactEntry
join_key(str, [str, str]) 조인에 사용할 키 또는 키 목록
아티팩트 컨텍스트에서 이전에 로깅한 두 개의 Table을 조인하려면, 먼저 아티팩트에서 해당 Table들을 가져온 뒤 조인 결과로 새로운 Table을 만듭니다. 예를 들어, 다음 코드 예제는 'original_songs'라는 이름의 원본 곡이 담긴 Table과, 같은 곡의 합성 버전이 담긴 또 다른 Table인 'synth_songs'를 읽는 방법을 보여 줍니다. 이 코드는 두 Table을 "song_id"로 조인한 뒤, 결과 Table을 새로운 W&B Table로 업로드합니다:
import wandb

with wandb.init(project="my_project") as run:

    # 원본 곡 테이블 가져오기
    orig_songs = run.use_artifact("original_songs:latest")
    orig_table = orig_songs.get("original_samples")

    # 합성 곡 테이블 가져오기
    synth_songs = run.use_artifact("synth_songs:latest")
    synth_table = synth_songs.get("synth_samples")

    # "song_id"를 기준으로 테이블 조인
    join_table = wandb.JoinedTable(orig_table, synth_table, "song_id")
    join_at = wandb.Artifact("synth_summary", "analysis")

    # 아티팩트에 테이블 추가 및 W&B에 로그 기록
    join_at.add(join_table, "synth_explore")
    run.log_artifact(join_at)
이 튜토리얼을 읽고, 서로 다른 Artifact 객체에 각각 저장된 두 개의 테이블을 결합하는 방법을 예제로 확인하세요.