Dropout Layer를 다음 모델 summary 구조로 추가해보기
Kaggle 데이터셋을 가져올 수 있는 환경 설정
Kaggle mypage에서 API 코드 받아오기
import os
os.environ['KAGGLE_USERNAME'] = 'yungsanghwang' # username
os.environ['KAGGLE_KEY'] = 'e57b686e5ced5139126b8cd598b7a958' # key
Kaggle에서 제공하는 데이터셋을 로컬로 다운로드 하지 않고 API Code를 가져와서 로드하기
Kaggle 데이터셋 압축풀기
!kaggle datasets download -d datamunge/sign-language-mnist
!unzip -q sign-language-mnist
sklearn?
model_selection - train_test_split
데이터셋을 train set/validation set 으로 나눠주는 라이브러리
preprocessing - StandardScaler
preprocessing - OneHotEncoder
출력 값을 컴퓨터가 읽기 편하도록 행렬 형식으로 변환하는 라이브러리. 인덱스 값과 일치하는 매트릭스로 바꿔줌
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.optimizers import Adam, SGD
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder
28*28 크기의 알파벳 사진을 일렬로 나열해 들어있는 픽셀 값을 표시한 것이다.
label은 알파벳에서 어떤 글자에 해당하는지 알려주는 필드
일렬로 정렬된 픽셀의 색 값을 통해서 어떤 알파벳인지를 예측해야 하는 모델을 만들어야 한다!
🧐따라서 x값은 색 값, y값은 라벨값이라고 판단하기!
train_df = pd.read_csv('sign_mnist_train.csv')
train_df.head()
test_df = pd.read_csv('sign_mnist_test.csv')
test_df.head()
출력값인 라벨값을 기준으로 데이터가 얼마나 들어있는지 확인 할 수 있다.
하나의 라벨에는 얼마만큼의 데이터가 들어있으며 대강의 수치를 파악하는데 사용한다고 생각한다
plt.figure(figsize=(16, 10))
sns.countplot(train_df['label'])
plt.show()
입력값 x는 28*28크기 픽셀에 들어있는 색값이 필요하다
라벨 + 색값이 들어있는 train/test table에서 label을 제거한다
출력값 y는 사진의 색값을 모두 취합해 무슨 알파벳인지 알려주기 위한 라벨값이 필요하다
라벨 + 색값이 들어있는 train/test table에서 label만을 가져온다
데이터 학습 모델을 만들기 위해서는 입출력 값을 numpy array 형태로 만들어줘야 한다.
float32비트 형태로 만드는 작업 또한 필요하다
28*28 사진의 색값을 일렬로 정렬한 784개의 열(column)
784개의 열로 구성된 데이터가 27455개의 행(row)이 있음
사진의 이름을 가리키는 라벨값을 1개의 열(column)
1개의 열로 구성된 데이터가 7172개의 행(row)이 있음
train_df = train_df.astype(np.float32)
x_train = train_df.drop(columns=['label'], axis=1).values
y_train = train_df[['label']].values
test_df = test_df.astype(np.float32)
x_test = test_df.drop(columns=['label'], axis=1).values
y_test = test_df[['label']].values
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
몇 번째 이미지 인지 하드로 코딩한 것. 범위 안의 숫자라면 별로 몇 번째 숫자라도 상관없음
사용하는 값은 y_train
사용하는 값은 x_train, reshape(size,size)
index = 1
plt.title(str(y_train[index]))
plt.imshow(x_train[index].reshape((28, 28)), cmap='gray')
plt.show()
학습데이터 x_train 이미지 10개를 출력하는 코드 작성하기
for i in range(10):
plt.title(str(y_train[i]))
plt.imshow(x_train[i].reshape((28, 28)), cmap='gray')
plt.show()
plt.subplots를 사용하면 이미지를 정렬하여 작은 화면으로 간단하게 확인할 수 있다!
f, ax = plt.subplots(2,5)
f.set_size_inches(10, 10)
k = 0
for i in range(2):
for j in range(5):
ax[i,j].imshow(x_train[k].reshape(28, 28) , cmap = "gray")
k += 1
plt.tight_layout()
One-hot Encoding 전의 y_train data shape, 후의 y_train data shape 출력하기
🧐 라벨 값의 크기가 하나기 때문에 1
print(y_train.shape)
🧐 라벨 값의 크기가 하나기 때문에 1
print( y_train[0].shape )
🧐 어떤 알파벳인지 라벨의 진짜 값을 보여줌
print( y_train[0])
컴퓨터가 값을 잘 알아먹을 수 있도록 행렬의 형태로 인코딩 하는 전처리
실제 라벨의 값이 3이라면 [0.0.0.1.0.0.0.0.0.0...] 이런 식으로 변환해준다!
바뀌어야 하는 값은 출력값 y다!
y_train과 y_test 모두 원-핫 인코딩으로 변경해준다
🚩맨뒤에 .toarray() 꼭 넣어주기
encoder = OneHotEncoder()
y_train = encoder.fit_transform(y_train).toarray()
y_test = encoder.fit_transform(y_test).toarray()
🧐 x값의 크기가 24 이기 때문에 1부터 24가 될 수 있도록 y값의 크기가 24의 행렬만큼 커졌다!
print(y_train.shape)
🧐 x값의 크기가 24 이기 때문에 1부터 24가 될 수 있도록 y값의 크기가 24의 행렬만큼 커졌다!
print(y_train[0].shape)
🧐아까 라벨 값이 3이라고 했으니까 그에 맞게 바뀌어진 모습이다!
print(y_train[0])
정규화를 위해서는 각 데이터들을 해당 데이터 셋이 가질 수 있는 값의 범위로 나눠주면 된다.
X_train의 경우 한 픽셀이 0~255사이의 값을 가질 수 있으므로 255로 나눠준다.
출처 : https://hyjykelly.tistory.com/16
x_train = x_train / 255.
x_test = x_test / 255.
🧐 x데이터는 28*28 크기의 값을 갖는다
print(x_test[0].shape)
🧐 x데이터는 모델에 넣어주기 위해 np.array 형식의 값을 갖고 있다.
print(type(x_test[0]))
🧐 x데이터는 모델에 넣어주기 위해 32비트 실수 형식의 값을 갖고 있다.
32비트 실수 : [0.15648954956...]
print(x_test[0].dtype)
두 개의 모델을 만들어 학습하기 1번.
위에서 x_test[0].shape를 찍어본 이유는 여기에 크기를 넣기 위해서!
28*28 사진의 784 픽셀 색 값 만큼 가지고 있다.
학습을 위해 무수히 학습하는 중간 층
덴스 레이어의 크기는 사실 정해져 있는 것은 아닌데 4배수로 256,512 이런식으로 많이 사용함
중간 층에서 학습을 담당한다. 인풋 -> 1번 히든 -> 2번 히든 -> 3번 히든 -> 출력
레이어가 줄어들면서 값을 추려준다고 생각하면 좋다!
덴스 레이어 24는 원-핫 인코딩을 통해서 늘어난 shape 크기 값을 의미한다!
activation=softmax 는 다항논리회귀로 이미지 분류에 사용한다
이렇게 설정할 레이어를 다 만들어주고, 케라스 모델을 활용하여 인풋과 아웃풋을 넣어준다
마지막으로 다 넣고 교과서를 찍어낼 준비를 한다!
손실에 softmax를 썼다면 categorical_crossentropy를 넣고, 옵티마이저와 애큐러시 속성을 넣고 컴파일한다
컴파일할 모델의 가설, 손실함수의 값을 최적화된 값으로 가기 위해서는 함수의 최소화지점으로 가야한다.
러닝레이트, 다가가는 발걸음의 크기를 조절해 가면서 다가가야 튕겨나가거나 왔다갔다하는 오버슈팅을 피할 수 있다
input = Input(shape=(784,))
hidden = Dense(1024, activation='relu')(input)
hidden = Dense(512, activation='relu')(hidden)
hidden = Dense(256, activation='relu')(hidden)
output = Dense(24, activation='relu')(hidden)
model1 = Model(inputs=input, outputs=output)
model1.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.001), metrics=['acc'])
🙄 이게 뭔데? : 784(인풋 레이어의 크기) * 1024(완전연결 레이어의 크기)
print(784*1024)
컴파일한 모델이 어떻게 생겼는지 요약으로 보자!
model1.summary()
🙄 이게뭔데? : 각 덴스레이어에서 학습할 파라미터의 값 약 140 여 만개
print(803840 + 524800 +131328 + 6168)
🙄 이게뭔데? : 무슨 모델인데 모델이 뭐야? 알려주려고 function 모델로 변경???
func_model = Model(inputs=input, outputs=output, name='FuncModel')
🙄 이게뭔데? : 플롯_모델 라이브러리를 임포트 해서 모델의 생김새를 이미지로 한 눈에 볼 수 있게 만들 준비!
from tensorflow.keras.utils import plot_model
🙄 이게뭔데? : 모델을 넣어 이미지로 보여주기!
plot_model(func_model, show_shapes=True, show_layer_names=True, to_file='model.png')
모델1과 동일 -> Dense 256
기존 레이어에서 드롭아웃 추가
https://keras.io/api/layers/regularization_layers/dropout/
각 단계에서 입력 단위를 무작위로 0으로 설정해서 과적합을 방지. -> 사공이 너무 많아서 산으로 가는 것을 막아줌
히든 레이어 마지막에 hidden 변수에 Dropout(rate=)(hidden)을 담아서 사용함
rate=0.5 삭제할 입력 단위 비율 50%
모델 1과 동일 -> Dense 24, softmax
모델 1과 동일 -> 변수만 2로 다르게 넣어주기
모델 1과 동일 -> loss=categorical_crossentropy, Adam lr=0.001 metrics=['acc']
input = Input(shape=(784,))
hidden = Dense(256, activation='relu')(input)
hidden = Dense(512, activation='relu')(hidden)
hidden = Dense(1024, activation='relu')(hidden)
hidden = Dense(512, activation='relu')(hidden)
hidden = Dense(256, activation='relu')(hidden)
hidden = Dropout(rate=0.5)(hidden)
output = Dense(24, activation='softmax')(hidden)
model2 = Model(inputs=input, outputs=output)
model2.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.001), metrics=['acc'])