인공신경망-2

seongyong·2021년 6월 9일
0

딥러닝 기초

목록 보기
2/4

학습내용

Optimizer

tf.keras.optimizers.SGD : 랜덤하게 추출한 일부 데이터에 대해 가중치를 조절한다. 학습 속도가 full batch의 경우보다 빠르다.

tf.keras.optimizers.RMSprop : Adagrad는 global minimum에 도달하기 전에 학습률이 0에 수렴할 수 있다. 이런 문제점을 해결한 것이 RMSprop이다.

tf.keras.optimizers.Adam : momentum과 RMSprop을 융합한 방법이다.

tensorflow-addons.keras.optimizers.AdamW : 컴퓨터 비젼 task에서는 adam이 momentum을 포함한 SGD에 비해 일반화가 많이 뒤쳐진다는 결과가 있다. 이를 보완해주기 위한 optimizer이다.

tf.keras.optimizers.SGD(momentum=0.9) : SGD방식에 관성을 적용시키는 것이다. SGD에 비해 안정적인 방향으로 학습한다.

tf.keras.optimizers.Adagrad : 변수의 업데이트 횟수에 따라 학습률을 조절하는 옵션이 추가된 방법이다. 많이 변화한 변수는 작은 크기로 이동하고, 적게 변화한 변수들을 학습률을 크게한다.

ANN model fit

results = model.fit(X,y, epochs=50)

results.history.keys() #dict_keys(['loss', 'mae', 'mse'])

plt.plot(results.history['loss'])
plt.plot(results.history['accuracy'])

데이터를 정규화시키면 global minimum에 다다를 확률이 더 높다.

ANN cross validation

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
df = pd.read_excel("https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/MouseProtein/mouse_protein_X.xls", header=None)
df_label = pd.read_excel("https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/MouseProtein/mouse_protein_label.xls", header=None)

#라벨값 변형
df_label = df_label-1

from sklearn.model_selection import train_test_split, cross_val_score, cross_val_predict, StratifiedKFold
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense


X_train_val, X_test, y_train_val, y_test = train_test_split(df, df_label, test_size=0.2, random_state=2)


act_func = ['relu', 'tanh', 'exponential']
nodes = {512:256, 256:128, 128:64, 64:32}

best_score = 0

#fold
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=2)
cvscores = []

for train, val in kfold.split(X_train_val, y_train_val):
    for activation in act_func:
        for i, j in nodes.items():

            model = Sequential()

            model.add(Dense(i, input_dim=69, activation='relu'))
            model.add(Dense(j, activation=activation))
            model.add(Dense(2, activation='sigmoid'))

            model.compile(
                optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy']
            )
            model.summary()

            model.fit(X_train_val.iloc[train], y_train_val.iloc[train], epochs=100)
            val_loss, val_acc = model.evaluate(X_train_val.iloc[val], y_train_val.iloc[val])
            
            if best_score < val_acc:
                best_param = {
                    'activation' : activation,
                    'hidden_layer1' : i,
                    'hidden_layer2' : j
                }
 
            #각 모델별 accuracy 저장
            cvscores.append(val_acc)

ANN구현(확인중)

2 - 3 - 1 구조의 Neural Network

# 음수 가중치를 가지는 활성화는 낮추고, 양수 가중치를 가지는 활성화는 높이고 싶습니다.
class NeuralNetwork:
    
    def __init__(self):
       # 신경망의 구조를 결정합니다. 입력층 2 노드, 은닉층 3 노드, 출력층 1 노드 / Bias 없음.
        self.inputs = 2
        self.hiddenNodes = 3
        self.outputNodes = 1
        
        # 가중치를 초기화 합니다.
        # layer 1 가중치 (2x3)
        self.w1 = np.random.randn(self.inputs,self.hiddenNodes)
        
        # layer 2 가중치 (3x1)
        self.w2 = np.random.randn(self.hiddenNodes, self.outputNodes)
        
    def sigmoid(self, s):
        return 1 / (1+np.exp(-s))
    
    def sigmoidPrime(self, sx):
        return sx * (1-sx) #수정
    
    def feed_forward(self, X):        
        # 가중합 계산
        self.hidden_sum = np.dot(X, self.w1)
        
        # 활성화함수
        self.activated_hidden = self.sigmoid(self.hidden_sum)
        
        # 출력층에서 사용할 은닉층의 각 노드의 출력값을 가중합 합니다.
        self.output_sum = np.dot(self.activated_hidden, self.w2)
        
        # 출력층 활성화, 예측값을 출력합니다.
        self.activated_output = self.sigmoid(self.output_sum)
        
        return self.activated_output
    
    def backward(self, X, y, o):
        # 역전파 알고리즘
        
        # 출력층의 손실값 (Error) 입니다.
        self.o_error = o - y #수정
        
        # 출력층 활성화함수인 시그모이드 함수의 도함수를 사용합니다. (dE / dY * dY / dy) - Latter A
        self.o_delta = self.o_error * self.sigmoidPrime(o) #행렬의 곱이 아닌 스칼라 곱
        
        # z2 error: 출력층의 가중치가 얼마나 에러에 기여했는지 
        self.z2_error = self.o_delta.dot(self.w2.T)
        
        # z2 delta: 시그모이드 도함수를 z2 error에 적용합니다. (d_HiddenE / dY) * (dY / dy) - Latter 
        self.z2_delta = self.z2_error*self.sigmoidPrime(self.acctivated_hidden) #acctivated_hidden이 들어가야할듯?? 수정

        # w1를 업데이트 합니다.
        self.w1 += X.T.dot(self.z2_delta) # X * dE/dY * dY/dy(=Y(1-Y))
        # w2를 업데이트 합니다.
        self.w2 += self.activated_hidden.T.dot(self.o_delta) # H1 * Y(1-Y) * (Y - o) # (Latter A)
        
    def train(self, X,y):
        o = self.feed_forward(X)
        self.backward(X,y,o)

0개의 댓글