Mini-ImageNet / src /collection /download_dataset_hf.py
ImAMJayKIM's picture
Upload 96 files
c1596ac verified
Raw
History Blame Contribute Delete
7.58 kB
import os
import re
import glob
from dotenv import load_dotenv
from datasets import load_dataset
from PIL import Image
# =====================================================================
# [μ„€μ • λΆ€λΆ„]
# =====================================================================
# 토큰
load_dotenv()
HF_TOKEN = os.environ.get("HF_TOKEN")
print(f"이거 토큰 : {HF_TOKEN}")
# μˆ˜μ§‘ν•  데이터셋
DATASET_NAME = "KrushiJethe/fashion_data"
# 데이터셋 λ‚΄μ˜ 이미지 데이터가 μžˆλŠ” ν•„λ“œλͺ…
IMAGE_FIELD_NAME = "image"
# 데이터셋 λ‚΄μ˜ 라벨 데이터가 μžˆλŠ” ν•„λ“œλͺ…
LABEL_FIELD_NAME = "articleType"
# μ—¬λŸ¬ 라벨을 ν•˜λ‚˜μ˜ λŒ€ν‘œ 클래슀둜 λ¬ΆλŠ” λ§€ν•‘ λ”•μ…”λ„ˆλ¦¬
CLASS_MAPPING = {
"t-shirt": ["Tshirts", "Tops"],
"sneakers":["Casual Shoes"],
#"umbrella":["Umbrellas"],
"glasses":["Sunglasses"],
"pants":["Jeans"],
}
# ν΄λž˜μŠ€λ³„λ‘œ μˆ˜μ§‘ν•  μ΄λ―Έμ§€μ˜ μ΅œλŒ€ 개수
NUM_IMAGES_PER_CLASS = 100
# μ €μž₯ν•  μ΄λ―Έμ§€μ˜ 해상도 (width, height)
TARGET_RESOLUTION = 256
# 이미지λ₯Ό μ €μž₯ν•  μ΅œμƒμœ„ 디렉토리λͺ…
BASE_SAVE_DIR = "./dataset_output"
# μˆ˜μ§‘ν•  λ°μ΄ν„°μ…‹μ˜ split 이름 (예: "train", "validation", "test")
SPLIT_NAME = "train"
# μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‹€ν–‰ν•œ μƒνƒœμ—μ„œλŠ” μ»¨ν…Œμ΄λ„ˆμ— μΊμ‹œ μ €μž₯됨
# μΊμ‹œ 확인 -> ls -lah ~/.cache/huggingface
# μΊμ‹œ μ‚­μ œ -> rm -rf ~/.cache/huggingface
USE_STREAMING = False
# =====================================================================
# 클래슀 λͺ…λͺ… κ·œμΉ™ 적용
def format_class_name(class_name: str) -> str:
"""
클래슀λͺ…은 μ†Œλ¬Έμžλ‘œ ν•˜κ³  띄어쓰기가 μžˆμ„ 경우 "-"둜 λŒ€μ²΄
"""
return str(class_name).lower().replace("_", "-").replace(" ", "-")
# λ§ˆμ§€λ§‰ μ΄λ―Έμ§€μ˜ 번호 + 1
def get_next_image_index(save_dir: str, formatted_class_name: str) -> int:
"""
이미지λ₯Ό μ—¬λŸ¬ μ°¨λ‘€ μ΄μ–΄μ„œ μˆ˜μ§‘ν•  수 μžˆλ„λ‘ λ§ˆμ§€λ§‰ 이미지 번호λ₯Ό 탐색
디렉토리λ₯Ό μŠ€μΊ”ν•˜μ—¬ κ°€μž₯ 높은 번호λ₯Ό 찾은 λ’€ +1을 λ°˜ν™˜
"""
if not os.path.exists(save_dir):
return 1
# jpg와 jpeg ν™•μž₯자 λͺ¨λ‘ 검색
search_pattern_jpg = os.path.join(save_dir, f"hf_{formatted_class_name}_*.jpg")
search_pattern_jpeg = os.path.join(save_dir, f"hf_{formatted_class_name}_*.jpeg")
existing_files = glob.glob(search_pattern_jpg) + glob.glob(search_pattern_jpeg)
max_idx = 0
# 파일λͺ…μ—μ„œ μ •κ·œν‘œν˜„μ‹μ„ 톡해 번호 μΆ”μΆœ (예: hf_fried-chicken_001.jpg -> 1)
regex = re.compile(rf"hf_{formatted_class_name}_(\d+)\.jpe?g$")
for file_path in existing_files:
basename = os.path.basename(file_path)
match = regex.match(basename)
if match:
idx = int(match.group(1))
if idx > max_idx:
max_idx = idx
return max_idx + 1
def collect_hf_images():
"""
메인 데이터 μˆ˜μ§‘ ν•¨μˆ˜.
Hugging Face λ°μ΄ν„°μ…‹μ—μ„œ 섀정을 λ°˜μ˜ν•˜μ—¬ 이미지λ₯Ό μˆ˜μ§‘ν•˜κ³  μ €μž₯
"""
label_to_rep_class = {}
for rep_class, labels in CLASS_MAPPING.items():
for label in labels:
label_to_rep_class[label] = rep_class
print(label_to_rep_class)
# 데이터셋별 λ‚±κ°œλ‘œ μˆ˜μ§‘
# streaming=True 속성을 μ‚¬μš©ν•˜λ©΄ 전체 데이터셋을 λ©”λͺ¨λ¦¬λ‚˜ λ””μŠ€ν¬μ— ν•œ λ²ˆμ— λ‹€μš΄λ‘œλ“œν•˜μ§€ μ•Šκ³ 
# generator ν˜•νƒœλ‘œ ν•˜λ‚˜μ”©(λ‚±κ°œλ‘œ) κ°€μ Έμ˜€λ―€λ‘œ λ©”λͺ¨λ¦¬μ™€ λ„€νŠΈμ›Œν¬ νš¨μœ¨μ„±μ΄ κ·ΉλŒ€ν™”
print(f"[{DATASET_NAME}] 데이터셋 슀트리밍 λ‘œλ“œ μ‹œμž‘...")
dataset = load_dataset(DATASET_NAME, split=SPLIT_NAME, streaming=USE_STREAMING, token=HF_TOKEN)
# 랜덀으둜 κ°€μ Έμ˜€κΈ°
# random_seed = random.randint(0, 10000)
# dataset = load_dataset(DATASET_NAME, split=SPLIT_NAME, streaming=USE_STREAMING).shuffle(seed=random_seed, buffer_size=1000)
# ν΄λž˜μŠ€λ³„λ‘œ ν¬λ§·νŒ…λœ 폴더λͺ…κ³Ό, ν˜„μž¬κΉŒμ§€ μˆ˜μ§‘λœ 개수, 그리고 μ €μž₯될 μ‹œμž‘ 번호λ₯Ό 관리할 λ”•μ…”λ„ˆλ¦¬
class_info = {}
for label in CLASS_MAPPING.keys():
formatted_name = format_class_name(label)
save_path = os.path.join(BASE_SAVE_DIR, formatted_name)
# [κ·œμΉ™ 1, 4] 클래슀λ₯Ό ν΄λ”λ‘œ κ΄€λ¦¬ν•˜λ©° 폴더λͺ…은 λ³€ν™˜λœ 클래슀λͺ…을 λ”°λ₯Έλ‹€.
os.makedirs(save_path, exist_ok=True)
# μ΄μ–΄μ„œ μˆ˜μ§‘ν•˜κΈ° μœ„ν•œ μ‹œμž‘ 인덱슀 탐색
start_idx = get_next_image_index(save_path, formatted_name)
class_info[label] = {
"formatted_name": formatted_name,
"save_path": save_path,
"collected_count": 0,
"current_idx": start_idx
}
print("데이터 μˆ˜μ§‘μ„ μ‹œμž‘ν•©λ‹ˆλ‹€...")
# 슀트리밍 데이터 순회
for item in dataset:
print("1. 데이터셋 λ‘œλ“œ μ‹œμž‘...")
# λͺ¨λ“  ν΄λž˜μŠ€κ°€ λͺ©ν‘œ μˆ˜μ§‘λŸ‰μ„ μ±„μ› λŠ”μ§€ 확인
if all(info["collected_count"] >= NUM_IMAGES_PER_CLASS for info in class_info.values()):
print("λͺ¨λ“  클래슀의 이미지 μˆ˜μ§‘μ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
break
print("2. 데이터셋 라벨 μ•„μ΄ν…œ κΊΌλ‚΄κΈ°...")
current_label = item.get(LABEL_FIELD_NAME)
print(current_label)
# ν˜„μž¬ λ½‘νžŒ 라벨이 μ •μ˜ν•œ λ§€ν•‘ λ”•μ…”λ„ˆλ¦¬μ— μ‘΄μž¬ν•˜λŠ”μ§€ 확인
if current_label in label_to_rep_class:
rep_class = label_to_rep_class[current_label]
target_info = class_info[rep_class]
print("4. 이미지 μœ νš¨μ„± 검사...")
# 이미 λͺ©ν‘œ 개수λ₯Ό μ±„μš΄ 클래슀라면 μŠ€ν‚΅
if target_info["collected_count"] >= NUM_IMAGES_PER_CLASS:
continue
# 이미지 μœ νš¨μ„± 체크
image = item.get(IMAGE_FIELD_NAME)
if image is None:
continue
print("5. 이미지 λ³€ν™˜...")
try:
# 이미지λ₯Ό jpg/jpeg둜만 μ·¨κΈ‰ν•˜κΈ° μœ„ν•΄ RGB λͺ¨λ“œλ‘œ λ³€ν™˜ (μ•ŒνŒŒ 채널 λ“± 제거)
if image.mode != "RGB":
image = image.convert("RGB")
#이미지 해상도가 μ΅œμ†Œ 256px만 μˆ˜μ§‘
if image.width < TARGET_RESOLUTION or image.height < TARGET_RESOLUTION:
continue
print("6. 클래슀 λͺ…λͺ… κ·œμΉ™μ— 따라...")
# [κ·œμΉ™ 3, 4] 이미지 λͺ…λͺ… κ·œμΉ™ (hf_[클래슀λͺ…]_[3자리숫자].jpg)
# {:03d}λ₯Ό 톡해 3자리 숫자둜 λ§žμΆ”κ³  λΉˆμžλ¦¬λŠ” 0으둜 채움
file_name = f"hf_{target_info['formatted_name']}_{target_info['current_idx']:03d}.jpg"
file_path = os.path.join(target_info["save_path"], file_name)
print("7. 이미지 μ €μž₯...")
image.save(file_path, "JPEG", quality=95)
# 카운트 및 인덱슀 증가
target_info["collected_count"] += 1
target_info["current_idx"] += 1
print(f"Saved: {file_path} ({target_info['collected_count']}/{NUM_IMAGES_PER_CLASS})")
except Exception as e:
# 였λ₯˜ λ°œμƒ μ‹œ μŠ€ν¬λ¦½νŠΈκ°€ λ©ˆμΆ”μ§€ μ•Šλ„λ‘ μ˜ˆμ™Έ 처리
print(f"이미지 μ €μž₯ 쀑 였λ₯˜ λ°œμƒ (Label: {current_label}): {e}")
if __name__ == "__main__":
collect_hf_images()