본문 바로가기
머신러닝 딥러닝

0916 Deep Learning

by 대금부는개발자 2021. 9. 16.
SMALL

Perceptron을 다중 layer(multilayer)로 사용하면 학습이 가능해요(XOR)

→ 가장 큰 문제는 시간이 오래 걸려요! → 1차 침체기 → 1974년에 폴 웨어보스(Paul Werbos)란 사람이 

박사학위 논문에서 neural network의 획기적인 기법을 발표 → 외면(아무도 안 하고 있어요)

→ 1982년에 다시 논문 발표 → 관심 없음.. → 1986년에 제프리 힌튼(AI 3 대장) 교수가 이 논문에 대한 기법에 대해 재조명 → 정말 되네요.. 너무 좋아요 → machine learning의 전성기 → 이 개념이 오차 역전파(Back-propagation)

 

현재까지 우리의 Neural Network → 전파(Feedforward)

layer 개수와 node의 개수가 늘어나면 편미분 하나하나 너무 많이 해야 해요. 
→ 시간이 오래 걸리는 것을 해결해 보아요 → 오차 역전파(Back-propagation) 미분을 하지 않아요.

 

오차 역전파(Back-propagation) 

뒤쪽 layer에서 앞쪽 layer로 특정 방식(편미분이 아닌 Matrix연산(행렬곱))으로 w를 갱신

 

우리나라에는 조금 늦게 1990년 초중반에 오차 역전파가 들어왔어요. → 대학교에서 AI학과

장밋빛이었다가 또 다른 문제에 봉착 오차 역전파(Back-propagation)는 Neural Network에서
layer를 많이 사용하면 할수록 성능이 떨어져요. → 여러 가지 이유가 존재하지만 가장 큰 이유는

Vanishing Gradient Problem : 오차 역전파가 진행되면서 weight와 bias가 뒤에서부터 앞으로

차근차근 update 되는데 뒤에 있는 layer의 weight와 bias는 update가 잘 되는데 앞으로 가면 갈수록 갱신이 잘 안돼요.

기울기 값이 사라지는 문제..

원인은 sigmoid함수(입력으로 들어온 값이 어떠한 값이라 하더라도 0~1 사이로 변해요.) → 1 미만의 값을 계속 곱해주면 값이 계속 작아져요. 

 

single perceptron → multi layer perceptron → 시간이 오래 걸려요 Back-propagation Vanishing Gradient Problem(layer를 늘리면 안 돼서 복잡한 문제를 해결할 수 없어요) → Neural Network 망함..(2차 침체기)

여러 가지 알고리즘이 등장! Regression, KNN, SVM, Decision Tree, Naive bayes → 1995년 'AI의 대부' 얀 르쿤이 Neural Network 보다 다른 알고리즘이 더 좋아요 발표

캐나다에서 만들 설립 기구 CIFAR(Canadian Institute for Advanced Research)에서 펀딩을 해요 제프리 힌튼 교수님이 canada로 이주해서 연구를 지속 → 2006, 2007년 두 개의 논문을 발표 

1. initialization(초기화의 문제) : weight의 초기값은 random으로 하면 안 돼요.

2. activation function(활성화 함수) : sigmoid에는 문제가 있어요.

→ Neural Network 망한 전적이 2번 있어요 → Rebranding(신분세탁) → Deep Learning(Deep Network)

 

이미지 처리와 같이 비정형 처리를 할 때는 딥러닝 기법
일반적으로 정형적인 처리를 할 때는 일반적인 머신러닝 기법을 사용 → 시간 절약

 

딥러닝의 여러 가지 알고리즘 CNN, RNN, LSTM, GRU

우리는 이미지 처리를 먼저 할 거니까 CNN을 먼저 할 거예요

 

initialization(초기화의 문제)와 activation function(활성화 함수)을 먼저 확인해 보러 가요.

 

# MNIST 구현

 

# 1. Training Data Set

# 2. sklearn으로 구현

# validation 이용하지 않고 test data로 최종적으로 평가할 거예요

 

import numpy as np

import pandas as pd   

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import MinMaxScaler

 

# raw data loading

df = pd.read_csv('/content/drive/MyDrive/9월 14일/mnist/train.csv')

# 여담으로 data의 크기가 너무 크면 구글 드라이브에서 불러드릴 수 없어요! → cloud system 이용

 

# training data와 test data(최종평가용) 분리

train_x_data, test_x_data, train_t_data, test_t_data = \

train_test_split(df.drop('label', axis=1, inplace=False), # 2차원 x데이터만 추출

                 df['label'],    # label은 0부터 9까지 1차원 series 

                 random_state=0# 어떻게 랜덤 하게 뽑을지 고정

                 test_size=0.3,

                 stratify=df['label']) # label의 비율대로  

 

# 결측치 이상치는 존재하지 않아요!

# 정규화는 진행해야 합니다. 

scaler = MinMaxScaler()

scaler.fit(train_x_data) 

train_x_data_norm = scaler.transform(train_x_data)

test_x_data_norm = scaler.transform(test_x_data)

 

# 2.sklearn 구현

 

from sklearn.linear_model import LogisticRegression

 

model = LogisticRegression(solver='saga'# 기본적으로 penalty는 l2규제, C는 regularization의 강도

 

model.fit(train_x_data_norm, train_t_data)

 

# model 평가

# 정확도를 판단할 때 score 함수가 가장 많이 쓰여요.

# score 첫 번째 입력 data 두 번째 t data

model_score = model.score(test_x_data_norm, test_t_data)

print('sklearn의 정확도:{}'.format(model_score))

# sklearn의 정확도:0.917063492063492

 

 

# tensorflow 1.15 구현 → jupyter notebook

# Colab에서는 실행 안됨! (1.15 버전을 설치하거나 다른 방법을 이용해야 합니다.)

# 앞에 raw data loading # training data와 test data(최종평 가용) 분리 까지는 똑같아요

import numpy as np
import pandas as pd   
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

 

# raw data loading
df = pd.read_csv('./data/mnist/train.csv ')
# 여담으로 data의 크기가 너무 크면 구글 드라이브에서 불러드릴 수 없어요! → cloud system 이용

# training data와 test data(최종평가용) 분리
train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(df.drop('label', axis=1, inplace=False), # 2차원 x데이터만 추출
                 df['label'],    # label은 0부터 9까지 1차원 series 
                 random_state=0, # 어떻게 랜덤 하게 뽑을지 고정
                 test_size=0.3,
                 stratify=df['label']) # label의 비율대로  

# 결측치 이상치는 존재하지 않아요!
# 정규화는 진행해야 합니다. 
scaler = MinMaxScaler()
scaler.fit(train_x_data) 
train_x_data_norm = scaler.transform(train_x_data)
test_x_data_norm = scaler.transform(test_x_data)

 

# tensorflow 1.15 구현(multinomial classification)
# placeholder →  Weight & bias → Hypothesis → loss → train → 반복 → accuracy
# label의 class 들에 대해 one-hot-encoding 처리를 해야 해요!
# 여기까지 똑같아요
import tensorflow as tf

sess = tf.Session() # Session이 있어야 node 안에 있는 값을 가져올 수 있어요!
train_t_data_onehot = sess.run(tf.one_hot(train_t_data, depth=10)) # depth는 class의 개수 현재 0~9 있어요.
# one-hot으로 바꿨기 때문에 train_t_data_onehot은 2차원
test_t_data_onehot = sess.run(tf.one_hot(test_t_data, depth=10))

# 그래프를 그려요- placeholder
# 독립변수의 개수만큼 노드를 잡아줘요. train_x_data_norm의 형태를 명시
X = tf.placeholder(shape=[None,784], dtype=tf.float32)
T = tf.placeholder(shape=[None,10], dtype=tf.float32)

# Weight & bias
W = tf.Variable(tf.random.normal([784,10])) # 힌튼교수가 random.normal이 문제..
b = tf.Variable(tf.random.normal([10]))

# Hypothesis(Model) 
# logit을 따로 만드는 이유는 loss 만들 때 linear regression이 들어가기 때문에
logit = tf.matmul(X,W)+b # linear regression 식
H = tf.nn.softmax(logit) # 다중 분류는 sotfmax , 총 10개 class에 대한 확률 값

# loss → Hypothesis와 실제값과의 차이
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit, 
                                                                 labels=T))

# train node
train = tf.train.GradientDescentOptimizer(learning_rate=1e-1).minimize(loss)

# session과 초기화(변수를 만들 때 내부에서 처리하는 초기화 기법)
sess.run(tf.global_variables_initializer())


# batch를 이용해서 training data를 분할해서 학습을 진행(메모리 문제 때문..)
# 여기서는 데이터 사이즈가 얼마 되지 않아 batch처리를 생략

# 학습을 진행
for step in range(3000):
    
    tmp, loss_val = sess.run([train, loss], feed_dict={X:train_x_data_norm,
                                                      T: train_t_data_onehot}) # one hot으로 자동으로 t 2차원
    
    if step % 300 == 0:
        print('loss : {}'.format(loss_val))        

        # loss : 0.6447577476501465

 

# Evaluation(accuracy를 측정해 보아요!)
predict = tf.argmax(H, 1) # 숫자 1 은 열 방향을 지칭 axis=1 # 어떤 index의 확률이 가장 높으냐?
correct = tf.equal(predict, tf.argmax(T,1)) # predict와 정답 T를 equal로 비교, True, False
acc = tf.reduce_mean(tf.cast(correct, dtype=tf.float32)) # 숫자로 바꿔 평균을 내줘요.

result = sess.run(acc, feed_dict={X:test_x_data_norm, 
                                 T: test_t_data_onehot})
print('Tensorflow 1.15의 정확도(multinomial):{}'.format(result))

#Tensorflow 1.15의 정확도(multinomial):0.8545238375663757

 

 

 

# 4. tensorflow 2.6 구현 (multinomial classification)

 

import tensorflow as tf

from tensorflow.keras.models import  Sequential

from tensorflow.keras.layers import  Flatten,Dense

from tensorflow.keras.optimizers import  Adam

 

keras_model = Sequential()

# hidden layer 없이,  # shape 입력데이터 column

keras_model.add(Flatten(input_shape=(train_x_data_norm.shape[1],))) 

keras_model.add(Dense(10, activation='softmax')) # Dense안에는 node의 개수

 

keras_model.compile(optimizer=Adam(learning_rate=1e-1),    # 3가지 설정

                    loss='sparse_categorical_crossentropy',# spare는 one hot 안 한다는

                    metrics=['accuracy'])  # 학습할때 이름으로 accuracy출력

 

# 학습마다 어떻게 진행되고 있는지 결과에 대해 저장

history = keras_model.fit(train_x_data_norm,

                          train_t_data,

                          epochs=100,

                          verbose=0,

                          batch_size=100,

                          validation_split=0.2)

 

result = keras_model.evaluate(test_x_data_norm,test_t_data)

 

print('Tensorflow 2.6(multinomial:{}'.format(result))

 

#Tensorflow 2.6(multinomial:[2.5401549339294434, 0.8788889050483704]

            

 

 

# 5. tensorflow 1.15로 구현(multilayer neural network을 이용한 multinomial classification)
# label의 class 들에 대해 one-hot-encoding 처리를 해야 해요!
hidden layer가 포함돼요! 이번에는 3개의 hidden layer를 이용해 볼거예요.

# weight의 초깃값을 random이 아닌 2가지 기법 중 하나를 이용

# bias는 random으로 잡아도 돼요 크게 중요하지 x
# weight의 초기화
# Xavier 초기화,  He's 초기화(Xavier 초기화의 개량 버전, 많이 이용)
# weight의 값을 랜덤으로 하지 않고 계산하는 기존에 사용한 복잡한 수식이 존재했었어요.
# 그래서 2가지 알고리즘이 나왔는데 그게 xavier 초기화, He's 초기화
# 입력의 개수와 출력의 개수를 기반으로 적절한 수식을 이용해서 초깃값을 설정



# Xavier 초기화 
# W = np.random.randn(input의 개수, output의 개수) / np.sqrt(input의 개수) 

                                      784             10          sqrt는 제곱근(root)를 구해줘요.

# He's 초기화
# W = np.random.randn(input의 개수, output의 개수) / np.sqrt(input의 개수 / 2) 

# activation function을 기존의 sigmoid → relu(Rectified Linear Unit)로 변경

# sigmoid 0~1 , relu는 0보다 크면 입력값 그대로 출력해요 즉 큰 값에 대해서 1로 치환하지 않아요.

(Vanishing Gradient 문제 해결)

 

 

# raw data loading, training data와 test data(최종 평가용) 분리, 정규화까지 코드 똑같아서 생략

import tensorflow as tf

sess = tf.Session() # Session이 있어야 node 안에 있는 값을 가져올 수 있어요!
train_t_data_onehot = sess.run(tf.one_hot(train_t_data, depth=10)) # depth는 class의 개수 현재 0~9 있어요.
# one-hot으로 바꿨기 때문에 train_t_data_onehot은 2차원
test_t_data_onehot = sess.run(tf.one_hot(test_t_data, depth=10))

# 그래프를 그려요
# placeholder
X = tf.placeholder(shape=[None,784], dtype=tf.float32)
T = tf.placeholder(shape=[None,10], dtype=tf.float32)

# Weight & bias - 다중 layer이기 때문에 weight와 bias가 늘어났어요!!
# He's 초기화
# 1. Variable → get_variable로 함수가 바뀌어요.
# 2. 겹치지 않게 내부적으로 사용하는 이름을 넣어줘요.

# 3. weight의 형태에 대한 정보 shape 추가

# 4. he's 초기법으로 초기화를 해야하니 initializer=tf.contrib.layers.variance_scaling_initializer

 → 초기화는 정해져 있어요

# Xvavier는 이렇게 하시면 돼요

# initializer=tf.contrib.layers.xavier_initializer())


# W2 = tf.Variable(tf.random.normal([784,512])) 
W2 = tf.get_variable('weight2', shape=[784,512],
                    initializer=tf.contrib.layers.variance_scaling_initializer())
b2 = tf.Variable(tf.random.normal([512]))
layer2 = tf.nn.relu(tf.matmul(X,W2) + b2)

# W3 = tf.Variable(tf.random.normal([512,256])) 
W3 = tf.get_variable('weight3', shape=[512,256],
                    initializer=tf.contrib.layers.variance_scaling_initializer())
b3 = tf.Variable(tf.random.normal([256]))
layer3 = tf.nn.relu(tf.matmul(layer2,W3) + b3)

# W4 = tf.Variable(tf.random.normal([256,128])) 
W4 = tf.get_variable('weight4', shape=[256,128],
                    initializer=tf.contrib.layers.variance_scaling_initializer())
b4 = tf.Variable(tf.random.normal([128]))
layer4 = tf.nn.relu(tf.matmul(layer3,W4) + b4)

W5 = tf.get_variable('weight5', shape=[128,10],
                    initializer=tf.contrib.layers.variance_scaling_initializer())
b5 = tf.Variable(tf.random.normal([10]))


# hypothesis
logit = tf.matmul(layer4,W5) + b5
H = tf.nn.softmax(logit)  # 마지막 분류해 주는 softmax는 건드리지 않아요.

# loss
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit,
                                                                 labels=T))

# train
train = tf.train.GradientDescentOptimizer(learning_rate=1e-1).minimize(loss)

# session과 초기화
sess.run(tf.global_variables_initializer())

# batch를 이용해서 training data를 분할해서 학습을 진행(메모리 문제 때문에...) 해야 해요!
# 여기서는 batch처리를 생략해서 구현할게요!

# 학습을 진행
for step in range(3000):
    
    tmp, loss_val = sess.run([train,loss], feed_dict={X:train_x_data_norm,
                                                      T:train_t_data_onehot})
    
    if step % 300 == 0:
        print('loss : {}'.format(loss_val))
        
# Evaluation(accuracy를 측정해보아요!)

predict = tf.argmax(H,1)  # 숫자 1은 axis=1의 의미.
correct = tf.equal(predict, tf.argmax(T,1)) # predict와 정답 T를 equal로 비교, True, False
acc = tf.reduce_mean(tf.cast(correct, dtype=tf.float32)) # 숫자로 바꿔 평균을 내줘요.


result = sess.run(acc, feed_dict={X:test_x_data_norm,
                                  T:test_t_data_onehot})

print('Tensorflow 1.15의 정확도(neural network multinomial) : {}'.format(result))

# Tensorflow 1.15의 정확도(neural network multinomial) : 0.9697619080543518
   


# anaconda prompt => conda install tensorflow-estimator==1.15.1

 

 

 

# 6. tensorflow 2.6로 구현(multilayer neural network을 이용한 multinomial classification)

import tensorflow as tf

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Flatten, Dense

from tensorflow.keras.optimizers import Adam

 

keras_model = Sequential()

 

# train_x_data_norm.shape[1] 은 결과적으로 독립변수의 개수를 나타내는 값

keras_model.add(Flatten(input_shape=(train_x_data_norm.shape[1],)))

 

keras_model.add(Dense(512, activation='relu'))

keras_model.add(Dense(256, activation='relu'))

keras_model.add(Dense(128, activation='relu'))

 

keras_model.add(Dense(10, activation='softmax'))

 

keras_model.compile(optimizer=Adam(learning_rate=1e-4),

                    loss='sparse_categorical_crossentropy',

                    metrics=['accuracy'])

 

histroy = keras_model.fit(train_x_data_norm,

                          train_t_data,

                          epochs=100,

                          verbose=1,

                          validation_split=0.2,

                          batch_size=100)

 

result = keras_model.evaluate(test_x_data_norm,test_t_data)

 

print('Tensorflow 2.6의 정확도(multilayer neural network) : {}'.format(result))

 

# Tensorflow 2.6의 정확도(multilayer neural network) : 0.9721428751945496

LIST

'머신러닝 딥러닝' 카테고리의 다른 글

0917 CNN 합성곱 신경망  (0) 2021.09.17
0917 Image 처리의 기본  (0) 2021.09.17
0915 mnist  (0) 2021.09.16
0915 Neural Networks, XOR  (0) 2021.09.15
0914 MNIST_ keras  (0) 2021.09.14

댓글