반응형


안녕하세요~



오늘은 신경망의 정확도를 높이기위한 여러가지 방법을 소개하겠습니다.


Ⅰ. 매개변수 갱신


Ⅱ. 가중치 초기값 설정


Ⅲ. 배치 정규화


Ⅳ. Dropout / weight decay


Ⅴ. 적절한 하이퍼 파라미터 값 찾기



이제 각각의 방법에 대해 자세히 다뤄보도록 하겠습니다.



Ⅰ. 매개변수 갱신 ( 고급 경사하강법 )


underfitting을 해결하기위한 방법 중 하나입니다.



GD(GradientDescent)에는 큰 단점 2가지가 있습니다.


1) 계산량이 많아서 속도가 느리다.


2) local minima에 빠질 수 있다.



GD는 가장 기본적인 뉴럴넷 학습 방법으로


전체 데이터에 대한 비용함수의 weight 과 미분하고


각 W(가중치) 파라미터에 대한 기울기를 이용하여


W를 업데이트하는 방법입니다.



그런데 이러한 GD는 층이 많아질수록 parameter의 복잡도가 늘어남에 따라


비용함수가 더욱 복잡해져서


local minima에 빠지는 현상이 더욱 잘 발생하게 됩니다.



이러한 문제를 해결하기 위해 나온 것이


SGD(Stochastic Gradient Descent) 확률적 경사하강법입니다.



1. SGD


전체 data 중 랜덤하게 추출한 1/N의 데이터만을 사용해서 빠르게 가중치를 업데이트 하는 방법입니다.


[SGD 식]



GD의 단점을 해결한 SGD에도 문제가 있는데,

단순하고 구현도 쉽지만 문제에 따라 비효율 적일 때가 있다는 것입니다.


또한 아래와 같은 그래프의 경우 global minima 쪽으로 기울기 방향이 있는게 아니기 때문에

local minima에 빠지고 global minima 쪽으로 도달하지 못하는 단점이 있습니다.




2. Momentum


Momentum은 운동량을 뜻하는 단어로 기울어진 방향으로 물체가 가속되는 물리 법칙을 나타냅니다.


[Momentum 식]




(α: 마찰계수, v: 속도, η : 학습률, W: 가중치, ∂L / ∂W : W에 대한 손실함수 미분)



원리:


내리막: 기울기가 음수이면 속도가 증가


오르막: 기울기 양수이면 속도 감소



3. AdaGrad


learning rate 가 학습되면서 자체적으로 조정되는 경사하강법


보통 처음에는 크게 학습하다가 조금씩 작게 학습을 진행하는 방법입니다.


[AdaGrad 식]



(h: 기울기에 값을 제곱하여 더해줌, ◎: 행렬의 원소별 곱셈)



원리:


learning rate가 클 경우: 발산될 위험은 있지만 수렴의 속도가 빨라진다.


learning rate가 작을 경우 : 발산될 위험은 작지만 local minima에 빠지거나 학습이 안될 수 있다.



각각의 매개변수 원소가 갱신되는 값이 다르다는 것이 특징입니다.



4. Adam


Momentum의 장점 (가속도) + RMSProp의 장점 (각 매개변수마다 학습률 조절) == Adam


최근 딥러닝에서 가장 많이 사용하는 최적화 방법이라고 합니다! : )


* 참고: RMSProp는 가장 최근 반복에서 비롯된 그래디언트만 누적함으로

AdaGrad의 단점(local minima에 수렴함)을 보안한 옵티마이저 입니다.


[각각의 optimizer를 파이썬으로 구현하는 코드]


# gradient descent 종류 class SGD: def __init__(self, lr=0.01): self.lr = lr def update(self, params, grads): for key in params.keys(): params[key] -= self.lr * grads[key] class Momentum: def __init__(self, lr=0.01, momentum=0.9): self.lr = lr self.momentum = momentum self.v = None def update(self, params, grads): if self.v is None: self.v = {} for key, val in params.items(): self.v[key] = np.zeros_like(val) for key in params.keys(): self.v[key] = self.momentum * self.v[key] - self.lr * grads[key] params[key] += self.v[key] class AdaGrad: def __init__(self, lr=0.01): self.lr = lr self.h = None def update(self, parmas, grads): if self.h is None: self.h = {} for key, val in params.items(): self.h[key] = np.zeros_like(val) for key in parmas.keys(): self.h[key] += grads[key] * grads[key] params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7) class Adam: def __init__(self, lr=0.001, beta1=0.9, beta2=0.999): self.lr = lr self.beta1 = beta1 self.beta2 = beta2 self.iter = 0 self.m = None self.v = None def update(self, params, grads): if self.m is None: self.m, self.v = {}, {} for key, val in params.items(): self.m[key] = np.zeros_like(val) self.v[key] = np.zeros_like(val) self.iter += 1 lr_t = self.lr * np.sqrt(1.0 - self.beta2 ** self.iter) / (1.0 - self.beta1 ** self.iter) for key in params.keys(): self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key]) self.v[key] += (1 - self.beta2) * (grads[key] ** 2 - self.v[key]) params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)



[각 optimizer 가 최소값에 수렴하는 방법]





Ⅱ. 가중치 초기값 설정


underfitting을 해결하기위한 방법 중 하나입니다.


가중치 초기값을 적절히 설정하면 각 층의 활성화 값의 분포가 적당히 퍼지는 효과가 발생합니다.


활성화 값이 적당히 퍼지게 되면 학습이 잘되고 정확도가 높아집니다.



1. 초기값을 0으로 설정


초깃값을 모두 0으로 설정하면

오차역전파법에서 모든 가중치의 값이 똑같이 갱신되기 때문에

학습이 올바르게 이뤄지지 않습니다.


2. 표준편차가 1인 정규분포를 사용해 초기값 설정


- 표준편차가 작을수록 데이터가 평균에 가깝게 분포


- 표준편차가 클 수록 데이터가 많이 흩어져 있다.


즉 데이터가 0과 1에 치우쳐 분포하게 되면 역전파의 기울기 값이 점점 작아지다 사라집니다.


층을 깊게 하는 딥러닝에서는 기울기 소실은 더 심각한 문제가 될 수 있습니다.


3. Xavier 초기값 설정


- 표준편차가 √1/n 인 정규분포로 초기화한다.


- sigmoid 와 짝꿍


각 층의 활성화 값들을 광범위하게 분포 시킬 목적으로 적절한 분포를 찾고자 했습니다.


그리고 앞 계층의 노드가 n개라면 표준편차가 √1/n 인 분포를 사용하면 된다는 결론을 이끌었습니다.



4. He 초깃값


- 표준편차가 √2/n 인 정규분포로 초기화한다.


- ReLU 와 짝꿍


ReLU는 음의 영역이 0이라서 더 넓게 분포시키기 위해


Xavier함수보다 2배의 계수가 필요하다고 해석할 수 있습니다.



[초기화 그래프]





Ⅲ. 배치 정규화


마찬가지로 underfitting을 해결하기 위한 방법 중 하나 입니다.


앞에서 가중치 초기값을 적절히 설정하면 각 층의 활성화 값의 분포가 적당히 퍼지는 효과를 보았습니다.


그런데,

배치 정규화는 바로 각 층에서의 활성화 값이 적당히 분포되도록 강제로 조정하는 것을 말합니다.



딥러닝의 경우는 hidden layer가 많아서


가중치의 조금한 변화가 가중되어서 쌓이면


hidden layer가 많아질수록 출력되는 값의 변화가 크기 때문에


학습이 어렵습니다.



배치 정규화는 값이 활성화 함수를 통과하기 전에 가중의 변화를 줄이는 것이 목표


가중의 합이 배치 정규화에 들어오게 되면 기존의 값의 스케일을 줄여버리게 됩니다.



[ 배치초기화 식]



[파이썬으로 구현하기]


class BatchNormalization: """ http://arxiv.org/abs/1502.03167 """ def __init__(self, gamma, beta, momentum=0.9, running_mean=None, running_var=None): self.gamma = gamma self.beta = beta self.momentum = momentum self.input_shape = None # 합성곱 계층은 4차원, 완전연결 계층은 2차원 # 시험할 때 사용할 평균과 분산 self.running_mean = running_mean self.running_var = running_var # backward 시에 사용할 중간 데이터 self.batch_size = None self.xc = None self.std = None self.dgamma = None self.dbeta = None def forward(self, x, train_flg=True): self.input_shape = x.shape if x.ndim != 2: N, C, H, W = x.shape x = x.reshape(N, -1) out = self.__forward(x, train_flg) return out.reshape(*self.input_shape) def __forward(self, x, train_flg): if self.running_mean is None: N, D = x.shape self.running_mean = np.zeros(D) self.running_var = np.zeros(D) if train_flg: mu = x.mean(axis=0) xc = x - mu var = np.mean(xc**2, axis=0) std = np.sqrt(var + 10e-7) xn = xc / std self.batch_size = x.shape[0] self.xc = xc self.xn = xn self.std = std self.running_mean = self.momentum * self.running_mean + (1-self.momentum) * mu self.running_var = self.momentum * self.running_var + (1-self.momentum) * var else: xc = x - self.running_mean xn = xc / ((np.sqrt(self.running_var + 10e-7))) out = self.gamma * xn + self.beta return out def backward(self, dout): if dout.ndim != 2: N, C, H, W = dout.shape dout = dout.reshape(N, -1) dx = self.__backward(dout) dx = dx.reshape(*self.input_shape)

return dx def __backward(self, dout): dbeta = dout.sum(axis=0) dgamma = np.sum(self.xn * dout, axis=0) dxn = self.gamma * dout dxc = dxn / self.std dstd = -np.sum((dxn * self.xc) / (self.std * self.std), axis=0) dvar = 0.5 * dstd / self.std dxc += (2.0 / self.batch_size) * self.xc * dvar dmu = np.sum(dxc, axis=0) dx = dxc - dmu / self.batch_size self.dgamma = dgamma self.dbeta = dbeta return dx



[구현 예]

# 계층생성 layers = OrderedDict() # 순전파 순서의 반대로 역전파가 된다. layers['Affine1'] = Affine(params['W1'], params['b1']) layers['BatchNorm1'] = BatchNormalization(gamma=1.0, beta=0.) layers['Relu1'] = Relu() layers['Affine2'] = Affine(params['W2'], params['b2']) layers['BatchNorm2'] = BatchNormalization(gamma=1.0, beta=0.) layers['Relu2'] = Relu() layers['Affine3'] = Affine(params['W3'], params['b3']) lastLayer = SoftmaxWithLoss()




Ⅳ. Dropout / weight decay


두 방법 모두 overfitting을 규제하기 위한 방법입니다.



1. Dropout(드롭아웃)


오버피팅을 억제하기 위해서 뉴런을 임의로 삭제하면서 학습시키는 방법


사공이 많으면 배가 산으로 간다는 속담이 있습니다.


따라서 몇 명의 전문가만 선별해서 반복적으로 같은 결과가 나오면 그것을 답으로 보는 방법입니다.



일반적으로 입력층에서는 20% ~ 50% 정도,


은닉층에서는 50% 정도의 노드를 생략한다고 합니다.



[파이썬 코드]

class Dropout: """ http://arxiv.org/abs/1207.0580 """ def __init__(self, dropout_ratio=0.15): self.dropout_ratio = dropout_ratio self.mask = None def forward(self, x, train_flg=True): if train_flg: self.mask = np.random.rand(*x.shape) > self.dropout_ratio return x * self.mask else: return x * (1.0 - self.dropout_ratio) def backward(self, dout): return dout * self.mask


[구현 예]

# 계층생성 layers = OrderedDict() # 순전파 순서의 반대로 역전파가 된다. layers['Affine1'] = Affine(params['W1'], params['b1']) layers['BatchNorm1'] = BatchNormalization(gamma=1.0, beta=0.) layers['Relu1'] = Relu() layers['Dropout1'] = Dropout() layers['Affine2'] = Affine(params['W2'], params['b2']) layers['BatchNorm2'] = BatchNormalization(gamma=1.0, beta=0.) layers['Relu2'] = Relu() layers['Dropout2'] = Dropout() layers['Affine3'] = Affine(params['W3'], params['b3']) lastLayer = SoftmaxWithLoss()




2. Weight Decay(가중치 감소)


학습과정에서 큰 가중치에 대해서는 그에 상응하는 큰 패널티를 부여하여 오버피팅을 억제하는 방법


가중치 감소는 모든 가중치 각각의 손실함수에 (1/2) * λW **2를 더합니다.



[구현 예]

weight_decay_lambda = 0.001


# 1. 비용함수 수정

weight_decay = 0 for idx in range(1, 4): # 3계층 하드코딩 W = self.params['W' + str(idx)] weight_decay += 0.5 * self.weight_decay_lambda * np.sum(W ** 2)


# 2. 기울기 계산하는 코드 변경

for idx in range(1, 4): grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + \ self.weight_decay_lambda * self.layers['Affine' + str(idx)].W grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db



Ⅴ. 적절한 하이퍼파라미터 값 찾기


신경망에서 말하는 하이퍼파라미터는 각 층의 뉴런 수, 배치 크기, 매개변수 생신 시의 학습률과 가중치 감소 등입니다.



1. 검증데이터


우선 하이퍼파라미터를 조정할 때는 검증데이터로 하이퍼파라미터의 적절성을 평가해야합니다.


test_data에서 하이퍼파라미터를 조정하면 값이 test_data에 오버피팅 되기 때문에

범용 성능이 떨어지는 모델이 될 수도 있기 때문입니다.



즉, 아래와 같이 데이터를 나눠서 사용할 수 있습니다.


- 훈련데이터: 매개변수 학습


- 검증데이터: 하이퍼파라미터 성능 평가


- test 데이터: 신경망의 범용 성능 평가



※ Tip! 만약 적은 양의 데이터라면 교차검증(cross validation)방법을 사용할 수 있습니다.



2. 하이퍼 파라미터 최적화


하이퍼파라미터를 최적화할 때의 핵심은


무작위로 샘플링 후 정확도를 살피면서 하이퍼파라미터의 '최적 값'이 존재하는 범위를 조금씩 줄여간다는 것입니다.


0단계: 하이퍼파라미터 값의 범위를 설정합니다.


1단계: 설정된 범위에서 하이퍼파라미터의 값을 무작위로 추출합니다.


2단계: 1단계에서 샘플링한 하이퍼 파라미터 값을 사용하여 학습하고, 검증 데이터로 정확도를 평가합니다.


3단계: 1단계와 2단계를 반복하며, 그 정확도의 결과를 보고 하이퍼파라미터의 범위를 좁힙니다.



※ Tip!


위에서 설명한 하이퍼파라미터 최적화 방법은

과학이라기보다는 직관에 의존한다는 느낌이 들지만 많이 사용되는 실용적인 방법입니다.


더 세련된 기법을 원한다면 베이즈 최적화(수학이론을 구사)를 사용할 수 있습니다 : )




오늘은 여기까지!!


유난히 긴 포스팅이었네요!


※ '밑바닥부터 시작하는 딥러닝' 을 참고하였습니다


도움이 되었다면 공감♡ 꾸욱 

반응형
반응형



안녕하세요~ 오늘은 드디어! 신경망에 대해 살짝 맛보도록 하겠습니다!



우선, 퍼셉트론과 신경망의 차이부터 알아봅시다!


퍼셉트론을 모른다면 "퍼셉트론(Perceptron)이란?" 을 참고하세요!



1. 퍼셉트론은 원하는 결과를 출력하도록 사람이 직접 가중치를 정해줘야 합니다!


AND, OR, NAND 게이트를 만들때 가중치를 채워 넣는 문제를 냈습니다!


어떻게 찾으셨나요? 저는 직접 숫자를 대입해보며 찾았답니다!


 혹시 더 쉽게 찾는 방법을 아시나요? 아신다면 댓글로 공유해주세요!



2. 신경망은 가중치 매개변수의 적절한 값을 기계가 데이터로부터 학습해서 자동으로 알아냅니다!





" 신경망 학습하기 "




이전 포스팅에서 신경망에 들어가는 함수


계단함수, 시그모이드 함수, 렐루 함수에 대해 알아보았습니다!



좀더 자세히 말하자면 위의 3가지 함수는


은닉층에 들어가는 함수 중 3가지를 의미합니다.




그렇다면 마지막 출력층에 들어가는 함수는 어떻게 될까요?


출력층 함수란,


그동안 흘러온 확률의 숫자를 취합해 결론을 내는 함수입니다.



신경망으로 구현하고자 하는 문제에 따라 사용하는 출력층 함수가 다릅니다.



1. 회귀(Regression)의 경우, 항등함수를 사용합니다.


항등함수란, 어떤 변수도 자기 자신을 함수값으로 하는 함수입니다.


[파이썬코드]

def identity(x): return x

간단하죠?




2. 분류(Classfication) 의 경우, 두 가지로 나뉘는데요.


2-1) 시그모이드(Sigmoid) 함수 : 2클래스 분류에서 사용합니다. ( ex, 개 vs 고양이 분류)


2-2) 소프트맥스(Softmax) 함수 : 다중 클래스 분류 (ex, 정상 폐사진 vs 폐결절, 폐혈증... 등 분류)



시그모이드는 은닉층의 활성화 함수에서 알아봤으니,



새로운 함수인, 소프트맥스 함수에 대해 더 자세히 알아보겠습니다.


소프트 맥스(Softmax) 함수란?


0과 1사이의 숫자를 출력하는 함수로, 출력하는 값은 확률입니다.


[파이썬 코드]


def softmax(a): C = np.max(a) exp_a = np.exp(a-C) sum_a = np.sum(exp_a) return exp_a / sum_a


[소프트 맥스 함수식]


e%203.10.png



소프트 맥스 함수식과 위의 파이썬 코드가 조금 다르죠?


그 이유는, overflow때문입니다!



우선, 소프트 맥스 함수는 지수함수를 사용하는데 이 지수함수라는 것은 아주 쉽게 아주 큰 값을 내뱉습니다.



예를 들어


exp == e (무리수: 자연상수)


e ^10 > 20000: 자연상수의 10승은 20000보다 크고


e ^1000 == inf : 자연상수의 1000승은 무한대(inf)를 나타냅니다.



따라서 표현할 수 없는 큰 값을 해결하기위해 아래와 같은 식으로 변형을 해서 사용합니다.




지수함수와 로그함수를 잘 모르겠다면 "여기"를 참고하세요!






" 이제, 아래의 신경망을 직접 구현해보도록 하겠습니다!"





import numpy as np # 신경망 함수 def sigmoid(x): return 1 / (1 + np.exp(-x)) def identity(x): return x def init_network(): network = {} network['W1'] = np.array([[1,3,5],[2, 4, 6]]) # weight 은 관습적으로 W라고 합니다. network['W2'] = np.array([[1,2],[3,4],[5,6]]) network['W3'] = np.array([[1,2],[3,4]]) return network

# 신경망 구현 def forward(network, x): W1, W2, W3 = network['W1'], network['W2'], network['W3'] y = np.dot(x, W1) y_hat = sigmoid(y) k = np.dot(y_hat, W2) k_hat = sigmoid(k) j = np.dot(k_hat, W3) j_hat = identity(j) # identity 대신 softmax함수를 사용할 수 있습니다. return j_hat network = init_network() x = np.array([1,2]) # 입력 y = forward(network, x) # 출력 print(y)





오늘은 여기까지!


신경망 학습 방법은 다음 포스팅에서 더 자세히 다루겠습니다!


좋은 하루 보내세요! 

반응형
반응형



안녕하세요~


오늘은 XOR(다층 퍼셉트론)신경망 활성화 함수(activation function) 에 대해 알아보겠습니다.



우선, 이전 포스팅 퍼셉트론에 이어


XOR에 대해 먼저 알아보도록 하겠습니다.


[ XOR 진리표 ]


XOR 게이트는 단층 퍼셉트론으로 구현이 되지 않습니다.


따라서, 다층 퍼셉트론으로 구현해야합니다.



" 단층 퍼셉트론 vs 다층 퍼셉트론 "


"단층 퍼셉트론"이란,

AND, OR, NAND 게이트와 같이


입력층에 가중치를 곱해 바로 출력되는 퍼셉트론입니다.


아래와 같이 표현할 수 있습니다. 




"다층 퍼셉트론"이란,

퍼셉트론을 층으로 쌓은 것으로,


입력층과 출력층 사이 은닉층이 존재하는 것입니다.




위와 같은 다층 퍼셉트론으로 XOR 게이트를 구현할 수 있습니다.



XOR 게이트는 아래와 같이 AND, OR, NAND를 조합해서 만들 수 있습니다.






※ 참고: 각각의 게이트는 아래와 같은 의미 갖고 있습니다.




이제 XOR 진리표를 완성해볼까요?




문제1. XOR 게이트를 파이썬으로 구현해보세요








활성화 함수란?


입력신호의 총합을 출력신호로 변환하는 함수를 일반적으로 활성화 함수라고 합니다.

활성화 함수는 입력신호의 총합이 활성화를 일으키는지 정하는 역할을 합니다.


출처: Deep Learning from Scratch



" 활성화 함수의 종류 3가지 "


1. 계단함수(Step Function) : 0 또는 1 의 값을 출력하는 함수


2. 시그모이드 함수(Sigmoid Function) : 0 ~ 1 사이의 실수를 출력하는 함수


3. ReLu(Rectified Linear Units) : 입력이 0이 넘으면 그 입력값을 그대로 출력하고 0 이하이면 0을 출력하는 함수




이제 각각의 특징을 알았으니, 파이썬으로 구현해보도록 하겠습니다.




1. 계단함수 (Step Function)


" 퍼셉트론에서는 활성화 함수로 계단함수를 이용한다. "



" numpy로 계단함수 구현하기 "

import numpy as np


def step_function(x_data): # return [0 if x<=0 else 1 for x in x_data ]

# np.array.astype(np.int): bool type을 정수로 변환하기 return (x_data > 0).astype(np.int)


문제2. 위에서 만든 계단함수를 이용해서, 아래와 같이 그래프를 그리시오







2. 시그모이드 함수 (Sigmoid Function)



※ 계단함수와 시그모이드 함수의 공통점 & 차이점


[공통점]


둘다 0과 1 사이의 데이터만 출력한다

비선형 함수이다.


[차이점]


계단함수는 숫자 1 과 0만 출력하는데 시그모이드 함수는 0과 1사이의 실수를 출력한다.



[시그모이드 함수식]

sigmoid



" 통계학에서 성공할 확률이 실패할 확률보다 얼마나 큰지를 나타내는 오즈비율이라는 값이 있다. "



오즈비율(Odds ratio) = 성공 / 실패 = P / (1 - P)



성공할 확률 P를 0에서 1사이의 값으로 나타내면,

실패할 확률은 (1 - P)이다.


위에 그래프에서 확인할 수 있듯이,

P(성공할 확률)가 1에 가까워지면 오즈 비율 값이 급격히 커지는 현상이 발생한다.



그러한 현상을 방지하기 위해, 로그를 취한 Logit이라는 함수를 만든다.



로그를 사용하는 이유: 큰 숫자를 작은 숫자로 표현하기 위해





Logit Function = log(P/(1-P)) = wx + b



이 로짓 함수를 뉴런의 출력값에 따라 확률 P를 구하기 쉽도록 지수 함수 형태로 바꾸면,


위에서 확인한 시그모이드 함수가 됩니다.



" numpy로 Sigmoid 함수 구현하기"


import numpy as np def sigmoid(x): return 1 / (1 + np.exp(-x))


문제3. 위에서 만든 시그모이드 함수를 이용해서, 아래와 같이 그래프를 그리시오





3. ReLu 함수( RectifiedLinearUnits Function)


" 최근에는 활성화 함수로 ReLU(렐루)함수를 주로 이용합니다 "


이유는 이후 포스팅에 설명하겠습니다.



"numpy로 ReLU 함수 구현하기"

import numpy as np

def relu(x):
# if x <= 0: # return 0 # return x

# maximum 은 두 입력 중 큰 값을 선택해 반환하는 함수이다.
return np.maximum(0,x)


문제4. 위에서 만든 렐루(ReLU)함수를 이용해서, 아래와 같이 그래프를 그리시오







오늘은 여기까지!!


다음 주에는 신경망으로 돌아올게요!!

반응형
반응형



안녕하세요~


오늘은 신경망의 기본! 퍼셉트론에 대해 알아보겠습니다~


퍼셉트론이란? 다수의 신호를 입력받아 하나의 신호를 출력하는 알고리즘입니다.



1943년 미국 신경외과 의사인 워렌 멕컬록에 의해서 발단이되었고


1957년 프랑크 로젠 블라트가 퍼셉트론 알고리즘을 고안했습니다.


사람의 뇌의 동작을 전기 스위치의 on / off 로 흉내낼 수 있다는 이론을 증명하였습니다.


간단히 말하면, 인간의 신경 세포 하나를 흉내낸 것으로

기본 가정은 아래와 같습니다.




1. 자극(simulus)   2. 역치(threshold)  3. 반응(response)



" 특정 자극이 있다면 그 자극이 어느 역치(theta: 임계값) 이상이어야지만 세포가 반응한다. "




입력신호의 연결강도가 가중치(Weight)인데,


입력신호가 뉴런에 보내질 때는 각각의 고유한 가중치가 곱해집니다.



퍼셉트론은 n 개의 이진수가 하나의 뉴런을 통과해서


가중치의 합이 0보다 크면 활성화되는 가장 간단한 신경망입니다.



문제1. 위의 식을 파이썬 Numpy 패키지로 구현하시오.



가정: theta = 0 ; x1 = 0; x2 = 1; w1 = 0.5; w2 = 0.5





퍼셉트론으로 단순한 논리 회로 4가지를 구현해보도록 하겠습니다.



1. AND 게이트




def AND(x1, x2): x = np.array([x1,x2]) w = np.array([0.5,0.5]) theta = 0.7 if np.sum(w*x) <= theta: return 0 else: return 1



inputData = np.array([[0,0],[1,0],[0,1],[1,1]])

for x in inputData: print(x[0],", ",x[1]," ==> ",AND(x[0],x[1]), sep = '')



2. OR 게이트




def OR(x1,x2): x = np.array([x1,x2]) w = np.array([?,?]) # 채워넣으세요~ theta = ? # 채워넣으세요~ if np.sum(w*x) <= theta: return 0 else: return 1


inputData = np.array([[0,0],[1,0],[0,1],[1,1]]) for x in inputData: print(x[0],", ",x[1]," ==> ",OR(x[0],x[1]), sep = '')





3. NAND 게이트




def NAND(x1,x2): x = np.array([x1,x2]) w = np.array([?,?]) # 채워넣으세요~ theta = ? # 채워넣으세요~ if np.sum(w*x) <= theta: return 0 else: return 1

inputData = np.array([[0,0],[1,0],[0,1],[1,1]]) for x in inputData: print(x[0],", ",x[1]," ==> ",NAND(x[0],x[1]), sep = '')





4. XOR 게이트




XOR 게이트를 퍼셉트론으로 해결해보세요!


결과는 다음 포스팅에서!





오늘은 여기까지~


다음 포스팅은

활성함수로 돌아오겠습니다!

반응형

+ Recent posts