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
'머신러닝 딥러닝' 카테고리의 다른 글
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 |
댓글