# CSV 파일을 이용해서 Kaggle Dogs vs Cats 전체 이미지 학습
# 런타임 : 메모리 디스크 등 실행시켜주는 환경
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
# iuput layer, hidden layer, 합성곱 연산, pooling, drop out
from tensorflow.keras.layers import Flatten, Dense,Conv2D, MaxPooling2D,Dropout
from tensorflow.keras.optimizers import Adam #RMSprop, SGD 등 많아요!
import matplotlib.pyplot as plt # 이미지 확인
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
# 현재 예제는 결측치, 이상치가 없어요. 다른 작업을 수행할 땐 꼭 확인!!
# Raw Data Loading
df = pd.read_csv('/content/drive/MyDrive/9월 30일/train.csv')
display(df.head(),df.shape) # (25000, 6401) label과 해당 사진에 대한 pixel data 확인
# 이미지 데이터 분리
t_data = df['label'].values # 1차원 ndarray
x_data = df.drop('label', axis=1, inplace=False).values # 2차원 ndarray
# 이미지 확인
# 형, 열중 열을 안 쓰면 행을 지칭, 행만 뽑아낸걸 2차원 다시 변환, 컬러 → 흑백
plt.imshow(x_data[150].reshape(80,80), cmap='gray')
plt.show()
# 데이터 전처리 - train, test → 분리 2개를 4개로
train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(x_data,
t_data,
test_size=0.3,
stratify=t_data,
random_state=0)
# 정규화(Nomalization)
scaler = MinMaxScaler()
scaler.fit(train_x_data)
train_x_data_norm = scaler.transform(train_x_data)
test_x_data_norm = scaler.transform(test_x_data)
# CNN Model 구현 → 큰 box
model = Sequential() # 순차적으로 통과
# 첫 번째 Convolution Layer
# filter하나당 feature map하나, filter가 많으면 계산해야 하는 weigh수가 늘어나요.
# 메모리 차원에서 DNN보다 CNN이 월등히 좋아요.
# filter 수는 임의로 지정.. kernel_size=filter size
model.add(Conv2D(filters=32,
kernel_size=(3,3),
activation='relu',
padding='SAME',
input_shape=(80,80,1))) # 세로, 가로 , channel
# pooling
model.add(MaxPooling2D(pool_size=(2,2))) # stride는 pool_size와 같이 가요
# 두 번째 Convolution Layer
model.add(Conv2D(filters=64,
kernel_size=(3,3),
activation='relu',
padding='SAME')) # input_shape은 처음에만 나중엔 알아서~
# pooling
model.add(MaxPooling2D(pool_size=(2,2))) # stride는 pool_size와 같이 가요
# 세 번째 Convolution Layer
model.add(Conv2D(filters=128,
kernel_size=(3,3),
activation='relu',
padding='SAME'))
# 여기선 pooling 뺐어요
# 네 번째 Convolution Layer
model.add(Conv2D(filters=64,
kernel_size=(3,3),
activation='relu',
padding='SAME'))
# pooling
model.add(MaxPooling2D(pool_size=(2,2)))
# 다섯 번째 Convolution Layer
model.add(Conv2D(filters=32,
kernel_size=(3,3),
activation='relu',
padding='SAME'))
# pooling
model.add(MaxPooling2D(pool_size=(2,2)))
# FC layer - DNN 학습
# 4차원 개수 세로 가로 채널 → 2차원
# 2차원 → 1차원
# input layer
model.add(Flatten())
# Flatten은 전체 데이터를 2차원으로 변형?? 이미지의 개수는 제외하고 3차원 데이터를 1차원으로 바꿔준다고 생각하시는게 좋습니다. 즉, 4차원에서 맨 앞 차원이 이미지 개수이기 때문에 이 부분을 제외하고 3차원을 1차원으로 바꿔서 전체를 2차원으로 바꾸는거라고 생각하시면 됩니다.이미지는 2차원변환!
# Dropout layer(over fitting을 피하기 위해서 사용) dense잡기 전에 drop을 먼저 잡는 게 일반적
model.add(Dropout(rate=0.5))
# Hidden layer(옵션)
model.add(Dense(units=256,
activation='relu'))
# output layer
model.add(Dense(units=1,
activation='sigmoid')) # 이진 분류는 sigmoid
# model summary
print(model.summary()) # 10
# Optimizer 설정
model.compile(optimizer=Adam(learning_rate=1e-4),
loss='binary_crossentropy',
metrics=['accuracy'])
# 학습 진행
# train_x_data_norm 2차원 → 4차원
# train_t_data → binary → 1차원 → 2차원 변환
# history는 loss와 accuracy에 대한 그래프를 그릴 수 있어요!
history = model.fit(train_x_data_norm.reshape(-1,80,80,1),
train_t_data.reshape(-1,1),
epochs=200,
batch_size=100,
verbose=1,
validation_split=0.3)
# loss: 0.0240 - accuracy: 0.9909 - val_loss: 1.2334 - val_accuracy: 0.7686
# train data에서는 잘 적합되는데 validation data는 그렇지 못해서 (overfitting)
# Evaluation (test data를 이용)
# accuracy 계산
result = model.evaluate(test_x_data_norm.reshape(-1,80,80,1),
test_t_data.reshape(-1,1))
print('우리 model의 accuracy : {}'.format(result))
# loss: 1.1749 - accuracy: 0.7781
# 우리 model의 accuracy : [1.1749205589294434, 0.7781333327293396]
# 정확도가 낮아요..
# train을 이용한 loss와 accuracy
# validation을 이용한 loss와 accuracy를 그래프로 비교해 보아요!!
# history를 조사하면 학습하면서 나온 loss와 accuracy를 알아낼 수 있어요(dictionary 형태)
# print(history.history)
# print(history.history.keys()) # dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
train_acc = history.history['accuracy'] # train accuracy
train_loss = history.history['loss']
valid_acc = history.history['val_accuracy']
valid_loss = history.history['val_loss']
# matplotlib을 이용해서 graph를 그려보아요!
# train, validation 비교 - 왼쪽은 accuracy 비교 그림, 오른쪽은 loss 비교 그림
fig = plt.figure()
fig_1 = fig.add_subplot(1,2,1)
fig_2 = fig.add_subplot(1,2,2)
fig_1.plot(train_acc, color='b', label='training accuracy')
fig_1.plot(valid_acc, color='r', label='validation accuracy')
fig_1.legend()
fig_2.plot(train_loss, color='b', label='training loss')
fig_2.plot(valid_loss, color='r', label='validation loss')
fig_2.legend()
plt.tight_layout()
plt.show()
# validation acc는 어느 순간부터 늘지 않아요. 학습을 지속하면, overfitting만 심해져요.
# 50번 정도가 최적..
'머신러닝 딥러닝' 카테고리의 다른 글
1001 Data Augmentation (0) | 2021.10.01 |
---|---|
0930 Image generator (0) | 2021.09.30 |
0929 Dogs vs Cats csv 파일로 저장 (0) | 2021.09.29 |
0928 CNN 구현(tf 1.15, tf 2.x) (0) | 2021.09.28 |
0927 CNN(Convolution Neural Network) (0) | 2021.09.27 |
댓글