2019년 8월 13일 화요일

[GIT] 브랜치 (1)

   참고

   브랜치란 무엇인가

Git은 데이터를 Change Set이나 변경사항(Diff)로 기록하지 않고 일련의 스냅샷으로 기록한다.

커밋하면 Git은 현 Staging Area에 있는 커밋 개체(커밋 Object)를 저장한다(이 때, 커밋 개체는 스냅샷의 포인터, 저자나 커밋 메시지 같은 메타 데이터, 이전 커밋에 대한 포인터 등을 포함한다.). 이전 커밋 포인터가 있어서 현재 커밋이 무엇을 기준으로 바뀌었는지를 알 수 있다.

파일이 3개 있는 디렉토리가 있고 이 파일을 Staging Area에 저장하고 커밋하는 예제를 살펴 보자. 파일을 Stage하면 Git 저장소에 파일을 저장하고(이것을 Blob이라고 부른다) Staging Area에 해당 파일의 체크섬을 저장한다.(checksum은 중복 검사의 한 형태)

git commit을 하면 먼저 루트 디렉토리와 각 하위 디렉토리의 트리 개체를 체크섬과 함께 저장소에 저장한다. 그 다음에 커밋 개체를 만들고 메타데이터와 루트 디렉토리 트리 개체를 가리키는 포인터 정보를 커밋 개체(커밋 Object)에 넣어 저장한다. 그러면 언제든지 스냅샷을 만들 수 있다.

이 작업을 끝내면 저장소에는 5 개의 데이터 개체가 생긴다. 각 파일에 대한 Blob 세 개, 파일과 디렉토리 구조가 들어 있는 트리 개체 하나, 메다 데이터와 루트 트리를 가리키는 포인터가 담긴 커밋 개체 하나이다.



Git에서 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터같은 것이다. 기본적으로 Git 은 master 브랜치를 만든다. 처음 커밋하면 master 브랜치가 생성된 커밋을 가리킨다. 이후 커밋을 만들면 master 브랜치는 자동으로 가장 마지막 커밋을 가리킨다.

새 브랜치 생성하기
testing 브랜치 생성, testing 브랜치를 가리키는 새로운 포인터 생성.
새로 만든 브랜치도 지금 작업하고 있던 마지막 커밋을 가리킴

$ git branch testing



Git은 현재 작업중인 브랜치가 무엇인지를 가리키는 포인터로 HEAD를 사용함.
HEAD 포인터와 현재 브랜치를 가리키는 포인터는 다른 포인터이므로 주의해야 함.

현재 브랜치(포인터들)가 어떤 커밋을 가리키는지 확인.

$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project


*git log 명령어 옵션 조사해볼 것

브랜치 이동하기
checkout으로 HEAD가 가리키는 브랜치를 이동할 수 있음

$ git checkout testing


커밋을 새로 해보면

$ vim test.rb
$ git commit -a -m 'made a change'


testing 브랜치에서 작업을 하고 새로 커밋했기 때문에 testing 브랜치는 앞으로 이동했다. 하지만 master 브랜치는 여전히 이전 커밋을 가리킨다. master로 되돌아가보자.


$ git checkout master


이후 커밋을 하면 다른 브랜치의 자업들과 별개로 testing 브랜치에서 작업이 진행된다. 그래서 testing 브랜치에서 임시로 작업하고 master 브랜치로 돌아와서 하던 일을 계속할 수 있다.

   브랜치와 Merge의 기초
브랜치의 기초
아래와 같은 프로젝트가 존재한다고 가정하자.
그리고 이슈 관리 시스템에 등록된 53번 이슈를 처리한다고 하면 이 이슈에 집중할 브랜치를 만든다. 브랜치를 생성하면서 checkout까지 한번에 처리하려면 -b 옵션을 추가한다.

$ git checkout -b iss53
Switched to a new branch "iss53"

iss53 브랜치를 checkout했기 때문에(HEAD가 iss53을 가리킨다) 일을하고 커밋하면 iss53 브랜치가 앞으로 나간다.


다른 상황을 가정해보자. 프로젝트에 문제가 생겨서 즉시 고쳐야 하는 상황일 때, 버그를 해결한 Hotfix에 iss53이 섞이는 것을 방지하기 위해 iss53과 관련된 코드를 어딘가에 저장해두고 원래 운영 환경의 소스로 복구해야 한다면 master 브랜치로 돌아오면 된다.

하지만 브랜치를 이동하려면 워킹 디렉토리를 정리해야 한다. 아직 커밋하지 않은 파일이 checkout할 브랜치와 충돌나면 브랜치를 변경할 수 없기 때문이다. 지금 작업하던 것을 모두 커밋하고 master 브랜치로 옮긴다.

$ git checkout master
Switched to branch 'master'

그러면 워킹 디렉토리는 53이슈를 시작하기 이전 모습으로 되돌려진다.

핫픽스가 생겼을 때를 살펴보자. 'hotfix' 브랜치를 만들고 문제를 해결할 때까지 사용한다.


$ git checkout -b hotfix
$ vim index.html
$ git commit -a -m 'fixed the broken email address'



운영 환경에 적용하려면 문제를 제대로 코쳤는지 테스트하고 배포하기 위해 hotfix 브랜치를 master 브랜치에 합쳐야 한다. git merge 명령어를 사용하면 된다.


$ git checkout master
$ git merge hotfix

"fast-forward"는 hotfix 포인터가 가리키는 커밋이 master 포인터가 가리키는 커밋에 기반한 브랜치이기 때문에 브랜치 포인터는 merge과정 없이 그저 최신 커밋으로 이동하는 Merge 방식을 말한다.

문제를 해결했으면 다시 일하던 브랜치로 돌아가야 한다. 일하던 브랜치로 돌아가려면 hotfix를 master 브랜치에 적용하고 hotfix 브랜치가 필요없으면 hotfix 브랜치를 삭제한다.


$ git branch -d hotfix

이슈 53번을 처리하던 환경으로 되돌아가서 작업을 마무리 해보자.

git merge master 명령으로 master 브랜치를 iss53 브랜치에 Merge하면 iss53 브랜치에 hotfix가 적용된다. 아니면 iss53 브랜치가 master에 Merge할 수 있는 수준이 될 때까지 기다렸다가 Merge하면 hotfix와 iss53 브랜치가 합쳐진다.

Merge의 기초
53번 이슈를 해결하고 master 브랜치에 merge하는 과정을 살펴보자.


$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

hotfix와 달리 iss53은 현재 master 브랜치( 현재 브랜치가 가리키는 커밋)을 물려받은 것이 아니므로 'Fast-forward' Merge를 하지 않는다. 이 경우 Git은 각 브랜치가 가리키는 커밋들과 공통 조상을 사용하여 3-way Merge를 한다.


3-way Merge의 결과를 별도의 커밋으로 만들고 해당 브랜치가 그 커밋을 가리키도록 한다.


그 후, iss53 브랜치는 더이상 필요하지 않으므로 삭제하고 이슈의 상태를 처리 완료로 표시한다.

충돌의 기초
3-way Merge가 실패할 때도 있다. Merge하는 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하고 Merge하면 Git은 해당 부분을 Merge하지 못한다. 그러면 Git은 Merge 하지 못하고 충돌(Conflict) 메시지를 출력한다.


$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Merge를 하지 못했으므로 새 커밋이 생기지 않는다. Merge 과정을 진행할 수 없다. 충돌이 일어났을 때, 어떤 파일을 Merge 할 수 없었는지 살펴보려면 git status를 이용한다.


$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

충돌이 일어난 파일은 unmerged로 표시된다.

충돌이 일어난 부분을 고치고 git add으로 저장한다.


$ git add index.html

또는 git mergetool 도구로 충돌을 해결할 수도 있다.

$ git mergetool

   브랜치 관리

브랜치 목록 보기
* 기호가 붙어 있는 브랜치는 현재 checkout해서 작업하는 브랜치를 가리킴.
-v 옵션은 브랜치별로 마지막 커밋 메시지도 보여줌

$ git branch
  iss53
* master
  testing
$ git branch -v
  iss53   93b412c fix javascript issue
* master  7a98805 Merge branch 'iss53'
  testing 782fd34 add scott to the author list in the readmes

Merge된 브랜치인지 아닌지 확인하기
* 기초가 붙어 있지 않은 브랜치는 다른 브랜치와 Merge했기 때문에 삭제해도 되는 브랜치를 가리킴.


$ git branch --merged
  iss53
* master

현재 checkout한 브랜치에 Merge 하지 않은 브랜치 보기


$ git branch --no-merged
  testing

2019년 8월 10일 토요일

[GIT] Git 저장소 (1)

   참고
아래의 글은 위의 포스터를 참조하여 정리, 재가공한 글입니다.

   Git 저장소 만들기

기존 디렉토리를 Git 저장소로 만들기
Git으로 관리하고 싶은 프로젝트의 디렉토리로 이동 한 후, 다음 명령어를 실행(.git 디렉토리가 생성. .git 디렉토리는 뼈대 파일임.).

$ git init

Git이 파일을 관리하게 하려면 저장소에 파일을 추가하고 커밋해야 함.

$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'

기존 저장소를 Clone하기
프로젝트의 히스토리를 전부 받아옴.

$ git clone <url>
$ git clone <url> newname

   저장소 수정하고 저장하기

워킹 디렉토리에서 파일의 상태
Tracked(관리대상임)
스냅샷에 포함되어 Git의 관리 대상이 되는 파일.
  • Unmodified(수정하지 않음) 
  • Modified(수정함)
  • Staged(커밋으로 저장소에 기록할 예정)

Untracked(관리대상이 아님)
스냅샷에도 Staging Area에도 포함되지 않는 파일. Git의 관리 대상이 아니기 때문에 버전관리를 할 수 없음.


실제로 커밋을 하기 위해서는 수정이나 추가한 파일을 Staged 상태로 만들고 Staged 상태의 파일을 커밋해야 한다. 파일은 아래의 라이프사이클을 계속 반복한다.



파일의 상태 확인하기

$ git status
$ git status -s

clone을 한 후 Git의 상태

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

위의 내용은
'현재 작업중인 브런치는 master 이며, Tracked(관리하고 있는) 파일은 수정되지 않았고, Untracked 파일은 나타나지 않았다. 그리고 현서버의 같은 브랜치로부터 진행된 작업이 없다.'
는 것을 나타낸다.

* Git의 기본 브랜치의 이름은 master.

README 파일을 새로 만든 후 Git의 상태

$ echo 'My Project' > README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

   README

nothing added to commit but untracked files present (use "git add" to track)

위의 내용은
'현재 작업중인 브랜치는 master이며, commit할 것은 추가되지 않았지만  Untracked(관리하고 있지 않은) 파일이 있으므로 "git add <file> ..."로 untracked 파일을 추가하라'
는 것을 나타낸다.

파일을 새로 추적하기
$ git add README

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Modified 상태의 파일을 Stage 하기
Tracked 파일을 수정하면 modified file로 나온다.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

"Changes not staged for commit"은 수정한 파일이 Tracked 상태이지만 아직 Staged 상태는 아니라는 뜻이다. Staged 상태로 만드려면 git add 해야 한다.
git add 명령어는 프로젝트에 파일을 추가한다는 개념보다 다음 커밋에 추가한다고 이해하는 게 좋다.


$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

다음 커밋내용에 추가되었다. 하지만 커밋하지 않고 같은 파일을 수정하면 Git은 그 파일을 Staged하고 동시에 Unstaged한 파일로 생각한다.


$ vim CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

이전의 커밋버전에 이전의 수정만 입력되었으므로 이번에 수정한 내용을 커밋하려면 git add를 다시 실행해야 한다.


$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Staged와 Unstaged 상태의 변경 내용 보기
Unstaged(add도 하지 않은)상태의 파일과 Staged(add만 하고 commit하지 않은)상태의 파일의 변경 내용 보기

$ git diff

commit한 파일과 Staging Area(add하고 commit하지 않은)에 넣은 파일의 변경 내용 보기

$ git diff --staged
$ git diff --cached

파일 무시하기
Git의 관리가 필요하지 않은 파일을 설정. .gitignore 파일을 다음 규칙에 따라 생성한 후, add, commit 함
  • 아무것도 없는 라인이나, '#'로 시작하는 라인은 무시함
  • 표준 Glob 패턴을 사용한다. 이는 프로젝트 전체에 적용됨
  • 슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않음
  • 디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표시함
  • 느낌표(!)로 시작하는 패턴의 파일은 무시하지 않음
$ nano .gitignore
$ git add .gitignore
$ git commit -m ".gitignore file"

mv, rm
Git은 다른 VCS와 달리 파일 이름의 변경이나 파일의 이동을 관리하지 않으므로 Git이 파일의 이름이 변경되거나 이동된 것을 알 수 있도록 해야 한다.
(아래의 명령어들은 그저 몇가지 명령어를 차례로 수행한 것과 같은 기능을 한다. 그냥 이동하거나 제거하고 ADD했다는 것이다.)


$ git mv file_from file_to
$ git rm file

Origin, Remote and Branch

2019년 8월 9일 금요일

[GIT] Git 설치

   참고

   Git

간단하게 설치하기
Linux
RPM 기반 패키지 시스템을 사용하는 Linux(RHEL, CentOS)


$ sudo dnf install git-all


데비안 계열 Linux


$ sudo apt install git-all


MAC
http://mac.github.com

Windows
http://git-scm.com/download/win

   Git 최초 설정

Git 설정 파일
설정 파일의 종류
  1. /etc/gitconfig: 시스템의 모든 사용자와 모든 저장소에 적용되는 설정

    $ git config --system
    

  2. ~/.gitconfig, ~/.config/git/config: 특정 사용자(현재 사용자)에게만 적용되는 설정

    $ git config --global
    
  3. .git/config: git 디렉토리 안에 존재. 특정 저장소에만 적용되는 설정.
설정 파일의 우선 순위

.git/config  >  ~/.gitconfig, ~/.config/git/config  >  /etc/gitconfig


사용자 정보
커밋할 때마다 이 정보를 사용함. 한 번 커밋한 후에는 정보를 변경할 수 없음.

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

프로젝트마다 다른 이름과 이메일주소를 사용하고 싶을 때

$ git config user.name "John Doe"
$ git config user.email johndoe@example.com


설정 확인


$ git config --list

2019년 8월 7일 수요일

[GIT] log 닫기

   참고

   git log OR git diff를 종료할 때

h: 도움말
q: 종료

[GIT] Git 기초

   참고

   버전 관리란?

VCS(Version Control System)
버전 관리 시스템은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템이다.

로컬 버전 관리
아주 간단한 데이터베이스를 사용해서 파일의 변경 정보를 관리한다.

중앙집중식 버전관리(CVCS)
프로젝트를 진행하는 도중 다른 개발자와 함께 작업을 해야할 경우, 변경 사항을 적절히 관리하여 충돌과 같은 다양한 문제를 방지하는 것이 중요하다. 이런 문제를 해결하기 위해 CVCS가 개발됐는데 CVS, Subversion, Perforce 같은 시스템이 중앙집중식 버전관리에 해당된다.

중앙집중식 버전관리는 파일을 관리하는 서버가 별도로 존재하고 파일을 수정 및 업데이트하는 개발자가 클라이언트가 되어 중앙 서버에서 파일을 받아서 사용(checkout)한다. (이 때, 받아서 사용하는 것을 checkout이라고 하는데, 여기여기여기를 보면 서버에서 클라이언트로 원본 파일과 버전관리를 위한 파일들을 받아오는 행위를 말하는 것 같다.)

중앙 서버에서 프로젝트를 모두 관리할 수 있기 때문에 서버의 관리자와 서버와 연결된 클라이언트들은 모두 누가 무엇을 하고 있는지 알 수 있고, 관리자는 중앙 서버의 파일만 관리하면 되기 때문에 더 잘 관리할 수 있는 장점이 있다.

하지만, 서버에 문제가 생기면 클라이언트들은 서로 다른 클라이언트와 협업할 수 있고, 클라이언트에서 했던 작업을 백업할 방법도 없다. 또한, 서버의 하드디스크에 문제가 생기면 프로젝트의 모든 히스토리를 잃는다. (클라이언트가 가진 스냅샷은 괜찮다.) 로컬 VCS 시스템도 비슷한 결점이 존재한다. (스냅샷이란, 여기를 보면 특정 시간에 저장 장치의 상태를 나타낸다고 말한다. 이 글에서는 checkout할 때 프로젝트의 모든 파일을 말하는 것 같다.)

분산 버전 관리 시스템(DVCS)
Git, Mecurial, Bazaar, Darcs와 같은 시스템이 DVCS에 해당된다. 이와 같은 분산 버전 관리 시스템은 중앙 서버의 기능적 구분이 거의 없다. CVCS에서 클라이언트는 중앙 서버의 파일의 마지막 스냅샷을 checkout한다. 하지만, DVCS는 저장소에서 클라이언트로 가져올 때, 파일 뿐만 아니라 히스토리까지 복제한다.

이런 특징은 CVCS의 단점을 보완할 수 있어서 서버에 문제가 생겨도 복제물로 버전 관리 기능을 완전히 사용할 수 있다. 클라이언트를 통해 서버를 복원할 수 있다는 것이다.

이런 복제행위를 clone이라고 하며 모든 데이터를 가진 진정한 백업이라고 볼 수 있다.

그리고 대부분의 DVCS는 리모트 저장소가 존재한다. (리모트 저장소는 인터넷이나 네트워크 어딘가에 있는 저장소를 말한다. remote는 멀리 떨어진이라는 뜻으로, 먼 곳에 존재하는 저장소를 말한다.) 리모트 저장소가 많을 수도 있어서 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다.

   Git의 기초
Git의 탄생 목표
  • 빠른 속도
  • 단순한 구조
  • 비선형적인 개발(수천 개의 동시 다발적인 브랜치)
  • 완벽한 분산
  • Linux 커널 같은 대형 프로젝트에도 유용할 것(속도나 데이터 크기 면에서)

스냅샷(SnapShot)
Subversion과 같은 시스템과 Git의 가장 큰 차이점은 데이터를 어떻게 다루는지이다. 크게 봤을 때 VCS 시스템 대부분은 관리하는 대상이 파일들의 목록이다. CVS, Subversion 등의 시스템은 각 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리한다(보통 이를 델타 기반 버전관리 시스템이라 함. 아마 Subversion과 같은 시스템은 버전을 저장할 때 스냅샷 자체를 버전으로 저장하는 것 같다.).

Git은 이런 식으로 데이터를 저장하거나 취급하지 않는다. 데이터를 파일 시스템 스냅샷의 연속으로 취급하여 크기가 아주 작다. 파일이 달라지지 않았으면 Git은 성능을 위해 파일을 새로 저장하지 않고 이전 상태의 파일에 대한 링크만 저장한다.

깃의 히스토리는 개념적으로 스냅샷의 연속이자 델타의 연속이기도 하다. Git은 각 시점의 스냅샷을 저장하기도 하지만 그 스냅샷 사이의 델타를 저장하기도 한다.

커밋을 하면 그 시점의 스냅샷이 저장되는데, 커밋은 영구적으로 저장하는 것이기 때문에 델타도 저장되는 것이라 할 수 있다. 필요하면 과거에 저장된 스냅샷들의 델타를 바로 구할 수 있기 때문이다.

Git은 처음에는 이런방식으로 스냅샷들을 저장하고 적절한 시점이 되면 GC(Garbage Collection)이 실행된다. 그러면 마지막 버전의 스냅샷의 파일만 통째로 저장하고 이전 버전들은 델타만 저장한다. 또한, GC는 델타로 저장한 것을 gzip으로 압축하기 때문에 실제로 저장하는 용량이 더욱 작아진다.

세 가지 상태
  • Committed, 데이터가 로컬 데이터베이스에 안전하게 저장됐다.
  • Modified, 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않았다.
  • Staged, 현재 수정한 파일을 곧 커밋할 것이라고 표시했다.
이 세 가지 상태는 Git 프로젝트의 세 가지 단계와 연결돼 있다. Git 디렉토리, 워킹 트리, Staging Area 세 단계이다.

Git directory는 Git이 프로젝트의 메타 데이터와 객체 데이터베이스를 저장하는 곳을 말한다. 이것이 Git의 핵심이다. 저장소를 clone할 때 만들어진다.

워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것이다. Git 디렉토리는 지금 작업하는 디스크에 있고 그 디렉토리 안에 압축된 데이터베이스에서 파일을 가져와서 워킹 트리를 만든다.

Staging Area는 Git 디렉토리에 있다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다. Git에서는 기술용어로는 “Index” 라고 하지만, “Staging Area” 라는 용어를 써도 상관 없다. (아마 git add를 한 후의 상태인 것 같다.)

Git으로 하는 일은 기본적으로 아래와 같다.
  1. 워킹 트리에서 파일을 수정한다.
  2. Staging Area에 파일을 Stage 해서 커밋할 스냅샷을 만든다. 모든 파일을 추가할 수도 있고 선택하여 추가할 수도 있다. (git add)
  3. Staging Area에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장한다. (git commit)
Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged이다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified이다.

   Git 설치

설치 명령어는 무의미한 받아쓰기가 될 것 같아 링크로 대체한다.

Git 설치

2019년 8월 6일 화요일

[세미나 발표] Colab

   발표 자료

   PCA 발표_ajh

* 차원의 저주: 고차원으로 갈수록 성능이 떨어진다.

* PCA와 Convolution Layer은 같은 기능을 한다. 특징을 찾는 기능이다.

* PCA의 단점
  - 선형으로만 축을 찾아낸다. 비선형 주축은 찾을 수 없다.
  - 특징들의 범위 차이가 너무 클 때, 축을 찾기 힘들다.
  - 하나의 주축을 찾은 후, 더 좋은 주축을 찾기 힘들다.

다음주에 다시 발표하기로 함


2019년 8월 1일 목요일

Convolution vs Cross-correlation


   참조
https://tensorflow.blog/2017/12/21/convolution-vs-cross-correlation/

Andrew Ng CNN

이 글은 위 강의와 게시글을 참조하여 개인적으로 정리한 글입니다.

   Convolution VS Cross-correlation

CNN(Convolutional Neural Network)에서 사용되는 convolution 연산은 수학에서 의미하는 convolution 연산과 다르다.

CNN에서 사용하는 convolution 연산은 실제로 cross-correlation이라 부르고, 연산 행렬과 피연산 행렬의 같은 위치의 값들을 각각 곱한 후 모두 더한 값을 출력으로 낸다.


수학에서 의미하는 convolution 연산은 조금 달리 연산 행렬의 가로행과 세로행을 바꾼 후 값들을 각각 곱하고 모두 더하는 연산을 한다.
가로행과 세로행을 바꾸는 부분을 넣지 않아도 실제 연산결과와 크게 차이가 없기 때문에 그 과정을 생략한 후 계산하지만 Machine Learning 에서는 통상적으로 Convolutional neural network라고 부른다.


2019년 7월 17일 수요일

[백설공주 거울과 인공지능 이야기] Machine Learning 용어 정리 (2)


   개요
백설공주 거울과 인공지능 이야기 - 오제키 마사유키

이 글은 위의 책을 보고 필요한 부분을 발췌하여 가공한 글입니다.

Machine Learning에 대한 책을 찾아보던 중 위의 책이 머신러닝의 기초 용어들에 대해 잘 정리해 둔 것 같아 정리해 둔다.

책의 화자는 백설공주의 계모인 왕비가 가진 마법 거울이다. 계모는 자신의 미모가 어떤 수치를 가지고 있는지를 알아내고자 마법 거울을 학습시킨다.

   소제목

분리 초평면( Separating Hyperplane)
파라미터 값으로 영역이 나뉘어질 때, 나눠지는 영역의 경계를 나타낸 것이다.

퍼셉트론(Perceptron)
분리 초평면을 움직이면서 공간을 나누는 모형을 말한다. 1950년대에 프랭크 로젠블랫(Frank Rosenblatt)이 사람의 뇌를 모방하여 만든 것으로, 학습을 통해 자율적으로 식별하기 위한 방법으로 고안되었다.

서포트 벡터 머신(Support Vector Machine)
마진이 가능한 한 커지도록 분리 초평면을 설정한느 방법을 말한다. 이 기법은 퍼셉트론보다 조금 늦은 1960년대 블라디미르 바프닉(Vladimir Vapnik)에 의해 고안되었다.

분리 대상이 되는 데이터 점과 분리 초평면의 거리를 고려에 넣어 분리 초평면을 결정한다. 다층 신경망을 이용하여 분리가 잘 되는 비선형 변환을 찾기 위한 최적화 문제를 푸는 것이다.

커널법(Kernel Method)
특징값을 있는 그대로 사용하는 대신, 비선형 변환을 거쳐 변형하여 사용한다는 아이디어다.

변형 후의 거리에 대한 척도를 바꾸는 방법으로 사용하게 될 비선형 변환을 결정하는 것이다. 거리 계산이 쉬우며, 까다로운 비선형 변환을 직접 도입하지 않고 장점만을 누릴 수 있다.

희소(Sparse)
중요도가 떨어지는 특징값의 가중치를 0으로 만들어 특징값을 학습에 고려하지 않을 수 있다. 중요하지 않은 특징값을 0으로 만들었을 때, 요소 대부분이 0인 상태를 희소하다라고 한다.

희소 모델(Sparse Modeling)
희소한 상태를 만들기 위한 방법을 말한다.

볼츠만 머신(Boltzmann Machine)
어떤 자리에는 어떤 색이 자주 나오고, 어떤 색 픽셀 주변에는 어떤 색이 자주 나오는 경향이 있다. 이렇게 위치에 따른 관계성을 학습해서 이미지를 만들어 낼 수 ㅣㅇㅆ는 모형을 말한다.

볼츠만 머신러닝
볼츠만 머신에 이미지 데이터를 입력하고 데이터와 모형을 부합시키면 실제 이미지의 특징, 관계성의 경향을 학습하는 것을 말한다.

우도(Likelihood)
그럴듯함

앞먹임 신경망(Feedforward Neural Network)
일단 입력이 들어가면 출력을 향해 한쪽으로만 정보가 전달되는 것이다.

양방향 신경망(Bidirectional Neural Network)
입력이 양쪽방향으로 전달되면서 학습되는 것이다.

마르코프 체인 몬테카를로(Markov Chain MonteCarlo, MCMC)
마르코프 연쇄의 구성에 기반한 확률 분포로부터 원하는 분포의 정적 분포를 갖는 표본을 추출하는 알고리즘의 한 부류이다.

평균장 근사(Mean Field Approximation)

신뢰전파(Belief Propagation)

제약 볼츠만 머신(Restricted Boltzmann Machine, RBM)
DBN이라고 하는 딥러닝의 일종인 심층신뢰신경망을 구성하는 기본적인 요소이다.

대조적 발산(Contrastive Divergence)
RBM을 학습하기 위한 알고리즘이다.

딥 볼츠만 머신(Deep Boltzmann Machines, DBM)

차원축소(Dimensionality Reduction)
특징값의 수를 줄이는 방법

전이학습(Transfer Learning)


※ 설명을 남기지 않은 부분은 음.. 책만으로 이해하기 어려워서 나중에 다시 깊이 정리해보려고 한다.

2019년 7월 12일 금요일

Cross-Entropy


   출처

   Cross Entropy

Information, 정보는 추상적인 개념이므로 정보의 양을 나타낼 때 '놀람의 정도'로 나타낸다.

Entropy, 엔트로피는 그런 정보의 평균을 말하는데, 정보의 평균이라는 것은 한 개의 사건이 있을 때, 그 사건에 대한 일어날 확률과 일어나지 않을 확률의 평균이라고 생각하면 된다.

> Entropy 계산
  A사건에 대해 두가지 경우의 결과가 존재할 때, 각 결과가 일어날 확률을 a, b라고 할 때 수학적 계산은 다음과 같다.

  E(-log P(x)) = a(발생확률)*-log(정보량=놀람의 정도) + b*-log(정보량=놀람의 정도)

KL-divergence, 상대적인 엔트로피를 뜻한다. 사건이 일어날 확률을 예측했을 때, 예측한 값에서 실제 발생한 확률을 뺀 값을 의미한다. (실제 확률에서 예측한 확률 값을 빼는 경우는 KL-divergence에 해당하지 않으므로 거리값으로 사용할 수 없다.)

> KL-divergence 계산
  A사건에 대해 예측한 엔트로피를 Q라고 하고 실제 엔트로피를 P라고 했을 때, 수학적 계산은 다음과 같다.

  KL-divergence = relative entropy = E(-log(Q(x))) - E(-log(P(x)))


  ※ KL-divergence 값은 항상 0이상이라는 성질은 jensen 부등식으로 증명된다고 한다.

KL은 예측한 확률이 실제와 같아질수록 0에 가까워진다.

Cross Entropy
하지만 실제 엔트로피는 구할 수 없으므로 KL-divergence를 minimize 하려면, E(-log(Q(x)))를 minimize해야 한다.

이 때, minimize해야 하는 E(-log(Q(x)))를 cross entropy라고 한다.

2019년 7월 11일 목요일

opencv install


 OS  Ubuntu 16.04 LTS
 VERSION  Opencv 4.0.1



   참고
https://webnautes.tistory.com/1030
https://stackoverflow.com/questions/45518317/in-source-builds-are-not-allowed-in-cmake

   CMake Error


cmake 하는데 계속 에러가 남.
저 에러가 난 이유는 CMakeCache.txt 파일을 지우면 해결됐지만, cmake가 안됐음.

해결
opencv4.0.1 폴더에 build 폴더를 만들라고 했는데, cmake를 build 폴더 안에서 해야됐던 거임.

$ cd build
$ sudo cmake ../



2019년 7월 3일 수요일

[백설공주 거울과 인공지능 이야기] Machine Learning 용어 정리 (1)


   개요
백설공주 거울과 인공지능 이야기 - 오제키 마사유키

이 글은 위의 책을 보고 필요한 부분을 발췌하여 가공한 글입니다.

Machine Learning에 대한 책을 찾아보던 중 위의 책이 머신러닝의 기초 용어들에 대해 잘 정리해 둔 것 같아 정리해 둔다.

책의 화자는 백설공주의 계모인 왕비가 가진 마법 거울이다. 계모는 자신의 미모가 어떤 수치를 가지고 있는지를 알아내고자 마법 거울을 학습시킨다.

   소제목

특징값
기계는 추상적인 말을 이해할 수 없기 때문에 추상적인 말을 표현하기 위해서는 수치화해야 한다.
이 때, 추상적인 것을 수치화하기 위해서는 추상적인 것의 어떤 점을 보아야 하는지를 알아야 하는데, 추상적인 것의 어떤 점을 수치로 나타낸 것을 특징값이라고 한다.

데이터
특징값을 많이 모아놓은 것을 데이터라고 한다.

특징값 벡터
숫자를 모아 놓은 것을 벡터라고 하고 특징 값을 나타낸 숫자들을 모아 놓은 것을 특징값 벡터라고 한다.
A를 나타내기 위한 특징값 벡터에는 A에 대한 정보만 들어 있어야 한다.

컴퓨터의 학습
책의 비유에 따라 왕비가 자신의 미모가 어떤 수치를 가지고 있는지 말하게 하려 할 때, 컴퓨터가 하는 일은 특징값 벡터 x를 입력했을 때, 이 사람이 얼마나 예쁜지를 출력하는 함수를 만드는 것이다.

컴퓨터는 어떻게 학습하는가?
우선 컴퓨터는 적당한 함수를 출발점으로 하여 이 함수의 모양을 데이터에 맞춰서 미세조정한다.

파라미터
일차함수로 가정하였을 때, 직선의 모양을 결정하려면 기울기와 직선의 위치를 결정해 주어야 한다. 이 두 값이 바로 직선을 결정하는 파라미터가 된다. 이와같이 함수를 결정하는 값들을 파라미터라고 한다.

함수를 조정하는 방법은?
파라미터 값을 바꿔 주면 여러 직선을 만들 수 있다.

정방향 문제(Forward Problem)
함수가 주어져 있을 때, 어떤 입력에 대한 함수의 출력 값을 구하는 문제를 말한다.

역방향 문제(Backward Problem)
입력과 출력 사이의 관계가 이미 존재할 때, 이 관계와 모순되지 않는 함수를 찾아내는 문제를 말한다.

머신러닝(Machine Learning)
서로 관련있는 입력값과 출력값을 데이터로 주었을 때, 데이터에 함수가 부합하도록 파라미터를 움직여 맞푸는 과정을 학습이라고 한다. 그리고 이렇게 함수를 찾는 과정을 자동으로 수행하는 것이 머신러닝이다.
함수를 결정하는 파라미터를 조금씩 바꿔가면서 그 중 모든 데이터를 가장 잘 나타낼 수 있는 함수 하나를 찾는다.

최적화 문제(Optimization Problem)
컴퓨터는 함수를 추정하면서 출력이 데이터와 부합하도록 반복해서 파라미터를 조정한다. 정확도를 높이기 위해 파라미터를 반복 조정하는 것이다. 이와 같이 함수의 출력과 데이터의 오차가 적은 최적의 함수를 찾는 문제를 최적화 문제라고 한다.
정확도나 점수가 최대가 되도록, 만점을 목표로 파라미터를 미세 조정하는 문제를 말한다.

가중치(Weight)
한 데이터를 나타내는 특징값이 여러 개일 때, 어떤 특징값은 데이터를 나타내는 데 중요할 수도 중요하지 않을 수도 있다. 이런 중요도를 나타내는 값을 가중치라고 한다.
가중치는 학습해야 하는 함수의 파라미터로 가중치를 바꿔가면서 고정된 데이터에 함수의 모양을 맞준다.

모형(Model)
데이터에 맞는 함수를 학습할 때, 컴퓨터가 추정하여 학습하는 함수를 모형이라고도 한다.

오차함수(Error Function)
모형의 출력과 데이터가 얼마나 들어맞는지를 알아보기 위해 사용하는 것이다.
데이터와 모형의 출력이 얼마나 다른지를 나타내는 지표로 오차함수 값이 최대한 작아지도록 하는 것이 학습의 목표가 된다.

머신러닝에 맡기고 싶은 일이 무엇이냐에 따라 적합한 오차함수도 달라진다.

제곱합(Sum of Squares)
오차함수의 한 종류이다. 각 데이터와 모형의 출력값의 차를 제곱하여 합한 값인데, 데이터와 출력의 차이가 음수이든 양수이든 차이가 나는 것은 같기 때문에 제곱한 값을 기준으로 하면 편리하다.

지도학습(Supervised Learning)
데이터에 맞춰 오차함수 값을 줄이는 방법으로 데이터에 잠재된 입력과 출력의 관계를 학습하는 것이다. 실제 문제에서는 오차함수 값이 완전히 사라지는 경우는 드물기 때문에 개새는 오차함수 값이 가장 작아지는 것을 목표로 한다. 가능한 한 출력과 데이터의 차이가 작아지도록 하는 것이다.

비지도학습(Unsupervised Learning)
출력 값이 없는 경우에 사용한다. 데이터의 구조나 특징의 유사도 혹은 경향 같은 것을 기준으로 그룹을 나누는 작업인 클러스터링(Clustering) 등에 사용된다.
비지도학습의 개념은 매우 중요하다. 데이터를 있는 그대로 보지 않고 그룹으로 나눠진 결과를 보아야 발견할 수 있는 것도 있다.
ex) 이런 그룹에 속하는 사람은 피부 관리에 신경을 쓰는구나 등

미분(Derivative)
최적화 문제를 쉽게 푸는 요령에는 레버(파라미터, 가중치)를 살짝 움직여보고 오차가 줄어드는지 확인한 후 해당 레버를 움직이는 방법이 있다. 이 때, 레버를 살짝 움직여보는 과정을 미분이라고 한다.

경사 하강법(Gradient Descent)
학습의 목적은 오차를 줄이는 것으로, 미분을 통해 줄이는 방향이 맞는지 확인하고 오차가 줄어드는 게 멈출 때까지 레버(가중치)를 움직인다.
이렇게 오차가 줄어드는 방향으로 가중치를 조정해 가는 과정을 경사 하강법이라고 한다. 레버를 조금씩 움직일 때 오차가 어떻게 변하는지를 알아보는 방법인 미분, 이 미분 결과를 이용해서 최소가 될 때까지 오차를 점점 줄여나가는 것이다.

경사 하강법의 취약점
미분으로 알 수 있는 것은 레버를 아주 살짝 움직였을 때 오차가 어떻게 변할지 정도만이다. 아주 가까운 주변에 대해서만 알 수 있는 방법이기 때문에 그보다 거리가 멀어지게 되면 알 수 없게 된다. 전체 범위에서 최대로 작아진 것인지는 알 수 없다는 뜻이다.
다시 말하자면, 경사 하강법으로 다다를 수 있는 지점은 극소점(Local minima)이다. 이 극소점은 반드시 최소점(Global minimum)이 되지는 않는다.

훈련 데이터(Training Data)
데이터에 맞는 최적의 함수를 찾는 학습 과정에서 사용되는 데이터이다.

테스트 데이터(Test Data)
훈련 데이터로 학습한 결과를 적용하여 오차가 얼마나 생기는지 살펴보는 데 사용하는 데이터이다.
학습에 사용되지 않은 테스트 데이터에도 정확한 예측을 내릴 수 있다면 학습이 잘 되었다고 볼 수 있다. 반대로 예측이 정확하지 못하다면 학습이 잘 되지 않은 것이다.

일반화 성능(Generalized Performance)
일부 데이터만으로 학습한 후 전체 데이터로 모델을 사용하였을 때 보이는 성능을 말한다. 머신러닝의 요점은 이 일반화 성능을 좋게 하는 것이라 할 수 있다.

과적합(Overfitting)
훈련 데이터에 대한 예측은 정확한데 테스트 데이터에 대한 예측이 정확하지 못한 경우를 말한다. 연습문제를 가지고 시험공부를 열심히 해서 연습문제는 만점인데 정작 시험문제는 못 푸는 상황과 같다.

교차검증(Cross Validation)
가지고 있는 데이터의 종류를 훈련 데이터와 테스트 데이터로 나누어서 검증하는 것을 말한다. 가장 많이 쓰이는 방법은 데이터를 몇 갈래로 나누어서 그 중 한 갈래를 테스트 데이터 나머지 모두를 훈련 데이터로 삼는 방법이다.

예를 들어, 데이터를 4개로 나누었다면 하나는 테스트 데이터, 나머지 셋은 훈련 데이터로 사용한다.
테스트 데이터로 사용할 조각을 바꿔가면서 같은 과정을 반복한다(여기서는 4회 반복). 그렇게 모든 과정에서 예측이 정확한지 알아보는 것이다.


   소제목

알고리즘에서 배울 수 있는 것

같은 문제를 푸는 알고리즘에도 여러 방법이 있다. 이들 각각은 다른 특징을 갖고 있다. 계산량 등이 이런 특징으로 꼽을 수 있는데, 계산량이란 퍼즐을 푸는 데 얼만큼의 단계가 필요한지를 나타내는 척도라고 할 수 있다. 계산량이 적다면 문제를 푸는 데 걸리는 단계 수가 적으므로 간단한 문제라고 판단할 수 있다. 그러나 계산 과정에서 기억해 두어야 하는 중간 계산 값이 있는 문제처럼 메모리의 사용량이 늘어나는 경우도 있다.
계산량 외에도 이러한 메모리 사용량, 또 계산장치와 기억장치 사이에 정보가 오가게 되는 횟수 등 다양한 요소를 고려한 계산 과정을 누구나 그대로 수행할 수 있도록 표현한 것이 알고리즘이다.

알고리즘 연구의 역사를 거슬러 올라가면 배울 점이 아주 많다. 연구할 여지는 다시 말해 해결해야 할 약점이 있다는 의미다. 이러한 약점과 해결책의 관계를 파악할 수 있다면 다른 문제를 푸는 알고리즘에서 비슷한 한계에 부닥치게 되었을 때 대처할 수 있을 것이다. 알고리즘 공부는 현재 맞닥뜨린 문제를 풀기 위해 과거의 경험으로부터 힌트를 얻을 수 있는 효과적인 방법이다.


2019년 4월 9일 화요일

[세미나 발표] Logistic Regression Classification


   참조
아래의 게시글은 모두의 딥러닝 강의를 참조하여 재가공한 글입니다.

   Classification이란?

Classification은 Supervised Learning의 일종이다. 학습을 위해 이미 분류된 데이터를 주는데, 이 데이터를 기반으로 데이터의 Category 관계를 파악한다.

주어진 데이터로 학습을 완료한 후에는 새롭게 주어진 데이터를 Category에 분류할 수 있게 된다.


  • Spam Email Detection: Spam (1) or Ham (0)
  • Facebook feed: Show (1) or hide (0)
  • Credit Card Fraudulnet Transaction Detection: Legitimate (1) or Fraud (0)

   Logistic Regression Classification
어떻게 Classification 할 것인가?
그렇다면 Logistic Regression Classification은 어떻게 그룹을 나눈다는 것일까? 우선 가장 간단한 모델인 Linear 모델을 통해 Classification하면서 생각해보자.

위와 같은 데이터가 주어졌다고 가정하고, 이 데이터를 Classification해보자. Linear한 모델을 통해 Classification한다면 다음과 같은 모델을 예상할 수 있을 것이다.

2개의 그룹으로 데이터를 나눠야 하기 때문에 y축을 절반으로 나눌 수 있는 값을 0.5로 정하면 데이터를 두 그룹으로 나누는 x축의 값을 구할 수 있다. 이제 이 모델을 사용하여 데이터가 0그룹에 속하는지 1그룹에 속하는지 데이터의 hours의 값으로 구분할 수 있게 되었다.

이 모델은 얼핏 완성된 것처럼 보이지만, Linear 모델은 한계를 가진다. 새로운 데이터 가 들어왔을 때를 살펴보자.
현재까지 학습된 모델은 새로운 데이터와 맞지 않으니 새로운 데이터를 포함할 수 있는 모델을 다시 학습해야 한다.
새로운 데이터를 포함한 새로운 모델을 만들었으나 문제가 생긴다. 이전에 1에 속했던 데이터들이 더 이상 1그룹에 속하지 못하게 되었다.

이 예시는 다소 비약적일 수 있으나 Linear 모델의 한계를 잘 보여주는 예시이다. 위의 예시에서 볼 수 있는 문제 외에도 Linear 모델의 경우 학습한 데이터의 범위를 넘어가는 경우가 생길 수 있기 때문에 문제가 생길 수 있다.

Logistic Regression
그런 Linear한 모델의 한계점을 보완하기 위해 사용할 수 있는 방법중 하나가 Logistic Regression이다.

Logistic Regression은 통계 기법으로 일종의 확률 모델으로(로지스틱의 자세한 사항은 이 블로그가 도움되더라.) 아래 그림과 같은 모양을 가진다.


Logistic Regression Classification
Logistic Regression Classification은 Linear 모델을 Logistic Regression을 지나도록 하려 Non-Linear하게 만들어 Linear 모델의 한계점을 보완한 Classification을 말한다.

Linear 모델에 Logistic Regression만 추가하여 사용하면 좋겠지만, Linear 모델에 Logistic Regression만 추가하면 문제가 생긴다.

머신러닝은 문제를 해결하는데 최적의 weight 값을 찾아가는 과정이다. 그렇기 때문에 cost(비용, err값)을 구하고 구한 cost를 통해 weight값을 수정하는 과정이 필수적이다.

그래서 Linear 모델에 Logistic Regression을 추가시킨 후에도 cost를 구하고 weight를 수정해야 한다. Linear Regression에서 사용한 Cost Function은 아래 그림과 같다.
이 그래프의 장점은 Convex하다는 것이다. Convex한 함수는 처음 시작 지점이 어디든 최저점을 찾을 수 있는 매우 편리한 그래프라는 것이다.

Linear Regression에서 사용한 Cost Function은 Convex한 그래프이지만 Logistic Regression을 사용한 모델의 Cost Function은 Convex한 모양을 유지하지 못한다.
그렇기 때문에 Logistic Classification은 Cost Function을 변형하여 사용한다.