Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -62,45 +62,59 @@ if os.path.exists(weights_path):
|
|
| 62 |
else:
|
| 63 |
print(f"오류: {weights_path} 파일을 찾을 수 없습니다. 먼저 학습을 수행하세요.")
|
| 64 |
# 3. 예측 함수 정의
|
|
|
|
|
|
|
|
|
|
| 65 |
def classify_alphabet(sketchpad):
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
# 3-1. 이미지 데이터 추출 (Gradio의 Sketchpad는 dict 형태일 수 있음)
|
| 70 |
-
# 배경은 검은색(0), 글씨는 흰색(255)인 그레이스케일로 변환
|
| 71 |
-
img = sketchpad["composite"][:, :, 3] # Alpha 채널 사용
|
| 72 |
-
|
| 73 |
-
# 3-2. 전처리 (EMNIST 특유의 회전/반전 해결)
|
| 74 |
-
img = tf.convert_to_tensor(img, dtype=tf.float32)
|
| 75 |
-
img = tf.image.resize(tf.expand_dims(img, axis=-1), (28, 28))
|
| 76 |
-
|
| 77 |
-
# 중요: EMNIST는 이미지가 전치(transpose)되어 있음
|
| 78 |
-
# 사용자가 똑바로 쓴 글씨를 모델이 학습한 방향으로 돌려줍니다.
|
| 79 |
-
img = tf.image.transpose(img)
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
-
# 4. Gradio 인터페이스
|
| 96 |
interface = gr.Interface(
|
| 97 |
fn=classify_alphabet,
|
| 98 |
inputs=gr.Sketchpad(label="알파벳을 그려보세요 (A-Z)", type="numpy"),
|
| 99 |
outputs=gr.Label(num_top_classes=3, label="예측 결과"),
|
| 100 |
title="Dynamic Conv Alphabet Recognizer",
|
| 101 |
-
|
| 102 |
-
live=True # 실시간 인식 활성화
|
| 103 |
)
|
| 104 |
|
| 105 |
if __name__ == "__main__":
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
else:
|
| 63 |
print(f"오류: {weights_path} 파일을 찾을 수 없습니다. 먼저 학습을 수행하세요.")
|
| 64 |
# 3. 예측 함수 정의
|
| 65 |
+
|
| 66 |
+
# ... (상단 모델 정의 및 로드 부분은 동일)
|
| 67 |
+
|
| 68 |
def classify_alphabet(sketchpad):
|
| 69 |
+
# 수정: sketchpad가 None이거나 데이터가 없는 경우 처리
|
| 70 |
+
if sketchpad is None or (isinstance(sketchpad, dict) and sketchpad.get("composite") is None):
|
| 71 |
+
return {"상태": "글씨를 기다리는 중..."}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
+
try:
|
| 74 |
+
# 3-1. 이미지 데이터 추출
|
| 75 |
+
# Gradio 버전에 따라 구조가 다를 수 있으므로 안전하게 접근
|
| 76 |
+
img_data = sketchpad["composite"]
|
| 77 |
+
|
| 78 |
+
# 만약 이미지가 투명도가 없는 3채널이라면 흑백 전환, 4채널이면 Alpha 사용
|
| 79 |
+
if img_data.shape[-1] == 4:
|
| 80 |
+
img = img_data[:, :, 3] # Alpha 채널 (글씨 부분)
|
| 81 |
+
else:
|
| 82 |
+
img = tf.image.rgb_to_grayscale(img_data)[:, :, 0]
|
| 83 |
|
| 84 |
+
# 3-2. 전처리
|
| 85 |
+
img = tf.cast(img, tf.float32)
|
| 86 |
+
img = tf.image.resize(tf.expand_dims(img, axis=-1), (28, 28))
|
| 87 |
+
|
| 88 |
+
# EMNIST 데이터 방향에 맞게 전치(Transpose)
|
| 89 |
+
img = tf.image.transpose(img)
|
| 90 |
+
|
| 91 |
+
img = img / 255.0
|
| 92 |
+
img = tf.expand_dims(img, axis=0)
|
| 93 |
+
|
| 94 |
+
# 3-3. 추론
|
| 95 |
+
preds = model.predict(img, verbose=0)[0]
|
| 96 |
|
| 97 |
+
results = {}
|
| 98 |
+
for i in range(26):
|
| 99 |
+
char = chr(ord('A') + i)
|
| 100 |
+
results[char] = float(preds[i])
|
| 101 |
+
|
| 102 |
+
return results
|
| 103 |
+
except Exception as e:
|
| 104 |
+
return {"에러": str(e)}
|
| 105 |
|
| 106 |
+
# 4. Gradio 인터페이스 설정 수정
|
| 107 |
interface = gr.Interface(
|
| 108 |
fn=classify_alphabet,
|
| 109 |
inputs=gr.Sketchpad(label="알파벳을 그려보세요 (A-Z)", type="numpy"),
|
| 110 |
outputs=gr.Label(num_top_classes=3, label="예측 결과"),
|
| 111 |
title="Dynamic Conv Alphabet Recognizer",
|
| 112 |
+
live=True
|
|
|
|
| 113 |
)
|
| 114 |
|
| 115 |
if __name__ == "__main__":
|
| 116 |
+
# 수정: SSR 모드와 Hot Reload 관련 에러를 방지하기 위해 설정을 추가합니다.
|
| 117 |
+
interface.launch(
|
| 118 |
+
server_name="0.0.0.0",
|
| 119 |
+
ssr_mode=False # 로그에 나온 SSR 관련 이슈 방지
|
| 120 |
+
)
|