티스토리 뷰
네이버 edwith AI/딥러닝 입문을 위한 학습 콘텐츠 추천에 따른 수업 + 3BlueBrown 강의
https://www.edwith.org/hellodl101/lecture/103151
[모두를 위한 머신러닝/딥러닝 강의2]
(https://deeplearningzerotoall.github.io/season2/lec_pytorch.html)
1. Tensor 문법
: https://colab.research.google.com/drive/1oXGdB4aPcGXDvvXRnovBg0UJbIS5c9eF#scrollTo=O6DUEZtGuYnv
epoch : 전체가 한번 사용이 되면 한회 폭이 다 돌았다.
batch size : 6만장을 한번에 사용 할 수 없어 잘라서 사용함(자르는 크기가 바로 batch size)
iterations : 이 batch를 몇번 학습에 사용을 했는가
ex. 1000개의 train이 필요한 예제가 있다.
batch size = 500 이면 -> 2 batch가 있다.
2개의 iterations을 사용하게 된다면 -> 1epoch이 끝났다고 볼 수 있다.
2. 선형회귀 Simple Linear Regression : 하나의 정보로 부터 하나의 결론을 얻는 모델
: https://colab.research.google.com/drive/1gO6hC0XXPvBPDjjaY25BJrHN9scdeD4o#scrollTo=JhPMGYl8Pt5G
[ Model - Activation Function]
- 선형함수와 비선형 함수
선형 함수란 출력이 입력의 상수배만큼 변하는 함수를 선형함수라고 한다. ex. f(x)=Wx+b라는 함수가 있을 때, W와 b는 상수입니다. 이 식은 그래프를 그리면 직선이 그려집니다.
비선형 함수란 직선 1개로는 그릴 수 없는 함수를 말합니다.
- 비선형을 사용하는 이유
비선형의(Non-linear) 활성화 함수(Activation Function)를 쓰는 이유는, 활성화 함수가 선형(Linear)일 경우 퍼셉트론(Perceptron)이 여러 개라도, 즉, 층(Layer)을 깊게 쌓더라도 층이 한 개인 경우와 차이가 없기 때문이다.
인공 신경망의 능력을 높이기 위해서는 은닉층을 계속해서 추가해야 합니다. 그런데 만약 활성화 함수로 선형 함수를 사용하게 되면 은닉층을 쌓을 수가 없습니다. 예를 들어 활성화 함수로 선형 함수를 선택하고, 층을 계속 쌓는다고 가정해보겠습니다.
활성화 함수는 f(x)=Wx라고 가정합니다. 여기다가 은닉층을 두 개 추가한다고하면 출력층을 포함해서 y(x)=f(f(f(x)))가 됩니다. 이를 식으로 표현하면 W×W×W×x입니다.
그런데 이는 잘 생각해보면 W의 세 제곱값을 k라고 정의해버리면 y(x)=kx와 같이 다시 표현이 가능합니다. 즉, 선형 함수로는 은닉층을 여러번 추가하더라도 1회 추가한 것과 차이를 줄 수 없습니다.
선형 함수를 사용한 은닉층을 1회 추가한 것과 연속으로 추가한 것이 차이가 없다는 뜻이지, 선형 함수를 사용한 층이 아무 의미가 없다는 뜻이 아닙니다. 학습 가능한 가중치가 새로 생긴다는 점에서 분명히 의미가 있습니다. 이와 같이 선형 함수를 사용한 층을 활성화 함수를 사용하는 은닉층과 구분하기 위해서 선형층(linear layer)이나 투사층(projection layer) 등의 다른 표현을 사용하여 표현하기도 합니다. 활성화 함수를 사용하는 일반적인 은닉층을 선형층과 대비되는 표현을 사용하면 비선형층(nonlinear layer)입니다.
선형회귀(Linear Function)이란? 학습 data와 가장 잘맞는 하나의 직선을 찾는 일
0. 데이터 정의 : x와 y를 정의
1. Hypothesis 초기화
w와 b를 0으로 초기화 ( 어떤 입력을 받아도 0을 예측하도록 함)
-> w와 b를 학습시키는게 목적이르모 requires_grad = true 처리
2. Optimizer 정의
[W,b]를 list를 만들어 넣어주고,
mean(평균)을 통해 Loss를 구한다 -> 평균 (실제 data - 가설이 나타내는 data)^2
3. 모델 개선 (for문 반복)
모델 예측
예측값,y 차이를 cost 계산
계산한 optimizer에 사용하는 3가지를 작성
step : 계산된 gradient 방향대로 weight,bias를 개선한다
-> w와 b가 최적의 숫자로 수렴한다.
[ Model - Optimizer]
optim.SGD
SGD = Stochastic Gradient Descent -> optimizer = optim.SGD([W, b], lr=1)
SGD (확률적 경사 하강법) : 기울어진 거리로 일정 거리만 가겠다.
단점 : 방향에 따라 성질,기울기가 달라지는 함수여서 탐색 경로가 비 효율적이다.
2-2 선형회귀: Cost Function
: 예측 데이터와 실제값데이터를 의 차의 거리(예측한것과 실제가 얼마나 다른지)
예측 데이터와 실제값데이터를 의 차로 예측(hypothesis)가 좋은지(가까움) 나쁜지(멀리있음) 판단.
제곱을 하는 이유 : 차이를 일정하게 양수로 표현하고, 제곱으로 인해 차가 클 때 값이 더 커져서 확인하기 좋다.
예측값 - 실제값의 n개를 평균을 구함.
결론 : 가장 작은 w와 b를 구하는 것
2-3 선형회귀 : Gradient Decent
cost 함수가 최소화 되는 점을 찾는것 = Gradient Descent 알고리즘(경사를 따라 내려가는 알고리즘)
- 아무점에서 시작해서 조금씩 W와 b를 바꾸면서 cost를 줄인다.
- 어느점에서 시작하든 항상 최저점에 도착한다.
어떻게 경사를 구하는가? 미분을 통해
W: = W - a(learning rate)*a/aw cost(w) (cost함수 미분한것)
W값이 계속 변화하면, cost값도 계속 변화하게 된다.
Convex Function =
어느점에서 시작하던, 도착하는 점이 원하는 지점 = gradient descent 알고리즘이 항상 답을 찾을 수 있다.
-> cost function의 모양이 convex function이 되는지 확인해야한다.
2-4 선형회귀 : Multi-variable linear regression
: 여러개의 정보로 부터 하나의 추측값을 계산
Matrix Data Representation :변수가 100이상일 경우 수식이 길어져서 Matrix방식을 통해 계산한다
각 뉴런이 0~1 사이의 값을 취하고 숫자와 입력값이 일치하는 정도를 나타냄
어떻게? 한층 → 다른층 활성화 유도
뉴런을 잇는 신경에 가중치 부여(w)
w1a1+w2a2++w3a3+...+wnan
주변 픽셀에 가중치를 두면 주변의 픽셀이 어두우면서 중앙의 픽셀이 밝을때 최대치를 얻을 수 있다.
weighted sum >10 으로 하고싶을때 양수값에 제한을 두고싶을때 ∂ :sigmode를 사용한다.
→ ∂(w1a1+w2a2+w3a3+...+wnan"-10") 음의 숫자를 더한다 (bias)
3. Logistic classification (regression)
https://colab.research.google.com/drive/1Xzw952RiOfsCAAwOA6USRiKJ5gy_k7L4#scrollTo=WFgy3N3P4THl
: Linear Regression의 경우, 0~1중에서 어떤곳에 가까운지 정답을 학습하기 때문에 학습때마다 0.5여서 불합격 처리가 될 수 있다.
또한 H(x) = wx+b의 경우, 0~1 사이의 값이 아닌 훨씬 크거나 작은값이 도출 될 수 있다.
-> 0~1사이로 압축을 시켜주는 함수가 필요성을 느낌. => sigmond function(=logistic function)
∂ :sigmode란? logistic classfication에서 어디에 속하는지 분류하기 위해 사용했다. 일정한 값을 넘겨야 참 가능
단점 : 매번 sigmond를 곱하는데 0~1 사이로 변형을 하면서 일정 비율로 줄어서 현저하게 작아진다. (처음 값의 1/1000 이 된다.)
backpropagation에서 결과를 전달할 때 sigmoid를 사용한다. 그런데, layer가 많을 때, 미분 결과를 최초 layer까지 전달하는것이 어렵다. (작은 음수 → 0, 큰 양수 →1)
3-2 Logistic regression : cost 구하기
sigmond function을 사용할경우 구부러진 모습이 된다. -> 시작점에 따라 끝나는 점이 달라질 수 있다.(=Local Minimum)
cost가 Local Minimum에서 학습이 멈춰버리면 모델이 나쁘게 예측하게 된다 -> 사용 불가
따라서 cost함수도 변경이 필요하다.
C(H(x),y) = -log(H(x)) : y=1
-log(1-H(x)) : y=0
H(x)의 가설(y=1)이 틀려서 y=0일경우 cost의 값이 굉장히 커져서 cost = 무한대 가 된다.
H(x)의 가설(y=1)이 맞을 경우 cost(1) = 0
H(x)의 가설(y=0)이 틀려서 y=1일경우 cost의 값이 굉장히 커져서 cost = 무한대 가 된다.
H(x)의 가설(y=0)이 맞을 경우 cost(1) = 0
-> 밥그릇 모양이 된다. (기울기 구할 수 있음)
if 컨디션에 따라 값이 다르게 표현되고 있어서 변경 필요
C(H(x),y) = -yLog(H(x)) - (1-y)log(1-H(x))
- Cost 최소화 구하기
Library Optimizer로 구한다.
4. Softmax Regression(정리중)
https://colab.research.google.com/drive/1IB5vu8dyWbk2HzWkLPDJGc6HD585mzON#scrollTo=KfWoGEIRF5pv
Softmax : max 값을 soft하게 뽑아준다.
기존에 max를 뽑으면,[1,2,3]이 주어지면 0,0,1로 결과를 받는다.
softmax는 tensor([0.0900, 0.2447, 0.6652]) 로 모두 더해서 1이되는 값(확률값)을 나타내준다.
H(x) = wx 리턴 값이 실수의 값이 되기 때문에 우리가 하려는 binary,logistic 0이나 1인지 고르는것에 적합하지 않았음
z축의 합이 커지더라도 g(z) 라는 함수가 있다면 이 함수가 큰 값을 압축을해서 0이나 1 값으로 나와 주면 좋겠다.
g(z) z축의 값이 커지더라도 g(z)는 1 보다 작은값에 머물고, 아주 작아도 0보다 큰 값에 머무르도록 하기 위해 sigmoid(=logistic) 을 만들었다.
hyposis 가 H(x) = g(H(x))
x1,x2가 있을때, logistic 를 학습, 두가지를 구분하는 선을 찾아내는 것
binary classification A or not / B or not / C or not
Multinomial classifiacation
각각 하나의 class file이 있을때 행렬로 구현 (w1x1+w2x2+w3x3) 세개의 독립된 classifiacation를 갖는다.
하나의 벡터로 처리시 바로 한번에 계산이 가능하고 독립된 classifiacation처럼 관리가 가능하다.
Softmax Regression : sigmoid로 0~1사이의 값으로 표현된 p를 모두 더했을때 1이 되는 형태로 포현
n개의 값을 Softmax에 넣으면
1. 0~1사이의 값
2. 전체의 sum이 1이 된다. (확률이 된다.)
3. 가장 큰 확률(제일 큰 값만) 가지고 오려고 할 때 그 값만 1로 표현하고 나머지는 0으로 표현한다 (one-hot encoding)
cost function : 예측한 값과 실제의 값이 얼마나 같은지 확인하기 위해 cost function
예측이 틀렸을때 무한대의 값을 준다.
0 : 무한대, 1: 0
L(실제값) S(예측값)
cross entropy: 두개의 확률 분포가 주어졌을때 두개의 확률분포가 얼마나 비슷한지 나타내는 수치
P: 철수가 가위를 냈을 때, 다음번에 무엇을 낼지에 대한 확률 분포 함수
P에서 x를 샘플링해서 Q에 넣은 후에 Log를 씌운 값의 평균을 구한값.
Log를 취하고 -를 취해서 H(P,Q1) < H(P,Q2) 일때,
Cross entropy로 최소화 하면, Q2 -> Q1 -> P에 다가가게 된다.
점점 P에 근사하게 된다.
Logistic cost VS cross entropy
C:(H(x),y) = yLog(H(x)) - (1-y)Log(1-H(x))
D(S,L) = -
왜 수식이 다름에도 같을까?
Cross Entropy에서는 A or B로 [1,0], [0,1]로써 서로 구분을 하는거지만,
Logistic은 정답이 A 혹은 B라고 했을때 이게 맞는지 아닌지를 판단하는 것
cost function : 전체의 차를 구하고 평균을 구해 개선을 한다.
Gradient descent = cost를 최소화 하는 값을 구한다. w 백터, Loss,Cost function 어떤점에서 시작해도 경사면(함수를 미분)에 따라 내려가면 최소값에 도달 할 수 있다.
5. Training / Test data set, Minist data set
5-1 Learning rate
Gradient descent 경사를 타고 내려가는 알고리즘
이때 알고리즘을 정할때 lr라는 알파값을 임의로 정했다.
우리가 구하는 것은 하나의 w나 e가 아니라, 여러 요소가 뭉쳐진 최종결과에 대한 손실함수 값의 '현재 영향력'을 찾아내는 것이므로,
편미분을 사용하여, 각 w와 b가 가지는 '방향성'과, 각 변수들간의 '비중'에 따라서 '일정량'을 갱신시켜줘야합니다.
이것이 바로 '학습률'이라는 것이다. 손실함수의 값이 0이되는 위치를 탐색하기 위하여, 각 변수들을 갱신하는 단위가 됩니다.
learning rate(= 경사를 따라 내려가는 step)를 잘 정하는 것이 중요하다 :
Large learning rate => ovgershooting : step 너무 크면 밖으로 튕겨나갈 정도로 값이 크다.(cost가 줄어들지 않고 계속 가다가 숫자가 아닌 값들이 출력)
Small learning rate => 시간이 오래걸리고 지역최소값에서 값이 멈춘다. cost값이 작은값으로만 변할 경우
전반적으로 learning rate를 정하는데 특별한 답은 없고 cost 함수의 값을 관찰한다.
평균 0.01을 기본으로 하고 값이 발산하면 : 값을 작게
값이 너무 조금씩 움직이면 : 값을 크게 한다.
5-2 Overfitting
[Overfitting]
주어진 데이터에 대해 실제 우리가 알고싶은 경계선이 아닌 과도하게 fitting된 상황.
주어진 데이터에 대해 그 데이터를 가장 잘 설명하는 확률분포 함수를 찾다보니 overfitting이 발생할 수 밖에 없다.
ML 학습을 통해서 모델을 만들어가다보니, 학습 data에 너무 딱 잘맞는 모델을 만들어 낼 수 있다.
이것이 학습 데이터를 다시 가지고 물어보면 잘 대답하지만 실제 테스트 데이터나 실제 사용시 잘 맞지 않는 문제.
discion bandary의 그래프가 구불구불할때 overfitting
어떻게 확인하는가? validatation set의 loss가 높아지고, training set의 loss는 낮아지고 있을 때
해결방법 : training data set ,test data set을 나눠서 실제 훈련후에 검증하는 방법.
1. More data : training data를 많이 가져야한다. : 적을 수 로 편향된 분포를 가질 수 있기 떄문에
2. Less features : feature(분포를 잘 나타내는 특징: 주걱턱 등등), feature 갯수 중 중복된것이 있으면 줄인다. Regularization(일반화) 시킨다.
3. Early Stopping : Validation Loss가 더이상 낮아지지 않을때, 학습을 중단한다.
4. 활성화 함수(Activation Function)앞에 Batch Normalization을 적용시켜준다.
5. Dropout방법을 적용시켜준다.
5-3 Normalization VS Standardization VS Regularization
사용이유: 특성들의 단위를 무시하고, 특성들의 값의 범위를 비슷하게 만들어서 데이터간의 비교를 하기 위해서
- Regularization : weight를 조정하는데 제약을 거는 기법 → overfitting을 막기 위함
- Standardization : 값의 범위를 평균 0, 분산 1이 되도록 변환 →학습전에 scaling해서 큰 feature의 영향이 비대해지는것을 방지. Local Minimal에 빠질 위험 감소
- Normalization : 값을 0~1사이의 값으로 바꾸는 것
Regularization : 우리가 가지고 있는 weight을 너무 큰 값을 가지지 말자.
cost 함수 뒤에 더하는 weight제곱의 값이 작아질 수 있도록 (크면 클수록 구불어지기 때문에)
- λ 이 값이 0 -> 값을 쓰지 않겠다.
- λ 이 값이 크면 -> Regularization을 굉장히 중요하게 생각한다.
- λ = 0.001 이면 크게 중요하지 않는다.
Standardization : 0의 평균, 1의 표준편차를 갖도록 정규 분포로 변환해줌.(0과 1의 범위로 균일하게 바뀌지는 않는다.)
대부분 8~40으로 평균 23인데, 특정 데이터 하나가 90일 경우 발생하는 문제로, 이런 경우를 outlier로 한다.
위 이미지의 수식으로 계산 후 -2~2를 벗어난 값들을 모두 지워서 0의 중앙값으로 갖는 값으로 모이게 한다.
정규분포를 만들어 주는 과정 : 우리의 데이터가 정규 분포를 따른다고 가정하고 정규분포의 값으로 만들어 준다.
어떤점에서 시작해서 step씩 경사면을 내려가서 최고로 낮은 지점에 도착하는것이 목표
내가 learning rate를 잘 잡았는데에도 불구하고 학습이 일어나지 않고 cost함수가 발산하거나 이상한 동작을 보일땐 데이터중에 차이가 크게 나는것이 있는지, 전처리를 했는지 확인해야한다.
x의 값을 우리가 계산한 평균과 분산값을 나눠준다.
Normalization : 한 특성내의 가장 큰 값을 1로, 가장 작은값은 0으로 변환하여 모두 0,1범위를 갖도록 하는 방법으로 값의 규모를 줄여준다. → 다른 열에 비해 데이터가 지나치게 큰 열에 사용한다.
feature data(x)를 전처리 할 경우 사용.
전처리를 안한다면? 만약 y_train이 (m,2) 일때, 한 열에 1000과 같이 큰 값, 다른 한 열에 0.1 과같이 작은값이면 mse가 최적화시 큰값이 있는곳만 최적화 진행을 하게 된다.
하지만 전처리 처리를 하게 된다면 똑같은 범위 값으로 변하게 되고 뉴런 네트워크는 동등하게 이 값을 학습하게 될것이다.
이와같이 데이터의 성질 형태에 따라 전처리하는 것도 중요하다 왜냐하면 gradient descent를 통해 maximumize를 하기 때문에 최적화가 원활히 되어야 최적의 para를 구할 수 있기 때문
3-1 : Early Stopping : 더이상 validataion loss가 낮아지지 않을때
3-2 : Reducing Network size : 뉴런 네트워크가 학습하는 양을 줄이는 것
3-4 : Dropout
3-5 : batch normalization
ML모델을 data를 가지고 학습을 시켰을 때, 이 모델이 얼마나 성공적으로 예측할 수 있을까?
training set을 가지고 model을 학습시키는데 다시 training set을 가지고 다시 물어보게 된다면,
답을 하거나 예측할 수 있다. -> 이 data를 다 외우고 있기때문에 100% 맞을 수 있다. (시험을 보고 똑같은 문제로 중간고사를 보는것)
그러므로 한 30%의 data를 잘라서 앞 부분의 data를 training data set이라 하고 뒷부분을 test set을 둔다.
training set(=교과서)으로 model 학습을 시킨 후, testing se(=실전 문제)t을 예측값과 실제 y의 값을 비교해서 정확도를 확인하는 방법으로 해야한다.
5-3 Training set
- Training set
- Validatation set : 일반 training 한 것을 validatation 값으로 이 값이 좋은지 모의 시험(tunning)을 한다. -> 완벽할 경우 testing data set으로 확인한다.
Online learning
첫번째 set -> 모델 학습 : 첫번째 학습한 모델이 model에 남아있고
두번째 set -> 학습이 model에 추가된다.
..... set ->
10만개가 추가시 새로 학습하는게 아닌 있는 data에 추가하여 학습함.
ex. Minist dataset
정확도 예측 방법 : 모델이 예측한 값과 실제값을 비교해서
Minist: 손으로 쓰여진 dataset (0~9까지 손으로 적혀있음)
입력으로 들어가는 x의 갯수가 784개(28*28)이고 실제 pytorch에서는 view라는 함수를 이용해 28by28 이미지를 784개의 이미지로 바꿔서 사용하게 된다.
*torchvision : popular datasets과 model architectures들을 data에 사용하는 transforms을 제공하는 package이다.
6. Perceptron and Backpropagation
https://colab.research.google.com/drive/1gd5fk3H3HOdbOE34nlJilSUnqYJ-shx0#scrollTo=gJwvt2xt0KsK
Perceptron : 인공 신경망의 한 종류
모든 학습 데이터를 정확히 분류시킬 때까지 학습이 진행되어 학습 데이터가 선형적으로 분리될 수 있을 때 적합한 알고리즘이다. (학습을 하면서 weight가 계속 조정된다.)
뉴런: 뇌파가 0과 1로 true/false를 나타낸것과 같다는것을 창안-> AND와 OR,XOR을 사용
Perceptron: 입력 x가 들어왔을대, 가중치(w)을 곱해서 bias를 더하고 activation(sigmoid)을 거쳐서 최종 output을 나오게 된다.
초창기 perceptron문제는 linear classifier을 위해 사용(두가지 클래스를 linear로 분리)
convolutional neural network 개발
고양이를 가지고 그림을 보게한 후 시신경 동작을 확인했는데
그림의 형태에 따라 일부의 뉴런만 활성화하고, 다른 그림일 경우 다른 형태의 뉴런이 활성화
-> 그림을 볼때 우리의 신경망 세포가 동시에 그림 전체를 보는게 아니라 아니라 일부의 부분부분들을 담당하는 신경망들이 있고 이게 나중에 통합되는게 아닐까?
그림을 잘라서 다음 layer로 부분부분 잘라서 보내서 나중에 합치는 방식으로 함
이전에 학습을 가능하게 해줬던 backpropagation 알고리즘이 몇개 layer에서 가능하지만
10여개 이상의 layer에서 학습시, 전달이 되지 않아 학습이 불가하는 문제 발생
많이 학습할수록 성능이 떨어지는 문제가 발생.
해결방법 : deep 신경망 학습 불가
처음에 초기 값(w)을 주고 학습하는데
AND, OR은 해결했지만, XOR의 경우는 풀지 못했다. -> 한개의 perceptron으론 X, 여러개의 multi layer를 쌓아야 가능하나 각 측의 w를 학습할 수 있는 방법이 존재하지x
해결방법 = 1개 이상의 multilayer perceptron을 통해 해결함
어떻게 multilayer을 구성하는가? backpropagation
- backpropagation 이란? 예측값과 실제값을 비교해서 거기서 나오는 오류 cost형태로 되는것을 뒤에서 앞으로 쭉 돌려서 미분값과 실제로 뭘 돌려서 조정해야하는지 알아내는 방법
신경망을 충분히 학습 되지 못한 경우는 오차가 발생하여 이 큰 오차값을 줄이기 위해 오차 역전파법을 쓴다.
more : 순전파(forwad): 예측값을 구함. 역전파 : 그 예측값을 토대로 신경망 내부의 파라미터들을 학습시킨다.
오차 역전파 : 파라미터 각각의 미분을 모든 파라미터 갯수만큼 반복하여 구하는것 (X)
편미분이란 개념에 따라, 미리 정해진 단순한 미분 계산법으로 구하고, (정답값 - 예측값) = 손실값, 이 손실값을 역전파하여 각 파라미터의 학습 방향과 정도를 효율적으로 계산할 수 있다.
- 어떻게? forward : 학습데이터에서 얻은 것을 넣어서 값 계산 -> backward : 편미분을 하면 다시 이전 값을 확인할 수 있다.
- 왜 하는가? chain rule 사용 (g로 먼저 미분 후, w로 g를 미분)
수치미분을 통하여 신경망을 갱신하려면, 미분 과정에서 delta값을 더한 순전파를 몇번이고 다시 행해야 한다. 바로 여기서 연산량이 매우 많아지게 된다.
각 에지들의 w, b변수들로 직접 미분을 행할 필요가 없이, 이러한 미분의 체인룰에 따라, 미리 정해진 계산법을 실행하기에 오차 역전파는 순전파를 여러번 행하여 미분을 할 필요가 없다 → 시간 단축(가장 큰 이점)
장점은, 이후 노드의 미분값을 '재활용' 할수 있다는 것과, 중간 결과가 많을시, 어느 위치에 대한 영향력도 쉽게 구할수 있다는 것이다.(원하는 부분에서부터 역전파를 실행하면 되기 때문)
- 오차 역전파법이 미분 시간을 단축시키는 이유그러니까, 그냥 편미분을 행하는 것은, 정직하게 미분 연산으로 기울기를 구하는 것이라면, 오차역전파는, 노드별 미리 정해진 미분을 마치 상수와 같이 사용하며 앞쪽으로 곱하고 곱해주는 것과 같은 것입니다.
- 오차역전파를 이용하여 미리 해당 노드에서 역전파되는 기울기의 변화에 대한 설정을 해두면, 따로 계산할 것도 없이 기울기를 알아낼수 있다.
- 이미 forward해서 얻은 값을 왜 backward하는가? (https://sacko.tistory.com/19)
- 우리가 임의로 한 번 순전파 했다고 출력 값이 정확하지는 않을 것이다. 우리가 임의로 설정한 가중치 값이 input에 의해서 한 번 업데이트 되긴 했지만 많은 문제가 있을 수 있다.
역전파 방법은 결과 값을 통해서 다시 역으로 input 방향으로 오차를 다시 보내며 가중치를 재업데이트 하는 것이다. 물론 결과에 영향을 많이 미친 노드(뉴런)에 더 많은 오차를 돌려줄 것이다.
앞에서 오차가 역전파되는 것을 알아보았는데 오차를 역전파하여 계속 업데이트 하는 이유는 신경망을 통해 더 나은 결과 값을 내기 위해서 weight를 조정하는데 오차가 영향을 주기 때문이다.
위의 예처럼 간단한 신경망이라면 오차를 계산하는 식은 굉장히 간단할 것이지만 효과적인 신경망은 절대 저렇게 간단하지 않다. 수십, 수백개의 노드(뉴런)이 연결되어서 수많은 가중치의 조합으로 특정 노드의 weight를 계산해야 한다면... 효율적인 방법이 필요할 것이다.
2. 일반적인 머신러닝 알고리즘에서는 y^ 값을 도출한 뒤, 오차를 계산하여 가중계수들을 학습하게 된다.
하지만 기존의 가중계수 업데이트 방법은 다중 레이어를 가진 신경망에서는 제대로 동작하지 않는다.
각 레이어에서의 가중계수가 최종 output에 미치는 영향을 알 수 없기 때문이다(연쇄적으로 레이어간 input과 output이 맞물려있기 때문).
이를 알아내기 위해서 생겨난 개념이 바로 역전파 연산이다.
역전파 알고리즘의 메인 아이디어는 Chain Rule에 기반하여, 각 레이어에서 편미분을 수행하고, 그 값을 알아냄으로써 레이어 가중계수마다의 영향력을 알게되는 것이다.
이러한 역전파 연산을 사용한다면 신경망 알고리즘에서 가중계수들을 효과적으로 학습하는 것이 가능하다.
- 편미분한 값의 의미는 :
편미분을 하면 출력쪽에 생기는 변화 역시 매우 작은 변화가 생기며, 작은 구간만을 보았을 때는 선형적인 관계가 있다. → 선형이기 때문에 출력에서 생긴 오차를 반대로 입력 쪽으로 전파시켜서 w와b를 갱신한다.
ex. b의 편미분 값이 1기 때문에, b가 값에 미치는 영향이 1배이다.(b의 값을 바꾸면 바로 직접적인 영향이 있다.)
w의 편미분 값이 5이므로, w가 값에 미치는 영향이 5배 이다.
좀 더 복잡한 경우(여러 hidden이 있다면)? 가장 마지막 node를 계산한다.
ex. 마지막 노드가 f=a+b이라면, a가 f에 미치는 영향을 알 수 있다(편미분으로) -> 처음 node까지 연쇄적으로 뒤로 온다. x에 입력이 g에 미치는 영향을 안다. (왜냐면 첫번째 node의 연산자가 뭔지를 알기 때문)
sigmoid는 어떻게 미분할까?
1/x해당하는 미분값(=L1) -> +1에 대한 미분값(=L2) -> exp(L3=L1*L2)->*-1(=L1*L2*L3).. 같은 방법으로 계속 곱하면 된다.
sigmoid : activation function : 하나의 값이 어느값 이상이면 active 아니면 unactive
hidden layer : input과 output 내의 있는 layer들은 보이지 않아 hidden layer라고 한다.
hl가 많을 경우에 10단 이상의 경우에 학습이 되지않는다. ->
왜? backprogation x가 최종 f에 구해지는 것을 확인하기 위해 전체 하기에는 어려워서 각각을 하나씩 미분을 해서 곱해나갔다.
sigmoid의 양 끝값이 0 혹은 0에 가까운 아주 작은값을 나오게 된다.
왜 문제인가? 계속 chain rule도 곱하다 보니까 점점 작은값이 된다. (0.0001) 0과 가까운 값이 된다.
backpropagation 알고리즘으로 gradient로 앞단을 전파 시킬 때, activation function에서 gradient를 곱하게 된다.
아주 작은 값들이 곱하지게 되면서, 뒷단에서 Loss로 부터 전파되는 gradient가 소멸되는 문제가 발생할 수 있다.
vanishing gradient : 경사 기울기가 사라지는 문제 : 앞단(최종단)의 기울기가 있어도, 단수,layer가 깊어질수록 기울기가 사라지게 된다.
-> sigmoid의 문제! : sigmoid는 항상 입력값이 1보다 작다. (sigmoid를 사용하는 여러 layers 생겼을때, 문제가 발생한다.)
마지막 단위 출력은 sigmoid여서 0~1사이로 출력을 받기 때문에 sigmoid로 해야 한다.
ReLU는 뭐가 좋기 때문에 사용하는 걸까?
수식 : f(x) = max(0,x)
ReLu: 0보다 작을 경우 0. 0보다 크면 자기자신.
L1 = tf.sigmoid(tf.matmul(X,W1)+b1)
L1 = tf.nn.relu(tf.matmul(X,W1)+b1) -> max(0,x)
https://www.slideshare.net/yongho/ss-79607172
8. Weight initialization
[Weight initialization]
왜 좋은 Weight initialization을 사용해야 하는가?
weight을 보통 랜덤값(-1~1)으로 초기화 했다. -> 이 값에 따라 그래프가 차이가 난다.
vanishing gradient 발생 이유2 : 초기값의 문제 : w가 0이면 뒤에 있는 기울기가 다 0이 되기 때문에 사라진다.
해결 방법 : 절때 0을 주면 안된다. 어떤 방법으로 초기화 시켜야 할까?
[restricted boltzmann machine(RBM) = encoder/decoder]
restricted : 한 layer안에서는 연결이 없지만 다른 layer과는 fully connected인 형태
하늘일 : 입력 x가 들어갔을 때,y로 만드는것과(incoding), y->x' (encoding)로 바꿔준다.
동일한 노드의 forward한 값 - backward : 받은 값을 w을 그대로 사용한 상태에서 뒤로 이동 = 차가 최저가 되도록 w를 조절한다.
[Deep Belif network(DBN)]
Layer중 두개만 encoder-decoder 해서 초기값이 내가 준값과 유사하게 나오는 w를 학습시킨다. -> 다음으로 이동
쌓고 RBM학습하고 고정 그위에 다시 layer 쌓고
1.pretraining : x라는 값으로 Layer 2개만 가지고 RBM 돌린다. 입력값과 유사한 값 w을 학습
2.이 값을 초기화 값으로 사용한다.
3.fine tunning : 학습하듯이 x데이터와 실제 label로 학습을 한다.(input들어가서~output~ backpro~_
이미 가지고 있는 weight가 학습되어있고, 조금만 튜닝하면 되니까.
but 요즘 사용하지 않는다 -> Xavier/ He initialization 사용함
RBM으로 pre training을 거치는게 아닌 간단하게 weight training하는 방법이다.
이전에는 무작위 수를 pre training하여 initialization 했으나 위 방법은 layer의 특성에 따라 initialization해야한다.
9. DropOut
어떤 데이터가 있을때, 데이터를 잘 fitting시키는 regression 모델을 학습
만약 Linear 방식으로 하면 아래와 같은 결과가 나온다. -> fitting을 못함(under fitting)
곡선으로 하면 -> 사람에 따라 다르게 판단할꺼같다.
모든 데이터를 지나간다면? ->overfitting(너무 데이터를 다 지난다.)
왜 모든 데이터를 지나는게 overfitting인가?
수치적으로 판단시
overfitting (응용력이 x 상황)
training dataset = 0.99 -> test data set = 0.85
layer가 많아질수록 에러율은 점점 떨어진다.(정상) -> 어느순간 에러가 올라간다(비정상)
layer가 여러개로 깊을 수록 overfitting될 가능성이 높다.
왜? 굉장히 많은 변수들이 사용되기 때무에
overfitting 해결방법
1. training data를 많이 해라
2. Regularization(= weight에 너무 큰값을 넣지 말아라)
cost + l2 regularzation
각각 element의 w를 곱한것이 최소화가 되게
dropout : 그만두는것 -> overfitting 방지, 성능 향상
학습할때 몇개의 node를 죽이자 라는 개념 -> 랜덤하게 뉴런들을 kill시키자.
왜 되는가? 각각의 뉴런들이 훈련시 남은것만 훈련, 랜덤하게 쉬게하고 훈련시키는 방법
어떻게? activation을 0으로 처리, L1 -> dropout처리(dropout_rate = 0.3,0.7등 마음대로) -> L1'
주의! 학습할때만 dropout하고, 실제에서는 모든 node를 사용해야한다.(dropout_rate = 1)
매학습 step마다 사용할 노드가 무작위로 변하기 때문에 네트워크 앙상블 모델로도 사용 가능하다.
모델들을 학습시킬 수 있는데, 앙상블 모델
내가 독립적으로 뉴런 네트워크를 만들었을때
똑같은 형태의 DL을 3개 만들고 학습을 시켰을때, 마지막에 합쳐서 결과를 낸다. -> 성능 향상
nn Lego
입력이 주어졌을때, 계속 쌓아옴. network이여서 굉장히 다양한 구조가 가능하다.
- fast forward : signal을 앞으로 확밀어줘서 만들수 있다.(2015, He~ , resnet?)
A나온 출력을 뽑아서 두단 앞 C에 붙인다.
-split&merge
출력시 두개로 나눠서 하다가, merge를 하기도 하고, 갈라지고 y를 예측할 수 있다.
-Recurrent network
앞으로만 가는게 아니라,옆으로도 나가는 방식 (RNN)
Gradient Vanishing : gradient가 너무 작아서 발생하는 문제, sigmoid function의 문제점으로 reLU하게된 원인
Gradient Exploding : gradient가 너무 커서 발생하는 문제
해결방법
Change activation function : sigmoid -> reLU로 변경
Careful initialization : weight 초기화시 initialization을 잘 해보자
직접적으로 해결하는 방식 : Batch Normalization 방식
-> Gradient Vanishing, Gradient Exploding 등 학습 과정이 안정화가 된다.
Internal Covariate Shift : Gradient Vanishing, Gradient Exploding 야기시키는 원인
train set과 test set의 분포가 차이가 있을때(입력과 출력의 분포가 다를때)
분포에 의해 한 레이어마다 coveriate shift 문제가 발생, 한 레이어 마다 입-출력을 가지고 있어 레이어끼리 문제가 발생
레이어가 많을 수록 더 크게 발생함
-> 각 layer들마다 data를 normalization해서 변형된 분포가 나오지 않도록 한다.
model.train() : Train dropout = true
model.eval() : Test dropout = false
어떤 network가 학습이 끝났다고 가정을 하고, impulse test시
test set
9. DNN Project
https://colab.research.google.com/drive/19hju4BB8litCjdwTW_ZgaGS9mLsPkU7V
CNN
10. NN,ReLu,Xavier,Dropout and Adam
nn을 통해 좀 더 깊게 Mnist를 할 수 있다.
1. weight의 크기를 구해야 한다. -> input,output(마지막에 열개인것만 확정이므로, 그 전 까지의 output은 마음대로 정해도 된다.)
2. 마지막 output을 제외한 layer1 : output - layer2 : input 의 값이 같아야 한다.
초기화를 잘해야한다! -> xavier initialization
ex. tf.get_variable("W1", shape=[784,256], initializer = tf.contrib.layers.xavier_initializer())
- 더 좋은 accuracy를 위해 Deep NN for MNIST
network가 학습 데이터를 너무 기억해서 새로운 testing data가 들어왔을때, 오히려 결과가 나빠진다. -> overfitting -> dropout으로 해결
tensor flow에서는 한 layer를 더 구현한다.
L1 = tf.nn.dropout(L1, keep_prob=keep_prob) keep으로 몇프로를 네트워크를 keep할것인지 정한다. - keep_prob : 통상적으로 학습시 0.5~0.7, testing/실전시에는 반드시 1
그래서 keep_prob = tf.placeholder(tf.float32)로 placeholder를 하고 학습/testing시 keep_prob -> feed_dict에 값을 넣어서 변수에서 변경하여 한다. - Optimizers
http://www.denizyuret.com/2015/03/alec-radfords-animations-for.html
CNN
10. NN,ReLu,Xavier,Dropout and Adam
nn을 통해 좀 더 깊게 Mnist를 할 수 있다.
1. weight의 크기를 구해야 한다. -> input,output(마지막에 열개인것만 확정이므로, 그 전 까지의 output은 마음대로 정해도 된다.)
2. 마지막 output을 제외한 layer1 : output - layer2 : input 의 값이 같아야 한다.
초기화를 잘해야한다! -> xavier initialization
ex. tf.get_variable("W1", shape=[784,256], initializer = tf.contrib.layers.xavier_initializer())
- 더 좋은 accuracy를 위해 Deep NN for MNIST
network가 학습 데이터를 너무 기억해서 새로운 testing data가 들어왔을때, 오히려 결과가 나빠진다. -> overfitting -> dropout으로 해결
tensor flow에서는 한 layer를 더 구현한다.
L1 = tf.nn.dropout(L1, keep_prob=keep_prob) keep으로 몇프로를 네트워크를 keep할것인지 정한다. - keep_prob : 통상적으로 학습시 0.5~0.7, testing/실전시에는 반드시 1
그래서 keep_prob = tf.placeholder(tf.float32)로 placeholder를 하고 학습/testing시 keep_prob -> feed_dict에 값을 넣어서 변수에서 변경하여 한다. - Optimizers
http://www.denizyuret.com/2015/03/alec-radfords-animations-for.html
11. Convolutional Neural Network
- Convolution이란? 이미지 위에서 stride 값 만큼 filter(kernel)을 이동시키면서 겹쳐지는 부분의 각 원소의 값을 곱해서 모두 더한 값을 출력으로 하는 연산
- stride : filter를 한번에 얼마나 이동할것인가
- 입력의 형태 : conv = nn.Con2d(1,1,3
- Input type : torch.Tensor
- Input shape : (NxCxHxW) = (batch_size,channel,height,width)
- 출력의 형태 : output size = {{inputSize(227) - filterSize(11) +(2*padding(0))} / stride(4) }+1
ex. input image size = 227x227, filter size = 11x11, stride = 4, padding =0, output image size =? 55
만약 소수점이 발생한다면? 소수점 이하 모두 버림 후 +1 한다.
문제 1)
문제 4)
((32-5,64-5)+(2x0))/stride(1) +1 = 28x60
https://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html
기본 개념 : 고양이의 실험에서 시작
고양이가 그림을 읽는 뉴런이 동시에 반응하는게 아니라 어떤 부분에 대해서만 반응 함
하나의 이미지에 대해 잘라서 각각의 입력으로 넘기게 되는데, 이 층을 convolutional layer 이라 한다.
FC: Fully connected Neural netowrk를 구성해서 labeling 하는 10개의 softmax파일을 붙인다.
- 32*32*3 크기의 이미지를 입력 받는다.
- 5*5(필터크기는 마음대로 정해서)*3(색은 항상 같은값) : 필터의 값만 읽어서 한 점만 뽑아낸다. (아래 설명)
어떻게 한 개의 값으로 만들어 낼 수 있을까? w1x1+w2x2+w3x3+....+b = y
3. 똑같은 필터로 다른 이미지도 확인하여 점차적으로 이동하면서 확인한다. (stride : 몇칸 움직일 수 있는가)
몇개의 값을 모을 수 있을까? 7x7의 이미지를 3x3 필터를 사용하여 했을때 stride 2(2칸씩 이동) 5x5 output을 뽑아낸다.
작아질수록 정보를 잃어버려서 padding이라는 개념을 쓴다. → 급격하게 작아지는것을 방지, 모서리임을 알려줌
padding : zero-padding (padding = 1이면 0으로 한번, padding = 2이면 0으로 두번)
원래 이미지가 7x7인데, padding을 해서 입력과 출력의 이미지가 같은 사이즈로 만들어 준다.
weigth에 사용되는 variable의 갯수는?
값들은 어떻게 정해질까요? random → initialization → training
각각의 필터와 weight 가 달라 크기가 다를 때, (28,28,필터의 갯수(앞의 깊이와 같아야 한다.))
12. Neuron(Perceptron) 과 Convolution의 관계
perceptron의 weight값으로 convolution의 filter가 들어간다. → input값 중 첫번째 값을 이 값에 곱한다.
1x1 = 1
2x0 = 0
3x1 = 3
0x0 = 0 => 1+3+1+1+2 = 8
1x1 = 1
5x0 = 0
1x1 = 1
0x0 = 0
2x1 = 2
13. Max Pooling and others
Pooling이란 ? 세로x가로 방향의 공간을 줄이는 연산. resize하여 Sampling하는 것과 같음
Max Pooling ? 2x2필터로 2칸씩 이동하면서 그 칸 중 가장 큰 값 하나를 넣는다. 6,8,3,4 → 2x2 값이 나온다.
convolution 하고 pooling 할 수 있고 몇 번 convolution 후에 pooling을 할 수도 있다.
값의 전체가 원하는 만큼의 깊이의 fully connected 에 넣어서 softmax해서 하나의 label을 고르는 형태로 된다.
특징 : 학습해야 할 매개 변수가 없고 채널 수가 변하지 않아 데이터의 채널 수 그대로출력 데이터로 내보낸다.
3d 합성곱 연산 : 기존 2d에 비교해서 길이 방향(채널 방향)으로 특징 맵이 늘어난다.
채널 쪽으로 특징 맵이 여러 개 있다면, 입력 데이터와 필터의 합성곱 연산을 채널마다 수행하고, 그 결과를 더해서 하나의 출력을 얻는다.
13.CNN mnist
3BlueBrown 강의
1강
ReLu : sigmode를 보완한 방법, 0보다 작을때 → 0 사용, 0보다 클때 → 값 그대로 사용
max(0,x) 로 큰값을 선택하는 방식
2강
기계학습은 근본적으로 특정한 함수의 최솟값을 찾는 일
bias : 뉴런이 active or inactive를 나타내는 지표
만약 가중치와 bias를 완전히 무작위로 설정한다면? 출력층이 엉망이 된다.
Cost function : 예측값과 실제결과값의 차이를 나타내는 함수 (= 신경망이 얼마나 엉망으로 작동하고 있는지 나타내는 숫자)
(잘못된 출력 - 원하는 출력)^2
계속 이동하여 함수의 지역 최소값에 접근한다.(경사 하강법)
기울기가 음수 \ : 오른쪽으로 이동
기울기가 양수 / : 왼쪽으로 이동
→ data set이 구조화 되어있으면 global 최소값을 더 쉽게 찾을 수 있다.
Cost gradient: 가중치와 bias를 어떻게 조정하는것아 cost 함수값을 가장 빠르게 줄여주는지 알려준다.
신경망 학습 : cost 함수를 최소화 하는 방법
cost 함수가 지역 최소값을 찾기 위해서 어떻게 해야할까? 연속적인 활성화 값을 갖게한다.(active,inactive로 결정x)
경사 하강법 : cost함수의 지역 최소값으로 수렴하기 위해 gradient를 음의 방향으로 함수의 입력값을 이동하는 방식
1번째 변수를 조정하는 것이 두번째 변수를 조정하는 것보다 3배 중요하다.
→ 곡선의 특성상 초반에 많은 폭으로 변화한다.
(너무 작게 점프 → 오랫동안 학습필요, 너무 크면→ 학습 결과 부정확함)
3강
순전파를 통해 이동시 w,b의 값이 계속해서 변하므로 Loss값도 변동이 발생 → 글로벌 미니멈을 찾기위해서 역전파를 통해서 변경된 값들을 확인함.
( = 입력을 변화시키면서 출력값을 가장 작은 형태로 바꾸는 행위 → 경사 사강법을 위해 미분필요)
Adam:
Adagrad:
4강: 내용이 잘 이해가 안감
활성화를 높이는 방법
1.편향을 증가시키거나(-10 : bias)
2.가중치를 증가시키거나(w)
3.이전 Layer의 활성도 변경(a)
0.2 = ∂(w1a1+w2a2+w3a3+...+wnan"-10")
역전파: 가중치와 편향을 조금씩 움직이기를 원하는지 결정하기 위해
data argumenation(ex. normalization)
다양한 이미지 -> data 양을 늘리는 효과가 있다.
우리가 만드는 것은 정확도를 어떻게 올릴까? 성능이 좋은 model을 가져온다.
ex. dnn의 경우 multi layers이므로 분류하는데 특화하는거 정확도가 높게 측정된 model을 가져온다. -> 동일한 data를 학습해도 model에 따라 다르므로
'DL' 카테고리의 다른 글
[DL] Custom data 결과 (0) | 2023.04.14 |
---|---|
[DL] Yolo일지 (0) | 2023.04.14 |
[DL] Yolo개념 정리 (0) | 2023.04.14 |
[DL] Pytorch문법 (0) | 2023.04.14 |