pycharm에서 tensorflow-cpu로 사용하기 위해서는 다음의 코드를 추가해야함(아마 그럴것.. 나는 주피터에서 돌려서)

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

 

 

categorical_crossentropy를 손실함수로 사용했을 때의 (대략적인) CNN 신경망 코드

import tensorflow as tf
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets.fashion_mnist import load_data
from tensorflow.keras.models import Sequential, save_model, load_model
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D

# Fashion-MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape(-1,28,28,1)
x_test = x_test.reshape(-1,28,28,1)

# 원핫인코딩 (one-hot encoding) 처리 (categorical_crossentropy를 사용하기 때문)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# train/valid 분류
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)

# 모델 생성
model = Sequential([
  Conv2D(64, kernel_size=(5,5),input_shape=x_train.shape[1:], activation='relu'),
  MaxPooling2D(pool_size=(2, 2), padding='same'),
  Dropout(0.2),
  Flatten(),
  Dense(128, activation='relu'),
  Dense(128, activation='relu'),
  Dense(32, activation='relu'),
  Dropout(0.2),
  Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 모델 학습
hist = model.fit(x_train, y_train, batch_size=100 ,epochs=20, validation_data=(x_val ,y_val))
print(model.evaluate(x_test,  y_test, verbose=1))

# 정확도 시각화
import matplotlib.pyplot as plt
# print(hist.history)

plt.plot(hist.history['accuracy'],'b-', label='training')
plt.plot(hist.history['val_accuracy'],'r:' , label='validation')
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
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', 'Test'], loc='upper left')
plt.show()

# 모델 저장
save_model(model,"c:\\data\\fashion_mnist.h5")

# 모델 불러오기
model2 = load_model("c:\\data\\fashion_mnist.h5")

# test 데이터를 사용해 불러온 모델 성능 평가
result = model2.evaluate(x_test,y_test)
print(dict(zip(model.metrics_names, result)))

# sklearn accuracy_score를 사용하여 모델 정확도 평가
from sklearn.metrics import accuracy_score
print(accuracy_score(model2.predict_classes(x_test), np.argmax(y_test,axis=1)))

 

categorical_crossentropy는 다중 분류 손실함수로 one-hot encoding 클래스를 사용한다. 따라서 출력값이 one-hot encoding된 결과로 나오고 정답(label)과 비교하며 학습을 진행하거나 정확도를 알아내기 위해서는 정답(label)도 one-hot encoding된 형태여야 한다. 따라서 위의 코드 구현에서 정답(y_train, y_test)에 대해 one-hot encoding을 하였다.

 

 

 

sparse_categorical_crossentropy를 손실함수로 사용했을 때의 완전연결신경망 코드

import tensorflow as tf
from tensorflow.keras.datasets.fashion_mnist import load_data
from tensorflow.keras.models import Sequential, save_model, load_model
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D

# Fashion-MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = load_data()

# 데이터 정규화
x_train, x_test = x_train / 255.0, x_test / 255.0

# sparse_categorical_crossentropy를 손실함수로 사용하기 때문에 one-hot encoding 사용 안함



# train 데이터 분리 (train/valid)
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)

# 신경망 모델 생성
model = Sequential([
  Flatten(input_shape=(28, 28)),
  Dense(128, activation='relu'),
  Dense(128, activation='relu'),
  Dense(32, activation='relu'),
  Dropout(0.2),
  Dense(10, activation='softmax')
])

# 학습할 때 사용할 옵티마이저, 손실함수, 기준에 대한 정보
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['sparse_categorical_accuracy'])

# 모델 학습
hist = model.fit(x_train, y_train, batch_size=64, epochs=20, validation_data=(x_val ,y_val))

# 학습 시각화
import matplotlib.pyplot as plt
# print(hist.history) # hist에 어떤 데이터가 있는지 확인할 수 있음
plt.plot(hist.history['sparse_categorical_accuracy'],'b-', label='training')
plt.plot(hist.history['val_sparse_categorical_accuracy'],'r:' , label='validation')
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Valid'], loc='upper left')
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', 'Valid'], loc='upper left')
plt.show()

# 구현한 model의 파라미터들 h5 파일로 저장
save_model(model, "c:\\data\\fashion_mnist2.h5")

# 모델 성능 평가
model2 = load_model("c:\\data\\fashion_mnist2.h5")
print(model2.evaluate(x_test,y_test,verbose=0))

# sklearn의 accuracy_score를 사용하여 정확도 확인
from sklearn.metrics import accuracy_score
print(accuracy_score(model2.predict_classes(x_test), y_test))

 

sparse_categorical_crossentropy 또한 다중 분류 손실함수로, categorical_crossentropy와 동일하지만 integer type 클래스라는 것이 다르다. 결론적으로 sparse_categorical_crossentropy는 정답(label)이 one-hot encoding 형태가 아니어도 된다.

 

sparse_categorical_crossentropy를 사용해서 모델을 학습시키고 이 학습된 모델을 불러와서 정확도를 측정하기 위해서는 metrics가 sparse_categorical_accuracy여야 한다. 안그러면 불러온 모델로 evaluate을 하면 정확도가 엉망으로 나온다...^^ (이걸로 개고생함) 만약 실수로 metrics를 sparse_categorical_accuracy로 안하고 그냥 accuracy로 했다면 evaluate으로 정확도를 평가하지말고 sklearn의 accuracy_score로 확인해야 제대로 값이 나온다는 것을 추가적으로 꼭꼭 알길 바란다.

 

 

 

h5 파일이 어떻게 구성되어 있는지 확인하는 파이썬 코드

import h5py
filename = "c:\\data\\fashion_mnist.h5"

def read_hdf5(path):

    weights = {}

    keys = []
    with h5py.File(path, 'r') as f: # open file
        f.visit(keys.append) # append all keys to list
        for key in keys:
            if ':' in key: # contains data if ':' in key
                print(f[key].name)
                weights[f[key].name] = f[key].value
    return weights

read_hdf5(filename)

 

 

 

 

 

+

 

 

 

 

 

Keras Callbacks

 

Callbacks - Keras Documentation

Usage of callbacks 콜백은 학습 과정의 특정 단계에서 적용할 함수의 세트입니다. 학습 과정 중 콜백을 사용해서 모델의 내적 상태와 통계자료를 확인 할 수 있습니다. 콜백의 리스트는 (키워드 인수

keras.io

 

추가적으로 모델 학습시, keras의 callback 기능으로 최적의 모델을 만들 수 있다. 이에 대한 부분은 위의 kears 링크를 참고하는 것이 빠르다.

 

from tensorflow.keras.datasets import fashion_mnist

# Fashion_MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()

import matplotlib.pyplot as plt
import numpy as np

# 정규화, 4차원으로 데이터를 만들어줌
x_train = np.reshape(x_train / 255, (-1, 28, 28, 1))
x_test = np.reshape(x_test / 255, (-1, 28, 28, 1))

from tensorflow.keras.utils import to_categorical
# one-hot encoding
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

from sklearn.model_selection import train_test_split
# train / valid 분리
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size = 0.3, random_state = 777)

print('Fashion-MNIST ready~')

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten

model = Sequential([
    # 항상 모델의 첫 번째 층은 입력의 형태를 명시해주어야함
    Conv2D(filters = 16, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu', input_shape = (28, 28, 1)),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),  
    Conv2D(filters = 32, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu'),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),
    Conv2D(filters = 64, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu'),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),
    Flatten(), # 완전연결층에 들어가기 전 데이터 펼치기
    Dense(64, activation = 'relu'),
    Dense(10, activation = 'softmax') # 10개의 출력을 가지는 신경망
])

model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['acc'])

# kears callbacks 사용
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

filepath = 'c:\\data\\fashion.hdf5'

# ModelCheckpoint : 학습 과정을 모니터링하다가 val_loss가 가장 작을 때 모델의 가중치를 저장
# EarlyStopping : 모니터링하는 평가지표에서 성능 향상이 일어나지 않는 경우
# (patience=5 면 향상이 일어나지 않는 경우 5번까지는 참아줌) 학습 중단
callbacks = [ ModelCheckpoint( filepath = filepath , monitor = 'val_loss' , verbose=1, save_best_only=True ),
            EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')]

model.fit(x_train, y_train, batch_size = 32 , validation_data=(x_val , y_val) , epochs=10, callbacks=callbacks )
model.summary() # 모델의 구조 확인

 

 

+ Recent posts