from keras.datasets.fashion_mnist import load_data
# keras 저장소에서 데이터 다운로드
(X_train, y_train), (X_test, y_test) = load_data()
print(X_train.shape, X_test.shape)
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(777)
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneakers', 'Bag', 'Ankle boots']
sample_size = 9 # 9개 뽑아줘
random_idx = np.random.randint(60000, size=sample_size) # 6만개 중 9개 랜덤하게 보여줘
plt.figure(figsize=(5,5))
for i, idx in enumerate(random_idx):
plt.subplot(3,3,i+1)
plt.xticks([]) # 안 그릴거라 비우기
plt.yticks([])
plt.imshow(X_train[idx], cmap ='gray')
plt.xlabel(class_names[y_train[idx]])
plt.show()
# 1) X feature의 값을 0-1 구간으로 정규화; MinMax 알고리즘 사용해 스케일링
# 2) Cov2D 신경망 사용하기 위해 3채원 배열으로 변환
X_train = np.reshape(X_train / 255, (-1, 28, 28, 1))
# -1: 개수가 맞지 않아도 오류내지 말고 reshape 해줘
X_test = np.reshape(X_test / 255, (-1, 28, 28, 1))
X_train.shape
# 3) 각 레이블을 범주형으로 변경
# 현재: 0-9 -> 변경 후: [1,0,0,0,0,0,0,0,0,0] (원핫 인코딩)
from tensorflow.keras.utils import to_categorical
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
y_test
# 4) 검증 데이터 셋 분리; 훈련 -> 훈련 70 : 검증 30
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.3,
random_state=777)
print(X_train.shape)
print(X_val.shape)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=3, strides=(1,1), padding='same',
activation='relu', input_shape=(28,28,1)))
model.add(MaxPool2D(pool_size=(2,2), strides=2, padding='same'))
# 2*2로 지나가면서 특징 추출하고 Max값으로 다운 샘플링해줄 것이다. -> (14, 14, 1)
model.add(Conv2D(filters=32, kernel_size=3, strides=(1,1), padding='same',
activation='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=2, padding='same')) # -> (7, 7, 1)
model.add(Conv2D(filters=64, kernel_size=3, strides=(1,1), padding='same',
activation='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=2, padding='same')) # -> (4, 4, 1)
model.add(Flatten()) # 2차원 배열을 Dense층에 입력하기 위해 1차원으로 펼침
model.add(Dense(64, activation ='relu'))
model.add(Dense(10, activation ='softmax')) # 10개의 출력을 가진 신경망
from tensorflow.keras.utils import plot_model
plot_model(model, 'model.png', show_shapes=True)
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
history = model.fit(X_train, y_train, epochs=30,
batch_size=32, validation_data=(X_val, y_val))
import matplotlib.pyplot as plt
his_dict = history.history
loss = his_dict['loss']
val_loss = his_dict['val_loss'] # 검증 데이터가 있는 경우 ‘val_’ 수식어가 붙습니다. # 추가
epochs = range(1, len(loss) + 1)
fig = plt.figure(figsize = (10, 5))
# 훈련 및 검증 손실 그리기
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(epochs, loss, color = 'blue', label = 'train_loss')
ax1.plot(epochs, val_loss, color = 'orange', label = 'val_loss') # 추가
ax1.set_title('train and val loss')
ax1.set_xlabel('epochs')
ax1.set_ylabel('loss')
ax1.legend()
acc = his_dict['acc']
val_acc = his_dict['val_acc'] # 추가
# 훈련 및 검증 정확도 그리기
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(epochs, acc, color = 'blue', label = 'train_acc')
ax2.plot(epochs, val_acc, color = 'orange', label = 'val_acc') # 추가
ax2.set_title('train and val acc')
ax2.set_xlabel('epochs')
ax2.set_ylabel('loss')
ax2.legend()
plt.show()
model.evaluate(X_test, y_test)
!wget --no-check-certificate \
https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip \
-O /tmp/cats_and_dogs_filtered.zip
# 압축풀기
import os
import zipfile
local_zip = '/tmp/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r') # 'r' = 읽기
zip_ref.extractall('/tmp')
zip_ref.close()
# 데이터 경로 설정
rootPath = '/tmp/cats_and_dogs_filtered' # 기본 경로
# 훈련 및 검증 데이터 경로
train_dir = os.path.join(rootPath, 'train')
# 운영체제에서 제공해주는 경로를 붙이는 함수 join -> /tmp/cats_and_dogs_filtered/train
val_dir = os.path.join(rootPath, 'validation')
# -> /tmp/cats_and_dogs_filtered/validation
# 훈련 데이터 중 고양이 사진 경로
train_cats_dir = os.path.join(train_dir, 'cats')
# -> /tmp/cats_and_dogs_filtered/train/cats
# 훈련 데이터 중 강아지 사진 경로
train_dogs_dir = os.path.join(train_dir, 'dogs')
# -> /tmp/cats_and_dogs_filtered/train/dogs
# 검증 데이터 중 고양이 사진 경로
val_cats_dir = os.path.join(val_dir, 'cats')
# -> /tmp/cats_and_dogs_filtered/validation/cats
# 검증 데이터 중 강아지 사진 경로
val_dogs_dir = os.path.join(val_dir, 'dogs')
# -> /tmp/cats_and_dogs_filtered/validation/dogs
train_cat_fnames = os.listdir(train_cats_dir)
train_cat_fnames.sort()
train_dog_fnames = os.listdir(train_dogs_dir)
train_dog_fnames.sort()
val_cat_fnames = os.listdir(val_cats_dir)
val_cat_fnames.sort()
val_dog_fnames = os.listdir(val_dogs_dir)
val_dog_fnames.sort()
# print(train_dog_fnames[:10])
print('훈련 고양이 데이터 사진 수: ', len(os.listdir(train_cats_dir)))
print('훈련 강아지 데이터 사진 수: ', len(os.listdir(train_dogs_dir)))
print('검증 고양이 데이터 사진 수: ', len(os.listdir(val_cats_dir)))
print('검증 강아지 데이터 사진 수: ', len(os.listdir(val_dogs_dir)))
import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 데이터 경로 설정
rootPath = '/tmp/cats_and_dogs_filtered'
# 각 데이터의 generate를 개별적으로 진행
# 훈련 데이터는 데이터 증식(속성) + 정규화(스케일링)
trainImageGenerator = ImageDataGenerator(rescale=1./255,
horizontal_flip = True,
vertical_flip = True,
shear_range = 0.5,
brightness_range = [0.5, 1.5],
zoom_range = 0.2,
width_shift_range = 0.1,
height_shift_range = 0.1,
rotation_range = 30,
fill_mode = 'nearest')
# 검증 데이터는 정규화만(스케일링)
testImageGenerator = ImageDataGenerator(rescale=1./255)
trainGen = trainImageGenerator.flow_from_directory(
os.path.join(rootPath, 'train'),
target_size = (64, 64),
class_mode = 'binary') # 0과 1로 라벨링을 하고 데이터를 읽어들임
testGen = testImageGenerator.flow_from_directory(
os.path.join(rootPath, 'validation'),
target_size = (64, 64),
class_mode = 'binary') # categorical로 주면 다중 분류 가능
# 라벨 확인
print(trainGen.class_indices)
print(testGen.class_indices)
# 훈련 데이터 그려보기
from tensorflow.keras.preprocessing.image import array_to_img
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(5,5))
for i in range(9):
data = next(trainGen)
arr = data[0][0]
plt.subplot(3, 3, i+1)
plt.xticks([]) #눈금 지우기 코드
plt.yticks([])
img = array_to_img(arr).resize((128,128))
plt.imshow(img)
plt.show()
# 검증 데이터 그려보기
from tensorflow.keras.preprocessing.image import array_to_img
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(5,5))
for i in range(9):
data = next(testGen)
arr = data[0][0]
plt.subplot(3, 3, i+1)
plt.xticks([]) #눈금 지우기 코드
plt.yticks([])
img = array_to_img(arr).resize((128,128))
plt.imshow(img)
plt.show()
# 정답지 그려보기
label_index = trainGen.class_indices
x,y = trainGen.next()
# print(len(x)) # next는 32개씩 줌
for i in range(0,3):
image = x[i]
label = y[i].astype('int')
plt.xticks([]) #눈금 지우기 코드
plt.yticks([])
print('사진: {}'.format([k for k, v in label_index.items() if v == label]))
# {'cats': 0, 'dogs': 1} -> {0 : 'cats', 1 : 'dogs'} 이름으로 보여주도록 코딩
print('사진: {}'.format(label)) # 원래 출력 데이터
plt.imshow(image)
plt.show()
from tensorflow.keras.models import Sequential
from tensorflow.keras import layers
model = Sequential()
model.add(layers.InputLayer(input_shape=(64, 64, 3)))
model.add(layers.Conv2D(16, (3,3), (1,1), 'same', activation = 'relu'))
# 필터 사이즈, 커널 사이즈, 스트라이드, 패딩 여부, 활성화 함수 순
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Conv2D(32, (3,3), (1,1), 'same', activation = 'relu'))
# 필터 사이즈, 커널 사이즈, 스트라이드, 패딩 여부, 활성화 함수 순
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Conv2D(64, (3,3), (1,1), 'same', activation = 'relu'))
# 필터 사이즈, 커널 사이즈, 스트라이드, 패딩 여부, 활성화 함수 순
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Dropout(rate=0.3))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
from tensorflow.keras.utils import plot_model
plot_model(model, 'model.png', show_shapes=True)
model.summary()
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
history = model.fit_generator(trainGen, epochs=32, validation_data = testGen)
import matplotlib.pyplot as plt
his_dict = history.history
loss = his_dict['loss']
val_loss = his_dict['val_loss'] # 검증 데이터가 있는 경우 ‘val_’ 수식어가 붙습니다. # 추가
epochs = range(1, len(loss) + 1)
fig = plt.figure(figsize = (10, 5))
# 훈련 및 검증 손실 그리기
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(epochs, loss, color = 'blue', label = 'train_loss')
ax1.plot(epochs, val_loss, color = 'orange', label = 'val_loss') # 추가
ax1.set_title('train and val loss')
ax1.set_xlabel('epochs')
ax1.set_ylabel('loss')
ax1.legend()
acc = his_dict['acc']
val_acc = his_dict['val_acc'] # 추가
# 훈련 및 검증 정확도 그리기
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(epochs, acc, color = 'blue', label = 'train_acc')
ax2.plot(epochs, val_acc, color = 'orange', label = 'val_acc') # 추가
ax2.set_title('train and val acc')
ax2.set_xlabel('epochs')
ax2.set_ylabel('loss')
ax2.legend()
plt.show()
model.evaluate_generator(testGen)
from tensorflow.keras.preprocessing.image import array_to_img
import numpy as np
label_index = ['고양이', '강아지']
x, y = testGen.next()
for i in range(0, 10):
image = x[i]
label = y[i].astype('int')
y_prob = model.predict(image.reshape(1, 64, 64, 3))
y_prob_class = (model.predict(image.reshape(1, 64, 64, 3)) > 0.5).astype('int')[0][0]
print('정답: {}'.format(label_index[label]), ' label : ', label)
print('예측: {}'.format(label_index[y_prob_class]), 'predicted value : ', y_prob)
plt.imshow(image)
plt.show()
history = model.fit_generator(trainGen, epochs=64, validation_data = testGen)
model.evaluate_generator(testGen)
참고. 검증 데이터는 원칙적으로 테스트 데이터와 달라야 하는데 우리는 이미지 데이터 분리 단계를 스킵했기 때문에 그냥 두 목적에 동일한 데이터를 중복 사용함.