03. CNN with TF

(참고) udemy - TF Developer in 2022

Contents

  1. Inspecting data
  2. end-to-end example
  3. Baseline model
  4. ConvNet with max pooling & Data augmentation
  5. Prediction
  6. Multi-class Classification


(1) Inspecting data

Example of file structure

pizza_steak <- top level folder
└───train <- training images
│   └───pizza
│   │   │   1008104.jpg
│   │   │   1638227.jpg
│   │   │   ...      
│   └───steak
│       │   1000205.jpg
│       │   1647351.jpg
│       │   ...
│   
└───test <- testing images
│   └───pizza
│   │   │   1001116.jpg
│   │   │   1507019.jpg
│   │   │   ...      
│   └───steak
│       │   100274.jpg
│       │   1653815.jpg
│       │   ...    


특정 directory 내부 샅샅히 뒤지기

import os

for dirpath, dirnames, filenames in os.walk("pizza_steak"):
  print(f"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'.")
There are 2 directories and 0 images in 'pizza_steak'.
There are 2 directories and 0 images in 'pizza_steak/test'.
There are 0 directories and 250 images in 'pizza_steak/test/steak'.
There are 0 directories and 250 images in 'pizza_steak/test/pizza'.
There are 2 directories and 0 images in 'pizza_steak/train'.
There are 0 directories and 750 images in 'pizza_steak/train/steak'.
There are 0 directories and 750 images in 'pizza_steak/train/pizza'.


특정 경로 내 파일 개수

len(os.listdir("pizza_steak/train/steak"))
# 750


요약 : class 별로,

  • 750개의 train image
  • 250개의 test image


(2) end-to-end example

  1. Import Packages
  2. Load Images
  3. Build Model
  4. Train Model


  1. Import Packages
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator


  1. Load Images
tf.random.set_seed(42)

# normalization
train_datagen = ImageDataGenerator(rescale=1./255)
valid_datagen = ImageDataGenerator(rescale=1./255)

train_dir = "pizza_steak/train/"
test_dir = "pizza_steak/test/"


train_data = train_datagen.flow_from_directory(train_dir,
                                               batch_size=32,
                                               target_size=(224, 224), 
                                               class_mode="binary", 
                                               seed=42)

valid_data = valid_datagen.flow_from_directory(test_dir,
                                               batch_size=32,
                                               target_size=(224, 224),
                                               class_mode="binary",
                                               seed=42)


참고 : data loader ( iterator )에서 하나의 예시 ( =하나의 batch ) 뽑아내기

images, labels = train_data.next() 
len(images), len(labels)
# 32, 32


  1. Build Model

Tiny VGG - https://poloclub.github.io/cnn-explainer/

model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(filters=10, 
                         kernel_size=3, # (3, 3)
                         activation="relu", 
                         input_shape=(224, 224, 3)), # (H, W, C)
  tf.keras.layers.Conv2D(10, 3, activation="relu"),
  tf.keras.layers.MaxPool2D(pool_size=2, # (2, 2)
                            padding="valid"), # or 'same'
  tf.keras.layers.Conv2D(10, 3, activation="relu"),
  tf.keras.layers.Conv2D(10, 3, activation="relu"),
  tf.keras.layers.MaxPool2D(2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(1, activation="sigmoid") 
])


  1. Train Model
model.compile(loss="binary_crossentropy",
              optimizer=tf.keras.optimizers.Adam(),
              metrics=["accuracy"])
              
history = model.fit(train_data,
                        epochs=5,
                        steps_per_epoch=len(train_data),
                        validation_data=valid_data,
                        validation_steps=len(valid_data))              


(3) Baseline model

일반적인 구조

  • Input
  • ( Conv + ReLU + Pooling ) x n
  • Flatten
  • FC layer


Padding

  • same : zero padding으로, 크기 유지되도록
  • valid : padding 안함
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D, Activation
from tensorflow.keras import Sequential
model = Sequential([
  Conv2D(filters=10, 
         kernel_size=3, 
         strides=1,
         padding='valid',
         activation='relu', 
         input_shape=(224, 224, 3)), 
  Conv2D(10, 3, activation='relu'),
  Conv2D(10, 3, activation='relu'),
  Flatten(),
  Dense(1, activation='sigmoid') 
])


(4) ConvNet with max pooling & data augmentation

Data Augmentation

train_datagen_augmented = ImageDataGenerator(rescale=1/255.,
                                             rotation_range=20, 
                                             shear_range=0.2, 
                                             zoom_range=0.2,
                                             width_shift_range=0.2,
                                             height_shift_range=0.2, 
                                             horizontal_flip=True) 

train_datagen = ImageDataGenerator(rescale=1/255.) 
test_datagen = ImageDataGenerator(rescale=1/255.)


  • Augment 된 이미지
train_data_augmented = train_datagen_augmented.flow_from_directory(train_dir,
                                                                   target_size=(224, 224),
                                                                   batch_size=32,
                                                                   class_mode='binary',
                                                                   shuffle=False) 


  • Augment 안된 (원본) 이미지
train_data = train_datagen.flow_from_directory(train_dir,
                                               target_size=(224, 224),
                                               batch_size=32,
                                               class_mode='binary',
                                               shuffle=False) # Don't shuffle for demonstration purposes

test_data = test_datagen.flow_from_directory(test_dir,
                                             target_size=(224, 224),
                                             batch_size=32,
                                             class_mode='binary')


Max pooling

순서 : ( conv-relu-maxpool )

model = Sequential([
  Conv2D(10, 3, activation='relu', input_shape=(224, 224, 3)),
  MaxPool2D(pool_size=2), 
  Conv2D(10, 3, activation='relu'),
  MaxPool2D(),
  Conv2D(10, 3, activation='relu'),
  MaxPool2D(),
  Flatten(),
  Dense(1, activation='sigmoid')
])


(5) Prediction

Input Size

  • (O) : (n, H,W,C)
  • (X) : (H,W,C)

맨 앞의 차원에 , n ( 이미지의 개수 )가 들어가야한다

pred = model.predict(tf.expand_dims(img, axis=0))


(6) Multi-class Classification

  • class_mode='categorical'
train_data = train_datagen.flow_from_directory(train_dir,
                                               target_size=(224, 224),
                                               batch_size=32,
                                               class_mode='categorical')


  • loss="categorical_crossentropy"
model.compile(loss="categorical_crossentropy",
                optimizer=tf.keras.optimizers.Adam(),
                metrics=["accuracy"])