(2주차) 9월9일
Path, 이미지 크롤링과 CNN모델
- (1/4) Path 설명
- (2/4) 이미지 크롤링
- (3/4) 모형학습 및 결과분석
- (4/4) 테스트
from fastai.data.all import *
from fastai.vision.all import *
- 기능: 현재폴더, 혹은 그 하위폴더들에 속한 파일의 목록을 볼 수 있다.
path=Path() # Path클래스에서 인스턴스생성
(path/'ghtop_images').ls()
- Path(...)에서 ...에 무엇을 넣느냐에 따라 원하는 경로를 설정할 수 있다.
path=Path('/home')
path.ls()
- 폴더를 만들수 있다.
path=Path()
(path/'asdf').mkdir()
(path/'asdf').ls()
- 이미 폴더가 존재할 때는 아래와 같이 에러가 발생
(path/'asdf').mkdir()
(path/'asdf').mkdir(exist_ok=True)
- 생성한 폴더를 지우는 방법
(path/'asdf').rmdir()
- 이미지 크롤링은 (1) 검색 (2) 이미지 주소를 찾음 (3) 해당주소로 이동하여 저장하는 과정을 반복하면 된다.
- 교재: 빙을 이용하여 이미지 크롤링
- 단점: 애져에 가입, 완전무료가 아님 (학생에게 1년간 무료)
- 다른방법: 덕덕고를 이용한 이미지 크롤링
def search_images_ddg(key,max_n=200):
"""Search for 'key' with DuckDuckGo and return a unique urls of 'max_n' images
(Adopted from https://github.com/deepanprabhu/duckduckgo-images-api)
"""
url = 'https://duckduckgo.com/'
params = {'q':key}
res = requests.post(url,data=params)
searchObj = re.search(r'vqd=([\d-]+)\&',res.text)
if not searchObj: print('Token Parsing Failed !'); return
requestUrl = url + 'i.js'
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0'}
params = (('l','us-en'),('o','json'),('q',key),('vqd',searchObj.group(1)),('f',',,,'),('p','1'),('v7exp','a'))
urls = []
while True:
try:
res = requests.get(requestUrl,headers=headers,params=params)
data = json.loads(res.text)
for obj in data['results']:
urls.append(obj['image'])
max_n = max_n - 1
if max_n < 1: return L(set(urls)) # dedupe
if 'next' not in data: return L(set(urls))
requestUrl = url + data['next']
except:
pass
- search_images_ddg(검색어)를 이용하여 검색어에 해당하는 url을 얻는다.
search_images_ddg('hynn',max_n=5)
- download_images(저장하고싶은폴더위치, url의리스트)를 이용하여 url에 해당하는 이미지를 저장하고 싶은 폴더에 저장.
path=Path()
path.ls()
download_images(path,urls=search_images_ddg('hynn',max_n=5))
- 현재 working dir에 5개의 이미지가 저장된다.
keywords = 'hynn', 'iu'
path=Path('singer')
if not path.exists(): # 현재폴더에 singer라는 폴더가 있는지 체크
path.mkdir() # 현재폴더에 singer라는 폴더가 만들어짐
for keyword in keywords: # keyword='hynn', keyword='iu' 일때 아래내용을 반복
lastpath=path/keyword # ./singer/hynn or ./singer/iu
lastpath.mkdir(exist_ok=True) # make ./singer/hynn or ./singer/iu
urls=search_images_ddg(keyword) # 'hynn' 검색어로 url들의 리스트를 얻음
download_images(lastpath,urls=urls) # 그 url에 해당하는 이미지들을 ./singer/hynn or ./singer/iu 에 저장
- 탐색기로 파일들을 살펴보니 조금 이상한 확장자도 있음.
- 조금 이상해보이는 확장자도 열리기는 함.
PILImage.create('./singer/iu/00000006.jpg:large')
verify_images(get_image_files(path))
- 위에 해당하는 이미지를 수동으로 지워줌.
- csv을 받았으면 df를 만들어야 하듯이, 이미지 파일들을 받았으면 dls를 만들어야 fastai가 지원하는 함수로 분석하기 좋다.
dls = ImageDataLoaders.from_folder(
path,
train='singer',
valid_pct=0.2,
item_tfms=Resize(224))
dls.show_batch(max_n=16)
- 모형을 만들고 학습을 시키자.
learn=cnn_learner(dls,resnet34,metrics=error_rate)
learn.fine_tune(7)
learn.show_results(max_n=16)
interp = Interpretation.from_learner(learn)
interp.plot_top_losses(16)
- 수동으로 특정 observation에 대한 예측결과를 확인하여 보자.
dls.train_ds
- training set
dls.train_ds[0]
- dls.train_ds[0] 가 의미하는 것은 첫번쨰 observation을 의미함. 즉 $(x_1,y_1)$
- $x_1=$PILImage mode=RGB size=960x960
- $y_1=$TensorCategory(1)
dls.train_ds[210][0]
- $x_{211}$=위의 이미지
dls.train_ds[210][1]
- $y_{211}=$TensorCategory(0)
x210=dls.train_ds[210][0]
learn.predict(x210)
path = Path()
if not (path/'test').exists():
(path/'test').mkdir()
urls=search_images_ddg('hynn 박혜원',max_n=20)
download_images(path/'test',urls=urls)
testset=get_image_files(path/'test')
testset
for i in range(len(testset)):
print(learn.predict(PILImage.create(testset[i])))
- 결과를 보니까 hynn이 많음 $\to$ 어느정도 맞추는것 같긴하다.
PILImage.create(testset[7])
- 실제로는 박혜원인데 아이유로 예측한 사진
path = Path()
if not (path/'test2').exists():
(path/'test2').mkdir()
urls=search_images_ddg('iu 아이유',max_n=20)
download_images(path/'test2',urls=urls)
testset=get_image_files(path/'test2')
testset
for i in range(len(testset)):
print(learn.predict(PILImage.create(testset[i])))
- 결과를 보니 아이유 역시 잘 맞추는 듯 보인다.
- 정확률이 아쉽긴 하지만 어느정도 유의미한 결과를 얻었다.
숙제
- 원하는 검색어로 이미지를 모은 뒤 결과를 제출