-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.json
1 lines (1 loc) · 50.6 KB
/
index.json
1
[{"categories":["Machine Learning"],"content":"시리즈를 시작하면서 머신러닝의 개념을 처음 접한 것은 대학에 입학했던 2016년도 였고, 구글 DeepMind 사의 AlphaGo와 이세돌의 대국이 이루어지고 있었습니다. 과거의 데이터에서 암묵적인 패턴과 규칙을 학습하고, 새로운 데이터에 이를 적용하여 즉각적으로 충분한 대답을 추론한다는 아이디어는 명시적인 지식만을 습득해왔던 저에게 있어서 정말 놀라웠습니다. 그렇기 때문에 어떻게 하면 과거의 데이터에서 패턴을 학습하여 모델로 만들 수 있는지에 대해서 강의, 책, 스터디, 블로그 포스트 등을 전전하며 조금씩 공부해왔으나, 정돈된 자료의 형태로 기록되어 있지 않아서 항상 아쉬움이 남고는 했습니다. 이 일련의 Machine Learning from Scratch 시리즈는 앞선 개인적인 고민을 해소하고, 이미 좋은 자료가 많이 공유되어 있지만 조금이라도 머신러닝을 새롭게 혹은 계속해서 배우고 있으신 분들에게 도움이 되었으면 좋겠다는 마음으로 연재를 시작하게 되었습니다. 연재의 전체적인 순서는 머신 러닝을 배우는데 있어서 가장 기초가 된다고 할 수 있는 Coursera 앤드류 응 교수님의 강의, Machine Learning을 기반으로 할 것이며, 대학에서 강의를 들었던 이재식 교수님의 저서 데이터 애널리틱스(2020, 위키북스)의 내용도 함께 정리하고자 합니다. 저도 공부하는 계속해서 공부하는 입장이기에 제가 아는 선에서는 최대한 수리적인 내용(e.g., 선형대수, 통계 등등)을 담을 수 있고자 하였고, 이부분이 아니더라도 Python numpy를 이용한 구현이나 모델의 인사이트를 포함한 경영학적 함의를 기술하여 이 글을 읽고 계신 여러 분야의 독자 분들께 도움이 되었으면 좋겠습니다. P.S. 밑바닥 부터 시작하는(from Scratch)라는 명칭은 이미 다들 아시겠지만, 제가 개인적으로 좋아하는 시리즈인 O’reilly 사의 밑바닥 부터 시작하는 데이터과학(Data Science from Scratch), 밑바닥 부터 시작하는 딥러닝(Deep Learning from Scratch)를 패러디한 것 입니다. ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:0:0","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"1. Machine Learning with numpy numpy는 수학 및 과학 연산을 위한 Python의 기본 패키지입니다. [공식 홈페이지] 코세라 Machine Learning 수업의 경우, 수치계산용 언어인 MATLAB 혹은 Octave로 과제를 진행하게 됩니다. 벡터 및 행렬 연산이 언어 자체에 정의되어 있으므로 별다른 라이브러리를 사용할 필요 없이 모델의 구현이 가능하다는 장점이 있습니다. 하지만 그 본질은 결국 벡터와 행렬 연산이기 때문에, 어떤 프로그래밍 언어로 구현하시더라도 원리만 이해한다면 쉽게 구현하실 수 있을 것입니다. 본래 수강할때는 자료에 맞추어 Octave로 구현했었으나, 이 시리즈에서는 Python으로 구현하고자 합니다. 그 중 numpy 라는 라이브러리를 사용할 것인데, C/C++, Fortran으로 작성되어 빠르면서도 정교한 수학 연산, 특히 벡터 및 행렬(선형대수) 연산이 가능하기 때문입니다. numpy의 강점 a powerful N-dimensional array object sophisticated (broadcasting) functions tools for integrating C/C++ and Fortran code useful linear algebra, Fourier transform, and random number capabilities 또한 numpy의 array 자료형은 Python의 딥러닝 라이브러리 양대산맥이라 할 수 있는 Pytorch의 tensor 자료형과도 쉽게 상호 전환이 되기 때문에 실질적인 모델링에도 부분적으로 활용될 수 있습니다. 추가로 numpy 기반의 연산과 모델링을 그대로 GPU 프로그래밍으로 전환시킬 수 있는 CUDA 기반의 CuPy라는 라이브러리도 존재하고 있습니다. 따라서 본인이 밑바닥부터 쌓아올리며 공부한 코드를 몇줄의 수정만으로도 실제 프로젝트에 적용해볼 수 있을 것입니다. ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:1:0","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"2. Linear Algebra with numpy ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:2:0","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"2.1. numpy 기초 관습적으로 numpy를 import 할때, np라는 약어를 사용하고 있습니다. import numpy as np 배열 생성 numpy의 자료 클래스를 ndarray(N-Dimensional Array)라고 합니다. np.array() 기존의 python list, tuple 등으로 생성 dtype을 조정하여 데이터 타입 지정 가능 print(np.array([2,3,4])) # 리스트를 이용한 array 생성 print(np.array([(1.5,2,3), (4,5,6)])) # 튜플을 이용한 array 생성 a = np.array( [ [1,2], [3,4] ], dtype=complex) # 데이터타입 지정 (복소수) print(type(a)) np.arrange() 범위를 지정하여 array 생성 첫번째와 두번째 인자로 range를 결정하고, 세번째 인자로 간격을 결정 np.arange(10, 30, 5) ## Output: array([10, 15, 20, 25]) np.zeros() or np.ones() or np.empty() 지정된 사이즈만큼의 array 생성 (순서대로 각각 0, 1, 초기화되지 않은 값) np.zeros((3,4)) # 3행 4열 크기의 모든 값이 0인 2차원 배열 # Out # array([[ 0., 0., 0., 0.], # [ 0., 0., 0., 0.], # [ 0., 0., 0., 0.]]) np.ones((2,3,4), dtype=np.int16) # (2, 3, 4) 크기의 모든 값이 정수 1인 3차원 배열 # Out # array([[[1, 1, 1, 1], # [1, 1, 1, 1], # [1, 1, 1, 1]], # [[1, 1, 1, 1], # [1, 1, 1, 1], # [1, 1, 1, 1]]], dtype=int16) np.empty((2,3), dtype=np.double) # (2, 3) 크기의 초기화되지 않은 값을 실수로 가지는 2차원 배열 # Out # array([[ 0., 0., 0.], # [ 0., 0., 0.]]) 산술 연산 ndarray는 기초적인 산술 연산을 지원하는데, +,-, *, /를 지원합니다. 이 연산들은 같은 자리의 성분끼리 연산되는 element-wise 방식으로, 기본적으로는 원소의 수가 같을 때 연산이 가능합니다. x = np.array([1.0, 2.0, 3.0]) y = np.array([2.0, 4.0, 6.0]) print(x + y) # 원소별 덧셈 [1.0 + 2.0, 2.0 + 4.0, 3.0 + 6.0] print(x - y) # 원소별 뺄셈 [1.0 - 2.0, 2.0 - 4.0, 3.0 - 6.0] print(x * y) # 원소별 곱셈 [1.0 * 2.0, 2.0 * 4.0, 3.0 * 6.0] print(x / y) # 원소별 나눗셈 [1.0 / 2.0, 2.0 / 4.0, 3.0 / 6.0] 다만 다음 그림1과 같이 boradcasting 이라는 방법으로 서로 다른 크기의 ndarray 간에도 연산이 가능한 경우가 있습니다. 따라서 본인의 의도에만 맞게 사용된다면 배열의 shape를 수정할 필요없이 바로 산술 연산을 적용할 수 있다는 장점이 있습니다. 그림1. broadcasting의 예시\" 그림1. broadcasting의 예시 [출처: “Computation on Arrays: Broadcasting\"] x = np.arange(3) x + 5 # [0 + 5, 1 + 5, 2 + 5] N 차원 배열 그림2 에서는 머신러닝을 적용하는 데이터가 이루고 있는 대부분의 형태를 보여주고 있습니다. 여기서는 소개하지 않겠지만, Pandas의 Series 형태의 데이터가 1D array와 같은 모양을 보이게 될 것이고, 데이터 프레임의 경우 2D array의 형태를 보여주게 될 것입니다. 3D array의 경우 주로 sequence를 가진 데이터를 다루게될 때 자주 접할 수 있는 차원이며, 4D array는 이미지 데이터를 다루게된다면 접하게되실 수도 있을 것 같습니다. 앞으로 연재하게될 데이터의 자료형태에 따른 모델링에서 해당 부분을 더욱 자세하게 다룰 수 있도록 하겠고, 여기서는 각 차원을 어떻게 생성하는지만 보여드리도록 하겠습니다. 그림2. 1 ~ 3차원의 배열에 대한 시각적 자료와 축(axis)의 위치\" 그림2. 1 ~ 3차원의 배열에 대한 시각적 자료와 축(axis)의 위치 [출처: “파이썬 데이터 사이언스 Cheat Sheet: NumPy 기초, 기본\"] A = np.array([1, 2, 3]) # 1D array B = np.array([[1, 2, 3], [4, 5, 6]]) # 2D array C = np.array([[[1, 2, 3], [4, 5, 6]], # 3D array [[7, 8, 9], [10, 11, 12]]]) print(A.shape, B.shape, C.shape) # (3,) (2, 3) (2, 2, 3) ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:2:1","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"2.2. 벡터 및 행렬 연산 벡터 연산 다음과 같은 벡터의 연산을 어떻게 구현할 수 있을지에 대해서도 한번 고민해보시면 좋을 것 같습니다. $$\\vec{a} = (1, 2, 3)$$ $$\\vec{b} = (4, 5, 6)$$ $$\\therefore \\vec{a} + \\vec{b} = (5, 7, 9)$$ numpy를 활용하면 위에서 봤던 것처럼 아주 간단하게 벡터를 생성하고 연산이 가능한데, 우선 기본적인 python만을 통해서 구현한 결과는 다음과 같습니다. python list a = [1, 2, 3] b = [4, 5, 6] print(a + b) # python의 리스트에서는 이게 아니다. print([a_i + b_i for a_i, b_i in zip(a, b)]) # zip 함수를 써서 묶고, list comprehension def vector_sum(a, b): # 함수화 return [a_i + b_i for a_i, b_i in zip(a, b)] numpy ndarray import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) print(a + b) 행렬 연산 기존의 ndarray 형태로도 물론 행렬에 관한 연산을 수행할 수 있지만, numpy에서는 보다 간편하게 행렬의 연산을 가능하게 하는 matrix의 데이터형도 제공하고 있습니다. np.array로 생성하던 것처럼 np.mat으로 생성할 수 있으며, 이미 존재하는 ndarray를 입력으로 받아서도 생성할 수 있습니다. # numpy.ndarray A = np.array([[1, 2], [2, 3]]) B = np.array([[1, 0], [2, 5]]) # numpy.matrix C = np.mat(A) D = np.mat([[1, 0], [2, 5]]) 두 데이터형의 연산을 비교하면 꽤나 유의미한 차이를 발견할 수 있습니다. 바로 기본 곱셈 연산을 어떻게 처리하는지에 관한 것인데, ndarray의 경우 같은 위치에 있는 원소간에 곱을 하는 element-wise 곱셈을 하지만 matrix의 경우 행렬곱 연산을 하게 됩니다. ndarray에서는 행렬곱을 하기 위해 np.dot(A, B)를 해야하므로 조금 더 직관적으로 행렬 연산을 통한 머신러닝 모델 구축을 하기 위해서는 matrix 데이터형이 조금 더 적합한 것을 알 수 있습니다. print(A * B) # elemnet-wise mul print(np.dot(A, B)) # or A.dot(B) print(C * D) # 행렬의 곱 # Out 1 [[ 1 0] [ 4 15]] # Out 2 [[ 5 10] [ 8 15]] # Out 3 [[ 5 10] [ 8 15]] 행렬곱이 아닌 행렬 간 덧셈, 그리고 스칼라곱은 두 데이터형에서 모두 예상하는 것처럼 작동합니다. print(A + B) print(C + D) print(3 * A) print(3 * C) # Out 행렬간 덧셈 [[2 2] [4 8]] # Out 스칼라곱 [[3 6] [6 9]] 다음으로는 특수한 연산인 전치(transpose) 행렬, 역(inverse) 행렬, 그리고 **특이값 분해(singular value decomposition)**에 대해서 알아보도록 하겠습니다. 전치(transpose) 행렬 전치 행렬은 행렬의 행과 열을 바꾸는 것으로 numpy의 배열의 property 중 T를 사용하여 쉽게 구할 수 있습니다. 향후 예측 혹은 분류 모델을 만들게 될 때, 여러 feature 열들을 포함한 행렬과 가중치 행렬 등을 곱하기 위해 중요하게 활용될 것입니다. B.T # Out # array([[1, 4], # [2, 5], # [3, 6]]) 역(inverse) 행렬 ndarray의 경우 numpy.linalg.inv() 라는 함수를 통해 구할 수 있습니다. matrix의 경우 간단하게 속성 중 I라는 속성을 호출하면 됩니다. ⚠ 다만 주의할 것은 ndarray의 경우 shape가 정방 행렬이 아니라면 pseudo inverse를 구할 수 있는 numpy.linalg.pinv()를 적용해야한다는 점입니다. 물론 matrix의 경우 정방 행렬이 아니더라도 동일하게 I 속성으로 값을 구할 수 있습니다. 😆 np.linalg.inv(A) # array([[-3., 2.], # [ 2., -1.]]) C.I # array([[-3., 2.], # [ 2., -1.]]) 특이값 분해 numpy.linalg.svd()라는 함수를 통해 구할 수 있습니다. 위에서 사용했던 numpy의 선형대수 관련 모듈은 향후에 더 자세하게 다루도록 하겠습니다. 인덱싱 원소에 대한 접근 X = np.array([[51, 55], [14, 19], [0, 4]]) print(X) print(f\"0행 {X[0]}\") # 0행 [51 55] print(f\"(0, 1) 위치의 원소 {X[0][1]}\") # (0, 1) 위치의 원소 55 for indexing # 모든 row를 순서대로 출력 for row in X: print(row) bool indexing condition = X \u003e 15 # 15 초과인 값만 subsetting하고자 할 경우 print(condition) X[condition] ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:2:2","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"3. Linear Algebra Application ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:3:0","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"3.1. 성적 처리 이름 중간 기말 수행 학생1 100 50 90 학생2 70 85 80 학생3 45 75 100 위와 같은 1학기의 성적표가 있고, (중간, 기말, 수행)의 반영 비율이 (35%, 45%, 20%) 일때의 총점 계산을 선형대수적으로 처리해 보겠습니다. 우선 위의 점수 테이블과 반영 비율을 각각, 행렬과 벡터로 표기하면 아래와 같습니다. (간단한 예시이므로, 각 영역별 총점이 모두 100점이라 가정하겠습니다) $$ X = \\begin{bmatrix} 100 \u0026 50 \u0026 90 \\\\ 70 \u0026 85 \u0026 80 \\\\ 45 \u0026 75 \u0026 100 \\end{bmatrix} $$ $$\\vec{p} = \\begin{bmatrix} 0.35 \u0026 0.45 \u0026 0.2 \\end{bmatrix} ^T$$ 따라서 이렇게 표현된 두 행렬의 곱을 통해 손쉽게 원하는 결과를 얻을 수 있게되는 것입니다. $$X \\cdot \\vec{p} = \\begin{bmatrix} 100 \u0026 50 \u0026 90 \\\\ 70 \u0026 85 \u0026 80 \\\\ 45 \u0026 75 \u0026 100 \\end{bmatrix} \\cdot \\begin{bmatrix} 0.35 \\\\ 0.45 \\\\ 0.2 \\end{bmatrix} $$ import numpy as np X = np.mat([[100, 50, 90], [70, 85, 80], [45, 75, 100]]) p = np.mat([0.35, 0.45, 0.2]).T print(X * p) # [[75.5 ] 학생1 # [78.75] 학생2 # [69.5 ]] 학생3 ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:3:1","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"3.2. 기술 통계(Descriptive statistics) 기술 통계는 정보 수집의 특징을 정량적으로 설명하거나 요약하는 요약 통계입니다[1]. 즉, 데이터를 요약, 설명하는데 초점이 맞추어져 있으며 다음과 같이 크게 2가지 기법이 있습니다. 집중화 경향 (Central tendency): 데이터가 어떤 값에 집중되어 있는가? 평균(Mean, Average) 분산도(Variation): 데이터가 어떻게 퍼져 있는가? 분산(Variance), 표준편차(Standard Deviation) 데이터의 갯수가 $n$개 이고, 데이터의 각 성분을 $d_i$로 표현할 때, $$\\text{Mean} = \\cfrac{d_1 + d_2 + \\cdots + d_n}{n} = \\cfrac{\\sum d_i}{n} = \\bar{d}$$ $$\\begin{aligned} \\text{Variance} \u0026= \\cfrac{(d_1 - \\bar{d})^2 + (d_2 - \\bar{d})^2 + \\cdots + (d_n - \\bar{d})^2}{n - 1} \\ \u0026= \\cfrac{\\sum (d_i - \\bar{d})^2}{n - 1} = \\sigma^2\\end{aligned}$$ $$\\text{Standard Deviation} = \\sqrt{\\sigma^2} = \\sigma$$ 그러면 머신러닝의 대표적인 예제 데이터 중 하나인 붓꽃(iris) 데이터에서 기술 통계량을 직접 구해보는 과정을 보여드리겠습니다. import numpy as np data = np.loadtxt(\"data/iris.csv\", delimiter=\",\", dtype=np.float32) d = data[:, 1:5] n = d.shape[0] data_mean = d.sum(axis=0) / n print(f\"각 열의 평균: {data_mean}\") data_var = ((d - data_mean)**2 ).sum(axis=0) / (n - 1) print(f\"각 열의 분산: {data_var}\") data_std = data_var**(1/2) print(f\"각 열의 표준편차: {data_std}\") 각 열의 평균: [ 5.84333333 3.05733333 3.758 1.19933333] 각 열의 분산: [ 0.68569351 0.18997942 3.11627785 0.58100626] 각 열의 표준편차: [ 0.82806613 0.43586628 1.76529823 0.76223767] ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:3:2","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"3.3. 기울기 하강법(Gradient Descent Method) 기울기 하강법이란 어떤 함수의 최솟값을 찾기 위해 그 함수를 1차 미분해서 기울기를 구한 후 그 기울기를 따라 내려가면서 최솟값을 찾는 방법이다. -데이터 애널리틱스(이재식, 2020)- 그림3. 비용(Cost) 함수 또는 손실(Loss) 함수에서의 기울기 하강법 적용\" 그림3. 비용(Cost) 함수 또는 손실(Loss) 함수에서의 기울기 하강법 적용 출처: “[Coursera Machine Learning - 읽기 자료]\"] 마지막으로 소개해드릴 응용 방안 중 하나는 앞으로 상당히 중요하게 쓰이는 기울기 하강법(or 경사 하강법)입니다. 머신러닝에서는 목적으로 하는 Task(e.g., 예측, 분류 등)를 잘 수행하기 위해서 완벽한 답을 찾기 보다는 최적의, 충분한 답을 찾기 위해 노력합니다. 기울기 하강법은 이러한 목적에 부합한 정답의 근사치(Approximation)를 찾기 위해 답안을 수정해나가는 방법론 중 하나로 이해하시면 좋을 것 같습니다. 시리즈의 바로 다음 글 부터는 그림3과 같이 기울기 하강법을 통해 가중치를 수정해나가는 과정을 보여드릴 것이므로, 여기서는 기본적인 이해를 위해 간단한 예시만 다루어보도록 하겠습니다. 우선 이차 함수 $f(x) = x^2 -2x + 3$의 최솟값을 구하는 상황을 가정해보겠습니다. 우리는 여기서 식을 $f(x) = (x - 1)^2 + 2$ 로 변환할 수 있고, 따라서 최솟값이 $2$라는 것을 금방 구살 수 있습니다. 하지만 컴퓨터의 수치계산으로는 이것을 어떻게 구할 수 있을지가 직면한 문제상황이라고 할 수 있습니다. 기울기 하강법의 아이디어로 문제를 푼다면 무작위의 위치에서 시작하고, 해당 위치에서 기울기가 가파르다면 값을 크게 수정하고 기울기가 완만하다면 값을 작게 수정하는 전략으로 설명될 수 있습니다. 따라서 이를 식으로 표현하면 다음과 같습니다. $$x_{t+1} = x_t - \\alpha \\cdot \\cfrac{df(x_t)}{dx_t} $$ 위 식을 통해 알 수 있는 것은 새로운 값의 수정을 위해서 기울기를 얼마만큼 반영하여 수정할 것이고, 최솟값을 구하고자 하는 함수의 도함수를 알아야한다는 것입니다. 도함수의 경우 $f’(x) = g(x) = 2x - 2$로 비교적 쉽게 구할 수 있고, $\\alpha = 0.3$으로 설정해보겠습니다. def f(x): return x**2 - 2*x + 3 def g(x): return 2*x -2 x = np.array([10]) # 시작 위치 x=10 alpha = 0.3 for i in range(10): x = x - alpha * g(x) print(f\"수정된 x: {x} \\t해당 함수값: {f(x)}\") # 수정된 x: [4.6] 해당 함수값: [14.96] # 수정된 x: [2.44] 해당 함수값: [4.0736] # 수정된 x: [1.576] 해당 함수값: [2.331776] # 수정된 x: [1.2304] 해당 함수값: [2.05308416] # 수정된 x: [1.09216] 해당 함수값: [2.00849347] # 수정된 x: [1.036864] 해당 함수값: [2.00135895] # 수정된 x: [1.0147456] 해당 함수값: [2.00021743] # 수정된 x: [1.00589824] 해당 함수값: [2.00003479] # 수정된 x: [1.0023593] 해당 함수값: [2.00000557] # 수정된 x: [1.00094372] 해당 함수값: [2.00000089] 이로써 최솟값을 만족하는 조건이 $x=1$ 일 경우이며, 값이 $2$로 근사해간다는 사실을 확인할 수 있었습니다. x 의 시작값이나 $\\alpha$를 다양한 값으로 조절하며 실험을 해보더라도, 적당한 반복만 주어지게 되면 앞선 최솟값을 만족하는 조건으로 수렴한다는 사실을 확인하실 수 있습니다. 마치며 항상 정리해야지하고 마음만 먹은 뒤에 코드만 대충 작성했던 부분을 드디어 한곳에 모아 정리하기 시작했다는 점에서 감회가 새로운 것 같습니다. 일단 시작을 했다는 점에서 절반(?)은 했다는 안도감도들지만, 시리즈의 첫글이자 오랜만에 작성하는 글이다보니 두서 없고 부족한 부분이 많기 때문에, 글에서 제가 오류를 범한 부분이나 추가적으로 필요한 부분에 대한 충고나 조언은 항상 감사히 받고 반영하도록 하겠습니다. 긴 글 읽어주셔서 감사합니다! 😂 Reference Coursera Machine Learning Week1: Linear Regression with One Variable Week1: Linear Algebra Review Numpy 밑바닥 부터 시작하는 딥러닝 Ch01 [github] numpy 공식 문서 quickstart [doc] 응용 파트 기술통계와 추리 통계란 무엇인가? [tistory] ","date":"2021-01-09","objectID":"/2021/01/ml-from-scratch-1/:3:3","tags":["python","linear algebra","gradient descent"],"title":"Machine Learning from Scratch - 1: Introduction","uri":"/2021/01/ml-from-scratch-1/"},{"categories":["Machine Learning"],"content":"Introduction fastai는 Pytorch 기반의 딥러닝 API로 딥러닝 기술을 누구나 쉽게 이용할 수 있도록 하는 것을 목표로 하며 강의와 라이브러리를 제공합니다. 이 글을 시작으로하는 Deep Learning with fastai 시리즈는 fastai의 강의를 정리하는 목적과 더불어, 실제로 실습을 진행하면서 새롭게 알게된 점이나 느낀점을 공유하고자 하는 목적을 가지고 있습니다. 첫강의의 내용은 강아지와 고양이의 품종 분류로 이미지 분류에 대해서 Quick Start 방식으로 내용을 진행하며, 이 강의 내용만으로도 fastai 가 추구하는 방향에 대해서 어렴풋이 알 수 있을 것입니다. 비단 첫강의 뿐만 아니라 강의 스타일 자체가 Top-Down 방식으로 진행되어, 우선 실습해보고 이를 기반으로 이론에 대해서 알아보는 방식이니 참고하시면 좋을 것 같습니다. 여기서 사용된 실습 자료는 Github Fastai-Practice 레포지터리에서 공유되고 있으며 해당 주소는 다음과 같습니다. https://github.com/sanghoho/Fastai-Practice/blob/master/Week%201/Study_Week_1_fastai.ipynb ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:0:0","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"Requirement fastai 라이브러리는 pytorch를 기반으로 만들어졌기 때문에 GPU 연산을 지원합니다. 그렇기 때문에 실습 시 GPU를 갖춘 클라우드 서버 환경을 준비하신다면, 원활한 실습을 진행하실 수 있습니다. 이에 적합한 환경은 구글에서 제공하는 **Colab**으로 기본적으로 fastai 라이브러리가 이미 설치되어 있기 때문에, Colab 환경에서 실습을 진행하였습니다. ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:1:0","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"Colab GPU 셋팅 우선 Colab에서 제공하는 GPU를 사용하시려면, 런타임 \u003e 런타임 유형 변경 을 클릭하시고 노트 설정이 뜨면, 하드웨어 가속기를 GPU로 설정해주시면 됩니다. ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:1:1","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"Google Drive 연동 다음은 구글 드라이브 연동 과정입니다. 이번 실습에서는 크게 중요하지 않지만, 앞으로 구글 드라이브에서 데이터를 읽어오고 결과를 저장하는 등의 작업을 하기 위해서는 구글 드라이브와의 연동이 필수적입니다. from google.colab import drive drive.mount('/content/gdrive', force_remount=True) 위의 코드를 실행하면 구글 로그인과 연계가 되고, 최종적으로는 인증키를 반환합니다. 이 키를 복사하셔서 Colab의 결과창에 입력해주시면 해당 계정의 구글드라이브와 연동이 됩니다. from pathlib import Path root_dir = Path(\"/content/gdrive/My Drive/Colab Notebooks/\" ) base_dir = root_dir / 'B-Cube-DA-1' 연동된 구글 드라이브의 진짜 root_dir은 /content/gdrive/My Drive/ 까지 입니다. 이 경로 이후로는 자신의 구글드라이브 작업 환경에 따라 다를 것입니다. 위의 코드는 경로 설정과 관련된 코드로, python의 pathlib 에 속한 Path 클래스를 이용하였습니다. 초기 경로가 지정된 Path 클래스는 / 연산자를 통해 손쉽게 경로를 추가할 수 있습니다. ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:1:2","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"Import fastai 이번 실습에서는 이미지 데이터를 다루기 때문에, fastai.vision 을 import 하면 됩니다. 필요한 메소드나 속성들만 가져올 수 있지만, 편의상 * 를 사용하여 모두 사용가능하게 합니다. 그리고 의존하고 있는 다양한 라이브러리들이 함께 불러와지기 때문에 pytorch, pandas, numpy등의 함수도 별다른 import 과정 없이 사용가능합니다. from fastai.vision import * from fastai.metrics import error_rate 2020년 7월 15일 기준으로 fastai 라이브러리 이용시 많은 경고 메세지가 발생하는 것을 확인하실 수 있습니다. 이는 Pytorch의 버전에 따른 문제로, 다음의 코드로 Pytorch를 설치해주시면 경고 메세지 없이 사용하실 수 있습니다. !pip install \"torch==1.4\" \"torchvision==0.5.0\" ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:1:3","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"1. fastai Quick Start 앞서 말씀드린 것처럼 이번 글에서는 강아지와 고양이의 품종 분류 문제를 풀기 위해 이미지 데이터를 활용합니다. 즉 이미지 분류(Image Classification)인데 fastai는 크게 3단계의 프로세스로 진행됩니다. 데이터 준비 (DataBunch) 모델 생성 및 학습 (Learner) 모델 해석 (ClassificationInterpretation) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:2:0","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"1.1. 데이터 준비 사용할 데이터는 O. M. Parkhi et al., 2012에서 사용된 Oxford-IIIT Pet Dataset 데이터입니다. 이 데이터는 12종의 고양이와 25종의 개를 가지고 있고, 만들어볼 모델은 이러한 37가지의 다른 종들을 구별해 낼 것입니다. 해당 논문의 연구결과에 따르면, 2012년 기준 가장 높은 정확도는 59.21% 였습니다. 이는 “이미지”, “머리”, 그리고 “몸\"을 사진으로부터 분리해서 만들어낸 다소 복잡한 모델의 성능입니다. fastai 에서는 Pytorch 공식문서에서 제공하는 예제 데이터나 기타 여러 데이터들을 쉽게 다운로드 받을 수 있도록 untar_data 함수와 URLs 클래스를 제공하고 있습니다. 이 untar_data 함수에 URLs에 속한 url을 인자로서 넘겨주면, 자동으로 데이터를 다운 받고 추출(untar)하게 됩니다. path = untar_data(URLs.PETS) path # 다운로드된 데이터 폴더의 구조를 확인 path.ls() path_anno = path/'annotations' path_img = path/'images' # 이미지들의 파일이름을 확인하기 위한 함수 사용 fnames = get_image_files(path_img) fnames[:5] 파일의 라벨링 규칙을 확인한 결과 정규표현식을 사용해야 하며, 이를 통해 DataBunch 생성합니다. np.random.seed(2) pat = r'/([^/]+)_\\d+.jpg$' data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs).normalize(imagenet_stats) # 샘플링된 데이터와 클래스를 확인 data.show_batch(rows=3, figsize=(7,6)) # 분류 클래스를 확인하는 코드입니다. print(data.classes) len(data.classes),data.c ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:2:1","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"1.2. 모델 생성 및 학습 DataBunch를 정상적으로 생성하셨다면, Learner라는 것을 만들어서 모델의 생성 및 학습을 진행하실 수 있습니다. 자주 사용하게될 Learner는 CNN(Convolutional Neural Network) 기반으로 cnn_learner로 생성합니다. 인자 설명 data는 앞서 만든 DataBunch 입니다. model 은 어떤 CNN 아키텍쳐를 쓸지에 관한 것으로, URLs와 유사하게 models라는 클래스를 사용하여 다양한 아키텍쳐 구조와 사전학습된 파라미터를 가져올 수 있습니다. metrics는 학습간에 어떤 출력을 보여줄지 learn = cnn_learner(data, models.resnet34, metrics=error_rate) 추가설명 기존 강의 자료에서는 ConvLearner 라고 나와있는데 cnn_learner 로 변경되었습니다. learn.fit_one_cycle(4) 손쉽게 약 92%의 정확도를 가지는 품종 분류 모델을 생성하였습니다! # 자신이 원하는 경로에 학습 결과를 저장할 수 있습니다. learn.save(base_dir/ 'stage-1', return_path=True) 저장된 pth 파일\" 저장된 pth 파일 ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:2:2","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"1.3. 모델 해석 fastai 라이브러리는 모델을 학습하는하는 것에서 끝나는 것이 아니라, 이를 분석할 수 있는 기능 또한 포함하고 있습니다. 학습이 완료된 Learner 를 ClassificationInterpretation.from_learner() 에 입력하여 생성합니다. interp = ClassificationInterpretation.from_learner(learn) losses,idxs = interp.top_losses() len(data.valid_ds)==len(losses)==len(idxs) # 해석에는 validatoin set 을 사용함 먼저 모델이 가장 혼란스러워한 데이터셋에 대해 살펴 보겠습니다. interp.plot_top_losses(9, figsize=(15,11)) interp.plot_confusion_matrix(figsize=(12,12), dpi=60) Confusion Matrix를 이용하면 한눈에 어느 클래스들 간에 혼동이 잦았는지에 대해서 파악할 수 있습니다. interp.most_confused(min_val=2) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:2:3","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"2. fastai Advanced Start 이번 섹션에서는 앞서 학습한 모델의 성능을 높일 수 있는 방법에 대해서 알아보고자 합니다. ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:3:0","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"2.1. Unfreezing and fine-tuning unfreezing은 사전학습 파라미터들을 파인튜닝(fine-tuning)하기 위해 사용됩니다. 처음에 사전 학습 파라미터를 사용하는 Learner를 생성하게 되면 마지막단에서 분류를 진행하는 레이어만 학습을 통해 파라미터가 조정됩니다. 즉, 이미지의 특징을 잡아주는 Convolution 레이어는 잠겨있는데, unfreeze() 함수로 잠금장치를 풀어주는 것과 같습니다. Unfreeze를 하는 이유 레딧 관련글 [link] fastai 포럼 [link] learn.unfreeze() learn.fit_one_cycle(1) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:3:1","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"2.2. learning rates fastai 는 적합한 학습률(learning rate)를 찾아주는 lr_find() 함수도 제공하고 있습니다. lr_find는 학습률을 점점 올려가면서 손실에 관한 탐색을 진행하고, 발산하게 되면 탐색을 멈추게 됩니다. 본격적인 파인튜닝을 위해 다시 이전에 학습된 결과를 불러오겠습니다. learn.load(base_dir / 'stage-1'); learn.unfreeze() # 학습률 탐색 및 시각화 learn.lr_find() learn.recorder.plot(suggestion=True) ## 어느 부분이 적합한지 추가로 표시 learn.fit_one_cycle(2, max_lr=slice(1e-6,1e-4)) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:3:2","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"2.3. Change Architecture Deep Learning은 층이 깊어질 수록 더욱 해당 Task를 잘 학습하는 방향으로 발전하게 되었고, 가장 대표적인 아키텍쳐는 ResNet일 것입니다. 이 아키텍쳐는 층이 깊어질수록 성능이 떨어졌던 기존의 아키텍쳐들의 문제를 해결하여 층이 깊어질수록 더 좋은 효과를 내고 있습니다. ResNet에 대해서는 차후의 강의에서 더욱 심도깊게 다룰 것이고, 지금은 품종분류에서 더 좋은 성능을 낼 수 있도록 34층(resnet34)에서 50층(resnet50)으로 아키텍쳐를 바꿔서 학습을 해보도록 하겠습니다. 혹시 이에 관한 읽을 자료가 필요하시다면 이미지 분류 모델의 발전 과정에 대한 블로그 포스트를 참조하시면 좋을 것 같습니다. 더욱 깊어진 아키텍쳐로 인해서 GPU 메모리가 부족하다는 경고를 보게 된다면, batch 사이즈를 줄여서 이를 해결할 수 있습니다. data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=299, bs=bs//2).normalize(imagenet_stats) learn = cnn_learner(data, models.resnet50, metrics=error_rate) learn.lr_find() learn.recorder.plot() learn.fit_one_cycle(8) learn.save(base_dir / 'stage-1-50') 성능 향상을 위한과정 learn.unfreeze() learn.fit_one_cycle(3, max_lr=slice(1e-6,1e-4)) learn.load(base_dir / 'stage-1-50') 결과 분석 interp = ClassificationInterpretation.from_learner(learn) interp.most_confused(min_val=2) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:3:3","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3. $(+\\alpha)$ MNIST Dataset 유명한 손글씨 분류 데이터셋인 MNIST 데이터셋으로 손글씨 분류기를 만들어보도록 하겠습니다. 여기서는 학습과정보다 다양한 방법으로 데이터를 준비하는 과정을 유의하여 보면 좋을 것 같습니다. 자세한 함수군들에 대한 설명은 해당 공식문서를 확인해주시면 됩니다. path = untar_data(URLs.MNIST_SAMPLE); path 손글씨 데이터는 좌우 반전등의 데이터 변형 기법들이 적용되면 안되기 때문에, get_transforms(do_filp=False) 를 이용합니다. tfms = get_transforms(do_flip=False) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:0","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.1. from_folder data = ImageDataBunch.from_folder(path, ds_tfms=tfms, size=26) data.show_batch(rows=3, figsize=(5,5)) 이번에는 error_rate가 아닌 accuracy를 표시해보도록 하였습니다. learn = cnn_learner(data, models.resnet18, metrics=accuracy) learn.fit(2) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:1","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.2. from_csv data = ImageDataBunch.from_csv(path, ds_tfms=tfms, size=28) ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:2","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.3. from_df df = pd.read_csv(path/'labels.csv') df.head() data = ImageDataBunch.from_df(path, df, ds_tfms=tfms, size=24) data.classes ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:3","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.4. from_name_re fn_paths = [path/name for name in df['name']]; fn_paths[:2] pat = r\"/(\\d)/\\d+\\.png$\" data = ImageDataBunch.from_name_re(path, fn_paths, pat=pat, ds_tfms=tfms, size=24) data.classes ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:4","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.5. from_name_func data = ImageDataBunch.from_name_func(path, fn_paths, ds_tfms=tfms, size=24, label_func = lambda x: '3' if '/3/' in str(x) else '7') data.classes labels = [('3' if '/3/' in str(x) else '7') for x in fn_paths] labels[:5] ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:5","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":["Machine Learning"],"content":"3.6. from_lists data = ImageDataBunch.from_lists(path, fn_paths, labels=labels, ds_tfms=tfms, size=24) data.classes Conclusion 이번 글에서는 강아지와 고양이의 품종 분류 문제를 풀어나가는 fastai Quickstart를 중점적으로 다루었고, 성능 향상을 위한 몇몇 방법들, 그리고 DataBunch를 만들기 위한 다양한 방법들에 대해서도 알아보았습니다. fastai 사용해보면서 느낀점은 모델링 작업을 하다보면 편의상 필요로 하는 부분들을 잘 구현해주어 보다 쉬운 사용이 가능하다는 것입니다. 또한 뒤에서 자세하게 다루겠지만, 전이학습(Transfer Learning) 및 One Cycle Policy가 잘 적용되어 있어서 대부분의 상황에서 좋은 모델 결과를 기대할 수 있습니다. fastai 시리즈는 강의를 기반으로 하지만, 포스팅 순서는 강의의 순서를 따르지는 않습니다. 앞으로의 포스팅 순서에 대해서 간략하게 말씀드리면 이번에는 이미지 분류 문제만을 다루어 보았는데, 이미지 데이터를 활용한 더욱 다양한 방법론들을 다루어 볼 것입니다. 다음으로는 테이블 데이터의 활용과 추천 시스템, 그리고 자연어 처리 (Natural Language Processing)의 순서로 진행할 예정입니다. 감사합니다! Reference 수업 실습 자료 [ipynb] 수업 강의 영상 [Video] 강의 상세 설명 [Github] Pytorch 공식 튜토리얼 [Doc] ","date":"2020-07-10","objectID":"/2020/07/fastai-1-quickstart/:4:6","tags":["fastai","python","colab"],"title":"Deep Learning with Fastai - 1: Quick Start","uri":"/2020/07/fastai-1-quickstart/"},{"categories":null,"content":"안녕하세요 이 블로그는 Hugo 기반 블로그로, 주로 머신러닝과 개발 관련 포스트를 올릴 생각입니다. 제가 진행했던 프로젝트나 개인 공부에서 배운 내용들이 시간이 지나가면서 잊혀지는 것이 아쉽기도 해서 이를 기록으로 남겨 놓자는 목적과, 공유를 함으로써 조금이라도 관련 분야를 공부하시는 분들께 도움이 되고자 하는 목적이 있습니다. 혹시 글에서 부족한점이 있어서 조언해주실 것이 있거나, 궁금하신 점이 있다면 언제라도 제 메일(ash1151@ajou.ac.kr)로 연락해주시면 감사하겠습니다. ","date":"2020-07-10","objectID":"/about/:0:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"Education Ansan Dongsan Christian High School, Ansan, Gyeonggi, South Korea (Mar 2012 ~ Feb 2015) Department of e-Business, Ajou University(AU), Suwon, South Korea (Mar 2016 ~ Present) ","date":"2020-07-10","objectID":"/about/:1:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"Interest Fields Natural Language Processing Satellite Image Processing Embedding Linear Algebra Probability and Statistic Bayesian Statistic Data Visualization ","date":"2020-07-10","objectID":"/about/:2:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"Skils Programming Python R Web (html, css, js (specially Vanila JS)) Java (specially Android) C# (specially WPF) Go Octave ETC Web Crawling ","date":"2020-07-10","objectID":"/about/:3:0","tags":null,"title":"About","uri":"/about/"},{"categories":null,"content":"Research Ahn, S., Kang, J., \u0026 Park, S. (2017). What makes the difference between popular games and unpopular games? analysis of online game reviews from steam platform using word2vec and bass model. ICIC Express Letters, 11(12), 1729-1737.[link] [Google Scholar] Ahn, S., Ko, H., \u0026 Kang, J. (2021). Regularized Categorical Embedding for Effective Demand Forecasting of Bike Sharing System. In Data Science and Digital Transformation in the Fourth Industrial Revolution (pp. 179-193). Springer, Cham. [Google Scholar] ","date":"2020-07-10","objectID":"/about/:4:0","tags":null,"title":"About","uri":"/about/"},{"categories":["Development"],"content":"This article shows the basic Markdown syntax and format.","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"Introduction 요즘은 정말 많은 블로그들이 운영되면서 양질의 정보들을 제공해주고 있습니다. 한국에서도 예전부터 다음, 네이버 블로그, 그리고 티스토리 등을 통해서 다양한 정보들이 제공되어 왔습니다. 그리고 최근들어서는 github 블로그, Medium 등의 매체로 전세계적으로 더욱 양질의 정보들이 제공되고 있습니다. 따라서 이 글에서는 github 블로그를 생성하도록 도와주는 많은 기술들 중, Go 언어 기반의 정적 웹사이트 생성기(Static Website Generator)를 소개해보고자 합니다. Hugo Quick Start 글을 통해 OS별 설치, 주요 명령어, 블로그 프리뷰 및 생성 까지 알아가실 수 있습니다. git을 사용하기 때문에, 우선 사전에 git 환경을 구성해주시면 되겠습니다. git: https://git-scm.com/downloads ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:0:0","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"1. Hugo 설치 Hugo로 블로그를 생성하기 위한 첫번째 단계로 Hugo를 설치해야 합니다. 제가 작업하고 있는 환경은 Ubuntu 20.04로 Linux 환경입니다. Unix 기반의 Linux와 MacOS의 경우 Hugo를 설치하는 방법이 상당히 간단합니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:1:0","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"1.1. Ubuntu sudo apt-get install hugo ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:1:1","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"1.2. MacOS brew install hugo ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:1:2","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"1.3. Windows 윈도우의 경우 휴고에서 릴리즈 버전만 다운 받아서 C 드라이브 밑에 압축을 해제한 파일을 넣어주고, 환경 변수를 세팅해주면 됩니다. 예를 들면 저는 C:\\Hugo\\bin에 해당 파일들을 넣어주고 환경변수에 해당 폴더 경로를 추가하였습니다. 이렇게 환경변수까지 설정해준다면, 윈도우에서도 cmd나 powershell을 띄워서 Hugo 명령어를 사용할 수 있습니다. 이렇듯 위의 방법들로 자신의 OS에 맞게 Hugo를 설치해주셨다면, 다음의 명령어로 현재 Hugo Version을 확인하여 정상적으로 설치가 되었는지 확인해줍니다. hugo version Hugo Version Check\" Hugo Version Check ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:1:3","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"2. Hugo 사이트 생성 이제 hugo의 사이트 생성 기능을 포함한 다양한 기능을 사용할 수 있습니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:2:0","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"2.1. new site new 키워드로 할 수 있는 작업은 크게 두가지로, 새로운 블로그 프로젝트를 생성할 때 사용가능합니다. hugo new site quickstart 다음의 명령어로 저희는 quickstart라는 폴더안에 새로운 블로그 프로젝트를 생성한 것입니다. 해당 프로젝트는 처음보면 복잡한 구조로 되어 있는데, 향후 Hugo에 관한 자세한 글을 작성하여 설명드리도록 하겠습니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:2:1","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"2.2. new posts new 키워드는 또한 새로운 포스트를 만들때도 사용할 수 있습니다. cd ./quickstart hugo new posts/my-first-post.md 해당 명령어를 통해 저희의 프로젝트에서 content/posts/my-frist-post.md라는 markdown) 문서가 생성되었습니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:2:2","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"3. Hugo 테마 사용하기 지금의 상태로는 프로젝트를 실행하더라도 아무것도 보이지 않는 상태일 것입니다. 이는 현재 블로그를 어떻게 보여줄지에 대한 테마가 지정되지 않았기 때문입니다. themes 폴더에서 직접 테마를 개발하여 사용할 수도 있지만, 이미 잘 만들어진 테마들을 빠르게 적용해보는 것도 좋은 방법입니다. Hugo Theme List: https://themes.gohugo.io/ ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:3:0","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"3.1. 테마 다운로드 처음 적용해보시는 분들을 위해서 간단하면서도 아름다운 Ananke 테마를 적용해보도록 하겠습니다. 다음과 같이 폴더에서 git 초기화를 해주신 다음, clone으로 받아오는 것이 아니라 사용하고자하는 테마를 submodule로 추가해주셔야 합니다. git init git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke 뒷부분의 themes/ananke는 해당 테마를 프로젝트의 themes 폴더에 하위에 ananke라는 폴더를 만들어 저장하겠다는 의미입니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:3:1","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"3.2. 테마 config.toml 적용 테마의 다운로드가 완료되었다면 프로젝트 폴더 안에 있는 config.toml을 수정하여 테마가 적용되도록 해야합니다. 다음과 같은 초기 파일의 내용에 baseURL = \"http://example.org/\" languageCode = \"en-us\" title = \"My New Hugo Site\" theme = ananke (앞서 저장된 폴더이름)를 한줄 추가하면 됩니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:3:2","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"4. Hugo 실행 및 생성 ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:4:0","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"4.1. 블로그 프리뷰 이제 드디어 블로그가 어떻게 생길지에 대해서 확인할 수 있게 되었습니다. hugo server -D 해당 코드를 실행하면 블로그에 테마가 적용된 모습과 작성된 포스트들에 대해서 볼 수 있습니다. hugo server -D\" hugo server -D 원래는 기본이 localhost:1313 혹은 127.0.0.1:1313 과 같이 1313 포트에서 실행돼야 하는데, 여러개를 실행할 경우 랜덤으로 남아있는 포트가 지정되게 됩니다. 혹시 theme를 가져왔는데 hugo server -D 가 실행되지 않는 경우가 간혹 있습니다. 이럴때는 hugo extended version을 추가 설치하면 대부분의 문제가 해결됩니다. ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:4:1","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"},{"categories":["Development"],"content":"4.2. 블로그 생성 앞선 명령어는 단지 자신의 로컬 환경에서 블로그가 어떻게 보여질지에 대한 피리뷰를 제공했다면, 다음의 명령어는 html, css, javascript 등으로 이루어진 실제 웹사이트를 생성해줍니다. hugo -D public 폴더가 새로 만들어지며 파일들이 생성되는데, 여기서 만들어진 파일을 호스팅할 github repository에 올리면 블로그가 호스팅되는 것입니다. Conclusion 이번 글을 통해 Hugo를 설치하는 과정부터 Github 배포를 위한 전단계까지의 과정에 대해서 알아보았습니다. 다음 Hugo 관련 글에서는 Github로 만들어진 웹사이트를 호스팅하는 방법에서부터 더 자세한 Hugo 구조에 대해서 다루어보도록 하겠습니다. 감사합니다. Reference Quick Start | Hugo ","date":"2020-07-10","objectID":"/2020/07/hugo-quick-start/:4:2","tags":["hugo","quick-start"],"title":"[Hugo] Quick Start 1","uri":"/2020/07/hugo-quick-start/"}]