[이 글은 "Do it 딥러닝 입문" 책을 보고 공부한 내용을 복습하고자 정리한 글입니다.]
bincount : 배열에 있는 정수값의 등장 횟수를 세어 정수값에 해당하는 인덱스 위치에 저장
reshape : 사진의 정보는 2차원으로 되어있기 때문에 (-1, "차원을 합친 길이")로 변환
to_categorical : 클래스의 구별을 위해 정수값으로 되있는 값들을 원-핫 인코딩 방식으로 변환
In [1]:
class MultiClassNetwork:
def __init__(self, units=10, batch_size=32, learning_rate =0.1, l1=0,l2=0):
self.units = units #은닉층의 뉴런개수
self.batch_size = batch_size
self.w1 = None
self.b1 = None
self.w2 = None
self.b2 = None
self.a1 = None #은닉층의 활성화 출력
self.losses = []
self.val_losses = [] #검증 손실
self.lr = learning_rate
self.l1 = l1
self.l2 = l2
def forpass(self, x):
z1 = np.dot(x, self.w1) + self.b1
self.a1 = self.sigmoid(z1)
z2 = np.dot(self.a1,self.w2) + self.b2
return z2
def backprop(self, x, err):
m = len(x) #샘플 개수
#출력층의 가중치와 절편에 대한 그레이디언트를 계산합니다.
w2_grad = np.dot(self.a1.T, err) / m
b2_grad = np.sum(err) / m
#시그모이드 함수까지 그레이디언트를 계산합니다.
err_to_hidden = np.dot(err, self.w2.T) * self.a1 * (1 - self.a1)
w1_grad = np.dot(x.T, err_to_hidden) / m
b1_grad = np.sum(err_to_hidden, axis=0) / m
return w1_grad, b1_grad, w2_grad, b2_grad
def sigmoid(self, z):
a = 1 / (1 + np.exp(-z))
return a
def softmax(self, z):
exp_z = np.exp(z)
return exp_z / np.sum(exp_z, axis = 1).reshape(-1,1)
def init_weigths(self, n_features, n_classes):
self.w1 = np.random.normal(0,1,(n_features, self.units)) #(특성 개수, 은닉층 크기)XW
self.b1 = np.zeros(self.units)
self.w2 = np.random.normal(0,1,(self.units , n_classes)) #(은닉층 크기, 클래스 개수)
self.b2 = np.zeros(n_classes)
def fit(self, x, y, epochs=100, x_val= None, y_val=None):
np.random.seed(42)
self.init_weigths(x.shape[1], y.shape[1]) #은닉층과 출력층의 가중치를 초기화.
#epochs만큼 반복
for i in range(epochs):
loss = 0
print('.', end='')
for x_batch, y_batch, in self.gen_batch(x,y):
a = self.training(x_batch, y_batch)
a = np.clip(a, 1e-10, 1-1e-10)
#로그손실과 규제 손실을 더하여 리스트에 추가함.
loss += np.sum(-y_batch*np.log(a))
self.losses.append((loss + self.reg_loss()) / len(x))
self.update_val_loss(x_val, y_val)
#미니 배치 제너레이터
def gen_batch(self,x,y):
length = len(x)
bins = length // self.batch_size #미니 배치 회수
if length % self.batch_size: #나누어 떨어지지 않을 때
bins += 1
indexes = np.random.permutation(np.arange(len(x))) # 인덱스를 섞음
x = x[indexes]
y = y[indexes]
for i in range(bins):
start = self.batch_size * i
end = self.batch_size * (i + 1)
yield x[start:end], y[start:end] #batch_Size만큼 슬라이싱하여 반환.
def training(self, x, y):
m = len(x)
z = self.forpass(x)
a = self.softmax(z)
err=-(y - a) #오차 계산
#오차를 역전파하여 그레이디언트를 계산.
w1_grad, b1_grad, w2_grad, b2_grad = self.backprop(x, err)
#그레이디언트에서 패널티 항의 미분값을 뺌.
w1_grad += (self.l1 * np.sign(self.w1) + self.l2 * self.w1) / m
w2_grad += (self.l1 * np.sign(self.w2) + self.l2 * self.w2) / m
#은닉층의 가중치와 절편 업데이트
self.w1 -= self.lr * w1_grad
self.w2 -= self.lr * w2_grad
self.b1 -= self.lr * b1_grad
self.b2 -= self.lr * b2_grad
return a
def predict(self, x):
z= self.forpass(x)
return np.argmax(z,axis=1) #가장 큰 값의 인덱스를 반환
def score(self,x,y):
#예측과 타깃 열 벡터를 비교하여 True의 비율을 반환
return np.mean(self.predict(x) == np.argmax(y, axis=1))
def reg_loss(self):
return self.l1 * (np.sum(np.abs(self.w1)) + np.sum(np.abs(self.w2))) + \
self.l2 / 2 * (np.sum(self.w1**2) + np.sum(self.w2**2))
def update_val_loss(self, x_val, y_val):
z = self.forpass(x_val)
a = self.softmax(z)
a = np.clip(a, 1e-10, 1-1e-10)
val_loss = np.sum(-y_val*np.log(a))
#크로스 엔트로피 손실과 규제 손실을 더해 리스트에 추가
self.val_losses.append((val_loss+ self.reg_loss())/len(y_val))
In [2]:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
tf.__version__
Out[2]:
In [3]:
(x_train_all, y_train_all), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
print(x_train_all.shape, y_train_all.shape)
In [4]:
plt.imshow(x_train_all[0], cmap='gray')
plt.show()
In [5]:
#y값 확인해보기
print(y_train_all[:10])
In [6]:
print(y_train_all[0]) # 9 == 앵글 부츠
In [7]:
#bincount = 배열에 있는 정수값의 등장 횟수를 세어 정수값에 해당하는 인덱스 위치에 저장
np.bincount(y_train_all)
Out[7]:
In [8]:
#훈련 세트와 검증 세트로 나누기
from sklearn.model_selection import train_test_split
x_train, x_val, y_train, y_val = train_test_split(x_train_all,y_train_all, stratify =y_train_all,
test_size =0.2, random_state =42)
np.bincount(y_train) # 8:2로 나뉨
Out[8]:
In [9]:
# 0~1의 값을 갖게 하려고
x_train = x_train / 255
x_val = x_val / 255
#reshape으로 훈련세트와 검증세트를 2,3번째 차원을 합친 길이로 바꿈
x_train = x_train.reshape(-1, 784) #28 * 28
x_val = x_val.reshape(-1, 784)
print(x_train.shape, x_val.shape)
In [10]:
# 타깃 데이터를 원-핫 인코딩으로 변환
# 예시
tf.keras.utils.to_categorical([0,1,3])
Out[10]:
In [11]:
#원-핫 인코딩
y_train_encoded = tf.keras.utils.to_categorical(y_train)
y_val_encoded = tf.keras.utils.to_categorical(y_val)
print(y_train_encoded.shape, y_val_encoded.shape)
In [12]:
fc = MultiClassNetwork(units=100, batch_size=256)
fc.fit(x_train,y_train_encoded,x_val=x_val, y_val= y_val_encoded, epochs=40)
In [13]:
plt.plot(fc.losses)
plt.plot(fc.val_losses)
plt.legend(['train_loss', 'val_loss'])
Out[13]:
In [14]:
#정확도
fc.score(x_val,y_val_encoded)
Out[14]:
In [15]:
#홀로 해보기
class_names =['티셔츠/윗도리','바지', '스웨터','드레스','코트','샌들','셔츠','스니커즈','가방','앵글부츠']
(x_train_all, y_train_all), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
plt.imshow(x_train_all[0], cmap='gray')
plt.show()
test = x_train_all[0].reshape(1,784)
print(fc.predict(test))
In [17]:
image = tf.keras.preprocessing.image
img = image.load_img('C:\jupyterNotebook\DeepLearning of DoIT\s.jpg', target_size=(28,28))
plt.imshow(img)
Out[17]:
In [18]:
img_tensor = image.img_to_array(img)# 이미지 배열화
a = np.resize(img_tensor,(1,28,28)) #(1,28,28)
a = a / 255 #0~1의 값
a = np.resize(a,(1, 784)) #벡터화
fc.predict(a) #예측
Out[18]:
In [19]:
print(class_names[fc.predict(a)[0]])
In [20]:
img2 = image.load_img('C:/jupyterNotebook/DeepLearning of DoIT/a.jpg',target_size=(28,28))
plt.imshow(img2)
Out[20]:
In [22]:
img_tensor2 = image.img_to_array(img2)
a = np.resize(img_tensor2,(1,28,28))
a = a/255
a = np.resize(a,(1,784))
fc.predict(a)
print(class_names[fc.predict(a)[0]])
만든 의류분류기로 내가 지정한 사진이 무엇인지 분류해봤다. 셔츠를 가방으로 인식하는게 조금 아쉽지만 다음 모델은 좀 더 정교하게 만들어 제대로 분류할 수 있게 만들어 봐야겠다. 스스로 해보는 과정이 얼마나 중요한지 다시 상기하게 됐고 배울것이 아직 너무 많다라는 것도 느끼게 되었다.
반응형
'빅데이터 | 머신러닝 | 딥러닝 > 딥러닝' 카테고리의 다른 글
[딥러닝 기초] Convolution Neuron Network 의류분류기 만들어보기 (0) | 2020.06.01 |
---|---|
[딥러닝 기초] 다층 신경망을 통해 의류분류기 만들어보기(2) (using keras) (1) | 2020.05.14 |
[딥러닝 기초] 다층 신경망 (MLPClassifier) (0) | 2020.05.08 |
[딥러닝 기초] k-fold 교차 검증(cross validation) (0) | 2020.05.02 |
[딥러닝 기초] Neural Network (L1, L2 규제) (0) | 2020.04.25 |