Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: 3팀 조명구 6주차 #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions week6/3팀_조명구.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
CH07 딥러닝을 시작합니다
===

패션 MNIST
---

```python
from tensorflow import keras
(train_input, train_target), (test_input, test_target) =\ keras.datasets.fashion_mnist.load_data()

#훈련데이터 배열 크기: (60000, 20, 20)
#타깃 배열 크기: (60000, )
#테스트 세트: (10000, 28, 28)
#테스트 타깃: (10000,)

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()

#훈련 데이터의 샘플을 그림으로 출력
```

패션아이템(레이블): 티셔츠(0), 바지(1), 스웨터(2), 드레스(3), 코트(4), 샌달(5), 셔츠(6), 스니커즈(7), 가방(8), 앵클 부츠(9)

```python
import numpy as np
print(np.unique(train_target, return_counts=True))

#0~9까지 레이블마다 6000개 샘플이 들어있는 것을 확인
```

로지스틱 회귀로 패션 아이템 분류하기
---

**SGDClassifier**는 2차원 입력을 다루지 못함.

```python
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)

#train_scaled 크기는 (60000, 784) = (샘플 개수, 픽셀 개수)

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)

#성능이 0.81945666666666으로 확인
```

로지스티 회귀 공식 이용
z_티셔츠 = w1*(픽셀1) + w2*(픽셀2) + w3*(픽셀3) + w4*(픽셀4) + ... + w784*(픽셀784) + b

z_바지에 대한 선형방정식은 또 다름. 티셔츠와 바지를 구분하기 위해 w1, w2... 의 가중치는 티셔츠, 바지가 서로 다름.

인공 신경망
---
>가장 기본적인 인공 신경망은 확률적 경사 하강법을 사용하는 로지스틱 회귀와 같다.

![](2022-05-23-15-29-31.png)

**출력층**: z1 ~ z10

**뉴런(유닛)**: z값을 계산하는 단위(선형 계산)

**입력층**: x1 ~ x784(픽셀값 자체, 계산x)

**w1.1**: **z1**을 만들기 위해 픽셀1인 **x1**에 곱해지는 가중치

**w1.2**: **z2**를 만들기 위해 픽셀1인 **x1**에 곱해지는 가중치

>인공신경망은 생물학적 뉴런이 하는 일을 실제로 구현한 것은 아님. 모양을 본뜬 수학 모델일 뿐.

텐서플로와 케라스
--

```python
import tensorflow as tf
```
텐서플로에는 저수준 API와 고수준 API가 있는데, **케라스**가 텐서플로의 고수준 API임.

딥러닝 라이브러리는 벡터, 행렬 연산에 최적화된 GPU 사용.

케라스는 직접 GPU 연산을 수행하지 않고, 텐서플로 등을 백엔드로 사용(대신 GPU 연산).

지금은 거의 *텐서플로 = 케라스*임.

```python
from tesorflow import keras
```

인공 신경망으로 모델 만들기
---

```python
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=42)

#훈련세트의 20%를 검증세트로 덜어냄
#훈련세트 크기: (48000, 784) / 타깃: (48000, )
#검증세트 크기: (12000, 784) / 타깃: (12000, )
```

![](2022-05-23-15-42-35.png)

케라스의 레이어(keras.layers) 패키지 사용.

**밀집층**: 왼쪽 784개 픽셀과 오른쪽 10개 뉴런이 모두 연결된 선 -> 784*10 = 7,840개. 양쪽 뉴런이 모두 연결해서 **완전 연결층**이라고도 함.

```python
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))
#Dense 클래스로 밀집층 만들기.
#10은 뉴런 개수
#2개 클래스를 분류하는 이진 분류라면 시그모이드 함수 쓰면 됨. activation='sigmoid'
#input_shape=(784, )는 입력의 크기. 10개의 뉴런이 각각 몇 개의 입력을 받는지 튜플로 지정. 여기서는 784개의 픽셀값 받음.

model = keras.Sequential(dense)

#model이 신경망 모델.
```

심층 신경망
---

입력층과 출력층 사이에 **은닉층** 추가하기.

```python
from tensorflow import keras
(train_input, train_target), (test_input, test_target) =\ keras.datasets.fashion_mnist.load_data()

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)
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784, ))
dense2 = keras.layers.Dense(10, activation='softmax')

#dense1이 은닉층, 100개의 뉴런을 가진 밀집층.
#뉴런 개수를 정하는 것은 경험으로 판단.
#출력층 뉴런보다는 많아야 됨. 클래스 10개 예측해야되는데 이전 은닉층 뉴런이 10개 미만이면 부족한 정보임.
#dense2는 출력층.
```

심층 신경망 만들기
---
```python
model = keras.Sequential([dense1, dense2])
mode.summary() #층에 대한 유용한 정보
```

층을 추가하는 다른 방법
---

```python
model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784, )))
model.add(keras.layers.Dense(10, activation='softmax'))

#Dense 클래스의 객체를 따로 변수에 담지 않고 바로 add() 메서드로 전달.

#5번 에포크 동안 훈련하기
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
#추가된 층이 성능을 향상시킴.
```

렐루 함수
---

층이 많은 심층신경망일수록 효과가 누적되어 학습을 어렵게 만듦.
이를 위해 입력이 양수면 통과, 음수면 0으로 만드는 **렐루 함수**를 활용.

Flatten 클래스는 배치 차원을 제외하고 나머지 입력 차원을 일렬로 펼치기만 함. 인공 신경망의 성능에 기여하진 않지만 입력층과 은닉층 사이에 추가하기 때문에 층이라고 함.

```python
model = keras.Sequentail()
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'))
print(model.summary())
#층이 3인건 아님. Flatten 클래스는 학습 안하니까. 그래서 summary에서 Flatten 클래스에 포함된 모델 파라미터는 0.

(train_input, train_target), (test_input, test_target) =\ keras.datasets.fashion_mnist.load_dat()
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)

#앞과 같이 훈련 데이터를 준비해서 모델을 훈련한 것.
#reshape() 메서드는 적용하지 않음.

print(model.evaluate(val_scaled, val_target))
#정확도 확인
```

옵티마이저
---
>하이퍼 파라미터
> - 추가할 은닉층의 개수
> - 은닉층의 뉴런 개수
> - 활성화 함수 선택
> - 밀집층 말고 다른 층 선택(ex)합성곱 층)
> - 케라스에서 기본적으로 사용하는 미니배치 경사 하강법에서 사용하는 미니배치 개수(default: 32개)
> - fit() 메서드의 epochs 매개변수
> - compile() 메서드에서 사용하는 경사 하강법 알고리즘 선택 <- **옵티마이저**
> - 기본 경사 하강법 알고리즘(RMSprop)을 사용했을 때 학습률

가장 기본적인 옵티마이저는 확률적 경사 하강법인 **SGD**