7-1. 인공신경망
텐서플로
Keras 케라스 _ '패션 MINIST 데이터셋 불러오기'
- 케라스 학습하기 위한 데이터 셋을 제공해줌
- from tensorflow import keras
- (train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
* load_data()
: 훈련 데이터와 테스트 데이터를 나누어 반환함
( 데이터 셋 마다 불러오는 방식은 차이가 있음)
💡 인공신경망
- 기존의 머신러닝 알고리즘이 잘 해결하지 못했던 문제에 대해 높은 성능을 발휘하는 새로운 종류의 알고리즘
- 입력층과 출력층 최소 두 개의 층이 필요해
ㆍ입력층
- 특성의 갯수만큼 받아주는 입력층
- 연산하지 않고 주는대로 받아서 다음 층에 넘겨줌
ㆍ밀집층
- 가장 간단한 인공 신경망의 층
- 입력된 모든 값과 출력층의 모든 값이 하나도 빠짐없이 밀집되어 연결된 형태
=> 완전 연결 레이어
- 가중치(weight)는 특성의 갯수만큼 생성돼서 각각의 픽셀에 곱해지고 절편(bias)는 한 번만 더해짐
- 각 레이블의 확률을 계산하기 위한 가중치와 절편을 다름
- 레이블의 갯수만큼 각각 연산이 이루어짐
ex) z_바지 =w1 x (픽셀1) + w2 x (픽셀2) +... + w784 x (픽셀784) + b
ㆍ은닉층
- 입력층과 출력층 사이에 있는 모든 층
- 활성화함수 적용(선형 방정식의 계산 값에 적용하는 함수로 비교적 자유롭게 사용- 시그모이드, 렐루 등)
- 선형 계산을 적당하게 비선형적으로 비틀어주기 위해 활성화 함수 적용
- 뉴런의 갯수는 경험에 의해 지정(단, 출력 층의 뉴런보다는 많게 만든다)
ㆍ출력층
- 타깃값, 레이블의 갯수만큼 출력하는 출력층
- 활성화 함수 적용(종류 제한되어 있어 - 이진분류:시그모이드/다중분류:소프트맥스)
💡 딥러닝
- 인공신경망과 동의어로 사용되는 경우가 많음
- 혹은 심층 신경망(deepl neaural network, DNN)을 딥러닝이라고 부름
- 반드시 그래픽 처리 장치 GPU 사용(복잡한 연산을 동시에 빨리 처리하기 위해 병렬처리 필요)
케라스 모델
1. Dense 클래스 이용해서 층 생성
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))
- 입력층, 출력층 동시에 생성하는 방식이지만, 일반적으로는 입력 부분 따로 만드는 경우가 많음
- Dense(출력 뉴런 갯수, ) 제일 먼저 작성 (이진분류-2개)
- 활성화 함수 입력 (이진분류-sigmoid / 다중분류 -softmax)
- 입력의 크기는 특성의 갯수 반드시 튜플 형태로 작성
2. 모델 만들기(순차적 모델)
- 실제 학습은 신경망 모델이 하는 것(층만 만들어서는 학습 못해)model = keras.Sequential(dense)
- 생성자에 layer 전달
- 층이 하나 이상일 경우 리스트 형태로 전달
3. 모델 만들었으면 훈련 전 반드시 compile
- loss매개변수에 내가 사용할 손실 함수 지정 (이진분류-binary / 다중분류 -categorical)model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
- 클래스 레이블 정수일 경우 원-핫 인코딩까지 해주는 sparse_categorical_crossentropy
(sparse_? 없으면 원핫 인코딩 작업 따로 해줘야 해)
- metrics 보고 싶은 값 지정해 ( 신경망 모델 훈련 할 때마다 정확도를 출력하겠다)
4. 모델 훈련 fit()
- 입력과 타깃 데이터 전달model.fit(train_scaled, train_target, epochs=5)
- epochs 훈련 반복횟수
5. 모델 성능 평가 evaluate()
- 따로 떼어놓은 검증 세트 사용model.evaluate(val_scaled, val_target)
7-2. 심층 신경망
<키워드 정리>
심층 신경망
: 2개 이상의 층을 포함한 신경망
( 종종 다층 인공 신경망, 심층 신경망, 딥러닝을 같은 의미로 사용..)
렐루함수
: 이미지 분류 모델의 은닉층에서 많이 사용하는 활성화 함수
- 시그모이드는 층이 많을수록 활성화 함수의 양쪽 끝에서 변화가 작기 때문에 학습이 어려워짐
- 렐루함수 시그모이드를 보완
- 입력된 값이 양수일 경우 통과, 음수일 경우 0으로 셋팅
옵티마이저
: 신경망의 가중치와 절편을 학습하기 위한 알고리즘 또는 방법
- 모델 컴파일 시 어떤 하강법을 쓸 건지 optimizer 지정
- 케라스에는 다양한 경사하강법 알고리즘 구현되어 있음(SGD, 네스테로프 모멘텀, RMSprop, Adam 등)
- adam 제일 많이 사용함
심층 신경망 만드는 세 가지 방법
방법1.
# 1) 각각의 dense 만들어 놓기 dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784,)) dense2 = keras.layers.Dense(10, activation='softmax') # 2) Sequential 모델에 리스트 형태로 전달 model = keras.Sequential([dense1, dense2]) # 모델 만들 때 순서 바뀌면 안돼 # 리스트 형태로 전달
방법2.# Sequential 클래스의 생성자 안에서 바로 Dense 클래스 객체 만들기 model=keras.Sequential([ keras.layers.Dense(100, activation='sigmoid', input_shape=(784,),name='hidden'), keras.layers.Dense(10, activation='softmax', name='output') ], name='패션 MNIST 모델')
방법3. - 가장 많이 사용# 1) 모델 객체 만들기 model = keras.Sequential() # 2) 각각의 layer를 모델 객체에 순서대로 add() model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784,))) model.add(keras.layers.Dense(10, activation='softmax'))
인공신경망 주입하기 위해 1차원 배열로 변환!
1. 넘파이 배열의 reshape()
2. 케라스 2차원배열을 1차원으로 펼쳐주는 Flatten 층 제공
- Flatten층 학습하는 층이 아니야
- 입력받은 것 전달만 하기 때문에 파라미터 값 붙을 수 없음
- flatten층 신경망 모델에 추가하면 입력값의 차원을 짐작할 수 있다는 장점
model = keras.Sequential() model.add(keras. layers.Flatten(input_shape=(28, 28)))
7-3. 신경망 모델 훈련
<키워드 정리>
드롭아웃
: 은닉층에 있는 뉴런의 출력을 랜덤하게 꺼서 과대적합을 막는 기법
- 드롭아웃 훈련 중에 적용되며 평가나 예측에서는 적용되지 않음
- 완벽하게 연결되어 있으면 과대하게 연산되기 때문에
- 은닉층에 틀정 일부 뉴런값을 다음 층에 전달 안해
- 훈련과정에서 은닉층의 일부 뉴런을 랜덤하게 출력을 0으로 만들어 과대적합을 막는 이론
- 얼마만큼 뉴런을 dropout 할 건지는 개발자가 지정 (경험에 의해...)
콜백
: 훈련 도중에 어떤 작업을 수행할 수 있도록 도와주는 도구
최상의 모델을 자동으로 저장해주거나 검증 점수가 더 이상 향상 되지 않으면 일직 종료할 수 있음
# keras.callbacks패키지 안에
# 콜백 객체를 넣어줘야 해
# 콜백 매개변수에는 객체를 리스트 형태로 전달한다.
# 콜백 조기종료하기 위해 사용
# 한 번 훈련이 끝날 때마다 계속 저장 체크포인트 콜백을 사용하기 위해서
# save_best_only = True 가장 낮은 검증 점수 = 검증 손실 점수 (낮으면 손 실값 낮아 좋아)
조기종료
: 검증 점수가 더 이상 감소하지 않고 상승하여 과대적합이 일어나면 훈련을 계속 진행하지 않고 멈추는 기법
가장 베스트인 모델에 해당하는 모델을 저장해
# epochs값이 20 훈련은 총 20번해 # 그중 15번했을 때 가장 낮은값이 들어왔어 그럼 훈련안해도 돼
# 문제는 손실값이 내려가 언제 멈출줄 몰라 튀고 내려오고 튀고 내려오고 partience
# 몇 번 튀었을 때 훈련을 멈추게 할 건지 설정
# fit callback쪽에 넣어줘야 해
#얼리스탑핑 객체 만들어(이때 몇 번 튀었을 때 멈추게 할거야?) 실제저장하는 데는 best-model.h5
# 멈출 때 가장 베스트인값을 넣어놔 restore 마지막 신규값을 저장하지 말고
# 콜백에 체크포인트와 얼리스타핑 넣어야 해
# 과대적합을 줄이고자 dropout
# 완벽하게 연결되어 있으면 과대하게 연산되기 때문에
# 은닉층에 틀정 일부 뉴런값을 다음 층에 전달 안해
# 훈련과정에서 은닉층의 일부 뉴런을 랜덤하게 출력을 0으로 만들어 과대적합을 막는 이론
# 얼마만큼 뉴런을 dropout 할 건지는 개발자가 지정 (경험에 의해...)
콜백
: 케라스 모델을 훈련하는 도중에 어떤 작업을 수행할 수 있도록 도와주는 도구
# 온클릭도 콜백 (클릭하고 뗐을 때 함수 불러와)
# 이벤트가 발생한 후에 바
# keras.callbacks패키지 안에
# 콜백 객체를 넣어줘야 해
# 콜백 매개변수에는 객체를 리스트 형태로 전달한다.
# 콜백 조기종료하기 위해 사용
# 한 번 훈련이 끝날 때마다 계속 저장 체크포인트 콜백을 사용하기 위해서
# save_best_only = True 가장 낮은 검증 점수 = 검증 손실 점수 (낮으면 손 실값 낮아 좋아)
조기종료
### 조기종료
# 가장 베스트인 모델에 해당하는 모델을 저장해
# epochs값이 20 훈련은 총 20번해 # 그중 15번했을 때 가장 낮은값이 들어왔어 그럼 훈련안해도 돼
# 문제는 손실값이 내려가 언제 멈출줄 몰라 튀고 내려오고 튀고 내려오고 partience
# 몇 번 튀었을 때 훈련을 멈추게 할 건지 설정
# fit callback쪽에 넣어줘야 해
#얼리스탑핑 객체 만들어(이때 몇 번 튀었을 때 멈추게 할거야?) 실제저장하는 데는 best-model.h5
# 멈출 때 가장 베스트인값을 넣어놔 restore 마지막 신규값을 저장하지 말고
# 콜백에 체크포인트와 얼리스타핑 넣어야 해
신경망 모델을 만들기 위해서
flatten 펼쳐주는 층
dense 밀집층
층은 학습 못해
모델 만들어줘야 해
우리가 배운 모델 sequential 순차적
학습하기 위해서는 compile 필요
fit
evaluate
함수 어느게 손실함수고 어느게 활성화함수인지 구별해야 해\\
하이퍼파라미터 레이어도 개발자가 순서 정해줘야 해 하이퍼파라미터야
케라스의 미니배치 32개
validation_data=(val_scaled, val_target))
튜플 형태로 보내줘야 해
추가되는 매개변수 ㅎ
정리
딥러닝 하려면
신경망
층이 필요해
이미지 분류
이미지가 2차원 배열 => 1차원으로 펼쳐
10가지로 ㅁ분류하려고 해
dense 대표적 밀집층
마지막 출력층 활서오하 함수가 필요해
softmax
-> 성능
은닉층 끼워놔
대표적인 레이어도 dense
- 훈련했더니 과대적합
=> 은닉층에 드롭아웃 레이어 넣어줘
내 팀원한테 모델을 전달하려고 해
모델 저장 1. 파라미터만 저장 / 2.모델구조 파라미터 다 저장
일반적으로 두 가지 방법 다 저장해놔
다른 사람이 층을 더 심고 싶을 때
파라미터만 있으면
훈련을 시킬때 최상의 값으로 저장하고 싶어
=>checkpoint
100번 훈련시키는데 최적의 값 나오면 멈춰
=>earlystopping
이 두개는 fit()안에 callbacks=[]에 리스트 형태로 넣어줘
7-1. 인공신경망
###############데이터 준비#################
# keras 데이터 불러오기
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
# 훈련 데이터의 크기 확인
print(train_input.shape, train_target.shape) >>> (60000, 28, 28) (60000,)
# 테스트 데이터의 크기 확인
print(test_input.shape, test_target.shape) >>> (10000, 28, 28) (10000,)
# 상위 10개 이미지를 가지고 출력
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 10, figsize=(10,10))
for i in range(10):
axs[i].imshow(train_input[i], cmap='gray_r')
axs[i].axis('off')
plt.show()
# 타깃값 확인해보기
print([train_target[i] for i in range(10)]) >>> [9, 0, 0, 3, 0, 2, 7, 2, 5, 5]
# 각 레이블 당 샘플 몇 개씩 가지고 있는지 확인하기
import numpy as np
print(np.unique(train_target, return_counts=True)) >>> (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000]))
#######################################################
############### 로지스틱 회귀로 분류하기 #################
### SGDClassifier() 사용
# 표준화 작업
train_scaled = train_input / 255.0 # 0~1 사이의 값으로 정규화(StandardSclaer 대신에 255로 나눴어 / 각 픽셀 0~255 사이의 정숫값)
# 2차원 배열을 1차원 배열로
train_scaled = train_scaled.reshape(-1, 28*28)
print(train_scaled.shape) >>> (60000, 784) # 784개의 픽셀로 이루어진 60,000개의 샘플 준비
#### 교차검증
from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=5, random_state=42)
scores = cross_validate(sc, train_scaled, train_target, n_jobs=-1)
# 첫 번째값 무조건 모델명 # 어떤 값 # 어떤 정답지로 #-1 모든 자원 다 사용해
print(np.mean(scores['test_score'])) >>> 0.8196000000000001
# 교차 검증 반환값 딕셔너리야
# scores 키에서 'test_score' 검증 셋에 대한 평가 결과
# max_iter 올려도 성능 크게 향상되지 않아....
#######################################################
############### 인공 신경망으로 모델 만들기 #################
# 검증 세트 덜어내기(딥러닝 교차검증 하면 시간 너무 오래 걸려)
from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)
print(train_scaled.shape, train_target.shape) >>> (48000, 784) (48000,)
###### 출력층과 입력층을 동시에 만들 때 사용하는 방법 #####
# 1. layer 층 만들기
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,)) # Dense라는 클래스를 이용해서 객체를 만들어
# 출력층 분류할 레이블 갯수(뉴런) / 뉴런의 출력에 적용할 활성화함수 / 입력층 입력의 크기 특성의 갯수(튜플 형태로 반드시 쉼표찍어야 해)
# 2. 모델 만들기(순차적 모델)
# 실제 학습을 하기 위해서는 모델을 만들어줘야 해(layer 층만 만들어 놓으면 학습 불가능)
model = keras.Sequential(dense) # 생성자에 layer 전달
# 3. 모델 만들었으면 반드시 compile
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
# loss매개변수에 내가 사용할 손실 함수
# 케라스에서 손실함수 두 가지 (이진분류-binary / 다중분류 -categorical)
# 원-핫 인코딩까지 해주는 sparse_categorical_crossentropy
# 신경망 모델 훈련할 때마다 정확도를 내보내줘
# metrics 보고 싶은 값 지정해 (출력할 값 정확도를 출력하겠다)
print(train_target[:10]) >>> [7 3 5 8 6 9 3 3 9 9]
# 4. 모델 훈련 fit()
model.fit(train_scaled, train_target, epochs=5)
>>> Epoch 1/5
1500/1500 [==============================] - 3s 1ms/step - loss: 0.6091 - accuracy: 0.7920
Epoch 2/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4745 - accuracy: 0.8391
Epoch 3/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4506 - accuracy: 0.8472
Epoch 4/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4373 - accuracy: 0.8518
Epoch 5/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4291 - accuracy: 0.8553
# 5. 모델 성능 평가 evaluate()
# 따로 떼어놓은 검증 세트 사용
model.evaluate(val_scaled, val_target)
>>> 375/375 [==============================] - 1s 1ms/step - loss: 0.4438 - accuracy: 0.8493
[0.4438328742980957, 0.8492500185966492]
7-2. 심층 신경망
# 데이터 불러오기
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
# 데이터 불러왔으면 반드시 샘플 데이터 확인하기
print(train_input.shape, train_target.shape) >>> (60000, 28, 28) (60000,)
print(test_input.shape, train_target.shape) >>> (10000, 28, 28) (60000,)
from sklearn.model_selection import train_test_split
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)
print(train_scaled.shape, train_target.shape) >>> (48000, 784) (48000,)
print(val_scaled.shape, val_target.shape) >>> (12000, 784) (12000,)
############ 인공신경망 모델에 층 2개 추가하기 ###########
# 은닉층 추가하기
# 은닉층에 활성화 함수를 적용해서 비선형으로 한 번 비틀어주고 마지막을 소프트맥스로
# 활성화함수는 정해져 있는 게 아니라 경험에 의해서...
# 은닉층의 뉴런의 갯수 출력층의 뉴런보다 많게(몇 개 정해져 있는 게 아니라 경험해 의해서...)
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784,))
# 출력층 최종 레이블 갯수(10개)
dense2 = keras.layers.Dense(10, activation='softmax')
# 회귀를 할 때는 활성화 함수 지정하지 않고 출력층의 선형 방정식 그대로 출력함
############### 심층 신경망 만들기 ##############
########### 방법1 ###########
# 1) 각각의 dense 만들어 놓기
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784,))
dense2 = keras.layers.Dense(10, activation='softmax')
# 2) Sequential 모델에 리스트 형태로 전달
model = keras.Sequential([dense1, dense2])
# 모델 만들 때 순서 바뀌면 안돼
# 리스트 형태로 전달
model.summary()
>>>
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 100) 78500
dense_1 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
########### 방법2 ###########
# Sequential 클래스의 생성자 안에서 바로 Dense 클래스 객체 만들기
model=keras.Sequential([
keras.layers.Dense(100, activation='sigmoid', input_shape=(784,),name='hidden'),
keras.layers.Dense(10, activation='softmax', name='output')
], name='패션 MNIST 모델')
########### 방법3 ###########
# 가장 많이 사용
# 1) 모델 객체 만들기
model = keras.Sequential()
# 2) 각각의 layer를 모델 객체에 순서대로 add()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784,)))
model.add(keras.layers.Dense(10, activation='softmax'))
########################################################
# compile
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
# 층 하나 추가했더니 정확도 2% 정도 상승
####################### 렐루 함수 ######################
model = keras.Sequential()
# 케라스에서 2차원 배열을 1차원으로 펼쳐주는 Flatten 층 제공
model.add(keras.layers.Flatten(input_shape=(28, 28)))
# 입력받은 거 전달많 하기 때문에 파라미터값 붙을 수 없어(활성화함수x)
model.add(keras.layers.Dense(100, activation='relu')) # 활성화 함수 relu
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary() # flatten층 신경망 모델에 추가하면 입력값의 차원을 짐작할 수 있다는 장점
>>>
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_1 (Flatten) (None, 784) 0
dense_10 (Dense) (None, 100) 78500
dense_11 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
##################################################
# 훈련 데이터 다시 준비해서 모델 훈련하기
# reshape() 적용 x
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)
# 컴파일
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
# 훈련
model.fit(train_scaled, train_target, epochs=5)
# 평가
model.evaluate(val_scaled, val_target)
# 은닉층 추가하니 성능 향상되었음
####################### 옵티마이저 ######################
# 컴파일 시 어떤 하강법 사용할 건지 optimizer 지정
#### Adam을 이용해 모델 훈련하기
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
model.evaluate(val_scaled, val_target)
'MLOps 개발자 양성과정 > ml&dl' 카테고리의 다른 글
[Day-57] chap.09 텍스트를 위한 인공 신경망(순환 신경망 (0) | 2023.03.17 |
---|---|
[Day-56] chap08. 이미지를 위한 인공신경망 (0) | 2023.03.15 |
[Day-54] chap.06_비지도 학습 (0) | 2023.03.12 |
[Day-53] chap.05_트리 알고리즘 (0) | 2023.03.10 |
[Day-52] 로지스틱 회귀 / 확률적 경사 하강법 (0) | 2023.03.08 |