예측 업로드하기
소개
이 예제에서는 API를 사용하여 이미 존재하는 데이터셋에 예측을 업로드하는 방법을 안내합니다.
단계
새 Python 파일을 만들고 다음 라이브러리를 임포트합니다.
import requests
from kognic.auth.requests.auth_session import RequestsAuthSession
base_url = "https://dataset.app.kognic.com/v1/"
client = RequestsAuthSession()1. 데이터셋의 UUID 가져오기
도구에 접속하여 URL에서 dataset/ 뒤에 오는 UUID를 복사하거나, 데이터셋 엔드포인트를 이용해 데이터셋의 uuid를 가져올 수 있습니다.
client.session.get("https://dataset.app.kognic.com/v2/datasets")2. 기존 예측 그룹의 UUID 가져오기 또는 새로 생성하기
2.a 기존 예측 그룹의 UUID 가져오기
예측을 업로드하려면 예측 그룹(prediction group)이 존재해야 합니다. 예측은 원하는 목적에 따라 그룹으로 구성할 수 있습니다. 기존 예측 그룹의 UUID는 URL에서 predictions/ 뒤에서 확인하거나 다음 엔드포인트를 사용하여 확인할 수 있습니다.
client.session.get(base_url + f"/datasets/{datasetUuid}/predictions-groups")2.b 예측 그룹 생성하기 (선택 사항)
세그멘테이션 작업을 포함하지 않는 데이터셋의 경우, 앱에서 클릭하거나(오른쪽 상단의 Manage Predictions를 클릭한 다음 + Create predictions group) 또는 다음 코드 스니펫을 사용하여 새 예측 그룹을 생성할 수 있습니다.
path = base_url + f"/datasets/{datasetUuid}/predictions-groups"
body = {"name": "My predictions group", "description": "A description of my new predictions group"}
try:
response = client.session.post(path, json=body)
response.raise_for_status()
response_json = response.json()
print(f"Created predictions group with uuid {response_json['data']}")
except requests.exceptions.RequestException as e:
msg = e.response.text
print(f"Request error: {e}. {msg}")특수한 경우: 세그멘테이션 데이터셋
세그멘테이션 데이터셋에 연결된 예측 그룹은 반드시 코드 스니펫을 사용하여 생성해야 하며, classMapping이라는 추가 파라미터도 필요합니다. 이 매핑은 예측과 어노테이션 간의 불일치를 계산할 때 사용되며, 정렬 방식과 갤러리에서 불일치가 표시되는 방식에도 영향을 줍니다. classMapping 파라미터는 딕셔너리 목록이며, 각 딕셔너리는 annotated와 predicted 키를 포함합니다. annotated 키는 어노테이션에서의 클래스 이름이고, predicted 키는 예측에서의 클래스 이름입니다. 예를 들어 여러 종류의 나무를 어노테이션했지만 나무인지 아닌지만 예측하는 경우 {"annotated": "oak", "predicted": "tree"}와 같이 사용합니다.
매핑이 필요하지 않더라도 예측과 어노테이션에 등장하는 모든 클래스 이름은 클래스 매핑에 포함되어야 합니다. 어노테이션에서 세그멘테이션되지 않은 영역은 클래스 이름 _background로 표시됩니다.
example_body = {
"name": "My predictions group",
"description": "A description of my new predictions group",
"classMapping": [
{"annotated": "oak", "predicted": "tree"},
{"annotated": "_background", "predicted": "not_tree"},
{"annotated": "only_in_annotations"}
]
}3. 예측 업로드하기
적은 양의 예측이라면 동기 호출(synchronous call)로 처리할 수 있습니다.
import requests
from kognic.auth.requests.auth_session import RequestsAuthSession
base_url = "https://dataset.app.kognic.com/v1/"
client = RequestsAuthSession()
predictions_group_uuid = "..."
openlabel_content = {"openlabel": ...}
data = {
"sceneUuid": "...",
"openlabelContent": openlabel_content,
}
try:
response = client.session.post(
base_url + f"predictions-groups/{predictions_group_uuid}/predictions",
json=data
)
response.raise_for_status()
response_json = response.json()
print(f"Created prediction with uuid {response_json['data']}")
except requests.exceptions.RequestException as e:
msg = e.response.text
print(f"Request error: {e}. {msg}")많은 양의 예측을 처리할 때는 비동기 호출을 사용하는 것이 좋습니다. 다음 예제는 kognic-auth 라이브러리의 비동기 클라이언트를 사용하여 100개의 비동기 호출을 수행합니다.
import asyncio
from kognic.auth.httpx.async_client import HttpxAuthAsyncClient
base_url = "https://dataset.app.kognic.com/v1/"
predictions_group_uuid = "..."
url = base_url + f"predictions-groups/{predictions_group_uuid}/predictions"
openlabel_content = {"openlabel": ...}
MAX_CONNECTIONS = 10
async def upload_prediction(payload, session, sem):
async with sem:
response = await session.post(url, json=payload)
response.raise_for_status()
return response.json().get("data")
async def main(n_runs: int):
client = HttpxAuthAsyncClient()
session = await client.session
sem = asyncio.Semaphore(MAX_CONNECTIONS)
tasks = []
for i in range(n_runs):
payload = {"sceneUuid": "...", "openlabelContent": openlabel_content}
task = upload_prediction(payload, session, sem)
tasks.append(task)
responses = await asyncio.gather(*tasks)
await session.aclose()
print(responses)
if __name__ == '__main__':
asyncio.run(main(100))MAX_CONNECTIONS를 10보다 크게 설정하면 제대로 작동하지 않을 수 있으므로 권장하지 않습니다.