본문 바로가기
LG 헬로비전 DX DATA SCHOOL/Python

Tensorflow를 이용한 회귀 와 분류

by 황밤 2023. 9. 15.
728x90
반응형

2023-09-15

1.Keras의 Dense

=>Dense: 완전 연결 층을 만들기 위한 클래스
=>생성할 때 파라미터
unit: 뉴런의 개수 - 많을 수록 학습을 잘함
activation: 활성화 함수 - sigmoid, softmax, tanh, relu 등
input_shape: 입력 데이터의 차원을 설정

 



2.선형 회귀 구현

=>하나 이상의 독립 변수들이 종속 변수에 미치는 영향을 추정하는 통계 기법


1)Keras의 모델 생성 방법
=>Sequential API: 순서대로 층을 쌓는 구조
=>Functional API: 함수에 대입하는 것
=>SubClassing: 기반 클래스로부터 상속을 받아서 사용
Inheritance -> Is A(기능 구형, 구체화, 구현) -> SubClassing(기능 확장 - Overriding)

2)Sequential API 사용
=>list 이용

model = tf.keras.Sequential([
tf.keras.layers.Dense(10),
tf.keras.layers.Dense(5),
tf.keras.layers.Dense(1)])



=>add로 추가하는 방법

model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10))
model.add(tf.keras.layers.Dense(5))
model.add(tf.keras.layers.Dense(1))



=>첫번째 층은 입력 층이어야 합니다.

  • 첫번째 층에서는 input_shape로 입력 데이터의 차원을 설정해 주어야 합니다.
  • 어떤 데이터가 (150, 4) 형식의 입력 구조라면 (4, ), [4] 로 설정하면 됩니다.
  • 데이터의 차원 중 첫번째는 데이터 개수 입니다.
  • Deep Learning에서 훈련을 하는 것은 데이터 개수와는 상관이 없고 데이터 구조와 관계가 있으므로 150 은 의미가 없고 4만 있으면 됩니다.

 


=>입력이 1개인 차원의 단순 선형회귀는 하나의 Layer로 해결이 가능

#입력 차원이 1개인 단순 선형 회귀

X = np.arange(1, 6)
y = 3 * X + 2

#모델 만들기
model = tf.keras.Sequential([
    tf.keras.layers.Dense(1, input_shape=[1])
])

#모델의 구조 확인
model.summary()



=>컴파일
훈련 과정에서 적용할 Optimizer, Loss Function(손실 함수), Metrics(평가 지표)

#컴파일
model.compile(optimizer='sgd', loss='mean_squared_error',
             metrics=['mean_squared_error', 'mean_absolute_error'])

#축약해서 작성
model.compile(optimizer='sgd', loss='mse', metrics=['mse', 'mae'])

#매개변수를 인스턴스 나 함수 또는 변수로 설정
model.compile(optimizer = tf.keras.optimizers.SGD(learning_rate=0.005),
              loss = tf.keras.losses.MeanSquaredError(),
              metrics = [tf.keras.losses.MeanSquaredError(), 
                         tf.keras.losses.MeanAbsoluteError()])



=>훈련

  • 훈련은 fit 함수로 수행을 하게 되는데 fit을 할 때는 데이터를 제공해야 하고 epoch을 설정하는데 epoch은 훈련 횟수이며 verbose=0 을 설정하면 훈련 과정이 출력이 안됩니다.
  • fit 함수에 옵션을 설정하면 검증 데이터 세트를 이용해서 검증을 할 수 도 있습니다.
  • fit 함수가 리턴하는 데이터는 epoch 별 훈련 손실 과 평가 지표가 dict 형태로 저장됩니다.
#verbose = 0을 추가하면 훈련 과정의 내용이 출력되지 않습니다. 
history = model.fit(X, y, epochs=2000)


=>훈련 과정에서 발생하는 손실 값 과 평가 지표 시각화

  • fit 함수를 호출하고 리턴되는 데이터를 이용하면 훈련 과정 중의 손실 과 평가 지표에 대한 내용을 확인할 수 있습니다.
#훈련 과정에서 발생하는 손실 값 과 평가 지표 시각화
plt.plot(history.history['loss'], label='loss')
plt.plot(history.history['mean_squared_error'], label='mean_squared_error')
plt.xlim(-1, 200)
plt.title("Loss")
plt.legend()
plt.show()



=>검증

model.evaluate(X, y)



=>예측

model.predict([10])

 



3.Classification(분류)

=>데이터
텐서플로 허브의 와인 데이터

레드 와 화이트 와인으로 분류가 되어 있습니다.
가져오는 URL이 달라서 가져온 후 하나의 데이터로 합쳐야 합니다.

피처 :

  • fixed acidity: 주석산
  • volatile acidity: 초산
  • citric acid: 구연산
  • residual sugar: 당도
  • chlorides: 소금
  • free sulfur dioxide: 자유 이산화 황
  • total sulfur dioxide: 총 이산화 황
  • density: 밀도
  • pH: 산도
  • sulphates: 황산 칼륨
  • alcohol: 알코올 도구
  • quality: 품질(1 ~ 10)

 


=>데이터 가져오기

import pandas as pd
white = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv', sep=";")
red = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv', sep=";")
print(white.head())
print(red.head())



1)이항 분류
=>두가지 중 하나로 분류하는 것

=>2개의 데이터를 합치고 타겟을 생성

red['type'] = 0
white['type'] = 1

#2개의 데이터를 세로 방향으로 합치기
wine = pd.concat([red, white])
print(wine.describe())



=>타겟의 분포를 확인: 분류의 경우는 분포가 고르게 되어야 하고 회귀의 경우는 정규 분포와 유사한 경우 예측이 잘 됩니다.
분류의 경우는 histogram을 많이 그리고 회귀의 경우는 scatter를 많이 그립니다.
분류의 경우는 차이가 많이 나면 샘플링을 할 때 층화 추출을 이용해서 비율을 조정하고 회귀의 경우는 값의 분포가 한쪽으로 쏠린 경우 로그 정규화를 수행

# 타겟 분포 확인

plt.hist(wine['type'])
plt.show()
#3배 정도 차이가 나는데 이 정도는 괜찮음



=>피처 정규화

#데이터 정규화
#sklearn 의 MinMaxScaler를 이용한 것 과 동일: 최대값은 1 최소값은 0
wine_norm = (wine - wine.min()) / (wine.max() - wine.min())
print(wine_norm.head())
print(wine_norm.describe())


=>데이터 샘플링

#데이터 샘플링
wine_shuffle = wine_norm.sample(frac=1) #데이터를 섞어서 리턴 - frac은 데이터의 비율
print(wine_shuffle.head())

=>Tensor 와 numpy 의 ndarray는 호환이 되지만 pandas의 DataFrame은 호환이 안되서 numpy 배열로 변경
#pandas의 DataFrame을 numpy 배열로 변환
wine_np = wine_shuffle.to_numpy()
print(wine_np[:5])



=>이전에 머신러닝에서 csv 파일의 데이터를 pandas의 DataFrame으로 읽은 경우 이렇게 랜덤하게 섞어서 numpy 배열로 변환하면 딥러닝에 이용 가능

=>현재 타겟은 0 과 1 인데 이를 맞다 틀리다로 할 것인지 아니면 서로 배타적인 분류로 취급할 것인지 결정

  • 맞다 틀리다로 분류하면 단항 분류로 간주하고 배타적인 분류를 하게 되면 이항 분류가 됩니다.
  • 이항 분류의 경우는 타겟을 원 핫 인코딩을 해주어야 합니다.
  • 원 핫 인코딩을 하고자 하는 경우는 tf.keras.utils.to_categorical(데이터, num_classes=클래스개수)를 이용해서 수행

 

=>훈련에 사용할 데이터 생성

#훈련에 사용할 데이터로 생성
train_idx = int(len(wine_np) * 0.8)

#train_idx 기준으로 행 단위로 분할해서 train 과 test로 분할하고
#맨 마지막 열을 기준으로 열 단위로 분할해서 feature 와 target으로 분리
train_X, train_Y = wine_np[:train_idx, :-1], wine_np[:train_idx:, -1] 
test_X, test_Y = wine_np[train_idx:, :-1], wine_np[train_idx:,-1]

#레드 와 화이트로 분류할 것이라서 타겟을 원핫 인코딩 수행
train_Y = tf.keras.utils.to_categorical(train_Y, num_classes=2)
test_Y = tf.keras.utils.to_categorical(test_Y, num_classes=2)
print(train_X.shape, test_X.shape)
print(train_Y.shape, test_Y.shape)



=>분류를 수행할 때 모델을 만드는 방법

  • 입력 층 1개 와 출력 층 1개는 필수
  • 입력 층에서 input_shape 에 입력 데이터의 열의 수를 설정해야 하고 출력 층에서는 activation 에 출력을 위한 함수를 지정해야 하는데 다항 분류에서는 softmax를 사용해야 합니다.
  • 중간의 히든 층은 몇 개를 설정하든 관계가 없는데 일반적으로 상위 층 보다 뉴런의 개수가 같거나 작아야 합니다.
#분류 모델
#이항 분류이고 피처의 개수가 12개입니다.
#첫번째 입력 층의 input_shape는 무조건 (12, )
#맨 마지막 출력 층의 units은 클래스 개수이므로 2 그리고 다항 분류이므로 activation은 softmax
#중간 층들의 units는 마음대로 설정 가능하지만 activation은 존재하는 이름을 사용해야 합니다.
model = tf.keras.Sequential(
    [tf.keras.layers.Dense(units=48, activation='relu', input_shape=(12, )),
     tf.keras.layers.Dense(units=24, activation='relu'),
     tf.keras.layers.Dense(units=12, activation='relu'),
     tf.keras.layers.Dense(units=2, activation='softmax')]
)
#최적화 함수는 Adam이고 학습률은 0.03
#손실 함수는 카테고리 크로스 엔트로피
#평가 지표는 정확도
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.03), 
              loss='categorical_crossentropy', metrics=['accuracy'])

#구조 확인
model.summary()

#훈련
history = model.fit(train_X, train_Y, epochs=25)


=>소프트맥스 함수(Softmax)

  • 출력 값들을 자연 로그의 밑인 e의 지수를 사용해서 계산한 뒤 모두 더한 값
  • 각 출력의 합은 1.0
  • 각 클래스 별 확률을 구해주는 함수
  • 분류 문제 나 RNN에서 다음 토큰을 예측, 강화학습에서 다음 행동 확률을 구하는 경우에 사용

 


=>entropy

  • 물리학에서 불확실한 정보를 숫자로 정량화 한 수치
  • 통계학에서는 확률의 역수에 로그를 취한 값
  • 확률의 역수를 취하는 이유는 확률이 높은 사건일 수 록 놀랍지 않다고 판단하기 때문
비가 올 확률이 1% 이고 비가 오지 않을 확률이 99% 라면

각 사건의 정보량은

h(비) = -log0.01 = 4.605
h(비가 오지 않음) = -log0.99 = 0.010

엔트로피의 기대값은 정보량에 확률을 곱해준 값

비: 0.01 * 4.605 = 0.0461
비가 오지 않는 겨우: 0.99 * 0.010 = 0.0099

엔트로피의 총 합을 줄여나가는 방식으로 알고리즘을 학습
엔트로피가 높은 사건이 더 가치있는 사건일 가능성이 높음

=>크로스 엔트로피는 확률 대신에 분류 네트워크가 예측한 라벨의 확률값
이 값도 손실이므로 낮은 쪽으로 가도록 학습을 하는 것

 

#훈련
#validation_split을 설정하면 그 비율만큼을 검증 데이터로 사용해서 검증을 수행
#batch_size는 데이터를 분할해서 학습을 수행
history = model.fit(train_X, train_Y, epochs=25, validation_split=0.25,
                    batch_size=64)

#평가
model.evaluate(test_X, test_Y)




2)3개의 클래스 분류
=>quality를 확인

print(wine['quality'].describe())
print(wine['quality'].value_counts())
#3~5를 0, 6을 1 7~9 를 2로 그룹화


=>타겟 생성

#타겟 생성
wine.loc[wine['quality'] <= 5, 'new_quality'] = 0
wine.loc[wine['quality'] == 6, 'new_quality'] = 1
wine.loc[wine['quality'] >= 7, 'new_quality'] = 2
print(wine.head())



=>피처만 정규화: 

  • 이전에는 타겟이 0 과 1로만 이루어져있으므로 min_max 정규화를 해도 그대로
  • 피처만 골라내서 정규화를 하기도 하고 전체 데이터를 카피를 해두고 전체를 정규화한 후 타겟만 복제본에서 가져오기
#피처 정규화
#del wine['quality']

wine_backup = wine.copy() #복제본 생성

#타겟을 제외한 부분을 정규화
wine_norm = (wine - wine.min()) / (wine.max() - wine.min())
wine_norm['new_quality'] = wine_backup['new_quality']
print(wine_norm.head())

#훈련 데이터 와 테스트 데이터를 분할
wine_shuffle = wine_norm.sample(frac=1)
wine_np = wine_shuffle.to_numpy()
train_idx = int(len(wine_np) * 0.8)
train_X, train_Y = wine_np[:train_idx, :-1], wine_np[:train_idx, -1]
test_X, test_Y = wine_np[train_idx:, :-1], wine_np[train_idx:, -1]
#타겟을 원핫인코딩 하기
train_Y = tf.keras.utils.to_categorical(train_Y, num_classes=3)
test_Y = tf.keras.utils.to_categorical(test_Y, num_classes=3)



=>분류해야 할 클래스 개수가 늘어나면 층의 깊이 더 깊어지거나 학습률을 더욱 낮추어야 잘 훈련을 하게 됩니다.


2)다항 분류
=>2개 보다 많은 클래스로 분류

 

........................................

=>평가

  • 테스트 데이터로 평가
  • 테스트 데이터로 평가하면 훈련 데이터나 검증 데이터로 평가할 때 보다 손실이 크고 정확도가 떨어짐
  • 성능 차이가 많이나면 다른 Optimizer 나 학습률 및 학습 횟수를 조절하고 다시 훈련
  • Hidden Layer를 추가하거나 뉴런의 개수를 조절하는 방법도 사용 가능

 

=>수정

  • model을 만드는 부분에서 Hidden Layer 개수나 뉴런의 개수 변경
  • compile 하는 부분에서 Optimizer를 변경
  • fit 에서 훈련 횟수 변경
  • evaluate로 다시 평가

 

=> 모델이 만들어지면 predict 함수로 새로운 데이터를 예측하고 서비스를 시작 : 론칭이라고 하기도 하고 배포라고 하기도 함.

 

 


 

4. 다항 회귀

1) 특징

  • 회귀는 출력이 1개

 

2) 모델 생성 및 훈련

  • 모델 생성
model = keras.models.Sequential([
		#입력 층
    	keras.layers.Dense(뉴런의 개수, activation="relu", input_shape=X_train.shape[1:])
    
   		#hidden layer
    	keras.layers.Dense(뉴런의 개수, activation="활성화 함수"
    
    	#출력 층
    	keras.layers.Dense(1, activation="softmax")
		])

 

  • 컴파일
model.compile(loss="mean_squared_error", optimizer=keras.optimizers.SGD(lr=0.003), metrics=["mean_squared_error"])

 

  • 훈련

history = model.fit(훈련 데이터 피처, 훈련 데이터 타겟, epochs=훈련횟수, validation_data = 검증 데이터)

 

  • 확인

mse_test = model.evaluate(확인 데이터 피처, 확인 데이터 타겟)

 

 

3) Functional API

  • Sequential API는 모든 데이터가 순차적으로 동일한 경로를 갖는 구조입니다.
  • 함수형 API를 이용하면 순차적으로 모든 층을 통과하고 일부는 모든 층을 통과하지 않는 구조를 만들 수 있습니다.
  • 모든 데이터가 동일한 순서대로 층을 통과하면 어떤 왜곡된 패턴이 만들어 질 수 있습니다.

데이터의 순서가 학습에 반영되는 결과가 만들어 질 수 있습니다.

  • 함수형 API를 사용하면 일부 또는 전체는 출력 층에 바로 연결 시킬 수 있고 히든 층을 통과하도록 할 수 있습니다.

 

#입력층 생성
input_ = keras.layers.Input(shape=X_train.shape[1:])
#input 다음 연결되는 층 생성
hidden1 = keras.layers.Dense(30, activation="relu")(input_)
#hidden1의 출력을 입력을 받는 층을 생성
hidden2 = keras.layers.Dense(30, activation="relu")(hidden1)
#이층은 input_ 나 hidden2의 출력을 입력으로 보다는 층을 생성
#연결만 시켜주는 층이라서, 뉴런의 개수나 활성화 함수는 의미가 없음
concat = keras.layers.concatenate([input_, hidden2])

#concat의 출력을 입력으로 받는 출력 층 생성
output = keras.layers.Dense(1)(concat)

#함수형 모델 생성 - inputs 에 Input 층을m, outputs에 Output 층을 설정하면 됩니다.
model = keras.models.Model(inputs=[input_], outputs=[output])

 

  • Input Layer를 2개를 만들면 서로 다른 데이터를 짧은 경로와 긴 경로를 통해서 전송되도록 할 수 있습니다.
  • Layer를 생성할 때 name을 설정하면 출력할 때 name 과 함께 출력하기 때문에 구조를 알아보기 편리해집니다.

4) 다중 출력

  • 딥러닝에서는 여러 개의 출력이 가능
  • 출력 층을 생성하고 Model을 만들 때 출력 층들을 여러 개 설정하면 됩니다.
  • 컴파일 할 때 loss를 리스트 형태로 여러 개 설정할 수 있고 1개만 설정하면 모든 출력에 동일한 loss 함수를 적용. 손실 값은 여러 개의 출력의 합으로 계산하는데 loss_weights 속성을 이용해서 가중치를 설정할 수 있습니다.

 


5. SubClassing

5.1) 함수형 프로그래밍과 객체 지향 프로그래밍

  • 함수형 프로그래밍은 클래스 없이 함수의 생성과 호출 만으로 프로그래밍 하는 것
  • 객체 지향 프로그래밍은 클래스를 기반으로 인스턴스를 생성해서 메서드를 호출하는 형태로 프로그래밍 하는 것
  • Optimizers 나 Loss Function, Metrics 등을 직접 만들어서 사용하기 위해 사용

 

6. 모델 저장과 복원

  • 딥 러닝은 모델을 저장한 후 복원해서 새로 추가된 데이터만 가지고 학습이 가능합니다.
  • 머신러닝은 새로운 데이터가 입력되면 처음부터 다시 훈련을 해야 합니다.
딥 러닝은 이전에 학습했던 내용을 가지고 만든 모델이 자신의 파라미터를 전부 기어갛고 있다가 새로운 데이터만 추가해서 학습을 하는 것이 가능합니다.
  • 하나의 모델을 만들어서 온라인 학습을 수행하고 서비스에도 활용하고자 한다면 모델을 학습하는 부분과 서비스하는 부분을 분리해서 모델을 복사해서 하나의 모델을 가지고 서비스를 하고 다른 모델을 가지고 계속 훈련 가능
  • 훈련 중 체크 포인트 설정도 가능
  • 모델 전체가 아니라 현재 모델이 학습한 가중치만 저장하고 가져올 수 있습니다. 
이 경우, save_weights 함수와 load_weights 라는 함수를 이용

 


 

7. 콜백

  • callback : 이벤트가 발생했을 때 호출되는 것
callback 함수 : 이벤트 발생시 호출되는 함수
EventListener : 이벤트 발생 시 호출될 함수를 가진 객체
  • 모델을 훈련 할 때 callbacks 라는 매개변수에 list 형태로 callback을 설정하면 이벤트가 발생했을 callback에 정의 된 동작을 수행
  • 훈련을 할 때 마다 가중치를 저장할 수도 있고 최적의 모델만 저장할 수도 있고 조기 종료 등도 가능.

7.1) Model Checkpoint

  • epoch 별 모델의 가중치를 저장
filepath : 체크 포인트의 저장 경로를 지정
save_weights_only : 가중치만 저장할 지 여부
save_best_only_monitor : 가장 우수한 epoch의 데이터만 저장할 지의 여부
monitor : 저장시 가장 우수한 모델의 epoch를 설정할 지표를 설정 (loss 나 val_loss 중 설정)
verbose : 매 epoch 별 저장 여부를 알려주는 로그 메세지를 출력

 

7.2) Ealry Stopping

  • 조기 종료 : 일정 epoch를 진행했을 때 loss 가 좋아지지 않으면 종료되도록 해주는 콜백

 

7.3) LearningRateScheduler

  • 일정한 epoch 단위로 학습률을 조정할 수 있는 스케쥴러
  • epoch를 진행할 때 마다 학습률을 감소시켜서 더 좋은 모델을 만들도록 하는 경우가 대부분
  • 조기 종료와 같이 사용하는 경우가 많음 (학습률 조정 후 일정 epoch 동안 변화가 없는 경우)
  • epoch와 learning_rate를 매개변수로 받아서 이를 수정하는 함수를 만든 후 LearningRateScheduler 인스턴스를 만들 때 매개변수로 대입해서 사용
def scheduler(epoch, lr):
    tf.print(f'learning_rate: {learning_rate:.5f}')
    # 첫 5 에포크 동안 유지
    if epoch < 5:
        return lr
    else:
    # 학습률 감소 적용
        return lr * tf.math.exp(-0.1)

# 콜백 객체생성 및 scheduler 함수 적용
lr_scheduler = tf.keras.callbacks.LearningRateScheduler(scheduler)

7.4) 제공되는 Callback 이 외의 작업을 수행

  • tf.keras.callback.Callback 클래스를 SubClassing

7.5) 딥 러닝 구현 알고리즘은 객체 지향 프로그래밍의 형태로 만들어져 있음

  • 클래스로 제공
  • 확장 가능성을 제공하기 위해서

 


 

8. Tensorboard

  • Tensorflow의 시각화 도구
  • 훈련하는 동안 학습 곡선을 그리거나 여러 실행 간의 학습 곡선을 기교하거나 훈련 통계 분석을 수행하기 위한 도구
  • 로그 기록 등을 수행할 수도 잇음
  • 콜백의 형태로 사용
콜백의 이름이 TensorBoard - 인스턴스 만들 때 로그를 기록할 디렉토리 경로를 설정
실행할 때 마다 별도의 디렉토리를 생성해서 훈련 로그를 기록

 


9. 하이퍼파라미터 튜닝

  • 하이퍼파라미터 튜닝은 sklearn에서 사용하던 개념
  • sklearn의 기능을 keras가 wrapping해서 예전에는 사용을 했습니다.
  • Tensorflow는 2.5 버젼까지 동작을 했었으나 최신 버젼에서는 keras 에서 sklearn의 알고리즘을 사용할 수 없도록 제거
  • 이 기능을 최신 버젼의 Tensorflow에서 사용하고자 하는 경우, scikeras 라는 패키지를 import해서 사용

 

9.1) 은닉층의 개수 - Hidden Layer의 개수

  • 은닉층이 하나이더라도 뉴런의 개수가 충분히 많으면, 아주 복잡한 함수도 모델링 할 수 있다고 합니다.
  • 은닉층이 여러 개인 경우 성능이 높은 경우가 많음.
  • 예전에는 은닉 층 안에서 뉴런의 개수를 깔대기 모양으로 줄여가면서 사용하는 것을 권장했는데 최근에는 동일한 뉴런의 개수를 사용해도 크게 관계없음

9.2) 학습률

  • 매우 낮은 학습률(0.00001) 에서 시작해서 조금씩 높여가면서 최적의 학습률을 찾는 것을 권장합니다.
  • 학습률을 조정해서 수행하면 특정 시점에 손실이 커지는 지점이 보이는데 이 지점 근처가 최적의 학습률임.

9.3) 옵티마이저

  • 경사하강법 보다 최근에 등장한 옵티마이저를 선택하는 것을 권장

9.4) 배치 크기

  • 32보다 작은 배치를 사용하는 것을 초창기에 권장하였으나, 최근에는 배치의 크기는 일반화 성능에 별 영향이 없으므로 훈련 속도 향상을 위해서 조금더 큰 배치를 사용하는 것도 권장(단, 너무 크면 초반에 훈련이 불안정해질 수 있어 조정하여 사용)

9.5) 활성화 함수

  • 현재까지 알려진 바로는 ReLU가 거의 모든 은닉 층에서 좋은 기본 값

9.6) 훈련 횟수

  • 크게 설정하고 조기 종료를 설정하는 것을 권장

10. 그라디언트 소실과 폭주 문제 : 최적화 문제

10.1) 개요

  • 역전파 알고리즘은 출력층에서 입력층으로 오차 그라디언트를 전파하면서 진행되는데 경사 하강법 단계에서 이 그라디언트를 사용해서 파라미터를 수정
  • 알고리즘이 하위 층으로 전파되면서 그라디언트가 점점 작아지게 되는데 이렇게 진행하다보면 그라디언트가 너무 작아져 소실되는 경우가 있는데 이를 Vanishing Gradient 라고 함. 반대로 오차가 너무 커져 가중치가 커지는 경우가 있는데 이 경우는 Exploding Gradient라고 하며, 이 경우 알고리즘이 발산되어 전혀 엉뚱한 예측을 하게되는데 주로 RNN에서 발생

10.2) 시그모이드 함수

  • (모델이 깊은 경우)그라디언트 소실을 발생시키는 하나의 요인으로 판단되며 하이퍼볼릭 탄젠트(tanh) 함수 등을 사용

10.3) 글로럿과 He 초기화

  • 그라디언트 소실을 가져온 다른 이유 중 하나는 초기값 설정 문제입니다.
  • 초창기 신경망에서는 초기값을 0에서 1사이의 정규분포에서 추출 - 이 방법이 그라디언트를 소실시켜버리는 요인 중 하나로 판단. 
fan-in 과 fan-out을 이용한 정규 분포나 균등 분포에서 초기값을 가져오는 방법을 제안
fan-in은 들어오는 개수이고 fan-out은 나가는 개수입니다.
이를 이용하는 방법으로는 Glorot 초기화 또는 Xavier 초기화 그리고 르쿤 초기화 등이 있으며 최근에는 ReLU 활성화 함수에 대한 초기화 전략으로 He 초기화가 등장

10.4) 활성화 함수

sigmoid -> ReLU -> LeakyReLU -> PReLU -> ELU -> SELU

 

10.5) 배치 정규화

  • 정규화 : 값의 스케일을 조정
  • 처음에는 대부분 입력 단계에서만 정규화를 수행. 최근에는 입력으로 발생하는 출력도 다음 층으로 전달하기 전에 정규화하는 것이 좋다고 알려져있습니다.
  • 입력 데이터는 우리가 가지고 있는 데이터라서 정규화를 할 수 있지만 각 Layer가 출력하는 데이터는 우리가 소유하고 있지 않아서 직접 정규화가 불가능
  • 텐서 플로우에서는 BatchNormalization 이라는 층을 제공하여 이 층의 객체를 만든 후 입력 앞에서 설정하면 배치 정규화를 수행해 줍니다. 
keras.layers.Flatten()

keras.layers.BatchNormalization()

keras.layers.Dense()

keras.layers.BatchNormalization()

keras.layers.Dense()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-상속을 만들어서 사용을 해보자!!!!!!!-

 

반응형
LIST