출처 : https://excelsior-cjh.tistory.com/184

 

 

NLP 자연어 처리를 위한 RNN 기초 (2)

NLP 자연어 처리를 위한 딥러닝 RNN 기초 (1) RNN RNN은 Recurrent Neural Network 의 줄임말로 순환 신경망이라 불립니다. RNN 모델은 시퀀스 데이터를 효율적으로 처리하기 위해 만들어진 딥러닝 모델입니

richdad-project.tistory.com

 

심층 RNN

지난 포스팅에서 SimpleRNN으로 모델을 구성해봤다면, 이 RNN 신경망 층을 여러개 쌓는 심층 RNN을 구현해보겠습니다. 구현은 매우 쉽습니다. SimpleRNN 층을 추가하면 됩니다.

import tensorflow as tf

model = tf.keras.models.Sequential([
    tf.keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    tf.keras.layers.SimpleRNN(20, return_sequences=True),
    tf.keras.layers.SimpleRNN(1)
])

model.compile(
    optimizer = tf.keras.optimizers.Adam(),
    loss = tf.keras.losses.MeanSquaredError(),
    metrics = [tf.keras.metrics.MeanSquaredError()]
)

history = model.fit(
    train_x,
    train_y,
    epochs=20,
    validation_data = (val_x, val_y)
)

 

심층 RNN으로 구현할 경우 validation MSE 지표에서 최소값이 0.00266 정도까지 나옵니다.

우리가 평가 기준으로 삼고 있는 MSE와 Loss의 변화 그래프입니다. 아주 예쁘게 좋은 성과를 보여주고 있습니다.


위 코드에서 RNN 층을 맨 마지막에 하나의 유닛으로 구성했습니다. 이는 결론이 하나의 값으로 귀결돼야 하기 때문입니다. 이 마지막 RNN층은 사실 타임 스텝이 넘어 갈 때 필요한 모든 정보를 하나로 축약해서 전달할 때 필요할 듯 싶습니다. 그래서 사실, 우리가 얻고 싶은 모델 결과에서 마지막 RNN층 보다는 다른 layer 쌓는 게 더 낳을 수도 있습니다. 왜냐면 RNN 층은 활성화 함수로 tanh 활성화 함수를 사용하기 때문에 다른 활성화 함수를 사용하는 layer를 넣는게 나을 수 있습니다. binary classification에서는 마지막 결론을 출력하는 층으로 Dense 층을 사용합니다.

import tensorflow as tf

model = tf.keras.models.Sequential([
    tf.keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    # 마지막 Dense 층에 모든 정보를 전달하면서 다른 활성화 함수를 사용하기 위해 
    # RNN의 마지막 층은 return_sequences=True 를 지정하지 않습니다.
    tf.keras.layers.SimpleRNN(20),
    tf.keras.layers.Dense(1)
])

model.compile(
    optimizer = tf.keras.optimizers.Adam(),
    loss = tf.keras.losses.MeanSquaredError(),
    metrics = [tf.keras.metrics.MeanSquaredError()]
)

history = model.fit(
    train_x,
    train_y,
    epochs=20,
    validation_data = (val_x, val_y)
)

 

결과는 앞에서 봤던 결과와 거의 동일하게 나옵니다. 이 모델로 훈련할 경우 빠르게 수렴하고 성능도 좋은 것으로 판단할 수 있습니다. 또한 출력층의 활성화 함수를 원하는 함수로 변동도 가능합니다.


1 이상 타임 스텝 예측

지금 까지는 바로 다음 타임 스텝의 값만을 예측해봤습니다. 그런데 10, 100, 1000 타임 스텝을 예측하고 싶을 때는 어떻게 해야할까요?

 

첫 번째 방법

pretrained model을 활용해서 다음 값을 예측한 후 다시 이 값을 입력값으로 넣어서 그 다음값을 예측하는 방식을 반복하면 여러 타임 스텝의 값을 예측할 수 있습니다.

 

새로운 데이터 예측 (심층 RNN 모델 활용)

# 새로운 데이터로 예측
new_series = generate_time_series(1, n_steps + 10)

new_x, new_y = new_series[:, :n_steps], new_series[:, n_steps:]

x = new_x
for step_ahead in range(10):
    # 처음부터 하나씩 증가하면서 다음 타임 스텝을 예측 후 결과 값을 기존 값(3차원)에 추가할 수 있도록 shape 변환
    recent_y_pred = model.predict(x[:, step_ahead:])[:, np.newaxis, :]
    x = np.concatenate([x, recent_y_pred], axis=1)

y_prd = x[:, n_steps:]

# MSE 점수
np.mean(tf.keras.losses.mean_squared_error(new_y, y_prd))
# ==> 0.014788166

# 그래프 시각화
# 폰트 설정
plt.rcParams['font.family'] = 'Malgun Gothic'

# 그래프 그리기
plt.plot(range(50), new_x[0].reshape(-1), 'c.-')
plt.plot(range(50,60), new_y.reshape(-1), 'mo-')
plt.plot(range(50,60), y_prd.reshape(-1), 'bx-')
plt.xlabel('t')
plt.ylabel('x(t)')
plt.legend(['학습','실제', '예측'])
plt.grid(True)
plt.show()

 

validation data 예측 (RNN 모델)

# 데이터 새로 다시 만들기
n_steps = 50 
series = generate_time_series(10000, n_steps+10) 

# train 데이터는 7000개로 구성하고 (7000, 50, 1) shape로 구성합니다. 
train_x, train_y = series[:7000, :n_steps], series[:7000, -10:] 
val_x, val_y = series[7000:9000, :n_steps], series[7000:9000, -10:] 
test_x, test_y = series[9000: , :n_steps], series[9000: , -10:]

# 위 방식을 valistion data에 적용해보기
X = val_x
for step_ahead in range(10):
    # 처음부터 하나씩 증가하면서 다음 타임 스텝을 예측 후 결과 값을 기존 값(3차원)에 추가할 수 있도록 shape 변환
    recent_y_pred = model.predict(X[:, step_ahead:])[:, np.newaxis, :]
    X = np.concatenate([X, recent_y_pred], axis=1)

Y_prd = X[:, n_steps:]

np.mean(tf.keras.losses.mean_squared_error(val_y, Y_prd))
# ==> 0.029840497

 

검증 데이터인 validation data에 적용할 경우 0.029 라는 error 값이 나옵니다. 기본 선형 모델로 적용해보면 어떻게 나올까요?

 

validation data 예측 (기본 선형 모델)

X = val_x
for step_ahead in range(10):
	# 선형 모델인 linear_model 사용
    recent_y_pred = linear_model.predict(X[:, step_ahead:])[:, np.newaxis, :]
    X = np.concatenate([X, recent_y_pred], axis=1)

Y_prd = X[:, n_steps:]

np.mean(tf.keras.losses.mean_squared_error(val_y, Y_prd))
# ==> 0.06303842

 

0.06으로 error 값이 더 높게 나왔네요. RNN 모델이든 기본 선형 모델이든 이 방식으로는 높은 성능을 기대하기 어려울 것 같습니다. 그럼 어떻게 해결할 수 있을까요? 두 번째 방법은 다음 포스팅에서 다뤄보겠습니다.

 

 

 

NLP 자연어 처리를 위한 RNN 기초 (2)

NLP 자연어 처리를 위한 딥러닝 RNN 기초 (1) RNN RNN은 Recurrent Neural Network 의 줄임말로 순환 신경망이라 불립니다. RNN 모델은 시퀀스 데이터를 효율적으로 처리하기 위해 만들어진 딥러닝 모델입니

richdad-project.tistory.com

 

 

 

출처 : https://subscription.packtpub.com/book/data/9781789136364/4/ch04lvl1sec60/simple-rnn

 

 

 

NLP 자연어 처리를 위한 딥러닝 RNN 기초 (1)

RNN RNN은 Recurrent Neural Network 의 줄임말로 순환 신경망이라 불립니다. RNN 모델은 시퀀스 데이터를 효율적으로 처리하기 위해 만들어진 딥러닝 모델입니다. 여기서 시퀀스 타입의 데이터란 시간에

richdad-project.tistory.com

 

RNN 훈련

RNN은 BPTT 전략으로 훈련하는데, BPTT란 Backpropagation through time 즉, 타임 스텝으로 네트워크를 펼치고 기본 역전파를 사용하는 방법입니다. 입력 데이터가 정방향으로 진행되면서 가중치를 계산하고 비용함수를 통해 출력 결과를 생성합니다. 그럼 여기서 사용된 그레디언트가 다시 역방향으로 돌아와 가중치를 업데이트 하면서 모델을 최적화 시킵니다.

지금까지 이론 내용에 대해서만 소개했는데 실제 시계열 데이터를 간단하게 샘플용으로 만들고 이 데이터를 가벼운 RNN 모델에 넣어서 어떻게 학습되는지 코드로 살펴보겠습니다.

import numpy as np

# batch_size 만큼 n_steps 길이의 여러 시계열 데이터 생성
# 시계열 데이터(텍스트 문장과 같은 다른 시퀀스 데이터들도)는 입력 특성으로 3D 배열 [배치 크기, 타임 스텝 수, 차원 수]로 나타낸다

def generate_time_series(batch_size, n_steps):
	
    # random하게 0 ~ 1 사이의 실수를 3차원으로 만들어보겠습니다.
    freq1, freq2, offsets1, offsets2 = np.random.rand(4, batch_size, 1)

    # 시간축 데이터 생성
    time = np.linspace(0,1,n_steps)
    # 사인 곡선 1
    series = 0.5 * np.sin((time - offsets1) * (freq1 * 10 + 10))
    # 사인 곡선 2
    series += 0.2 * np.sin((time - offsets2) * (freq2 * 20 + 20))
    # noise data
    series += 0.1 * (np.random.rand(batch_size, n_steps) - 0.5)

    return series[...,np.newaxis].astype(np.float32)

 

위 함수를 활용해서 훈련 데이터 세트, 검증 데이터 세트, 평가 데이터 세트를 만들어 보겠습니다

n_steps = 50

# 총 10000개의 시계열 데이터를 생성하고, 타입 스탭은 50 + 1 로 생성합니다.
series = generate_time_series(10000, n_steps+1)

# train 데이터는 7000개로 구성하고 (7000, 50, 1) shape로 구성합니다.
train_x, train_y = series[:7000, :n_steps], series[:7000, -1]
val_x, val_y = series[7000:9000, :n_steps], series[7000:9000, -1]
test_x, test_y = series[9000: , :n_steps], series[9000: , -1]

 

우리 모델의 성능을 비교할 기준 성능을 세팅합니다. 단순하게 각 시계열의 마지막 값을 그대로 예측해보는 성능을 기준으로 세워보겠습니다

import tensorflow as tf

pred_y = val_x[:, -1]
# 평균 제곱 오차 (MSE) 확인
print(np.mean(tf.keras.losses.mean_squared_error(val_y, pred_y)
# ==> 0.021878457

 

또 다른 간단한 방법으로 Fully Connected Network 를 사용해서 MSE를 구할 수 있습니다. 특별하게 이 완전연결층 네트워크는 입력마다 1차원 특성 배열을 요구하기 때문에 Flatten 층을 추가해야 합니다. 시계열 데이터를 선형 조합으로 예측할 필요가 있어, 간단한 선형 회귀 모델을 구현해보겠습니다.

# 모델 생성
model = tf.keras.models.Sequential([
	tf.keras.layers.Flatten(input_shape=[50,1]),
    tf.keras.layers.Dense(1)
    ])

# 모델 컴파일
model.compile(
    optimizer = tf.keras.optimizers.Adam(),
    loss = tf.keras.losses.MeanSquaredError(),
    metrics = [tf.keras.metrics.MeanSquaredError()]
)

# 학습
history = model.fit(
    train_x,
    train_y,
    epochs= 20,
    validation_data = (val_x, val_y)
)

#결론 (제일 마지막에 나온 MSE)
history.history['val_mean_squared_error'][-1]
# ==> 0.004973348695784807

 

결론을 확인해봤을 때, 위에서 세웠던 기준 성능보다 더 높은 성능을 보여줍니다(MSE가 낮을수록 높은 성능) 그럼, 기준 성능도 세웠으니깐 Simple RNN을 간단하게 구현해보겠습니다.

# Simple RNN Model
rnn_model = tf.keras.models.Sequential([
    tf.keras.layers.SimpleRNN(1, input_shape=[None, 1])])

# compile
rnn_model.compile(
    optimizer = tf.keras.optimizers.Adam(),
    loss = tf.keras.losses.MeanSquaredError(),
    metrics = [tf.keras.metrics.MeanSquaredError()]
)

# 학습
history = rnn_model.fit(
    train_x,
    train_y,
    epochs= 20,
    validation_data = (val_x, val_y)
)

#결과
history.history['val_mean_squared_error'][-1]
# ==> 0.011953050270676613

 

Simple RNN의 특징

- 하나의 뉴런, 하나의 층으로 구성

- RNN은 어떤 길이의 타임스텝도 처리가 가능해서 입력 시퀀스 길이 지정할 필요 없다 (input_shape =[None, 1])

- 기본적으로 하이퍼볼릭 탄젠트 활성화 함수 사용 

- 초기 상태 \( h_{(hint)} \)를 0으로 설정하고 첫 번째 타임 스텝 \( x_{(0)} \)와 함께 하나의 순환 뉴런으로 전달

- 뉴런에서 이 값의 가중치 합을 계산하고 하이퍼볼릭 탄젠트 활성화 함수를 적용해서 첫번째 결과 값 \( y_{(0)} \)을 출력한다.

- 이 출력이 새로운 \( h_{0} \) 상태가 되고 새로운 상태는 다음 입력값인 \( x_{(1)} \)과 함께 순환 뉴런으로 전달

- 이 과정을 마지막 타임 스텝까지 반복

- 이 RNN은 마지막 값 \( y_{49} \)를 출력

- 모든 시계열에 대해 이 과정 동시에 수행

- keras의 RNN layer는 최종 출력만 반환. 타임 스텝마다 출력이 필요할 경우 return_sequence=True 지정

 

위에서 만든 모델은 앞서 만들었던 기본 선형 모델보다는 못한 성능을 보여줍니다.  아무래도 층이 1개이고, RNN의 특성상 은닉층에서 갱신되는 파라미터 수의 제약이 어느 정도 영향을 미친 것으로 예상합니다. 다음 포스팅에서 심층 RNN으로 이어서 성능을 개선시켜 보겠습니다.

 

 

 

NLP 자연어 처리를 위한 딥러닝 RNN 기초 (1)

RNN RNN은 Recurrent Neural Network 의 줄임말로 순환 신경망이라 불립니다. RNN 모델은 시퀀스 데이터를 효율적으로 처리하기 위해 만들어진 딥러닝 모델입니다. 여기서 시퀀스 타입의 데이터란 시간에

richdad-project.tistory.com

 

출처 : https://pngset.com/download-free-png-fcvmu

RNN


RNN은 Recurrent Neural Network 의 줄임말로 순환 신경망이라 불립니다. RNN 모델은 시퀀스 데이터를 효율적으로 처리하기 위해 만들어진 딥러닝 모델입니다. 여기서 시퀀스 타입의 데이터란 시간에 따른 길이를 가진 데이터라고 볼 수 있습니다. 제가 지금 쓰고 있는 텍스트 데이터도, 첫글자부터 마지막 글자까지 길이와 순서가 있습니다. 주식 가격 데이터도 시계열로 나열했을 때, 시간에 따라 가격이 변동하는 데이터를 확인할 수 있습니다. 
이와 같이 시계열 개념이 들어가 있는 데이터를 시퀀스 데이터라 하고, 이런 시퀀스 타입의 데이터를 효율적으로 다룰 수 있는 신경망 모델이 RNN인 것입니다.

RNN은 DNN과 CNN에서 봤던 Feed Forward 방식과 매우 유사하지만 뒤쪽(역방향)으로 순환하는 연결이 있다는 점이 차이가 있습니다. 즉, 입력(input)을 받아 출력(output)을 만들어 내고, 출력값을 자기 자신에게 다시 보내 하나의 뉴런을 구성합니다.


타입 스텝

RNN은 학습 과정에서 타임 스텝이 존재 하며 각 타임 스텝을 밟을 때마다 해당 타임 스템의 입력값 X(t) 과 이전 타임 스텝의 출력값 Y(t-1)을 입력으로 함께 받습니다. 일반적으로 첫 번째 타입 스텝에서는 이전 출력이 없기 때문에 이전 출력값을 0으로 세팅합니다. 즉, 이런 순환 신경망 구조는 각 타임 스텝마다 벡터 형식의 입력값과 출력값이 함께 입력으로 들어오는 구조를 가지고 있습니다.


공식

순환 신경망의 layer(순환층)에는 다양한 순환 뉴런이 존재 하며, 이 순환 뉴런은 2개의 가중치를 가지고 있습니다. 하나는 입력값 X(t)을 위한 가중치 벡터 w(x)이고, 다른 하나는 이전 출력값 Y(t-1)을 위한 가중치 벡터 w(y)입니다. 이를 순환층 전체로 확대하면 가중치 행렬인 W(x), W(y) 로 표현할 수 있습니다. 그렇다면 RNN의 layer(순환층)의 출력 벡터는 아래 식과 같이 표현할 수 있습니다.

$$ y_{(t)} = ∮({W_x}^T x_{(t)} + {W_y}^T y_{(t-1)} + b) $$

※ 여기서 \(b\) 는 편향을 의미하고 \(∮()\) 는 ReLU와 같은 활성화 함수를 의미합니다.


메모리 셀

RNN 신경망은 타임스텝이라는 개념을 가지고 있기 때문에 이전 스텝에서 출력한 값을 저장할 공간이 필요합니다. 이 저장 공간을 메모리 셀이라고 표현합니다. 일반적으로 이 메모리 셀의 상태는 \(h_{(t)} = f(h_{(t-1)}, x_{(t)}) \) 함수 형태로 표현할 수 있습니다. 여기서 h는 hideen 즉, 은닉층의 결과를 의미한다고 볼 수 있겠네요. 그리고 이 \( h_{(t)}\) 함수는 출력값 \(y_{(t)}\) 와도 같다고 볼 수 있습니다. 하지만 다를 수 도 있기데 h와 y로 나눠서 표기하게 됩니다.


네트워크 종류

RNN은 시퀀스와 벡터의 관계를 활용해서 다양한 네트워크 종류를 구성할 수 있습니다.

1. 시퀀스 투 시퀀스 네트워크 : 주식 가격 같은 시계열 데이터에 적합합니다.

2. 시퀀스 투 벡터 네트워크 : 영화 리뷰 텍스트에서 연속적인 단어를 시퀀스 형태로 입력하고 감성 점수를 벡터로 출력 받을 수 있습니다.

3. 벡터 투 시퀀스 네트워크 : 반대로 하나의 벡터를 입력하고 이에 따른 시퀀스를 출력할 수 있는데, 예를 들어 이미지(or CNN의 출력)를 하나의 벡터로 입력하고 이에 대한 caption(시퀀스)을 출력할 수 있습니다.

4. 인코더 디코더 : 인코더[시퀀스 투 벡터 네트워크]와 디코더[벡터 투 시퀀스 네트워크]를 연결한 네트워크를 구성할 수 있습니다. 이는 언어를 번역하는 데 사용할 수 있습니다. 한 언어의 문장 텍스트를 입력하여 하나의 벡터로 표현하고 이 벡터를 디코더에 넣어 새로운 언어 문장인 시퀀스로 출력하는 알고리즘에 적용할 수 있습니다.

 

출처 : https://www.freepik.com/free-photo/ai-nuclear-energy-background-future-innovation-disruptive-technology_17850501.htm#page=1&query=deep%20learning&position=3&from_view=search

6개월정도 부트캠프 형식으로 AI 과정을 수료했지만 사실, 5분의 1은 웹 관련 내용, 5분의 1은 파이썬, 5분의 1은 머신러닝/딥러닝 5분의 2 정도 프로젝트로 진행되다 보니 딥러닝에 대한 깊이는 한없이 부족했습니다.

이 갈증을 해소하기 위해 네이버 커넥츠 재단의 부스트캠프 과정을 알게됐고, Pre Course 과정도 나름 알차게 돼 있어서 수강하고 있습니다. 공부 내용을 정리해 놓으면 좋을 것 같아 몇자 끄적여봅니다.

 

딥러닝이란?


딥러닝 관련 직군이 매우 다양하고 넓다고 생각합니다. 데이터 사이언티스트, 데이터 분석가, 머신러닝 엔지니어, 모델러 등 다양하게 구성돼 있습니다. 개인적으로 우수한 머신러닝/딥러닝 관련 전문가의 특징을 꼽자면

1. 우수한 프로그래밍 구현 실력
2. 딥러닝을 위한 기본이 되는 수학적 지식(ex. 선형대수, 확률)
3. 논문 리딩을 통한 학습 가능한 실력

이렇게 3가지 정도 특징을 언급할 수 있을 것 같습니다. 이 3가지를 다 잘 할 수 있다면, 저도 억대 연봉을 받을 수 있겠죠? ^^

정의, 개념에 대해 간단히 언급하고 넘어가겠습니다.
인공지능이란 사람의 지능을 모방하는 것이라고 설명할 수 있습니다. 그렇다면 머신러닝이란 기계로 사람의 지능을 모방하는 개념입니다. 여기서 기계는 컴퓨터를 의미하겠죠. 딥러닝이란 이 머신러닝의 여러 종류 중 하나로서 사람의 뇌 신경망을 모방해서 구현한 개념입니다.


그래서 사실 딥러닝을 학습하고, 딥러닝 전문가가 된다는 것은 머신러닝의 일부분을 깊게 다룬다는 개념이라고 보시면 됩니다. 딥러닝이 핫한 이유는 지금까지 해결하지 못했던 문제들을 높은 성능으로 해결하는 솔루션을 제공해주고 있기 때문입니다. 할 수 있는 게 너무 많아요

그럼 딥러닝의 핵심 요소를 정말 간략하게 확인해 보면

▶ 데이터
▶ 모델
▶ 손실함수(loss function)
▶ 알고리즘(optimizer)

이렇게 4가지를 확인할 수 있습니다. 딥러닝은 데이터에 아주 민감하고, 사실상 최근 빅데이터라는 방대한 데이터 시대가 도래했기 때문에 딥러닝이란 기술이 빛을 발할 수 있습니다. 모델은 데이터를 수학적 지식을 잘 활용해서 우리가 원하는 결과를 만들어주는 중추 역할이라고 볼 수 있습니다. 손실함수는 우리의 모델이 높은 성능을 낼 수 있는 의미 있는 기준, 조건이라고 보시면 됩니다. 알고리즘은 최적화 기법과 연결 돼 있습니다.

 

딥러닝의 목적


1. Loss (우리가 이루고자 하는 근사치)
- 뉴럴네트워크에 들어 있는 layer 안에서 weight와 bias를 어떻게 update할건지 결정하는 기법이 Loss입니다. 
- Loss값이 줄어든다고 해서, 우리가 원하는 결과를 항상 얻을 수는 없습니다.

문제 접근 방식마다 사용하는 loss 기법이 다른데,
Regression(회귀) 문제는 MSE(최소제곱법)
Classification(분류) 문제는 CrossEntrophy
Probabilistic(확률) 문제는 MLE 같은 loss를 활용합니다.

딥러닝에서 Optimizer(최적화)란 신경망 네트워크를 어떻게 줄일지에 대한 기술이라고 보시면 되는데 뉴럴 네트워크의 파라미터를 loss fuction에 대해서 1차 미분한 정보를 활용해서 최적화하는 작업을 의미합니다. 쉽게 말하면, 우리가 만들 모델의 목표 지점에 도달 할 수 있게끔 세팅하는 방식이라고 생각할 수 있습니다.

딥러닝의 목적은 단순히 loss fuction을 줄이는 게 아니라 학습하지 않은 데이터에도 정확하게 작동할 수 있도록 모델을 구현하는 것입니다. loss fuction이 감소하는 게 위와 같은 성능을 보장하기도 하지만 반드시 그런 것은 아니라서 이 목적을 잊지 않는 것도 중요합니다. 우리가 딥러닝이란 기술을 이용해서 뭘 하려고 하는지 끊임없이 되묻는 게 필요합니다.

 

딥러닝 역사적 흐름


1. AlexNet(2012)
- 이미지 분류 경진대회에서 처음으로 딥러닝 기술이 1등한 첫 모델

2. DQN (2013)
- 딥마인드가 블록깨기 게임을 강화학습으로 성공시킨 논문

3. Encoder/ Decoder(2014)
- AI 번역의 트렌드 변화 주도, 시퀀스 데이터(문자)를 encoder를 통해 숫자로 바꾸고 이를 다른 언어와 매칭하여 decoder로 출력해주는 과정

4. Adam Optimizer(2014)
- 다양한 optimaizer가 있는데, 보편적으로 무난하게 높은 성능을 내는 optimizer가 Adam.

5. GAN(Generative Adversarial Network)(2015)
- 이미지, 자연어를 어떻게 생성할 지 관련된 적대적 신경망의 시초

6. ResNet(2015)
- 네트워크를 깊게 쌓을 수 있도록 트렌드를 바꾼 논문

7. Transformaer (Attention is all you need) (2017)
- NLP 딥러닝 모델의 혁신, RNN 계열의 모델에서 가장 선두적인 성능을 보임

8. BERT(2018)
- fine-tuned NLP model / fine tuning의 중요성을 보여주는 모델 / 다양한 말뭉치로 pre train하고 내가 풀고 싶은 소량의 데이터로 fine tuning 기법 극대화

9. BIG Language Models GPT-3 (OpenAI, 2019)
- 1750억개의 파라미터로 이뤄진 모델, 모델이 무겁지만 그만큼 NLP 분야에서 어마무시한 성능을 보여줌.

10. Self Supervised Learning(2020, SimCLR)
- 한정된 학습데이터 외 라벨을 모르는 데이터에 대해 unsupervised learning 방식을 접목하여 성능을 향상

Multiprocessing 

파이썬에서 연산과정 중 자원을 분배해서 계산 속도를 빠르게 올리기 위해 사용하는 기법이다. Thred 즉 CPU의 Core와 연관돼 있는 개념이다. 파이썬은 절차형 언어라서 한 라인 명령어를 수행하고 다음 라인으로 넘어간다. 즉, 앞에 있는 계산이 끝나지 않는다면 다음 명령을 수행할 수 없다.
하지만 쓰레드 작업, 병렬처리 작업을 진행하면, 각각의 작업이 동시에 진행된다. 간단한 코드를 통해 예시를 확인해보자

 

기본 예시


# 작업 함수 1
def func1(num):
	cnt = 0
    while cnt < num :
    	print('작업함수1')
        cnt += 1

# 작업 함수 2
def func2(num):
	cnt = 0
    while cnt < num :
    	print('작업함수2')
        cnt += 1
위와 같은 함수를 구현해보고 함수1과 2를 차례로 실행해보자 총 10만번 작업을 수행할 것이다.
# 시간을 재기 위해서 time 라이브러리 사용
import time

# 시작 시간
start = time.time()

func1(100000)
func2(100000)

# 끝 시간
end = time.time()

# 총 걸린 시간
print('총 작업 시간 : ' + str(round((end-start),2)) + '초')

 

당연히 1번 함수부터 차례로 시작하고 2번 함수가 다음으로 이어지면서 마무리 된다. 총 걸리 시간은 10.82 초다.

 

그렇다면 병렬처리 작업을 하면 어떻게 될까요?

# multiprocessing 과 threading 둘 중에 마음에 들거나 편한걸 사용하면된다.
# 이번 예시에서는 threading 라이브러리를 사용하겠다
from multiprocessing  import Process, Queue
from threading import Thread

num = 100000
thred1 = Thread(target=func1)
thred1.start()

thred2 = Thread(target=func2)
thred2.start()

이런 식으로 섞여서 나옵니다. 즉 첫 번째 함수를 먼저 다 실행하고 두 번째 함수를 실행하는 게 아니라 2가지 함수를 동시에 진행하는 작업입니다.

 

응용


이번에는 제가 텍스트 분석하는 작업에 Multiprocessing 쓰레드 작업을 적용해보겠습니다.
텍스트 분석 부분에서 형태소 분석기(Okt)를 활용해서 품사별로 나누고 필요없는 품사를 제거하는 작업이 생각보다 오래걸립니다. 이 작업에 병렬처리를 적용해보겠습니다.

 

▶ 병렬 처리 전 코드

# 텍스트 전처리 함수
def prepro_text(raw_data):

    # 특수기호, 영어, 숫자 제거
    prepro_texts = re.sub(r'[^가-힣]',' ',str(raw_data))
    # 형태소 분석기 생성
    okt = Okt()
    # 조사와 복수표현 등 필요없는 품사 tag 제거
    prepro_word = []
    for word, tag in okt.pos(prepro_texts):
        if tag not in ['Josa', 'Suffix']:
            prepro_word.append(word)
    # 어간 추출 적용
    # result = ' '.join(okt.morphs(' '.join(prepro_word), stem=True))

    # 어간 추출 X
    result = ' '.join(prepro_word)

    return result

# 각 자소서 질문별 텍스트 전처리
for q in df.columns[2:7] :
    df[q] = df[q].map(prepro_text)
print('전처리 완료')
위 코드를 확인해 보시면, 총 5개 column에 대한 텍스트 데이터를 for문을 활용하여 차례차례 전처리 작업을 진행합니다. 그러다 보니 이 부분에서 시간이 오래 걸리고, 리소스를 많이 사용하게 되는데요. 이 부분을 병렬처리로 작업해보겠습니다.

 

 

▶ 병렬 처리 후 코드

# 텍스트 전처리
def text_preprocess(df, text, queue):
    df[text] = df[text].map(prepro_text)
    queue.put(df[text])
    return df[text]
    
q = Queue()
        
# 텍스트 전처리
# 쓰레드 병렬 처리
for col in df.columns[2:7]:
	thred = Process(target=text_preprocess, args=(df,col,q))    
    thred.start()

# queue 자료구조에 담은 데이터를 사용할 df에 적용
for col in df.columns[2:7]:
	df[col] = pd.Series(q.get())
이렇게 간단하게 병렬 처리 가능합니다. Process() 메써드네 target, args라는 파라미터를 넣어줍니다. target은 우리가 작업할 함수를, args는 그 함수들이 필요로 하는 파라미터 값입니다.

 

소감


사실 아직 정확하게 활용하고 있지 못하다는 느낌이 강합니다. 쓰레드라는 개념, 병렬처리라는 개념은 어느 정도 이해했는데, 이 기법을 내 코드에 잘 적용하고 있는지는 아직 미지수로 보입니다. 좀 더 업그레이드 되면 다시 한 번 공유하겠습니다. 감사합니다. 

안녕하세요. 부자아빠 셜로키입니다.

이번 포스팅은 머신러닝/딥러닝이라 부르는 AI 기술의 전문가로 거듭나기 위해 무엇을 공부해야하고, 어떻게 실력을 쌓아야 할지에 대해 다뤄보고자 합니다. 요새 산업 전반에 있어서 가장 널리 알려져 있고, 전도유망한 분야이기 때문에 많은 분들이 관심을 가지고 공부도 하고 도전하고 있습니다.

하지만. 워낙 기술 진입장볍이 높은 영역이기도 하고, 이론도 수학 & 통계를 기본으로 다루고 있어, 접근하기가 쉽지 않은 분야인건 확실합니다. 그럼에도 방법만 알면, 누군가 가이드 해준다면 도전해볼 의지가 있는 분들에게 조금이나마 길라잡이 역할을 해드리고자 이 포스팅을 작성해봅니다.

 

저도 처음에 어떻게 방향을 잡고, 뭘 해야할지 막막했는데, 한 책을 발견하고 어느 정도 정리 할 수 있을 것 같아서 공유해보려 합니다. (참고한 책 제목은 '1년 안에 AI 빅데이터 전문가가 되는 법' 입니다)

 

Step1. AIㆍ빅데이터 경영서적 독파


경영서적이라고 하면 좀 의아해할 수도 있습니다. 파이썬 언어를 배워야 하는거 아니야? 선형대수학이나 수리통계학 공부해야 하는거 아니야? 라고 생각하실수도 있는데 첫 스타트로는 먼저 인공지능 기술을 통해서 비즈니스 현장에서는 어떤 문제들을 풀고 있는지, 어떻게 적용하고 있는지 확인할 필요가 있습니다.

저 개인적으로는 이 단계를 문제 인식, 문제 정의라고 생각하는데요. 머신러닝, 딥러닝 영역에서는 문제를 어떻게 바라보고, 이 문제를 어떤 방식으로 풀건지 정의하고, 사고하는 과정이 너무나도 중요합니다. 첫 스타트이기 때문에 여기서 바로 세우지 못하고 꼬여 버리면 모델을 열심히 구현해도 성능이 안좋거나 잘못 접근해서 처음부터 다시 해야하는 상황도 발생하기 때문입니다.

출처 : https://www.clicdata.com/blog/what-can-business-intelligence-do-for-big-data/

그리고 이 영역이 연구분야도 활발하지만, 워날 실용 측면의 접근도 활발하기 때문에 이 기술을 실제 산업 현장에서는 어떻게 활용하고 있는지 선행 사례를 살펴보는 게 좋습니다.

그럼 어떤 경영서적을 읽으면 좋을지 소개해드리겠습니다.

▶ 『빅데이터 기초 : 개념, 동인, 기법』(시그마프레스) - 빅데이터 관련 개념 중점
▶ 『인공지능 시대의 비즈니스 전략』(더퀘스트) - AI 관련 개념 중점
▶ 『빅데이터가 만드는 제4차 산업혁명』(북카라반) - 실제 산업 현장에서 빅데이터 비즈니스 활용 사례
▶ 『빅데이터 비즈니스 이해와 활용』(위즈하임) - 실제 산업 현장에서 빅데이터 비즈니스 활용 사례
▶ 『빅데이터 분석과 활용』(학지사) - 실제 산업 현장에서 빅데이터 비즈니스 활용 사례


실제 비즈니스에서 마주하는 문제들을 어떻게 풀어내는지 어떤 데이터로, 어떻게 접근하는지 확인하고, 성과가 잘 나온 사례들을 적용해서 새롭게 현재 마주한 문제들을 해결할 수 있습니다. 

 

Step2. 기본 머신러닝 알고리즘


비즈니스 현장에서 적용 사례를 확인하고 실전 적용을 위한 기본기라고 생각하시면 좋습니다. 머신러닝에는 크게 지도학습, 비지도학습, 강화학습으로 나뉘고 지도학습에서는 회귀, 분류 비지도학습에서는 군집 등 다양한 종류와 방법으로 나뉩니다.

이러한 개념들을 익히고, 실제 프로그래밍으로 어떻게 구현하는지, 그 원리는 무엇인지 대략적으로 알고 있어도 실전에 적용하는데 큰 문제가 없습니다. 요즘 대세는 파이썬이기도 하고, 관련 라이브러리와 프레임워크가 잘 돼 있기 때문에 파이썬으로 시작하시는걸 추천드립니다.

기본적으로 숙지해야 할 내용들을 소개하자면

① 데이터 이해 : 데이터의 유형(명목, 이진, 순서, 이산형, 범주형 데이터) / 기술통계(평균, 표준편차 등)
② 데이터 전처리 : 결측치 제거 및 보간, 노이즈 제거, 정규화(데이터 범주 일치), 주성분분석, 샘플링 등
③ 알고리즘 : 상관관계, 연관관계, 클래스 분류(의사결정나무, 랜덤포레스트), 클러스터, 회귀 분석 등

 

 


위 내용이 어렵게 느껴질수도 있는데, 완벽히 암기하고, 완벽히 이해해서 내것으로 만들겠다는 접근보다는 전반적으로 어떤 개념이고, 어떤 내용인지 이해하고, 파악하고, 필요한 내용을 보고 따라서 구현할 수 있을정도의 실력까지 키우면 좋을 듯 싶습니다.

그럼 내용을 익히는 데 도움이 되는 책을 소개해드리겠습니다.

▶ 『데이터 마이닝 개념과 기법』(에이콘출판) - 각 알고리즘 동작 원리 이해 쉬움
▶ 『패턴인식』(교보문고) - 알고리즘의 수학적 설명 서술
▶ 『데이터 마이닝 기법과 응용』(한나래) - 알고리즘의 수학적 설명 서술


위 책을 활용해서 전반적인 데이터에 대한 개념과 처리, 알고리즘의 프로세스를 익히고, 이 개념들을 실제 현장 비즈니스에서 어떻게 사용하고 있는데 디테일하게 확인하는 게 좋습니다. 이 때 살펴보는 게 논문입니다.

<추천 논문 저널>

국내
▶ 『지능정보연구』
▶ 『한국경영과학회지』
▶ 『Information System Review』

국외
▶ 『IEEE Access』
▶ 『IEEE Transactions on Big Data』
▶ 『Information System Research』

 

Step3  수리 통계학


수리통계학을 공부해야 하는 이유는 우리가 사용하는 알고리즘에 대한 튜닝이 필요할 때, 좀 더 데이터와 문제에 맞는 방향으로 세팅하기 위해서 기본적인 이해가 바탕돼 있어야 하기 때문입니다. 수학적인 이론과 개념을 증명하고, 풀어야할 필요는 없고, 이해하는 선에서 익히는 방향을 추천드립니다.

<책 추천>

▶ 『수리통계학 개론』(경문사) - 수리통계학의 정석

 

<공부 방법>

1. 책 읽다가 수식 나오면 따라 적고, 이해해본다.
2. 이해가 안되면 구글링, 유튜브 등 인터넷을 활용해서 이해해본다.
3. 이해가 안되면 넘어간다.
4. 각 챕터별 연습문제는 해답을 보면서 이해해 보고, 해설과 정답을 적어본다. (증명이나 유도 문제는 건너띈다)

 

Step4. 딥러닝


딥러닝은 머신러닝의 한 종류다. 이 개념부터 시작해서, Neural Network의 개념, 오차역전파 등 다양한 개념을 익히고, 이런 이론과 개념을 어떻게 코드로 적용하는 지 숙지하는 과정이 중요하다.

<책 추천>

▶ 『딥러닝 제대로 시작하기』(제이펍) - 딥러닝의 기본 개념 정리
▶ 『밑바닥부터 시작하는 딥러닝』(한빛미디어) - 딥러닝 심화 & 기본 코드 내용까지 다룸
▶ 『케라스 창시자에게 배우는 딥러닝』(길벗) - 실전 딥러닝 모델 구현

<강의 추천>

▶ 『모두의 딥러닝 시즌1』 - https://youtu.be/BS6O0zOGX4E?list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm
▶ 『모두의 딥러닝 시즌2』 - https://youtu.be/qPMeuL2LIqY?list=PLQ28Nx3M4Jrguyuwg4xe9d9t2XE639e5C

책과 강의를 통해 기본기를 잘 다지길 추천드립니다.

출처 : https://velog.io/@kmnkit/Keras%EB%A1%9C-%EB%94%A5%EB%9F%AC%EB%8B%9D-%EB%AA%A8%EB%8D%B8-%EC%84%A4%EA%B3%84%ED%95%98%EA%B8%B0

 

Tip. 관심 가져볼만한 자격증


한 가지 유의할 점은 자격증이 목적이 아니라 실력 상승이 목적입니다. 즉, 자격증은 안따도 사실 괜찮습니다. 물론 기왕 공부하는 김에 자격증도 따는게 좋긴 하겠지만, 무튼 우리의 목적은 실력입니다. 단순히 자격증을 따기 위한 시험에 맞춘 공부가 아니라 실력 상승을 위한 공부임을 명심하시길 바랍니다.

<자격증 소개>

[책에서 소개하는 자격증]
▶ 데이터 분석 자격검정 - 한국데이터 산업 진흥원
▶ SQL 자격검정 - 한국데이터 산업 진흥원
▶ 사회조사분석사 필기 - 한국산업인력공단
▶ 경영빅데이터분석사 - 한국경제

[추가]
▶ 정보처리기사 - 한국산업인력공단
▶ 빅데이터 분석 기사 - 한국데이터 산업 진흥원

 

<자격증 공부를 위한 책 추천>

▶ 『데이터 분석 전문가 가이드』 for '데이터 분석 자격검정'
▶ 『경영 빅데이터 분석사』 for '경영 빅데이터 분석사'
▶ 『SQL 전문가 가이드』 for 'SQL 자격검정'

 

자격증과 공부에 필요한 책들을 간략히 추천드렸습니다. 자격증은 오랜 기간 보다는 단기간에 집중해서 취득하는 것을 추천드리고, 그만큼 내용을 깊게 보는 것이 아니라 전반적인 흐름과 개념을 잡는다는 생각으로 빠르게 공부하시길 추천드립니다.
그리고 SQL 자격검정 시험에서는 데이터 모델링, 기본적인 SQL 쿼리 부분을 중점으로 숙지하는 게 도움이 됩니다.

그럼 지금까지 AI 머신러닝/딥러닝 성장 루트 및 가이드, 공부법에 대한 소개를 마치겠습니다. 감사합니다.



종목분석 기준 선별 및 학습


우선 '경제적 자유'블로그 글 중 '투자철학' 관련 글을 모두 다 읽었다.

PER, PSR, PCR, 시가총액, 영업이익, 매출액, 당기순이익, 부채비율, 당좌비율, 배당 등 기초적인 개념을 세웠다.

각 개념을 학습하면서 이 개념을 기준으로 사용할지 결정했다.

예를들어 3년 이상 당기순이익 연속 흑자 기업을 하나의 조건으로 설정했다.

PER 20배 이하 / 부채비율 150% 이하 / 매출액, 영업이익 5년 이상 연속 흑자 / 배당 유무 등 기초적인 투자 관련 수치를 조건으로 설정했다.


그렇게 해서 처음 설정한 종목은 대부분 대형주들이었다.

조건이 매우 깐깐하고 안정적인 큰 수치만을 원하다 보니 어쩔 수 없었다.

모두 장기투자의 관점으로 종목을 선정했다.

큰 분류로는 배당주 / 대형 안정주 2가지로 분류했다.


<배당주>

KB금융

삼성증권

신한지주

하나금융지주


<대형 안정주>

현대차

기아차

현대모비스

삼성전자

포스코케미칼


이와 같이 초기 종목을 선정하고 이 종목 모두 적당한 가격에 진입하기로 계획을 세웠다.

자금이 적기 때문에 7개 계좌로 나누는 것은 어려웠고, 

우선 4개 계좌로 나눠 '경제적자유'(박성현)님 처럼 넘버1~넘버4로 분류했다.


삼성전자를 하나 예를 들면, 넘버1 계좌에서 59,200원 가격으로 처음 매수했다.

이 가격을 기준으로 5%씩 떨어지면 진입하기로 전략을 세웠다. 

전문 용어로 말하자면 분할 매수 계획을 세운 것이다.


<시나리오>

넘버1 진입가 : 59,200원

넘버2 진입가 : 56,200원

넘버3 진입가 : 53,400원

넘버4 진입가 : 50,700원


넘버1 수익률 : 10% 이상

넘버2 수익률 : 5%

넘버3 수익률 : 5%

넘버4 수익률 : 5%


위와 같이 진입가와 수익구간까지 미리 시나리오 결정을 완료했다.

각 종목마다 진입할 때마다 기준을 미리 설정했고, 저 수치에 다다르면 아무 생각없이 행동하기로 결정했다.

즉, 사고와 행동을 분리시켜, 주관적인 감정에 휘둘려 잘못된 판단 할 리스크를 감소시켰다.

한마디로 퀀트 개념을 접목시킨 것이다.


종목도 정해지고 투자 시나리오도 심플하게 결정되니 빠르게 투자를 하고 싶었다.

하지만 과거 단타 트레이딩 경험을 통해 주식투자는 빨라서 좋을게 없다는 사실을 깨달았다.

오늘 올랐다고 계속 오른다는 보장도, 오늘 떨어졌다고 계속 떨어진다는 보장이 없다.

단기간의 오르내림을 맞추는 그런 마법은 없다.

그래서 이 스프릿 방식의 투자가 굉장히 매력적인 것이다. 

매우 안정적이고 검증된 종목에 투자하면서 떨어지면 싼값에 산다는 생각으로 기분 좋고

오르면 수익 실현 할 수 있어서 기분 좋고 어떤 상황에서도 기쁨을 유지할 수 있는 방식이다.

이제는 적당한 가격에 들어가서 위 시스템을 돌리는 일만 남았다.

바로 매수하게 될 종목은 무엇일까!? 기대가된다.






투자 복기 #1


【투자 테스트】 - 100만원으로 한달동안 수익율 10% 달성 목표

【기간】 - 2020.10.6 ~ 11.13 (1month + 5 days)

【결과】 - 6.6% 수익율 달성 (확정손익)

【투자범위】 - 한국주식 + 미국주식

【투자 방법】 - '경제적자유' 블로그 & '1타 7피' 저자 박성현님의 세븐스프릿 방식


【종목 선정 원칙】 

1. 매출액, 영업이익, 당기순이익 5년 연속 흑자 

2. 상대적인 저 PER(동일업종 타종목 비교) 

3. 배당 있으면 너무 좋음 

4. 미래 성장 동력 분야 굳


【느낀점】 

1. 투자의 세계, 주식 시장의 움직임을 쉽게 느낄 수 있었음. 

2. 시간을 내편으로 만들면 주식은 쉬움. 

3. 분할매수 분할매도의 매력.

4, 일하면서 투자 종목 가격을 보지 않음

5. 자동 매매, 매수 시스템 이용 가능

6. 안정적인 퀀트 투자 시스템

7. 내가 사면 떨어지고, 내가 팔면 오르는 게 아니라 --> 떨어지면 싸게 살 수 있어서 좋고, 오르면 수익 낼 수 있어서 좋고. 누이좋고 매부좋은 모든 상황이 나의 편


【한계】

1. 시간을 내편으로 만드는 개인투자자에게 적합

2. 개인투자자도 시간을 내편으로 만들 수 없으면 잘못된 투자 행동 나타남

3. 반드시 내 경제 활동, 생계에 마이너스(-)가 없는 상황에서 해야함

4. 왜냐면 시간을 내편으로 만든다는 말은 주식에 들어간 돈을 건드리지 않고 오를 때까지 기다릴 수 있는 경제적 여유 상황이 필요

5. 처음부터 큰 투자 금액은 필요없지만 정기적으로 주식 시장에 보급할 수 있는 플러스(+) 자금 원천이 필요함


【과거 투자 히스토리】

2019년 3월부터 10만원으로 단타 트레이딩을 시도한적 있다. 

당시 알게된 전업투자자 유튜버는 창원개비, 주식마블, 일조TV 등 빠르게 많은 돈을 벌 수 있는 데 집중했다.

이 이상의 돈은 투입되지 않았기 때문에 당연히 큰 투자는 할 수 없었다.

이 당시 목표는 10만원으로 100만원을 벌 수 있으면 주식 전업투자자의 길을 걸어야겠다 생각했다.

하지만 결과는 역시나였다.

단타 투자의 마지막은 ETF로 끝났다. 그것도 코로나 이후에...

코로나로 인해 3월 폭락장에서 인버스로 남은 돈을 다 투입했다. 지금까지 손실은 계속 이어져 오고 있고, 10만원은 2~3만원 정도 돼 있다.

이로써 나는 트레이딩으로서는 정말 실력이 없다는 것을 깨달았다. 

또한, 나랑 맞지 않는 방법인 것도 깨달았다.

이런 투자 과정 가운데 2019년 중순부터 '경제적자유' 블로그를 알게 됐다.

카지노 도박에서 살아남는 법을 터득하고 그 시스템을 주식과 부동산 등 재태크에 접목하여 성공적으로 자산을 축적했다.

이 투자 방식을 선택하기 까지 1년 반정도 시간이 걸렸고, 다행히 잃은 돈은 적었다.

+ Recent posts