본문 바로가기
AI & 머신러닝 coding skill

[CONVOLUTIONAL NEURAL NETWORKS IN TENSORFLOW] Multi-class classifier

by 호빵님 2020. 11. 16.
반응형

코세라의   deeplearning.AI tensorflow developer 전문가 자격증 과정내에

Convolutional Neural Networks in TensorFlow

과정의 4주차

Multiclass Classifications

챕터의 코드 예제입니다.

 

1) 알파벳을 손가락 모양으로 표현한 이미지 dataset인, sign MNIST dataset을 다운로드받는다.

 

2) image dataset을 image set과 label set으로 나누는 get_data함수 구현

 

3) Training set과 Test set 디렉토리 경로 설정

 

4) np.expand_dims mathod를 사용해서 이미지데이타에서 차원을 하나 추가한다. (하나의 이미지는 2차원 + 색깔차원 필요)

 

5) preprocessing.image name space의  ImageDataGenerator를 사용해서, ImageDataGenerator를 이용해서, 밝기를 1/255로 정규화한다. data augmentation기능을 사용해서 학습데이터를 증가시킨다. rotation, shift, shear, zoom, flip 등의 이미지를 변환하여, traing set의 수를 증가시킨다. 이 변환된 이미지들은 실재 디스크에 저장되지 않고, 원본을 바꾸지도 않는다. model fit traing중에 RAM memory에서만 생성되어, training set으로만 사용된다. 증가된 다양한 종류의 augmentation 된 training set들은 기존 training set에 너무 overfitting되는 학습을 막아준다.

keras.io/ko/preprocessing/image/

 

Image Preprocessing - Keras Documentation

이미지 전처리 [source] ImageDataGenerator 클래스 keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, zca_epsi

keras.io

6) Conv2D, Maxpooling 3개 layer을 이용한 모델 구성. output은 class종류수 만큼 Dense layer로 ouput unit설정.

 

7) drop out로 0.2로 설정하면, 20% unit이 랜덤하게 학습시마다 drop되어 overfitting을 막아준다.

 

8) flow_from_directory method를 이용해서, training data와 validation data가 있는 디렉토리를 설정하고, target image size와 class mode, batch size를 설정한다. train generator와 validation generator를 각각 선언한다.

 

9) 모델이 학습되도록 한다. fit_generator를 이용해서 모델을 훈련한다.  train generator와 validation generator를 인자로 받는다. flow method를 이용해서, 설정한 batch size만큼씩, 계속 data를 가져와서 모델이 학습될 수 있도록 한다.

 

www.kaggle.com/datamunge/sign-language-mnist

 

Sign Language MNIST

Drop-In Replacement for MNIST for Hand Gesture Recognition Tasks

www.kaggle.com

 

#!/usr/bin/env python
# coding: utf-8

# In[28]:


# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated
# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.
# ATTENTION: Please use the provided epoch values when training.

import csv
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from os import getcwd


# In[29]:


def get_data(filename):
  # You will need to write code that will read the file passed
  # into this function. The first line contains the column headers
  # so you should ignore it
  # Each successive line contians 785 comma separated values between 0 and 255
  # The first value is the label
  # The rest are the pixel values for that picture
  # The function will return 2 np.array types. One with all the labels
  # One with all the images
  #
  # Tips: 
  # If you read a full line (as 'row') then row[0] has the label
  # and row[1:785] has the 784 pixel values
  # Take a look at np.array_split to turn the 784 pixels into 28x28
  # You are reading in strings, but need the values to be floats
  # Check out np.array().astype for a conversion
    with open(filename) as training_file:
      # Your code starts here
        labels=[]
        images=[]
        
        data_reader = csv.reader(training_file)
        skip_header = True
        if skip_header:
            next(data_reader)
            
        for row in data_reader:
            labels.append(row[0])
            images.append(np.array_split(row[1:], 28))
                
        labels=np.array(labels).astype(np.float64)
        images=np.array(images).astype(np.float64)
      # Your code ends here
    return images, labels

path_sign_mnist_train = f"{getcwd()}/../tmp2/sign_mnist_train.csv"
path_sign_mnist_test = f"{getcwd()}/../tmp2/sign_mnist_test.csv"
training_images, training_labels = get_data(path_sign_mnist_train)
testing_images, testing_labels = get_data(path_sign_mnist_test)

# Keep these
print(training_images.shape)
print(training_labels.shape)
print(testing_images.shape)
print(testing_labels.shape)

# Their output should be:
# (27455, 28, 28)
# (27455,)
# (7172, 28, 28)
# (7172,)


# In[30]:


# In this section you will have to add another dimension to the data
# So, for example, if your array is (10000, 28, 28)
# You will need to make it (10000, 28, 28, 1)
# Hint: np.expand_dims

training_images = np.expand_dims(training_images, -1) # Your Code Here
testing_images = np.expand_dims(testing_images, -1) # Your Code Here

# Create an ImageDataGenerator and do Image Augmentation
train_datagen = ImageDataGenerator(
    # Your Code Here
    rescale=1./255,
    featurewise_center=False,  # set input mean to 0 over the dataset
    samplewise_center=False,  # set each sample mean to 0
    featurewise_std_normalization=False,  # divide inputs by std of the dataset
    samplewise_std_normalization=False,  # divide each input by its std
    zca_whitening=False,  # apply ZCA whitening
    rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
    zoom_range = 0.1, # Randomly zoom image 
    width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
    height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
    horizontal_flip=False,  # randomly flip images
    vertical_flip=False  # randomly flip images
    )

validation_datagen = ImageDataGenerator(rescale=1./255) # Your Code Here
    
# Keep These
print(training_images.shape)
print(testing_images.shape)
    
# Their output should be:
# (27455, 28, 28, 1)
# (7172, 28, 28, 1)


# In[36]:


# Define the model
# Use no more than 2 Conv2D and 2 MaxPooling2D
model = tf.keras.models.Sequential([
    # Your Code Here
    tf.keras.layers.Conv2D(75, (3,3), activation='relu', input_shape=(28,28,1)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(50, (3,3), activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(25, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(26, activation='softmax')
    ])

# Compile Model. 
model.compile(loss = 'sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # Your Code Here

# Train the Model
history = model.fit_generator(train_datagen.flow(training_images,
                                                 training_labels,
                                                 batch_size=32),
                              steps_per_epoch=len(training_images)/32,
                              epochs=2,
                              validation_data=validation_datagen.flow(testing_images,
                                                                 testing_labels,
                                                                 batch_size=32),
                              validation_steps=len(testing_images)/32) # Your Code Here (set 'epochs' = 2))

model.evaluate(testing_images, testing_labels, verbose=0)


# In[35]:


# Plot the chart for accuracy and loss on both training and validation
get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib.pyplot as plt
acc = history.history['accuracy'] # Your Code Here
val_acc = history.history['val_accuracy'] # Your Code Here
loss = history.history['loss'] # Your Code Here
val_loss = history.history['val_loss'] # Your Code Here

epochs = range(len(acc))

plt.plot(epochs, acc, 'r', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()

plt.plot(epochs, loss, 'r', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()
반응형