▶5.1 딥러닝의 등장
1980년대의 깊은 신경망
- 구조적으로는 쉬운 개념이다.
- 다층 퍼셉트론에 은닉층을 많이 두면 깊은 신경망
- 하지만 학습이 잘 안 된다.
- 그레이디언트 소멸 문제
- 작은 데이터셋 문제
- 과다한 계산 시간
5.1.1 딥러닝의 기술 혁신
딥러닝은 새로 창안된 이론이나 원리는 빈약하다.
- 신경망의 구조와 동작, 학습 알고리즘의 기본 원리는 거의 동일하다.
딥러닝의 기술 혁신 요인
- 값싼 GPU 등장
- 데이터셋 커짐
- 학습 알조리즘의 발전
- ReLU 활성 함수
- 구제 기법
- 다양한 손실 함수와 옵티마이저 개발
학술적인 측면의 혁신 사례
- 컨볼루션 신경망이 딥러닝의 가능성을 열었다.
- 1990년대 LeCun은 필기 숫자에서 획기적인 성능 향상
- AlexNet은 컨볼루션 신경망으로 자연 영상 인식이 가능하다는 사실을 보여줬다.
- 음성 인식에서 혁신
5.1.2 딥러닝 소프트웨어
대표적인 딥러닝 소프트웨어
- 현재는 텐서플로와 파이토치가 대세
▶5.2 텐서플로 개념 익히기
5.2.1 텐서플로와 넘파이의 호환
tf가 제공하는 random 클래스의 uniform 함수로 난수 생성
- [0, 1] 사이의 난수를 2*3 행렬에 생
import tensorflow as tf
print(tf.__version__)
a = tf.random.uniform([2, 3], 0, 1)
print(a)
print(type(a))
tensorflow와 numpy로 2*3 난수 행렬 생성 후 더한다.
import tensorflow as tf
import numpy as np
t = tf.random.uniform([2, 3], 0, 1)
n = np.random.uniform(0, 1, [2, 3])
print(t)
print(n)
res = t + n
print(res)
5.2.2 텐서 이해하기
딥러닝에서 텐서
- 다차원 배열을 텐서라 부른다.
- 데이터를 텐서로 표현한다.
- 신경망의 가중치(매개변수)를 텐서로 표현한다.
- 넘파이는 ndarray 클래스, 텐서플로는 Tensor 클래스로 표현한다. (둘은 호환된다.)
0~5차원 구조의 텐서의 예
- 0차원 : iris label
- 1차원 : iris 샘플 하나
- 2차원 : iris 샘플 여러 개, 명암 영상 한 장
- 3차원 : 명암 영상 여러 개, 컬러 영상 한 장
- 4차원 : 컬러 영상 여러 개, 컬러 동영상 하나
- 5차원 : 컬러 동영상 여러 개
텐서플로가 제공하는 데이터셋의 텐서 구조
- MNIST, cifar10, Boston housing, Reuters 데이터셋의 텐서 구조 확인
import tensorflow as tf
import tensorflow.keras.datasets as ds
# mnist 읽고 텐서 모양 출력
(x_train, y_train), (x_test, y_test) = ds.mnist.load_data()
yy_train = tf.one_hot(y_train, 10, dtype=tf.int8) # 원핫코드로 변환
print('mnist : ', x_train.shape, y_train.shape, yy_train.shape)
# cifar10
(x_train, y_train), (x_test, y_test) = ds.cifar10.load_data()
yy_train = tf.one_hot(y_train, 10, dtype=tf.int8) # 원핫코드로 변환
print('cifar10 : ', x_train.shape, y_train.shape, yy_train.shape)
# boston housing
(x_train, y_train), (x_test, y_test) = ds.boston_housing.load_data()
print('boston : ', x_train.shape, y_train.shape)
# reuters
(x_train, y_train), (x_test, y_test) = ds.reuters.load_data()
print('reuters : ', x_train.shape, y_train.shape)
▶5.3 텐서플로 프로그래밍 기초
sklearn 라이브러리로는 다양한/복잡한 딥러닝 구현이 어렵다.
그래서 딥러닝 전용 프레임워크인 텐서플로나 파이토치를 사용해야 한다.
5.3.1 sklearn의 표현력 한계
from sklearn import datasets
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
# 1
digit=datasets.load_digits()
x_train,x_test,y_train,y_test=train_test_split(digit.data,digit.target,train_size=0.6)
# 2
mlp=MLPClassifier(hidden_layer_sizes=(100),learning_rate_init=0.001,batch_size=32,max_iter=300,solver='sgd',verbose=True)
# 3
mlp.fit(x_train,y_train)
딥러닝은 sklearn의 #2로는 표현이 불가능하다.
- 다양한 형식의 layer를 구성할 수 없다.
텐서 플로나 파이토치는 딥러닝의 복잡도를 지원할 수 있게 완전히 새로 설계한다.
5.3.2 텐서플로로 퍼셉트론 프로그래밍
Variable 함수는 그레이디언트를 구하고 가중치를 갱신하는 연산을 지원한다.
import tensorflow as tf
# OR 데이터 구축
x = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
y = [[-1], [1], [1], [1]]
# 퍼셉트론
w = tf.Variable([[1.0], [1.0]])
b = tf.Variable(-0.5)
# 퍼셉트론 동작
s = tf.add(tf.matmul(x, w), b)
o = tf.sign(s)
print(o)
아래 코드는 퍼셉트론을 학습하는 프로그램 5-5이다.
import tensorflow as tf
# OR 데이터 구축
x = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
y = [[-1], [1], [1], [1]]
# 가중치 초기화화
w = tf.Variable(tf.random.uniform([2, 1], -0.5, 0.5))
b = tf.Variable(tf.zeros([1]))
# 옵티마이저
opt = tf.keras.optimizers.SGD(learning_rate=0.1)
# 전방 계산
def forward():
s = tf.add(tf.matmul(x, w), b)
o = tf.tanh(s)
return o
# 손실 함수 정의
def loss():
o = forward()
return tf.reduce_mean((y - o) ** 2)
# 500세대까지 학습 (100세대마다 학습 정보 출력)
for i in range(500):
opt.minimize(loss, var_list=[w, b])
if i % 100 == 0:
print('loss at epoch ', i, ' = ', loss().numpy())
# 학습된 퍼셉트론으로 OR 데이터를 예측
o = forward()
print(o)
5.3.3 케라스 프로그래밍
[프로그램 5-5]의 문제점
- 신경망 동작을 직접 코딩해야 한다.
- 케라스는 이런 부담을 덜기 위해서 탄생했다.
프로그래밍의 추상화
- 컴퓨터 프로그래밍은 추상화를 높이는 방향으로 발전해 왔다.
- 텐서플로 자체가 아주 높은 추상화 수준이지만 추가로 추상화할 여지가 있다.
- 케라스는 이 여지를 활용한 라이브러리이다.
- model.add(Dense(노드 개수, 활성함수,...)) 방식의 코딩
케라스로 퍼셉트론 프로그래밍
- tensorflow.keras : tensorflow의 하위 클래스로 keras
- keras 클래스의 중요한 세 가지 하위클래스
model 클래스 : Sequential과 functional API 모델 제작 방식 제공
layers 클래스 : 다양한 종류의 층 제공
optimizers 클래스 : 다양한 종류의 옵티마이저 제공
전형적인 절차
- 데이터 구축 → 신경망 구조 설계 → 학습 → 예측
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
# OR 데이터 구축축
x = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
y = [[-1], [1], [1], [1]]
n_input = 2
n_output = 1
# Sequential 클래스로 객체를 생성
perceptron = Sequential()
# add 함수로 Dense(완전 연결) 층을 쌓는다.
perceptron.add(Dense(units=n_output, activation='tanh', input_shape=(n_input,),
kernel_initializer='random_uniform', bias_initializer='zeros'))
# 신경망 학습습
perceptron.compile(loss='mse', optimizer=SGD(learning_rate=0.1), metrics=['mse'])
perceptron.fit(x, y, epochs=500, verbose=2)
# 학습된 신경망으로 예측
res = perceptron.predict(x)
print(res)
Dense로 완전연결층을 쌓는 방식이다.
- 아래 그림은 units와 input_shape 매개변수에 대한 설명이다.
▶5.4 텐서플로로 다층 퍼셉트론 프로그래밍
5.4.1 MNIST 인식
다층 퍼셉트론으로 MNIST 인식하는 프로그램
- 퍼셉트론을 코딩한 위 프로그램과 디자인 패턴 공유.
- 복잡도만 다르지 핵심은 같다.
단계 1 : 데이터 준비
import numpy as np
import tensorflow as ts
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
# MNIST 읽어 와서 신경망에 입력할 형태로 변환
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 텐서 모양으로 변환 - 2차원 구조 텐서를 1차원 구조로 변환(reshape)
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
# ndarray로 변환환
x_train = x_train.astype(np.float32) / 255.0
x_test = x_test.astype(np.float32) / 255.0
# 원핫 코드로 변환
y_train=tf.keras.utils.to_categorical(y_train,10)
y_test=tf.keras.utils.to_categorical(y_test,10)
단계 2 : 신경망 구조 설계
- Sequential 모델을 생성하여 mlp 객체에 저장
- 은닉층 추가 (input_shape는 입력층, units는 현재 쌓고 있는 은닉층으로 설정)
- 출력층 추가 (input_shape는 생력 가능, units는 현재 쌓고 있는 출력층으로 설정)
n_input = 784
n_hidden = 1024
n_output = 100
mlp = Sequential()
mlp.add(Dense(units=n_hidden, activation='tanh', input_shape=(n_input,),
kernel_initializer='random_uniform', bias_initializer='zeros'))
mlp.add(Dense(units=n_output, activation='tanh',
kernel_initializer='random_uniform', bias_initializer='zeros'))
단계 3 : 신경망 학습
- compile 함수로 학습을 준비한다. (loss 매개변수는 손실 함수, optimizers는 옵티마이저로 설정)
- fit 함수는 실제 학습을 수행한다.
(batch_size는 미니배치 크기, epochs는 최대 세대수, validation_data는 학습 도중에 사용할 검증 집합 설정)
단계 4 : 예측
- evaluate 함수로 정확률 측정
# 손실 함수로 mse 사용, 옵티마이저로 Adam 사용
mlp.compile(loss='mean_squared_error',optimizer=Adam(learning_rate=0.001),metrics=['accuracy'])
# 학습 도중 발생한 정보를 hist에 저장해둔다.
hist=mlp.fit(x_train,y_train,batch_size=128,epochs=30,validation_data=(x_test,y_test),verbose=2)
res=mlp.evaluate(x_test,y_test,verbose=0)
print("정확률은",res[1]*100)
5.4.2 학습 곡선 시각화
hist 객체가 가진 정보를 이용해 학습 곡선을 그린다.
import matplotlib.pyplot as plt
# 정확률 곡선
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train','Validation'], loc='upper left')
plt.grid()
plt.show()
# 손실 함수 곡선
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train','Validation'], loc='upper right')
plt.grid()
plt.show()
5.4.3 fashion MNIST 인식
fasion MNIST 데이터셋
- MNIST와 비슷하다.
- 내용이 패션 관련 그림이고 레이블이 {T-shirt/top, Trouser, Pullover,...)인 점만 다르다.
원래는 train_set과 test_set을 나누는 부분이 아래와 같다.
from tensorflow.keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
fashion MNIST는 이 부분만 달라지고 나머지는 동일하다. (아래 코드와 같이 변경)
from tensorflow.keras.datasets import fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
'컴퓨터공학 > 인공지능' 카테고리의 다른 글
[인공지능] 5장. 딥러닝과 텐서플로3 (0) | 2023.04.12 |
---|---|
[인공지능] 5장. 딥러닝과 텐서플로2 (0) | 2023.04.12 |
[인공지능] 4장. 신경망 기초3 (3) | 2023.04.06 |
[인공지능] 4장. 신경망 기초2 (0) | 2023.04.06 |
[인공지능] 4장. 신경망 기초1 (1) | 2023.04.05 |