최초 작성일 : 2021.06.02
최종 작성일 : 2021.06.02
1. 개요 및 목표
ASL 알파벳은 American Sign Language의 약자로 손을 이용해 알파벳을 표현한 지화(指話)이다. 청각 장애가 있거나 소리를 들을 수 없는 경우 사용할 수 있다.
이 프로젝트에서 별다른 언급이 없을 경우 "지화"는 "ASL 알파벳"을 의미한다.
참고로 대한민국에도 한글 지화가 있다.
지화가 어느정도 글자 모양을 띄는 경우도 있으나 지화를 모르는 사람의 경우 대부분 손의 모양을 보고 글자를 유추하기 힘들다. 지화 영상을 입력받아 이를 글자로 바꿔준다면, 또 글자를 지화로 바꿔준다면 언어로 인한, 장애로 인한 장벽이 어느정도 허물어질 수 있지 않을까?
본 프로젝트의 아이디어는 이런 인사이트를 통해 얻게 되었다.
프로젝트의 목표는 크게 2가지로 나뉘어진다.
1) 지화를 인식하는 classification모델 train (accuracy 90% 이상)
2) train된 모델을 활용한 지화 번역 프로그램 개발
1편에서는 step1인 ASL 인식 모델 train을 진행한다.
2. 데이터 수집 및 분석
데이터는 kaggle의 데이터를 활용했다.
https://www.kaggle.com/grassknoted/asl-alphabet
ASL Alphabet
Image data set for alphabets in the American Sign Language
www.kaggle.com
데이터파일 구조
├ asl_alphabet_test
└ asl_alphabet_train
└ A ~ Z
데이터 구성
데이터 구분 | 종류 | 갯수 |
train | A ~ Z, space, del, nothing | 각 3,000개 |
test | - | 각 1개 |
모든 이미지데이터는 200x200px jpg파일이며, 조명과 거리에 따라 다르게 촬영되었다.
모든 class의 갯수가 동일하므로 편중을 걱정할 필요는 없어 보인다.
train데이터는 알파벳마다 이미지가 한장씩 있으며, 파일명으로 구분되어있다.
우선 파일명이 알파벳으로 되어 있기에 아래 표를 따라 파일명을 변경했다.
모델에 입력되는 데이터는 200x200크기를 유지했고, normalize를 수행했다.
trans = transforms.Compose(
[
transforms.Resize((200, 200)),
transforms.ToTensor(),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
]
)
3. 모델 train
모델 train을 진행하기 전 두 가지 방법을 고민했다.
- object detection을 이용해 화면의 손을 인식하고, 손 bounding box부분만 잘라내어 사용한다.
- 원본 이미지대로 사용한다.
당연히 1)의 방법이 훨씬 성능이 좋을 것이다. 하지만 object detection과 classification 두 개의 모델을 사용하기에 기기에 따른 속도저하 문제가 있을 것이며, annotation에 시간이 너무 많이 소비될 것이라 생각하여 2)의 방법으로 진행했다.
ResNet50을 이용하여 train을 진행했다.
모델은 pytorch에서 기본적으로 제공하기 때문에 마지막 fully connected layer만 추가해주면 된다.
loss는 다중 분류에 사용되는 CrossEntropyLoss를 사용했다.
optimizer는 Adam이 가장 보편적으로 사용되기에 Adam optimizer를 사용하였으며, learning rate는 0.001로 설정했다.
model = models.resnet50(**pretrained=**True)
last_node = model.fc.in_features
model.fc = nn.Linear(last_node, len(classes))
model = model.to(DEVICE)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), **lr=**0.001)
exp_lr_sheduler = lr_scheduler.StepLR(optimizer, **step_size=**5, **gamma=**0.1)
또한 매 epoch마다 weights를 저장하게 했다.
torch.save(
model.state_dict(), "./model/asl_resnet50_epoch" + str(epoch + 1) + ".pth"
)
epoch를 30으로 하고 train을 진행했다.
4. 결과
Device : cuda:0
Epoch : 30
====================
Data Ready
Total Data : 87000
Train Data : 60900
Test Data : 26100
====================
====================
epoch : 1
Training...
Loss : 0.156
Train Acc : 61.906 %
Evaluating...
Test Acc : 93.475 %
====================
epoch : 2
Training...
Loss : 0.010
Train Acc : 97.388 %
Evaluating...
Test Acc : 96.674 %
====================
(중략)
====================
epoch : 9
Training...
Loss : 0.001
Train Acc : 99.693 %
Evaluating...
Test Acc : 96.498 %
====================
epoch : 10
Training...
Loss : 0.001
Train Acc : 99.732 %
Evaluating...
Test Acc : 97.747 %
====================
train진행중 train, test의 accuracy가 높게 유지되었다. epoch가 많이 진행되지 않았음에도 불구하고 높은 성능을 가질 수 있었던 이유는 class별로 데이터가 많고, 구분이 쉬워서로 추청된다. 충분히 높은 성능을 보여주기에 train을 중지하였다.
성능을 확인하기 위해 10epoch의 weight를 이용하여 테스트를 진행했다.
모든 class를 맞춰 100% 맞추는 성능을 보여줬다.
모델 학습은 여기서 끝!...인줄 알았지만...
해당 모델이 train외의 일반적인 상황에서 잘 동작하는지 확인할 필요가 있다.
그래서 kaggle에서 또다른 asl이미지 데이터를 수집했다.
https://www.kaggle.com/danrasband/asl-alphabet-test
ASL Alphabet Test
ASL Alphabet Images with a variety of backgrounds for validating a model
www.kaggle.com
train data와 비슷한 포맷을 갖고 있으며 각 class마다 30개의 이미지 데이터가 존재한다.
이 데이터를 앞서 train된 weight에 통과시켜보았다. 그 결과,
Test data : 870
Acc : 35.287356321839084
해당 모델이 약 35%의 accuracy를 가졌다. 앞서 test데이터를 이용한 출력과 상반되는 결과이다. precision, recall등을 측정하기 전 먼서 accuracy를 높일 필요가 있다.
5. 개선방안
train 데이터를 다시한번 살펴보았다.
데이터의 양은 많으나, 모든 데이터가 동일한 환경(배경)에서 조명과 손의 위치만을 다르게 하여 촬영된 데이터다.
반면 test를 위해 새로 수집한 데이터를 보면...
데이터의 수는 적으나, 여러 종류의 배경에서 이미지가 촬영되었다.
결국 앞선 성능테스트에서 낮은 성능이 나온 것은 데이터의 다양성이 부족으로 추정된다. train데이터와 동일한 배경에서 촬영된 데이터는 높은 성능을 보였으나 그 외의 상황은 train이 되지 않았기에 성능이 급감한 것이다.
따라서 다양한 환경에서의 데이터를 이용하여 train을 진행할 필요가 있다고 판단했다.
6. 데이터셋 만들기
train데이터셋에 다양한 환경을 넣기 위해 kaggle에서 다른 asl데이터를 추가적으로 수집했다.
ASL Sign Language Alphabet Pictures [Minus J, Z]
Image data for training American Sign Language alphabet character recognition
www.kaggle.com
기존 train에 사용한 데이터의 약 20%와 이후 수집한 모든 데이터를 합쳐 데이터셋을 구성했다.
데이터 구성을 위해 파일을 일일히 옮기는것은 코드를 작성해서 사용했기에 그리 오랜 시간이 걸리지 않았다.
7. 다시 모델 train
epoch를 동일하게 30으로 하고 train을 진행했다.
그 결과
Device : cuda:0
Epoch : 30
====================
Data Ready
Total Data : 11023
Train Data : 7731
Test Data : 3292
====================
====================
epoch : 1
Training...
Loss : 0.398
Train Acc : 8.718 %
Evaluating...
Test Acc : 13.761 %
====================
epoch : 2
Training...
Loss : 0.322
Train Acc : 23.154 %
Evaluating...
Test Acc : 29.860 %
====================
(중략)
====================
epoch : 29
Training...
Loss : 0.002
Train Acc : 99.366 %
Evaluating...
Test Acc : 94.563 %
====================
epoch : 30
Training...
Loss : 0.006
Train Acc : 98.383 %
Evaluating...
Test Acc : 94.441 %
finish
train, test데이터 모두 95%정도의 accuracy를 가졌다.
8. 성능 테스트
새로 학습된 모델을 이용해 다시한번 성능테스트를 진행했다.
테스트는 맨 처음 수집한 데이터 중 사용하지 않은 데이터와 아래의 데이터를 사용했다.
https://www.kaggle.com/yashudaykulkarni/asl-alphabet-new-test
ASL Alphabet New Test
Real-Life Testing Data for ASL Letter Classification
www.kaggle.com
테스트 결과
Test data : 5539
Acc : 93.32009387976169
class별 precision과 recall도 계산해 보았다.
첫번째 숫자가 precision, 두번째 숫자가 recall이다.
A : 0.941 0.889
B : 0.979 0.950
C : 1.000 0.985
D : 1.000 0.975
E : 0.920 0.864
F : 1.000 0.990
G : 0.994 0.874
H : 0.883 0.990
I : 0.975 0.985
J : 0.980 0.980
K : 0.735 0.935
L : 1.000 0.980
M : 0.755 0.819
N : 0.791 0.799
O : 1.000 0.940
P : 0.995 0.985
Q : 0.975 0.985
R : 0.917 0.889
S : 0.792 0.955
T : 0.989 0.945
U : 0.892 0.915
V : 0.912 0.678
W : 0.980 0.980
X : 0.908 0.945
Y : 0.995 0.990
Z : 1.000 0.979
space : 1.000 0.972
del : 1.000 0.950
nothing : 0.939 0.986
precision이 비교적 낮은(0.8 이하) class : K, M, N, S
recall이 비교적 낮은(0.8이하) class : N, V
K, M, N, S, V의 수치가 낮은 이유는 이들의 모양이 비슷하기 때문으로 추청된다.
9. 중간결론
이번 프로젝트의 첫번째 목표인 asl알파벳 인식 모델 학습을 마쳤다.
resnet을 사용해보고 성능이 생각만큼 안나오면 다른 여러 모델도 활용해볼 계획이었는데 성능이 생각 이상으로 잘나와줬다.
다만 실사용을 할 때 어느정도의 속도가 나와줄지 확인이 필요할 것 같으며 상황에 따라 경량화가 필요할 수도 있을것 같다.
또한 실제 필드에서도 이런 성능을 낼 수 있을지도 확인해봐야 한다.
본 프로젝트의 목표는 "asl 번역기 제작"이므로 이제 train된 모델을 활용한 번역기 제작이 남아있다. 이는 다음편에서 계속 진행할 계획이다. 다만 시간을 쪼개가며 진행중이라 완성까지 얼마나 걸릴지 잘 모르겠다. 못해도 6월 중으론 완성할 계획이다.
<이미지 출처>
[그림 1] https://www.kaggle.com/signnteam/asl-sign-language-pictures-minus-j-z
[그림 2] https://welfare24.net:56715/ab-welfare_dic_v-11571?pc=m
[그림 3] 자체
[그림 4] https://www.kaggle.com/grassknoted/asl-alphabet
[그림 5] https://www.kaggle.com/grassknoted/asl-alphabet
[그림 6] 자체
[그림 7] 자체
[그림 8] 자체
[그림 9] https://www.kaggle.com/grassknoted/asl-alphabet
[그림 10] https://www.kaggle.com/grassknoted/asl-alphabet
[그림 11] 자체
[그림 12] 자체
'프로젝트' 카테고리의 다른 글
[아쿠쿠아] v1.4.0 출시! (4) | 2024.02.25 |
---|---|
ASL 알파벳 번역기 만들기 2편 (0) | 2021.06.27 |
평점기반 도서 추천 (1) | 2020.10.27 |
X-ray 사진을 이용한 폐렴 진단(CNN) (0) | 2020.10.06 |
CNN으로 남성, 여성 구분하기 (0) | 2020.10.03 |