Dense 레이어는 입력과 출력을 모두 연결해줍니다. 예를 들어 입력 뉴런이 4개, 출력 뉴런이 8개있다면 총 연결선은 32개(4*8=32) 입니다. 각 연결선에는 가중치(weight)를 포함하고 있는데, 이 가중치가 나타내는 의미는 연결강도라고 보시면 됩니다. 현재 연결선이 32개이므로 가중치도 32개입니다.
예를 들어 성별을 판단하는 문제있어서, 출력 뉴런의 값이 성별을 의미하고, 입력 뉴런에 머리카락길이, 키, 혈핵형 등이 있다고 가정했을 때, 머리카락길이의 가중치가 가장 높고, 키의 가중치가 중간이고, 혈핵형의 가중치가 가장 낮을 겁니다. 딥러닝 학습과정에서 이러한 가중치들이 조정됩니다.
이렇게 입력 뉴런과 출력 뉴런을 모두 연결한다고 해서 전결합층이라고 불리고, 케라스에서는 Dense라는 클래스로 구현이 되어 있습니다. 아래는 Dense 클래스 사용 예제입니다.
Dense(8, input_dim=4, init='uniform', activation='relu'))
주요 인자는 다음과 같습니다.
첫번째 인자 : 출력 뉴런의 수를 설정합니다.
input_dim : 입력 뉴런의 수를 설정합니다.
init : 가중치 초기화 방법 설정합니다.
‘uniform’ : 균일 분포
‘normal’ : 가우시안 분포
activation : 활성화 함수 설정합니다.
‘linear’ : 디폴트 값, 입력뉴런과 가중치로 계산된 결과값이 그대로 출력으로 나옵니다.
‘relu’ : rectifier 함수, 은익층에 주로 쓰입니다.
‘sigmoid’ : 시그모이드 함수, 이진 분류 문제에서 출력층에 주로 쓰입니다.
‘softmax’ : 소프트맥스 함수, 다중 클래스 분류 문제에서 출력층에 주로 쓰입니다.
Dense 레이어는 입력 뉴런 수에 상관없이 출력 뉴런 수를 자유롭게 설정할 수 있기 때문에 출력층으로 많이 사용됩니다. 이진 분류문제에서는 0과 1을 나타내는 출력 뉴런이 하나만 있으면 되기 때문에 아래 코드처럼 출력 뉴런이 1개이고, 입력 뉴런과 가중치를 계산한 값을 0에서 1사이로 표현할 수 있는 활성화 함수인 sigmoid을 사용합니다.
논문에서 주장하는 Batch Normalization의 장점은 다음과 같다.
기존 Deep Network에서는 learning rate를 너무 높게 잡을 경우 gradient가 explode/vanish 하거나, 나쁜 local minima에 빠지는 문제가 있었다. 이는 parameter들의 scale 때문인데, Batch Normalization을 사용할 경우 propagation 할 때 parameter의 scale에 영향을 받지 않게 된다. 따라서, learning rate를 크게 잡을 수 있게 되고 이는 빠른 학습을 가능케 한다.
Batch Normalization의 경우 자체적인 regularization 효과가 있다. 이는 기존에 사용하던 weight regularization term 등을 제외할 수 있게 하며, 나아가 Dropout을 제외할 수 있게 한다 (Dropout의 효과와 Batch Normalization의 효과가 같기 때문.) . Dropout의 경우 효과는 좋지만 학습 속도가 다소 느려진다는 단점이 있는데, 이를 제거함으로서 학습 속도도 향상된다.
모델결합
모델 결합(model combination)을 하게 되면 학습의 성능을 개선할 수 있다 모델 결합이 효과를 얻으려면, 서로 다른 학습 데이터를 이용해서 학습을 하거나,
모델이 서로 다른 구조를 가져야 한다. 하지만, 망이 깊은 경우에 1개의 망을 학습시키는 것도 만만치 않은 일인데 복수개의 망을 학습시키는 것은 매우 힘든 작업이 된다.
또한 어떻게 해서 다양한 모델을 학습시켰을지라도 (학습은 offline으로 시키므로) 다양한 모델을 실행시킬 때 연산 시간을 잡아먹기 때문에 빠른 response time이 요구되는 경우에는 곤란함이 있다.
Dropout은 위 2가지 문제를 해결하기 위해 개발된 것이다. 여러 개의 모델을 만드는 대신에 모델 결합에 의한 투표효과(Voting)와 비슷한 효과를 내기 위해 학습 사이클이 진행되는 동안
무작위로 일부 뉴런을 생략한다. 그렇게 되면 생략되는 뉴런의 조합만큼 지수함수적으로 다양한 모델을 학습시키는 것이나 마찬가지 이기 때문에 모델 결합의 효과를 누릴 수 있다.
또한 실제로 실행을 시킬 때는 생략된 많은 모델을 따로 실행시키는 것이 아니라, 생략된 모델들이 모두 파라미터를 공유하고 있기 때문에 모두 각각의 뉴런들이
존속할 (dropout 하지 않을) 확률을 각각의 가중치에 곱해주는 형태가 된다.
이것을 그림으로 표현하면 아래와 같은 형태가 된다. 학습 시에는 뉴런은 존속할 확률 p로 학습을 진행하고, 실행할 때는 각각의 넷에 얻어진 가중치에 존속할 확률 p를 곱해준다.
cnn 모델
model.add(Conv2D(32,kernel_size=(3,3),padding='same',activation='relu',input_shape=(height,width,1)))
#이미지크기 : height*width 채널 : 1 필터크기 3*3 필터수 32
#나오는 이미지크기 (32-3)//1+1 => ((input_image_size)-fillter)/stride + 1
#max_pooling 과적합을 방지하기 위해서 가장큰값을뽑아냄
#mean_pooling 평균값을 뽑아내는 풀링
#stride 필터 적용할때 이동거리를 뜻한다.
#dropout
#drop out은 일종의 regularization(일반화)의 방법이다.
#dropout은 과적합(overfiting)을 막기위한 하나의 방법으로 합성곱에서
#여러 연결중 일부를 생략하는것이라 볼수있다.
ast는 문법을 구조화 시켜주는 모듈
eval : String의 int 값을 숫자로 인식하는것처럼 계산가능
literal_eval
literal_eval은 eval 과는 다르게 built-in 함수는 아니며,
AST(Abstract Syntax Trees) module 에서 제공하는 함수 중 하나이다.
numpy arange의 개념
>>> import numpy as np
>>> np.arange(3) array([0, 1, 2])
>>> np.arange(3.0) array([ 0., 1., 2.])
>>> np.arange(3,7) array([3, 4, 5, 6])
>>> np.arange(3,7,2) array([3, 5])
train_grand=train_grand.reshape((-1,(height*width+1))) #32*32로 배열 변경 reshape의 -1의 의미는 남은 차원의 수에 맞춰주는것
Error when checking target: expected dense_19 to have shape (340,) but got array with shape (1,) 문제점
sparse_categorical_crossentropy one_hot encoding 일때는 categorical_crossentropy를쓰지만 그렇지않을경우 sparse를붙여줘야한다
그림을 리스트에 추가하는 부분 해설
tdqm for문의 진행을 알수 있음.
glob os.listdir 과 달리 파일리스트를 가져올 경우
검색시 사용했던 경로명까지 전부 가져옴.
train=pd.read_csv(c,usecols=['drawing','recognized'],nrows=per_class*2) #drawing recognized 불러오기
nrows 옵션은 읽을 파일의 행수를 말한다 . 대용량 파일 읽는데에 유용합니다.
2000*2 = 4000
train_array=np.reshape(train_array,(per_class,-1)) 2000개로 나눠서 -1을 넣으면 계산해서 알아서됌
ex) a = [3,4,5,6,7,8,9,10,11,12,13,14]
a= a.reshpe(3,-1)
print (a)
a = [[3,4,5,6],
[7,8,9,10],
[11,12,13,14]]
train_array=np.array(imagebag.compute())#unmpy 형식으로 그림을 그려줌 #그림아니고 배열형식 3중배열 그래서 그림형식이 아니고
그림끼리 같이 되있음
train_array=np.reshape(train_array,(per_class,-1)) #2000 -1로 reshpae로 행렬 형식 변경 그림 1개씩을 reshape해서 쪼개줌.
#2중배열임 reshape으로 쪼개줘서 2000개로 쪼개줌
label_array=np.full((train.shape[0],1),i)# label 붙여주기 full로 i로 채워주고 train[0]=2000 2000개씩 라벨 0 ,1,2,3,4,5 ~으로붙여줌
train_array=np.concatenate((label_array,train_array),axis=1) #concatenate : 데이터 결합, axi=1로 하면 열로 연결
train=train[train.recognized==True].head(per_class) # recognized가 트루인 것만 뽑아냄
bag은 병렬화 시킴
간단한 계산을 병렬화 시킴
imagebag=bag.from_sequence(train.drawing.values).map(stroke_to_img)
bag이 drawing의 values을 뽑아내 map 으로 그려줌
map 함수는 list 같은 sequence 형 데이터를 argument로 받아서 각 원소에 입력 받은 함수를 적용시키고 list로 반환되니ㅏ다.
trainarray=np.array(imagebag.compute()) imagbag
compute는 트레인의 어레인의 실제값을 계산하게 해줌 (np.array)
imagebag=bag.from_sequence(train.drawing.values).map(stroke_to_img)
어려운부분
trainarray=np.reshape(trainarray,(per_class,-1))형식변경 reshape으로
막 써놨지만 추후 정리예정
'Machine Learning > Deep Running' 카테고리의 다른 글
Tensorflow 1.5 사용시 "Could not flatten dictionary: key Tensor("MultiRNNCellZeroState/BasicLSTMCellZeroState/zeros:0", shape=(int, int ), dtype=float32) is not unique" 오류 발생시 (0) | 2020.07.17 |
---|---|
IMDB 데이터를 이용한 간단한 LSTM, GRU, Simple RNN 구현 (0) | 2020.07.15 |
딥러닝 프로젝트 결과 보고서 (0) | 2019.12.05 |
yolo를 이용한 영상 객체인식 (0) | 2019.10.22 |
신경망 (0) | 2019.09.27 |