이미지로 이미지 검색하기¶
- 튜토리얼 난이도: ★☆☆☆☆
- 읽는데 걸리는 시간: 7분
- 사용 언어: SQL (100%)
- 실행 파일 위치: tutorial/thanosql_search/search_image_by_image.ipynb
- 참고 문서: MNIST 데이터 세트 소개, A Simple Framework for Contrastive Learning of Visual Representations
튜토리얼 소개¶
이미지 수치화 기술 이해하기
이미지는 고차원 데이터(높이x너비x채널[RGB]x색의 강도)로써 각 픽셀의 정보를 무작위로 생성한다면 아무 의미를 갖지 않는 이미지가 생성됩니다. 즉, 각 픽셀은 주변 픽셀과 연관된 특정 패턴을 갖는 경우에만 사람이 이미지로 인식을 할 수 있게 됩니다. 이는 이미지를 실제보다 저차원적 특성 벡터에 표현할 수 있다는 의미입니다. 최근에는 인공지능을 이용해서 각 이미지가 갖는 의미의 유사도에 따라 저차원 공간에 수치화하여 표현하는 연구들이 다방면으로 이루어지고 있으며 이는 이미지 수치화, 벡터화(Vectorization), 임베딩(Embedding) 등의 이름으로 다양하게 활용되고 있습니다.
이미지의 유사도를 정의하는 방법은 여러가지가 있습니다. 색상이 비슷하거나, 이미지 내의 사물이 비슷하거나, 손글씨처럼 의미가 동일할 수도 있습니다. 유사한 이미지에 대한 정확한 정의를 내리기 어렵지만 이미지가 보유하고 있는 일반적인 특징을 인공지능은 학습하고 수치화합니다.
ThanoSQL에서는 이미지를 입력하고 데이터베이스에서 유사한 이미지를 검색하기 위해 자가학습모델(Self-Supervised Learning Model)을 사용합니다. 사용자가 보유하고 있는 이미지들을 ThanoSQL의 데이터베이스에 올리면 인공지능 알고리즘을 통해 비슷한 이미지는 가깝게 다른 이미지들은 멀리 배치하며 스스로 학습을 진행합니다. 정답이 없는 데이터 세트에서 이미지의 일반적인 표현을 학습하고 소량의 목푯값(Target)이 있는 이미지로 미세 조정하여 분류나 회귀 작업에 활용할 수 있습니다.
또한, ThanoSQL은 인공지능 알고리즘을 이용해서 데이터 세트를 수치화 합니다. 이렇게 수치화 된 데이터는 데이터베이스의 컬럼 내에 저장되고, 이미지 간 유사도(거리) 계산을 통해 비슷한 이미지를 검색하는데 사용됩니다.
아래는 ThanoSQL 유사 이미지 검색 알고리즘의 활용 및 예시 입니다.
- 사용자가 좋아하는 이미지를 입력받으면 데이터베이스 상에 저장되어 있는 미술 작품 중에서 비슷한 느낌의 미술 작품들을 검색하고 사용자에게 추천합니다.
- 수천장의 사진이 담겨있는 앨범에서 유사 이미지를 찾아낼 수 있습니다.
- 이미지의 수치화 된 값을 ThanoSQL의 데이터베이스에 저장하고, ThanoSQL AutoML 회귀/분류 예측 모델을 이용해서 나만의 검색 엔진이나 인공지능 모델을 만들 수 있습니다.
본 튜토리얼에서는
👉 이번 튜토리얼에서는 MNIST 손글씨 데이터 세트를 사용합니다. 각 이미지는 0~1 사이의 값을 갖는 고정 크기(28x28 = 784 픽셀) 이며, 여러 사람들이 손으로 쓴 0~9까지 숫자를 정답과 함께 제공합니다. 1,000개의 학습용 데이터 세트와 200개의 테스트용 데이터 세트로 이루어져 있습니다.
ThanoSQL을 사용하여 손글씨 데이터를 입력하고 데이터베이스 내에서 입력 이미지와 유사한 이미지를 검색해주는 모델을 만들어 봅니다.
0. 데이터 세트 준비¶
ThanoSQL의 쿼리 구문을 사용하기 위해서는 ThanoSQL 워크스페이스에서 언급된 것처럼 API 토큰을 생성하고 아래의 쿼리를 실행해야 합니다.
%load_ext thanosql
%thanosql API_TOKEN=<발급받은_API_TOKEN>
데이터 세트 준비¶
%%thanosql
GET THANOSQL DATASET mnist_data
OPTIONS (overwrite=True)
Success
쿼리 세부 정보
- "GET THANOSQL DATASET" 쿼리 구문을 사용하여 원하는 데이터 세트를 워크스페이스에 저장합니다.
- "OPTIONS" 쿼리 구문을 통해 GET THANOSQL DATASET에 사용할 옵션을 지정합니다.
- "overwrite": 동일 이름의 데이터 세트가 존재하는 경우 덮어쓰기 가능 여부 설정. True일 경우 기존 데이터 세트는 새로운 데이터 세트로 변경됨 (bool, optional, True|False, default: False)
%%thanosql
COPY mnist_train
OPTIONS (if_exists='replace')
FROM 'thanosql-dataset/mnist_data/mnist_train.csv'
Success
%%thanosql
COPY mnist_test
OPTIONS (if_exists='replace')
FROM 'thanosql-dataset/mnist_data/mnist_test.csv'
Success
쿼리 세부 정보
- "COPY" 쿼리 구문을 사용하여 데이터베이스에 저장 할 테이블명을 지정합니다.
- "OPTIONS" 쿼리 구문을 통해 COPY에 사용할 옵션을 지정합니다.
- "if_exists": 동일 이름의 테이블이 존재하는 경우 처리하는 방법 설정. 오류 발생, 기존 테이블에 추가, 기존 테이블 대체 (str, optional, 'fail'|'replace'|'append', default: 'fail')
1. 데이터 세트 확인¶
손글씨 분류 모델을 만들기 위해 ThanoSQL 워크스페이스 데이터베이스에 저장되어 있는 mnist_train 테이블을 사용합니다. mnist_train 테이블은 MNIST 이미지 파일들이 저장되어 있는 경로와 파일 이름 그리고 라벨 정보가 담겨 있는 테이블입니다. 아래의 쿼리 구문을 실행하고 테이블의 내용을 확인합니다.
%%thanosql
SELECT *
FROM mnist_train
LIMIT 5
image_path | filename | label | |
---|---|---|---|
0 | thanosql-dataset/mnist_data/train/6782.jpg | 6782.jpg | 5 |
1 | thanosql-dataset/mnist_data/train/1810.jpg | 1810.jpg | 5 |
2 | thanosql-dataset/mnist_data/train/33617.jpg | 33617.jpg | 5 |
3 | thanosql-dataset/mnist_data/train/27802.jpg | 27802.jpg | 5 |
4 | thanosql-dataset/mnist_data/train/50677.jpg | 50677.jpg | 5 |
데이터 테이블 이해하기
mnist_train 테이블은 아래와 같은 정보를 담고 있습니다. "6782.jpg" 이미지 파일은 숫자 5를 쓴 손글씨 이미지입니다.
- image_path: 이미지 경로
- filename: 파일 이름
- label: 이미지 라벨
2. 이미지 수치화 모델 생성¶
이전 단계에서 확인한 mnist_train 테이블을 사용하여 이미지 수치화 모델을 만듭니다. 아래의 쿼리 구문을 실행하여 my_image_search_model이라는 이름의 모델을 만듭니다.
(쿼리 실행 시 예상 소요 시간: 1 min)
%%thanosql
BUILD MODEL my_image_search_model
USING SimCLR
OPTIONS (
image_col='image_path',
max_epochs=1,
overwrite=True
)
AS
SELECT *
FROM mnist_train
Success
쿼리 세부 정보
- "BUILD MODEL" 쿼리 구문을 사용하여 my_image_search_model이라는 모델을 만들고 학습시킵니다.
- "USING" 쿼리 구문을 통해 베이스 모델로 SimCLR을 사용할 것을 명시합니다.
- "OPTIONS" 쿼리 구문을 통해 모델 생성에 사용할 옵션을 지정합니다.
- "image_col": 데이터 테이블에서 이미지의 경로를 담은 컬럼 (str, default: 'image_path')
- "max_epochs": 이미지 수치화 모델을 생성하기 위한 데이터 세트 학습 횟수 (int, optional, default: 5)
- "overwrite": 동일 이름의 모델이 존재하는 경우 덮어쓰기 가능 여부 설정. True일 경우 기존 모델은 새로운 모델로 변경됨 (bool, optional, True|False, default: False)
다음 "CONVERT USING " 쿼리 구문을 실행하여 mnist_test 이미지를 수치화 합니다. 수치화 된 결과는 mnist_test 테이블에 사용자가 옵션으로 지정한 이름(default: 'convert_result')의 컬럼에 저장됩니다.
%%thanosql
CONVERT USING my_image_search_model
OPTIONS (
image_col='image_path',
result_col='convert_result'
)
AS
SELECT *
FROM mnist_test
image_path | filename | label | convert_result | |
---|---|---|---|---|
0 | thanosql-dataset/mnist_data/test/5099.jpg | 5099.jpg | 6 | [b'\xd7', b'q', b'&', b'<', b'\xa1', b'<', b'\... |
1 | thanosql-dataset/mnist_data/test/9239.jpg | 9239.jpg | 6 | [b'\x1e', b'@', b'\xa9', b'=', b']', b'K', b'\... |
2 | thanosql-dataset/mnist_data/test/2242.jpg | 2242.jpg | 6 | [b'\x87', b'\xd1', b' ', b'>', b'\x83', b'e', ... |
3 | thanosql-dataset/mnist_data/test/3451.jpg | 3451.jpg | 6 | [b'\xac', b'\xd2', b"'", b'>', b'*', b'\xfa', ... |
4 | thanosql-dataset/mnist_data/test/2631.jpg | 2631.jpg | 6 | [b'O', b'\xf1', b'M', b'=', b'9', b'w', b'?', ... |
... | ... | ... | ... | ... |
195 | thanosql-dataset/mnist_data/test/8045.jpg | 8045.jpg | 8 | [b'\x00', b'\x00', b'\x00', b'\x00', b'\xa4', ... |
196 | thanosql-dataset/mnist_data/test/9591.jpg | 9591.jpg | 8 | [b'\x99', b'\x15', b'9', b'>', b'\xb7', b'\x88... |
197 | thanosql-dataset/mnist_data/test/7425.jpg | 7425.jpg | 8 | [b'\x1c', b'H', b'\x8a', b'>', b'f', b'\x83', ... |
198 | thanosql-dataset/mnist_data/test/2150.jpg | 2150.jpg | 8 | [b'\xf4', b'Y', b'S', b'>', b'\x96', b'^', b'\... |
199 | thanosql-dataset/mnist_data/test/5087.jpg | 5087.jpg | 8 | [b'\xc8', b'\x80', b'o', b'=', b'\xe6', b'\xdc... |
200 rows × 4 columns
쿼리 세부 정보
- "CONVERT USING" 쿼리 구문은 my_image_search_model 모델을 이미지 수치화를 위한 알고리즘으로 사용합니다.
- "OPTIONS" 쿼리 구문을 통해 이미지 수치화 시 필요한 변수들을 정의합니다.
- "image_col": 데이터 테이블에서 이미지의 경로를 담은 컬럼 (str, default: 'image_path')
- "result_col": 데이터 테이블에서 수치화된 결과를 담을 컬럼 이름 (str, optional, default: 'convert_result')
다음 "CONVERT USING" 쿼리 구문을 실행하여 변환된 결과를 다른 ThanoSQL 쿼리 구문들과 함께 활용할 수 있도록 새로운 테이블에 저장해봅시다.
%%thanosql
CREATE TABLE mnist_test_convert AS
SELECT * FROM (
CONVERT USING my_image_search_model
OPTIONS (
image_col='image_path',
result_col='convert_result'
)
AS
SELECT *
FROM mnist_test
)
Success
3. 이미지 수치화 모델을 사용하여 유사 이미지 검색¶
이번 단계에서는 my_image_search_model 이미지 수치화 모델과 테스트 테이블을 사용하여 "923.jpg" 이미지 파일(손글씨 8)과 유사한 이미지를 검색합니다.
923.jpg 이미지파일
%%thanosql
SEARCH IMAGE
USING my_image_search_model
OPTIONS (
search_by='image',
search_input='thanosql-dataset/mnist_data/test/923.jpg',
emb_col='convert_result',
result_col='search_result'
)
AS
SELECT *
FROM mnist_test_convert
image_path | filename | label | convert_result | search_result | |
---|---|---|---|---|---|
0 | thanosql-dataset/mnist_data/test/6308.jpg | 6308.jpg | 4 | [b'j', b'\x00', b'\xd9', b'@', b'\xf2', b'\xc8... | 0.581759 |
1 | thanosql-dataset/mnist_data/test/7283.jpg | 7283.jpg | 3 | [b'Z', b'\xda', b'\x13', b'A', b'z', b'A', b'\... | 0.581582 |
2 | thanosql-dataset/mnist_data/test/2064.jpg | 2064.jpg | 7 | [b'\t', b'\x1a', b'\x00', b'A', b'\xce', b'Y',... | 0.581389 |
3 | thanosql-dataset/mnist_data/test/9001.jpg | 9001.jpg | 7 | [b'*', b'\xa8', b'\x0f', b'A', b'\x1e', b',', ... | 0.580547 |
4 | thanosql-dataset/mnist_data/test/9023.jpg | 9023.jpg | 7 | [b'\xec', b'7', b'\x04', b'A', b'\xc1', b'\x9a... | 0.580506 |
... | ... | ... | ... | ... | ... |
195 | thanosql-dataset/mnist_data/test/1368.jpg | 1368.jpg | 0 | [b'\x12', b'M', b'\x1e', b'A', b'V', b'd', b'\... | 0.563993 |
196 | thanosql-dataset/mnist_data/test/4881.jpg | 4881.jpg | 3 | [b'\x8f', b'\n', b',', b'A', b'\xf2', b'l', b'... | 0.563783 |
197 | thanosql-dataset/mnist_data/test/2803.jpg | 2803.jpg | 3 | [b't', b'\xa7', b',', b'A', b'\xf2', b'\xf5', ... | 0.562967 |
198 | thanosql-dataset/mnist_data/test/2662.jpg | 2662.jpg | 6 | [b'\x86', b'\xbf', b'&', b'A', b'e', b'\xb2', ... | 0.562136 |
199 | thanosql-dataset/mnist_data/test/7601.jpg | 7601.jpg | 2 | [b'\x80', b'\xa0', b'\x16', b'A', b'\xbe', b'5... | 0.561050 |
200 rows × 5 columns
쿼리 세부 정보
- "SEARCH IMAGE [image|text|audio|video]" 쿼리 구문은 검색하고자 하는 이미지|텍스트|오디오|비디오 파일을 정의합니다.
- "USING"은 이미지 수치화에 사용할 모델을 정의합니다.
- "OPTIONS" 쿼리 구문을 통해 이미지 검색 시 필요한 변수들을 정의합니다.
- "search_by": 검색할 때 사용할 이미지|텍스트|오디오|비디오 타입 (str)
- "search_input": 검색할 때 사용할 입력값 (str)
- "emb_col": 데이터 테이블에서 수치화된 결과를 담은 컬럼 (str)
- "result_col": 데이터 테이블에서 검색 결과를 담을 컬럼 이름 (str, optional, default: 'search_result')
- "AS" 쿼리 구문은 검색에 사용할 임베딩 테이블을 정의합니다. mnist_test 테이블을 사용합니다.
다음 쿼리를 실행하여 "SEARCH" 결과를 ThanoSQL의 "PRINT" 쿼리 구문을 활용하여 가장 유사한 상위 4개를 출력합니다. 학습을 조금 밖에 진행하지 않았지만 8과 비슷한 이미지를 출력하는 것을 확인할 수 있습니다.
%%thanosql
PRINT IMAGE
AS (
SELECT image_path, search_result
FROM (
SEARCH IMAGE
USING my_image_search_model
OPTIONS (
search_by='image',
search_input='thanosql-dataset/mnist_data/test/923.jpg',
emb_col='convert_result',
result_col='search_result',
top_k=4
)
AS
SELECT *
FROM mnist_test_convert
)
)
/home/jovyan/thanosql-dataset/mnist_data/test/6308.jpg
/home/jovyan/thanosql-dataset/mnist_data/test/7283.jpg
/home/jovyan/thanosql-dataset/mnist_data/test/2064.jpg
/home/jovyan/thanosql-dataset/mnist_data/test/9001.jpg
참고 사항
이미지 유사도 검색 알고리즘의 기본 학습 옵션은 이미지의 좌우상하 반전, 색상의 변화 등에 관계없이 모두 같은 이미지로 인식하도록 학습이 진행 됩니다. 강아지의 사진은 뒤집히거나 색이 변해도 강아지로 인식되어야 하기 때문입니다. 의류 이미지 등과 같이 색의 변화가 중요하거나 숫자 처럼 상하, 좌우 반전이 중요한 경우 학습 시 옵션을 변경해 주어야 합니다. 본 튜토리얼에서는 이러한 이미지 유사도 검색의 특징을 보여주고 있습니다.
4. 튜토리얼을 마치며¶
이번 튜토리얼에서는 MNIST 손글씨 데이터 세트를 사용하여 이미지 수치화와 수치화 결과를 바탕으로한 유사 이미지 검색까지 진행해 보았습니다. 이번 튜토리얼에서는 이미지 유사도의 정확도보다도 작동 위주의 설명으로 진행하였습니다. 이미지 수치화 모델은 각 이미지 데이터 세트에 맞는 정밀한 튜닝과 소량의 정답을 학습 시에 추가하여 정확도를 향상 시킬 수 있습니다.
나만의 서비스를 위한 모델 배포 관련 문의
ThanoSQL을 활용해 나만의 모델을 만들거나, 나의 서비스에 적용하는데 어려움이 있다면 언제든 아래로 문의주세요😊
유사 이미지 검색 모델 구축 관련 문의: contact@smartmind.team