edwith CS50강의를 보며 정리했습니다.

● 인공지능 (자연어처리)

 

우리는 소프트웨어를 작동하거나 컴퓨터 언어(프로그래밍 언어) 를 통해 컴퓨터와 상호작용을 하지만, 인간은 일상에서 컴퓨터 언어가 아닌 언어를 사용한다. 이것을 자연어 라고 부르는데, 컴퓨터가 이를 이해하도록 만들려면 자연어를 이해할 수 있도록 처리해야 한다.

가장 최초의 자연어 처리 프로그램은 1966년 조셉이 만든 ELIZA 라는 소프트웨어이다. ELIZA에서 사용하는 시스템을 패턴 매칭 (pattern matching) 이라고 하는데, 입력 받은 문자의 일부를 활용해 다시 사용자에게 반환해주는 시스템을 의미한다. 요즘은 이러한 시스템을 활용하여 구현된 챗봇을 쉽게 만날 수 있다.

사람의 언어를 기계적으로 분석하여 컴퓨터가 이해할 수 있는 형태로 바꿔 처리하는 것을 자연어 처리라고 한다. 또, 단어들의 순서나 한 단어 뒤에 다른 단어가 나올 확률 등을 확률적으로 계산하여 시스템에 반영할 수 있다.

 

● 음성인식

 

요즘 대부분의 운영체제에는 음성인식 소프트웨어가 탑재되어 있다. 예시로는 iOS의 Siri, 삼성의 빅스비 등이 있다. 이러한 소프트웨어들은 가장 아래에 음성모델, 중간에 발음모델, 그 위에 언어모델을 넣어 이루어진다. 이렇게 여러 층으로 이루어진 소프트웨어로 음성을 인식하고, 인식된 문자를 또 다시 몇 개의 층으로(단계로) 분석한다. 

Syntactic Processing, Semantic Processing, Pragmatic Processing

문장을 인식했다면, 처음엔 그 문장의 구조를 분석하고 각 단어의 의미처리를 한다. 하지만 이 단계는 인간의 말을 그대로 이해하는 것이 아닌, 상징적인 것으로 앞에서와 마찬가지로 단어와 단어의 구조를 패턴화하고 확률적으로 구하는 것이다. 문장이 실제로 어떤 의미를 뜻하는지 인식하기 위해서는 더 복잡한 인지 모델이 필요하다. 

 

우리가 소통하는 요소 중 많은 부분을 차지하는 것이 비언어적 소통이다. 단순히 텍스트만으로 소통하기보다는 물리적 거리, 바라보는 시선, 목소리 톤, 억양, 제스처 등이 함께한다. 위에서 언급한 음성인식 시스템은 이러한 부분까지 고려할 수 없지만 비 언어적 행동까지 커버하는 카메라가 달린 로봇(지보)도 있고, 세상은 조금씩 발전하고 있다.

 

● 머신러닝

 

인공 지능을 구현하기 위한 하나의 분야로, 컴퓨터가 많은 데이터를 스스로 학습하고 그 데이터의 패턴을 파악할 수 있도록 하는 것이다. 일상에서 쉽게 사용할 수 있는 머신 러닝 시스템으로는 스팸 메일 분류기가 있다. 이러한 패턴을 잘 파악하기 위해서는 많은 양의 데이터가 필요하다.

내가 상장사라면 분기보고서를 공시하느라 고생했을텐데 기업이 아니라 사람이라 다행인 것 같다. 내가 뭘했나 싶은 현타감을 느끼며 공개처형 당할 생각만 해도 끔찍하다.

그래서 나는 1분기동안 뭘했을까? 정량적으로 체크할 수 있는 것부터 보려고 하니 노션밖에 생각이 나지 않는다.

중간중간 구멍이 뚫렸지만 10주 가까이 되는 주간회고를 작성했고, 그 사이 취업을 했다.

배움의 기록도 꾸준히 남기고 있다. 특히 기록하는 습관이 가장 크게 달라졌다. 기록을 하니 이룬 게 없는 것 같으면서도 뭐라도 남은 기분이 든다. 작년말보다 접한 텍스트와 읽은 책, 경험이 많아졌으니 어찌됐든 훨씬 풍부한 인생을 살고 있는 건 맞는 것 같다. 또, 물욕이 많이 줄었다. 소비지향과 충동구매를 일삼던 내가 왜 이럴까 고찰해보니 지식욕으로 옮겨간 것 같다. 개이득^ㅡ^


듀오링고 1,000일을 달성했다. 다음 목표는 10,000일!



업무적으로는 최소한 SOTA 모델에 대한 지식이 많아졌고 논문 템플릿이 익숙해져서 논문을 읽는 속도가 빨라졌다. 구글링하는 스킬도 훨씬 정교해졌다. 별건 아니지만 LaTex 문법, Vi 문법도 검색 없이 사용할 줄 안다. 모델링에 대한 경험, 선형대수나 통계적 지식도 많아졌다. 관심사도 훨씬 넓어졌고 리눅스 문법도 익숙해졌다. 요즘은 ocr, 추천모델, docker/kubernetes 등과 관련된 pipeline, 운영체제 등에 관심이 있다.


신체적으로는 직장에 다니기 전보다 운동량은 줄었지만, 몸무게는 늘지 않았다. 틈날때마다 운동을 하려고 노력중이다.


정신적으로는 훨씬 안정감이 생겼다. 돈을 벌지 않음으로써 당장 생활비를 걱정해야 하는 일이 나와는 먼 이야기라는 사실이 생각보다 나에게 큰 안정감을 안겨 주었다. 어딘가에 속해있다는 소속감도 더욱 강해졌다. 이런 안정감 덕분인지 그동안 못 읽었던 책도 읽고, 지저분한 머리도 자르고, 그림도 그리고, 악기 연주도 하고, 외국어 공부에 투자하는 시간도 늘었다.


사회적으로는 다양한 분야의 좋은 사람들을 많이 만났다. 5년전인가, 깊은 관계를 맺었던 사람에게 관심사가 너무 많은데 제대로 하는 건 아무것도 없어 빛 좋은 개살구 같다는 핀잔을 들었던 적이 있다. 생전 처음 들었던 말을 그것도 가까운 사람에게 들어 굉장히 충격적이었던 기억이 있다. 지금은 주위에 그런 말을 하는 사람이 없다. 유유상종이라는 옛 말이 맞는 말이라고 새삼 느낀다. 주변 사람들 덕분에 내 추진력도 더욱 빛을 발할 수 있어 감사하다.



생각나는대로 지껄여보니 그리 모난 삶을 살진 않은 것 같다. 2Q엔 더욱 값지고 풍부한 경험과 실패를 겪고 성장하길 바란다.

'Think' 카테고리의 다른 글

2022년 8월 회고  (0) 2022.09.01
2022년 상반기 회고  (0) 2022.08.01
2022년 3월 회고  (0) 2022.03.31
2022년 2월 회고  (0) 2022.02.28
2022년 1월 회고  (0) 2022.01.31

건강

아침운동을 하면 퇴근하고 공부할 시간이 더 많아져서 좋다. 아직 잠들어있는 뇌를 근력운동과 유산소로 깨우는 것이 짜릿하다. 미라클 모닝은 잘 모르겠지만 내게 있어 아침운동은 미라클은 맞는 것 같다. 

 

업무

정확히 어느 시점부터인지 모르겠지만, 언젠가부터 이해 안 되던 부분이 확실하게 이해가 되기 시작했다. 물론 여전히 부족한 부분이 많지만 암기가 아니라 이해를 하니 훨씬 내 것으로 만들기 쉬워졌다. 분야의 특성 상 하나를 배우면 수채화 물감이 번지듯 주변으로 확장되어가는 속도가 빠른 듯하다. 덕분에 OCR 구현도 해보고 pose estimation, word embedding, 거리추정 알고리즘, GAN, auto encoder, swin transformer, 이상치 탐지, 시계열 데이터 등 다양한 것들을 접할 수 있어 좋았다. 

서버를 잘못 건드렸다가 서버 통째로 날릴 뻔했다.. 아슬아슬하게 피해간 덕분에 서버를 살리고 5년뒤 술 안주거리를 날렸다. 학부시절에 우분투 리눅스 가상환경 구현해본 경험은 다 어디로 간걸까..  나중에 경력이 쌓여 MLOps까지 하고 싶으면 파이썬, 모델링만 할 게 아니라 이런 부분까지 잘 알고 서버 배포까지 할 줄 알아야 할 텐데.. 조금씩 시간을 내서 공부해두면 분명 득이 될 것 같다.

업무 외적으로..  지금의 월급이 많진 않지만, 월급보다 더 중요한 많은 것들을 배울 수 있어 아직까지는 출근하는 하루하루가 재미있고 기쁘다. 특히 대표님의 마인드와 선임님의 세심한 배려 덕분에 하루하루 버틸 수 있어서 너무 감사하다. 기회가 된다면 선임님께 식사를 대접하고 싶다.

 

배워서 남주는 스터디

책임님께 아무것도 남지 않는 스터디를 하지 말라는 이야기를 듣고 충격에 빠졌다. 과연 나는 내 시간을 비효율적으로 보내는걸까? 물론 누가 나를 비판하거나 비난한다해도 쉽게 마음이나 생활양식을 바꾸진 않지만, 나의 노력이 겉으로 보기에 그들 입맛에 맞게 드러나지 않는다면 더욱 쉽게 평가당할 수 있다는 것을 깨달았다. 

사실 난 배워서 남주려고 스터디를 한다. 남한테 가르칠 정도로 확실하게 알고 싶지만 그 남의 한마디 평가에 멘탈이 살짝 흔들렸던 걸 보니 나조차도 실력 향상에 확신이 없었던 것 같다. 이번에 몇 개의 스터디가 종료됐는데, 이번 기회에 방향을 더 잡고 마음을 단단히 해야겠다는 생각이 든다.

그래도 이번달에 책 한권을 끝냈다. 이 책 덕분에 굉장히 많은 걸 배웠다. 그럼 된 거 아닌가?

 

외국어

언어에 소질이 있는 것도 아니면서 여러 언어를 배우고 있다. 언어는 실력향상의 속도에 비해 실력 감퇴의 속도가 빠르기 때문에 최소한의 의무라도 하며 놓지 않으려고 한다. 언어를 잘하려면 많은 어휘를 아는 것과 올바른 발음을 하는 것도 중요하지만 자신감이 제일 중요한 것 같다.

2주전부터 영어 튜터링을 일주일에 1시간씩 하고 있다. 비록 2회밖에 진행을 안 했지만, 조금이나마 생각을 영어로 전달하는 속도에 버퍼링은 줄었다는 점 하나로 만족하고 있다. 독일어 문해력도 많이 늘었다.

 

부동산

개발자 모임에서 마음 맞는 분과 임장을 다녀왔다. 좋은 매물을 봤지만 가용 현금이 없어 답답한 요즘이다. 폭락론자와 떡상론자의 사이에서 고민할 것이 아니라 오히려 귀를 막고 내 생각대로 하는 게 나을 것 같다.


스스로를 칭찬해보자

아쉬운 점과 불평불만만 많은, 또 최근의 기억만 가득한 회고가 되기 싫어 한 달에 하나쯤은 나를 칭찬할만한 무언가가 있지 않을까 생각해보지만 도무지 떠오르지 않는다.

요새는 모든 모임을 개발자 모임에서 시작하는데 만날때마다 소속감을 느끼고 다른 분야의 이야기를 듣는 것이 흥미로워서 모임을 지속할 수 밖에 없게 된다. 체리피커도 없고 마음 씀씀이도 크고 배울점이 많아 아마 당분간은 계속 모임에 참가하지 않을까 생각한다. 이번달엔 독서 모임과 그림 모임을 했다.

나도 모임에서 누군가에게 작은 도움이라도 주는 사람이 되고 싶다. 그러기 위해 뭐라도 붙잡고 공부하는 나라도 칭찬해본다. 다음달엔 더 단단한 알멩이가 되길 바라며 4월을 기약한다.

'Think' 카테고리의 다른 글

2022년 8월 회고  (0) 2022.09.01
2022년 상반기 회고  (0) 2022.08.01
2022.1Q 회고  (0) 2022.04.07
2022년 2월 회고  (0) 2022.02.28
2022년 1월 회고  (0) 2022.01.31
edwith CS50강의를 보며 정리했습니다.

● 가상 현실과 증강 현실

 

우리는 일상에서 쉽게 가상 현실(VR, Virtual Reality)증강 현실(AR, Augmented Reality)을 접한다.
VR은 가상의 환경이나 상황을 컴퓨터로 만들어서 사람들이 실제로 그 상황에 들어와있는 것 처럼 느끼고 상호 작용할 수 있도록 만들어 주는 인터페이스를 뜻한다. AR은 가상현실과 기본적으로 비슷한데, 사용자에게 기존의 주변환경과 분리된 전혀 다른 환경을 경험하게 하지 않고 현재의 환경 위에 영상, 게임 등의 효과를 입히는 기술이다. 

간단한 형태로는 휴대폰을 통해 유튜브나 페이스북으로 3차원 공간을 둘러볼 수 있는데, 네모난 액정 안에 3차원 공간이 다 담긴다. 혹은 구글 카드보드나 삼성 기어, 오큘러스의 리프트, HTC의 바이브 등의 헤드셋을 통해 가상 세계로 갈 수도 있다. (논외지만 가상 현실 세계는 무궁무진하게 커질 것이라 생각해서 나는 카메라 기업들의 산업을 긍정적으로 투자해놨다.)

이러한 기술의 실질적인 목표는 강의실 혹은 해당 공연장에 하나의 창을 만들어서 공간에 없는 사람이라도 멀리서도 그 창을 통해 수업 혹은 공연을 들을 수 있게 하는 것이다.

 

원리

인간이 눈으로 보이는 것들을 입체적으로 느낄 수 있는 이유는 양쪽 눈의 시차가 있기 때문이다.  우리의 양 눈은 서로 떨어져있기 때문에 각각 보는 각도가 달라, 양안시차가 발생하기 때문에 원근감을 느끼고 물체를 입체적으로 인식할 수 있다.

이 원리를 이용하여 VR기기의 양 렌즈에는 사람의 양안 시차만큼 다른 각도로 촬영된 영상이 재생되기 때문에 일반 디스플레이에서 영상을 보는 것과 달리 입체감이 느껴지는 것이다.

또한 사람이 바라보는 방향에 따라 영상을 바꾸기 위해서 모션 트래킹 센서라는 것이 사용된다. 머리에 씌워진 기기 안에 가로, 세로, 높이를 모두 측정하는 센서가 있어 고개를 돌릴 때 마다 영상 화면도 같이 움직일 수 있다.

이 각각의 센서와 이미지를 활용하여 소프트웨어를 활용해 통합, 사용자가 보는 화면에 제공하여 입체감을 함께 느낄 수 있도록 하는 것이다. 보통 이러한 것을 체험하기 위해서는 AR 혹은 VR 기기를 사용하는데, 우리가 세상을 바라보는 눈으로 보면 마치 볼록렌즈처럼 왜곡되어 보이기 때문이다. 해당 기기를 사용해야만 소프트웨어와 연동이 되어 마치 가상현실을 진짜처럼 바라볼 수 있는 것이다.

 

 

가상 현실(VR)과 함께 가상의 정보를 이용한 기술이 증강 현실(AR)이다. 가상 현실과 증강 현실을 혼동하는 경우가 많은데, 가상현실은 가상의 환경에서 가상의 물체와 상호작용 하는 반면에, 증강현실은 현실의 환경에서 가상의 이미지가 겹쳐서 보여지는 것 이다.

AR은 스마트폰과 같이 카메라와 디스플레이가 함께 있는 기기가 필요하다. 카메라를 통해 사람의 시선이 닿는(카메라 렌즈를 통해 들어오는 화면) 장면이 기기에 들어오고 디스플레이에서 출력될 때 가상의 이미지가 덧붙여서 보이게 된다. AR 역시 VR과 마찬가지로 사람의 시선(카메라의 위치)를 계산하기 위하여 위치와 기울기를 측정하는 센서가 필요하다.

 

실제로, 이집트의 피라미드에서는 이 기술을 활용하여 그 곳까지 가지 못하는 사람들에게 가상 환경을 통해 경험할 수 있는 서비스를 제공한다고 한다. 이제는 우리가 접할 수 있는 구글맵의 거리뷰(로드뷰) 또한 3D 기술을 통해 구현된 것이다.

edwith CS50강의를 보며 정리했습니다.

 


● 이미지 파일

추리물을 좋아하는 사람이라면, 혹은 소싯적 TV 프로그램을 많이 봤다면 누구나 아는 프로그램이 있다.

바로 CSI 프로그램이다. 해당 프로그램에서 자주 나오는 화면이 영상을 멈춰서 확대하는 장면이다.

 

위의 이미지를 확대하면,,?

현실은 다르다. 한정된 비트들로 이루어진 이미지를 확대하면 이렇게 이미지가 번지거나 깨지는 현상을 볼 수 있다. 이런 현상이 발생하는 이유는 무엇일까?

우리가 컴퓨터와 해온 상호작용들은 대체로 모니터, 키보드, 마우스 등으로 이루어졌다. (물론 사람마다 다르겠지만) 하드디스크나 파일과 상호작용을 하는 빈도는 비교적 적다. 

 

'파일'은 무엇일까? 위의 사진은 'JPEG'의 확장명을 가지고 있는데, 이러한 파일들은 특정 비트 패턴으로 식별된다.  JPEG, GIF, PNG, WORD, EXCEL 파일 간에 구분되는 점은 무엇일까? 서로 다른 비트 패턴을 사용한다는 것이다. 그러한 비트 패턴들은 보통 파일 초반부에 있다. 

우리가 컴퓨터에서 JPEG 파일이나 워드 문서를 열면 대체로 파일의 첫 비트들을 본다 만약 그 패턴을 인식하여 이미지라는 것을 알면 사용자에게 그래픽으로 보여준다. 만약 그 패턴이 doc 형식이라면 문서형식을 보여줄 것이다.

 

이미지

우리가 사진을 찍어 이미지에 저장하면 보통 JPEG라는 확장자를 가지며 이미지를 압축하여 저장한다. 이미지 파일 형식으로는 비트맵(.bmp), JPG(.jpg), PNG(.png), GIF(.gif) 등이 있다. 각 유형에는 장단점이 있으며 유형에 따라 파일의 크기도 달라진다. 즉, 파일의 비트 데이터들의 구조가 다르다.

예를 들어 JPEG 확장자를 가진 파일의 첫 부분에는 256 216 255 의 숫자로 시작한다. 

비트맵 (BMP) 파일 형식의 경우 압축을 하지 않고 저장을 하며 이미지를 가장 단순하게 저장한다.

 

JPEG 파일은 이미지를 압축하는 장점을 갖고 있으며, GIF 파일이 256색을 표시할 수 있는데 비해 JPEG는 1600만 색상을 나타낼 수 있어 고해상도를 나타내기에 적합합니다. GIF는 이미지의 전송을 빠르게 하기 위한 압축저장 방식을 사용합니다. JPEG보다 압축률은 낮지만 압축 시 이미지의 손상이 적다.

PNG는 GIF와 JPEG의 장점만을 합쳐 놓은 압축방식이다. GIF보다 압축률이 좋고 JPEG보다 원본에 손상이 적어 효과적이다.

 

 

 

 

 

edwith CS50강의를 보며 정리했습니다.

● 16진수

 

사진 파일의 확장명인 jpg(jpeg)를 아는가? 모든 JPEG 파일의 첫 3byte는 이렇게 시작한다. 하지만 이렇게 10진수, 2진수만 사용하지는 않고 대체로 16진수 (hexadecimal) 를 사용한다. 0~9 다음부터 10~15의 숫자는 a,b,c,...f 등 알파벳으로 표현한다.

 

위의 숫자들을 2진수, 16진수로 나타내면 8bit 였던 걸 2bit로 구현할 수 있다.

 

하지만 ff, d8, ff 등으로 표현하지는 않고 16진수를 사용할 때는 관례적으로 빈 공간에 0x라는 것을 앞에 넣어서 위와 같은 표현으로 나타낸다.

 

16진수가 유용한 이유는 4bit 패턴과 완벽한 대응을 하기 때문이다. (2의 4제곱). 이를 활용하여 8bit나 1byte 등을 표현하기 용이하다. 실용적이다 ^ㅡ^

edwith CS50강의를 보며 정리했습니다.

● ASCII 코드

컴퓨터가 숫자가 아니라 문자나 다른 것들을 나타내기 위해 하는 것이 있을까? 컴퓨터 업계에서는 숫자를 알파벳 문자에 대응시키는 표준 방법을 채택하였다. ASCII 는 아스키라고 읽으며 글자를 10진수로 대응하는 것이다.

우리가 '문자'를 표현하고 싶지만 컴퓨터는 '숫자'로만 언어를 처리하기 때문에 숫자를 글자로 변환하려면 비트 패턴으로 변환이 필요하다. 그럴 때 사용하는 것이 ASCII 코드이다. 알파벳 'A'는 65로 시작하는데, 2의 6제곱인 64까지 표기를 하고 그 이후에 시작하는 순서이다. 

예를 들어 HI 라고 쓰고 싶다면, ASCII 코드로 숫자 72와 73을 나타내는 비트 패턴으로 전기신호를 보내 저장한다. 비단 문자뿐만 아니라 그래픽, 영상, 음악 등 다양한 것을 저장할 수 있다.

시계열 데이터는 다양한 패턴으로 나타날 수 있다.

시계열 패턴은 추세(trend), 계절성(seasonality), 주기(cycle) 이렇게 세 가지 패턴으로 나뉘는데 보통 추세와 주기를 결합하여 추세-주기 성분으로 다룬다. 일반적으로 추세-주기 성분, 계절성 성분, 나머지 성분의 세 가지로 구성된다고 여겨진다.

 

6.1 시계열 성분

$y_t$ 는 데이터, $S_t$ 는 계절성성분, $T_t$ 는 추세-주기 성분, $R_t$ 는 나머지 성분이다.

덧셈 분해(additive decomposition) 에 대한 수식은 아래와 같다.

$y_t = S_t+ T_t + R_t,$

곱셈 분해(multiplicative decomposition) 에 대한 수식은 아래와 같다.

$y_t = S_t\times T_t \times R_t.$

계절성분이나 추세-주기 성분이 시계열 level에 의해 변하지 않는다면, 덧셈 분해가 적절하다. 계절성분이나 추세-주기 성분이 시계열의 level에 비례한다면, 곱셈 분해가 더 적절하다. 경제 분야의 시계열 데이터를 다룰 때 곱셈 분해를 많이 사용한다.

데이터의 변동성이 시간에 따라 안정적으로 나타날 때까지 변환한 다음 덧셈 분해를 사용하는 법도 있다. 로그 변환을 통해 곱셈 분해를 사용하는 것과 같은 효과를 볼 수 있다.

$y_t = S_t\times T_t \times R_t$    equals    $logy_t = logS_t+ logT_t + 1$

 

위의 표에서 원본 데이터를 근무일 기준으로 맞춰 조절을 통해 조절을 한다면 추세-주기 성분에 맞춰 시계열대로 움직이는 것을 확인할 수 있다.

데이터를 나눠서 추세-주기 성분, 계절성성분, 나머지 성분으로 나눠서 위와 같이 볼 수 있다. 우측의 회색 막대를 통해 성분의 상대적 눈금을 확인할 수 있다. 나머지 성분의 회색 막대는 크게 나타나는 것으로 보아 다른 성분의 패널보다 변동성이 작다는 것을 알 수 있다.

계절성으로 조절된 데이터

원본 데이터에서 계절성을 제거한 것을 계절성으로 조절된(seasonally adjusted) 데이터라고 부른다. 덧셈 분해에서는 $y_t - S_t$와 같이 조정하고, 곱셈 분해에서는 $y_t/S_t$와 같이 조정할 수 있다.

데이터를 접근할 때 '계절성'이 포커스가 아니라면, 계절성으로 조절된 시계열 데이터는 유용하다. 계절성 변동보다는 다른 요인이 더 중요하거나 다른 요인을 강조하고 싶을 때는 데이터를 계절성으로 조정할 수 있다. 이렇게 조정된 시계열도 추세-주기 성분과 나머지 성분이 있다. 만약, 시계열에서 '전환점'을 살펴보거나 어떤 방향으로의 변화를 해석하는 것이 목적이라면 계절성 조절 시계열 데이터보다는 추세-주기 성분을 사용하는 것이 낫다.

 

6.2 이동 평균

고전적인 시계열 분해 방법은 이동평균 (moving average) 방법을 사용하는 것이다.

$\hat{T}_{t} = \frac{1}{m} \sum_{j=-k}^k y_{t+j},$

$k$ 기간 안의 시계열 값을 평균하여 시간$t$ 의 추세-주기를 측정할 수 있다. 여기서 $m = 2k + 1$ 이다. 측정 시기가 비슷하면 값이 비슷할 수도 있다. 이러한 이동 평균 계산을 통해 데이터의 무작위성을 줄이고 깔끔한 추세-주기 성분만 남길 수 있다. 이를 차수 $m$의 이동평균이라는 의미에서 '$m-$MA'라고 부르기도 한다.

autoplot(elecsales, series="Data") +
  autolayer(ma(elecsales,5), series="5-MA") +
  xlab("Year") + ylab("GWh") +
  ggtitle("Annual electricity sales: South Australia") +
  scale_colour_manual(values=c("Data"="grey50","5-MA"="red"),
                      breaks=c("Data","5-MA"))

위의 코드를 활용하여 추세-주기를 확인해 볼 수 있다.

추세가 원본 데이터보다 얼마나 깔끔한지(매끄러운지), 시계열이 어떻게 움직이는지 확인할 수 있다. 이동평균의 차수는 추세-주기의 매끄러운 정도를 결정하고, 일반적으로 차수가 클수록 곡선이 매끄럽다.

 

이동평균의 이동평균

이동평균값을 또다시 이동평균할 수 있다. $m=2k+1$이 짝수라면 대칭적이지 않기 때문에, 홀수의 값으로 계산을 해야 한다. 하지만 이동평균을 두 번 함으로써 짝수 차수의 이동 평균을 대칭적으로 만들 수 있다.

 


1. 직업을 취하다.

언제부터 취업이라는 말이 쓰였는지는 모르지만 직업을 취하게 되었다. 무척이나 기쁠 줄 알았는데 생각보다 어벙벙했다. 그렇게 어벙벙하게 들어간 회사는 정말 좋았다. 기대치가 없던 것도 아닌데 기대 이상이고 공부를 맘껏 할 수 있는 자유가 있어서 기쁘다. 배울 자유를 회사에서 누리다니!



2. 달라진 사람들

돌이켜보면 항상 관심사에 따라 만나는 사람들이 달라졌던 것 같다. 음악에 심취했을 때는 음악인들을 많이 만났고 요리에 미쳤을 때는 조리사들을 많이 만났다. 개발을 공부한 이후로 만나는 사람들은 공통점이 개발로 이어져있다. 어찌보면 당연해보이면서도 생각해보면 그리 쉬운 것이 아닌데 나는 내 삶의 터전과 방향을 잘 컨트롤 하고 있구나 하는 생각이 문득 든다.


3. 나를 기록하다.

지난달 회고에 적었듯 기록의 중요성을 느낀 이후로는 기록해야겠다는 마음이 없어도 이제는 습관적 혹은 본능적으로 기록을 하게 된다. 과거의 기록이 단순한 1차원의 나열이었다면 지금의 기록은 더 입체적이다. ‘잘’ 기록한다는 것이 어떤 것인지는 모르겠지만 내 입맛에 맞게 기록하는 방법을 여전히 찾고 있는 중이다.


4. 요즘 나는

  • 기타를 친다

간간히 기타를 연주해서 개인 유튜브에 올리는데 은근 아카이빙해두고 반복해서 보는 것이 재미있다.

  • 독일어를 깨우쳤다

출근길에 듀오링고를 하니까 확실히 머릿속에 잘 들어온다. 이래서 다들 미라클모닝을 하나보다. 독일어에서 매번 넘을 수 없던 벽은 바로 격 부분이었는데 아침의 듀오링고가 생각보다 쉽게 벽을 부숴줬다.

  • 질문을 한다

대화하는 상대방이 이해가 안 가면 다름을 인정하고 이해하려고 노력하지 않는 방식으로 살아왔다. 좋은 삶의 방식은 아니지만 어느 순간부터는 감정 소모하는 것이 싫었던 게 큰 이유 같다. 하지만 공부를 할 때는 반대다. 인간관계에 있어서는 이유가 없어도 되지만 공부에선 이유가 있어야 다음 단계로 넘어가게 된다. 공부에 이유가 있어야만 하는 건 아닌데 자꾸만 이렇게 하게 된다. 이유 없이 넘어가면 안되겠니..? 



5. 스스로를 칭찬해보자.


지난달의 회고를 보니 나의 수박 겉핥기식 학습법을 맘에 안 들어했는데, 지금은 조금이나마 개선이 되었다고 느낀다. 내가 그런 학습법을 가지게 된 가장 큰 이유는 왜? 라고 생각되는 의문점이 생겼을 때 학습을 멈췄기 때문이다. 공부할 건 많고 더 하고 싶지만 도저히 납득하지 않고 넘어갈 수가 없어서 에잉쯧 하고 눈길을 주지 않고 다른 걸 공부하다보니 이런 것들이 쌓이게 된 것이었다.
이제는 공부할 환경이 주어지니 학습을 멈추지 않고 더 깊게 들어갈 수 있어서 개선이 된 게 아닐까 짐작한다. 탐구하는 자세는 물론 좋겠지만 이게 탐구인지는 잘 모르겠다.



6. 개선할 것

당장은 개선이 필요한 무엇이 떠오르지 않는다. 다만 부족한 부분이 있는 부분을 수없이 많이 느꼈고, 그 부분을 집중적으로 공부하려고 한다. 2월달 고생했다!


'Think' 카테고리의 다른 글

2022년 8월 회고  (0) 2022.09.01
2022년 상반기 회고  (0) 2022.08.01
2022.1Q 회고  (0) 2022.04.07
2022년 3월 회고  (0) 2022.03.31
2022년 1월 회고  (0) 2022.01.31

07. 딥러닝

 

07-1 인공 신경망

  • 시작하기 전에




    럭키백의 성공 이후 타깃 고객의 연령대를 대상으로 패션 럭키백을 진행해보려 한다!
    는 사실 패션 mnist 데이터를 사용하기 위한 밑밥..이지만 박해선님의 스토리 라인에 감탄!

 

<패션 MNIST>

시작하기에 앞서, 머신러닝/딥러닝을 입문할 때 사용하는 데이터셋이 있다. 머신러닝에서 붓꽃 데이터셋이 유명하듯, 딥러닝에서는 MNIST dataset이 유명하다. 이 데이터에는 손으로 적은 숫자로 이루어져 있는데, 패션 mnist는 숫자가 아닌 패션 아이템이 들어가있는 데이터셋이다.
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()

print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)

패션 MNIST 데이터셋은 워낙 유명하기 때문에 라이브러리를 통해 import하여 사용이 가능하다. load_date() 메서드는 훈련 데이터와 테스트 데이터를 나눠 반환하는 함수다. 크기를 확인해보면 6만개의 이미지를 활용한 훈련 세트와 1만개의 이미지를 활용한 테스트 세트로 이루어진 것을 알 수 있다.

 

6장에서 matplotlib으로 이미지를 출력했던 것처럼 샘플을 출력할 수 있다. 이렇게 샘플 이미지를 확인해보면 데이터를 이해하고 주어진 task를 해결할 때 방향 잡기가 훨씬 수월하다.

 

 

앞서 출력한 10개의 이미지를 레이블과 함께 출력할 수 있다. 위의 레이블과 출력된 값을 비교함으로써 제대로 labelling되었는지 확인할 수 있다. 또한 레이블마다 6,000개의 샘플이 들어있는 것을 확인할 수 있다.

 

<로지스틱 회귀로 패션 아이템 분류하기>

6만개의 데이터를 한꺼번에 훈련하는 것보다 샘플을 하나씩 꺼내서 훈련하는 방법이 더 효율적이지 않을까?

이럴 땐 4장에서 배웠던 경사하강법을 사용해볼 수 있다. 이번 실습에서 사용하는 데이터셋의 경우 각 픽셀이 0-255 사이의 정수값을 가지기 때문에 이를 255로 나누어 0-1사이의 값으로 정규화할 수 있다. 정확한 표준화 방법은 아니지만 이미지를 전처리할 때 널리 사용되는 방법이다.

train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)
print(train_scaled.shape)

SGDClassifier 는 2차원 입력을 다루지 못하기 때문에 1차원 배열로 만든 후 크기에 맞춰 지정하면 샘플의 갯수는 변하지 않고 데이터의 차원이 1차원으로 합쳐진다. 변환된 데이터의 크기를 확인해보면 784개의 픽셀로 이뤄진 6만개의 샘플이 준비된 것을 알 수 있다.

 

from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss = 'log', max_iter = 5, random_state=42)
scores = cross_validate(sc, train_scaled, train_target, n_jobs=-1)
print(np.mean(scores['test_score']))

경사하강법의 반복 횟수를 max_iter =5로 지정하여 성능을 확인해볼 수 있다.

 

 

첫번째 레이블인 티셔츠와 두번째 레이블인 바지에 대해 생각해본다면, 각 레이블마다 다른 가중치(weight) 값과 절편(bias) 값을 적용하여 계산해야 한다. 동일한 픽셀값을 사용하기 때문에 동일한 weight와 bias를 사용한다면 클래스의 구분이 어렵다.

티셔츠를 계산하기 위한 가중치,절편값과 바지를 계산하기 위한 가중치,절편값은 다르다. 회귀를 통해 각 모델 파라미터(가중치,절편)를 찾은 후에는 각 클래스에 대한 확률을 계산하여 얻을 수 있다.

 

<인공 신경망>

인공신경망(Artificial Neural Network, ANN)은 1장에서 배웠듯이, 딥러닝의 다른 이름이기도 하다. 그림으로 신경망을 나타낸다면 위와 같이 나타낼 수 있는데, z1, z2, ..., z10 의 항목들은 티셔츠, 바지,... 등의 항목이다. 여기서 클래스가 총 10개 이므로 z10까지 계산을 하고, 이를 바탕으로 클래스를 예측한다. 신경망의 최종 값을 만든다는 의미에서 출력층(output layer) 이라고 부른다.

인공신경망에서는 z 값을 계산하는 단위를 뉴런(neuron)이라 부르는데, 유닛(unit)이라 부르기도 한다. x1, x2, ..., x784 까지의 항목은 입력층(input layer) 이라 부르는데, 입력층은 픽셀값 자체이고 특별한 계산을 수행하지는 않는다.

z1을 만들기 위해 x1픽셀에 곱해지는 가중치는 w1,1 이라 쓰고 z2를 만들기 위해 x1픽셀에 곱해지는 가중치는 w1,2 이라고 표기하였다. 절편은 뉴런마다 하나씩이기 때문에 b1, b2 등으로 표기하였다.

인공 신경망의 발견으로 올라가자면, (생물학적) 뉴런은 수상 돌기로부터 신호를 받아 신호체에 모은다. 이 신호가 어떤 임계값(threshold)에 도달하면 축삭 돌기를 통해 다른 세포에 신호를 전달한다. (생물학적) 뉴런이 신호를 전달하는 과정에서 영감을 받아 구현한 것이 인공신경망이다. 인공 신경망은 우리 뇌에 있는 뉴런과 같지는 않지만 머신러닝 알고리즘이 해결하지 못했던 문제에서 좋은 성능을 발휘하는 새로운 종류의 머신러닝 알고리즘이다.

인공 신경망, 혹은 심층 신경망(Deep Neural Network, DNN)을 딥러닝이라고 부른다. 심층 신경망은 여러 개의 층을 가진 인공 신경망이다.

 

<텐서플로와 케라스>

텐서플로(tensorflow)는 구글이 오픈소스로 공개한 딥러닝 라이브러리다. 이 때를 기점으로 딥러닝에 관심을 가지는 개발자들이 폭발적으로 증가했고, 텐서플로 출시 이후 알파고가 이세돌9단을 이기며 더욱 폭발적으로 딥러닝 분야가 성장하였다.

텐서플로는 저수준 API와 고수준 API가 있는데, 케라스(keras)가 고수준 API다. 딥러닝 라이브러리가 머신러닝 라이브러리와 다른점은 GPU를 사용하여 인공 신경망을 훈련한다는 점이다. GPU는 벡터연산, 행렬연산에 최적화되어있기 때문에 곱셈과 덧셈계산이 많은 인공 신경망을 계산할 때 많이 사용한다.

케라스 라이브러리는 직접 GPU 연산을 수행하지는 않고, GPU 연산을 수행하는 라이브러리를 백엔드로 사용한다. 예를 들면 텐서플로가 케라스의 백엔드 중 한개이다. 그 외에도 Theano, CNTK 등의 케라스 백엔드 라이브러리가 있다. 구글은 Tensorflow 2.0 이후 대부분의 고수준 API를 정리하고 Keras API만 남겼다. 그래서 거의 Keras와 Tensorflow는 동일한 개념이라고 생각해도 무방하다. 개인적으로 이러한 역사(?) 를 좋아해서 정리해봤다. ㅎㅎㅎ

import tensorflow as tf
from tensorflow import keras

텐서플로에서 케라스를 사용하려면 위와 같이 임포트하여 사용할 수 있다.

 

<인공 신경망으로 모델 만들기>

로지스틱 회귀에서는 교차 검증을 사용하여 모델을 평가하지만, 인공 신경망에서는 교차 검증을 사용하지 않고 검증(validation) 세트를 별도로 덜어내어 사용한다. 그 이유는

첫째로, 딥러닝 데이터셋은 너무 크기 때문이다. 그래서 따로 검증 세트를 덜어내어 사용해도 검증 점수가 안정적이다.
둘째로, 교차 검증을 계산하는 시간이 너무 오래걸린다. 훈련하는 데만 해도 며칠이 걸릴 수 있는데, 검증까지 한다면..?

from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)

test_size=0.2 로 지정하여 훈련 세트의 20%를 검증 세트로 덜어내었다. 훈련 세트 48,000개와 검증 세트 12,000개로 나뉘었다!

밀집층(dense layer)

케라스의 레이어에는 다양한 층이 준비되어 있는데, 그 중 가장 기본은 밀집층(dense layer)이다. 바로 위의 그림 중 밀집층의 그림을 보면, 10개의 뉴런이 모두 연결된 것을 생각해본다면 784 개의 픽셀이기 때문에 총 7,840개의 연결된 선을 볼 수 있다. 양쪽의 뉴런을 모두 연결하기 때문에 완전 연결층(Fully Connected Layer) 이라고 부른다.

인공 신경망

dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))
model = keras.Sequential(dense)

밀집층을 만들기 위해 매개변수를 뉴런 개수를 10개로 지정하고, 뉴런에서 출력되는 값을 확률로 바꾸기 위해서는 softmax 함수를 사용한다. activation 매개변수에 함수를 지정할 수 있고, 만약 2개의 클래스를 분류하는 이진분류라면 sigmoid 함수를 사용할 수 있다.

Sequential 클래스를 사용하면 앞서 만든 밀집층의 객체 dense를 전달할 수 있다. 소프트맥스와 같이 뉴런의 선형 방정식 계산 결과에 적용되는 함수를 활성화 함수(activation function)라 부른다.

 

<인공 신경망으로 패션 아이템 분류하기>

model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
print(train_target[:10])

 

케라스 모델에서 손실 함수의 종류를 지정해줘야한다. 이진 분류는 binary_crossentropy, 다중 분류는 sparse_categorical_crossentropy 로 사용한다.

 

이진 크로스 엔트로피 손실을 위해 -log(예측확률)에 타깃값(정답)을 곱할 수 있다. 이진 분류에서는 출력층의 뉴런이 하나이기 때문에 이 뉴런이 출력하는 확률값 a를 사용하여 양성 클래스와 음성 클래스에 대한 crossentropy를 계산할 수 있다.

두번째 뉴런의 활성화 출력만 남기려면 해당 두번째 원소만 1이고 나머지는 0으로 타깃값을 준비해야 한다. 이런 것을 원-핫 인코딩(one-hot encoding)이라 한다.

 

모델을 돌려보면 evaluate() 메서드가 fit() 메서드와 비슷한 출력을 보여주는 것을 알 수 있다.


# 기본미션

7-1.

Q1. 어떤 인공 신경망의 입력 특성이 100개이고 밀집층에 있는 뉴런 개수가 10개일 때 필요한 모델 파라미터의 개수는 몇 개일까? 
> 10개의 뉴런이 100개의 입력과 연결되기 때문에 1,000개의 가중치가 있고 뉴런마다 1개의 절편이 있기 때문에 1,010개의 모델 파라미터가 있다. 

Q2. 케라스의 Dense 클래스를 사용해 신경망의 출력층을 만들려고 한다. 이진 분류 모델이라면 activation 매개변수에 어떤 활성화함수를 지정해야 할까?
> 이진 분류일 경우 sigmoid를 사용한다.

Q3. 케라스 모델에서 손실함수와 측정지표를 지정하는 메서드는 무엇일까?
> compile() 메서드를 통해 loss 매개변수로 손실함수를 지정하고 metrics 매개변수에서 측정하는 지표를 지정할 수 있다.

Q4. 정수 레이블을 타깃으로 가지는 다중 분류 문제일 때 케라스 모델의 compile() 메서드에 지정할 손실함수로 적절한 것은 무엇일까?
> 타깃값이 다중일 경우에 'sparse_categorical_crossentropy' 를 사용한다.

 

# 선택미션

7-2

Q1. 모델의 add() 메서드 사용법이 올바른 것은 어떤 것일까?
> model.add(keras.layers.Dense(10, activation='relu')

Q2. 크기가 300 x 300인 입력을 케라스 층으로 펼치려고 할 때 어떤 층을 사용해야 할까?
> 입력의 차원을 일렬로 펼치려면 Flatten을 사용한다.

Q3. 이미지 분류를 위한 심층 신경망에 널리 사용되는 케라스의 활성화함수는 무엇일까?
> 'relu' 는 이미지 처리를 위해 자주 사용되는 함수이다.

Q4. 적응적 학습률을 사용하지 않는 옵티마이저는 무엇일까?
> 'sgd'는 모두 일정한 학습률을 사용한다.

 


● 마무리

이번 챕터에서는 딥러닝에서 사용하는 기본적인 개념에 대해 배웠다. 딥러닝은 머신러닝과 다른 부분이 다소 있고, '신경망'이라는 개념이 들어가기 때문에 확실히 입체적으로 접근할 수 있다. 하지만 더 깊게 들어가려면 수학적인 지식이 기본적으로 필요하기 때문에, 선수과목으로 선형대수나 통계/행렬을 배우는 것을 추천한다.

코랩에서 실행한 파일을 공유드리니, 필요하신 분은 다운받아 사용하시면 됩니다.

Chapter07_deep_learning.ipynb
0.05MB

+ Recent posts