Notice
Recent Posts
Recent Comments
Link
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

Silver bullet

Fashion-MNIST & cats-and-dogs data set & CIFAR-10 본문

AI/AI

Fashion-MNIST & cats-and-dogs data set & CIFAR-10

밀크쌀과자 2024. 7. 13. 08:44
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

print(tf.__version__)

mnist = tf.keras.datasets.fashion_mnist

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

plt.imshow(training_images[0])
plt.show()

training_images  = training_images / 255.0
test_images = test_images / 255.0

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), 
                                    tf.keras.layers.Dense(128, activation=tf.nn.relu), 
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
                                    
model.compile(optimizer = 'Adam',
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(training_images, training_labels, epochs=5)

model.evaluate(test_images, test_labels)
np.set_printoptions(linewidth=np.inf) # np.array에 대해 1개의 행을 1개의 line에 모두 보여주도록 하는 옵션 세팅

print(training_labels[0])
print()

print(training_images[0])

2. Use custom callback

import tensorflow as tf


class MyCallback(tf.keras.callbacks.Callback):
    
    def on_epoch_end(self, epoch, logs={}):
        try: 
            if(logs.get('accuracy') > 0.95):
                print("\nReached 95% accuracy so cancelling training!")
                self.model.stop_training = True
        except:
            pass
        

mnist = tf.keras.datasets.fashion_mnist

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images = training_images / 255.0
test_images = test_images / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

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

callbacks = MyCallback()
model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])

Fashion-MNIST 정확도 향상 코드

import tensorflow as tf

mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

training_images = training_images / 255.0
test_images = test_images / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)

test_loss, test_accuracy = model.evaluate(test_images, test_labels)

print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))
313/313 [==============================] - 0s 1ms/step - loss: 0.3456 - accuracy: 0.8742
Test loss: 0.3455561399459839, Test accuracy: 87.41999864578247

Your accuracy is probably about 89% on training and 87% on validation.


2. Convolutional network

mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

training_images = training_images.reshape(60000, 28, 28, 1) / 255.0
test_images = test_images.reshape(10000, 28, 28, 1) / 255.0

model = tf.keras.models.Sequential([
    
  # tf.keras.layers.Conv2D(필터 수(-> 피쳐 맵 수), 필터의 크기(가로 & 세로),  ~~~)
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(2, 2),
    
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    
    # Now flatten the output. After this you'll just have the same DNN structure as the non-convolutional version
    tf.keras.layers.Flatten(),
    
    # The same 128-dense-layers, and 10-output-layers as in the pre-convolution example.
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.summary()

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

model.fit(training_images, training_labels, epochs=5)

test_loss, test_accuracy = model.evaluate(test_images, test_labels)

print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))
313/313 [==============================] - 5s 14ms/step - loss: 0.2564 - accuracy: 0.9048
Test loss: 0.2564435601234436, Test accuracy: 90.47999978065491

It's likely gone up to about 93% on the training data and 91% on the validation data.

 

result = model.evaluate(test_images, test_labels)

print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']

x_len = np.arange(len(acc))

plt.plot(x_len, acc, marker='.', c='blue', label="Train-set Acc.")
plt.plot(x_len, val_acc, marker='.', c='red', label="Validation-set Acc.")

plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('Accuracy')
plt.show()
loss = history.history['loss']
val_loss = history.history['val_loss']

x_len = np.arange(len(acc))

plt.plot(x_len, loss, marker='.', c='blue', label="Train-set loss.")
plt.plot(x_len, val_loss, marker='.', c='red', label="Validation-set loss.")

plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('Cross-entropy')
plt.show()

cats-and-dogs data set → large data set

데이터셋 및 모델의 크기가 크므로 본 실습파일은 Google Colab 에서 실행하기를 적극 권장합니다.

import random
import zipfile
import shutil
import os

import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator

import warnings                   
warnings.filterwarnings('ignore')

# # If the URL doesn't work, visit https://www.microsoft.com/en-us/download/confirmation.aspx?id=54765
# # And right click on the 'Download Manually' link to get a new URL to the dataset 

# # Note: This is a very large dataset and will take time to download
!wget --no-check-certificate "https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip" -O "/tmp/cats-and-dogs.zip"

local_zip = '/tmp/cats-and-dogs.zip'
zip_ref   = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp')
zip_ref.close()

print(len(os.listdir('/tmp/PetImages/Cat/')))
print(len(os.listdir('/tmp/PetImages/Dog/'))) 

# # Expected Output:
# # 12501
# # 12501
try:
    os.mkdir('/tmp/cats-v-dogs')
    os.mkdir('/tmp/cats-v-dogs/training')
    os.mkdir('/tmp/cats-v-dogs/testing')
    os.mkdir('/tmp/cats-v-dogs/training/cats')
    os.mkdir('/tmp/cats-v-dogs/training/dogs')
    os.mkdir('/tmp/cats-v-dogs/testing/cats')
    os.mkdir('/tmp/cats-v-dogs/testing/dogs')
except OSError:
    pass

def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):
    files = []
    for filename in os.listdir(SOURCE):
        file = SOURCE + filename
        if os.path.getsize(file) > 0:
            files.append(filename)
        else:
            print(filename + " is zero length, so ignoring.")

    training_length = int(len(files) * SPLIT_SIZE)
    testing_length = int(len(files) - training_length)
    shuffled_set = random.sample(files, len(files))
    training_set = shuffled_set[0:training_length]
    testing_set = shuffled_set[:testing_length]

    for filename in training_set:
        this_file = SOURCE + filename
        destination = TRAINING + filename
        shutil.copyfile(this_file, destination)

    for filename in testing_set:
        this_file = SOURCE + filename
        destination = TESTING + filename
        shutil.copyfile(this_file, destination)


CAT_SOURCE_DIR = "/tmp/PetImages/Cat/"
TRAINING_CATS_DIR = "/tmp/cats-v-dogs/training/cats/"
TESTING_CATS_DIR = "/tmp/cats-v-dogs/testing/cats/"
DOG_SOURCE_DIR = "/tmp/PetImages/Dog/"
TRAINING_DOGS_DIR = "/tmp/cats-v-dogs/training/dogs/"
TESTING_DOGS_DIR = "/tmp/cats-v-dogs/testing/dogs/"
 
split_size = .9
split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)
split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)

# Expected output
# 666.jpg is zero length, so ignoring
# 11702.jpg is zero length, so ignoring
# You can check to see if your data is properly unpacked using the following code:
    
print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))
print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))
print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))
print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))

# Expected output:
# 11250
# 11250
# 1250
# 1250

you can train the model using an ImageDataGenerator.

model = tf.keras.models.Sequential([
    
    tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
]) 

model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=0.001), 
              loss='binary_crossentropy', 
              metrics=['accuracy'])
              
TRAINING_DIR = "/tmp/cats-v-dogs/training/"
train_datagen = ImageDataGenerator(rescale=1.0/255.)
train_generator = train_datagen.flow_from_directory(TRAINING_DIR,
                                                    batch_size=100,
                                                    class_mode='binary',
                                                    target_size=(150, 150))
 
VALIDATION_DIR = "/tmp/cats-v-dogs/testing/"
validation_datagen = ImageDataGenerator(rescale=1.0/255.)
validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,
                                                              batch_size=100,
                                                              class_mode='binary',
                                                              target_size=(150, 150))
 
# Expected Output:
# Found 22498 images belonging to 2 classes.
# Found 2500 images belonging to 2 classes.
# Note that this may take some time.
history = model.fit(train_generator,
                    epochs=15,
                    verbose=1,
                    validation_data=validation_generator)
import matplotlib.image  as mpimg
import matplotlib.pyplot as plt
%matplotlib inline


#-----------------------------------------------------------
# Retrieve a list of list results on training and test data
# sets for each training epoch
#-----------------------------------------------------------
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
 
epochs = range(len(acc)) # Get number of epochs
 

#------------------------------------------------
# Plot training and validation accuracy per epoch
#------------------------------------------------
plt.plot(epochs, acc, 'r', "Training Accuracy")
plt.plot(epochs, val_acc, 'b', "Validation Accuracy")
plt.title('Training and validation accuracy')
plt.figure()
 

#------------------------------------------------
# Plot training and validation loss per epoch
#------------------------------------------------
plt.plot(epochs, loss, 'r', "Training Loss")
plt.plot(epochs, val_loss, 'b', "Validation Loss")
plt.figure()
# 아래 특정 이미지를 대상으로 한 prediction을 Windows OS 에서 진행할 경우,
# 앞선 실습 파일인 4번 파일의 [ 3. Predict on an image & visualize the layer and filter ] 코드를 활용해주세요.

# Here's a codeblock just for fun. 
# You should be able to upload an image here and have it classified without crashing

import numpy as np
from google.colab import files
from keras.preprocessing import image
 
uploaded = files.upload()
 
for fn in uploaded.keys(): 
    
    # predicting images
    path = '/content/' + fn
    img = image.load_img(path, target_size=(150, 150))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)

    images = np.vstack([x])
    classes = model.predict(images, batch_size=10)
    print(classes[0])
    if classes[0]>0.5:
        print(fn + " is a dog")
    else:
        print(fn + " is a cat")

Transfer learning for CIFAR-10 (using ResNet-50)

전이학습을 활용해 약 90% 수준까지 정확도를 높일 수 있습니다.

모델 학습에 시간이 무척 많이 소요됩니다. 아래 실습은 Google Colab을 활용해주세요!

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, models

import numpy as np
import matplotlib.pyplot as plt

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # https://stackoverflow.com/questions/35911252/disable-tensorflow-debugging-information

cifar10 = datasets.cifar10 
(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()

print("Train samples:", train_images.shape, train_labels.shape)
print("Test samples:", test_images.shape, test_labels.shape)

train_images = train_images / 255.0
test_images = test_images / 255.0

 

from tensorflow.keras.applications.resnet50 import ResNet50

conv_base = ResNet50(weights='imagenet', include_top=False, input_shape=(200, 200, 3))

conv_base.summary()

# # 보통 전이학습을 진행할 때는 사전 학습된 모델의 Parameter들은 추가적인 학습을 진행하지 않고 고정시킵니다.
# # 이 실습에서는 기존에 학습된 모델의 Parameter들 역시도 추가적으로 학습을 진행해야 성능이 향상되므로 고정시키지 않습니다. (Fine-tuning)
# # 추후 전이학습을 진행할 때에는 아래 코드를 활용해주세요.

conv_base.trainable = False
# conv_base.summary() # Trainable params가 0으로 바뀌고 전체 Parameter가 Non-trainable로 세팅됩니다.
model = models.Sequential()

# There needs to be some pre-processing done beforehand 
# since ResNet50 requires images to have a minimum of 200×200 pixels while the CIFAR-10 dataset has images of 32×32 pixels.
# This can be done by either reshaping the images beforehand 
# or up-scaling to images before we input them into the convolutional layers. 

# model.add(layers.UpSampling2D((2,2)))
# model.add(layers.UpSampling2D((2,2)))
# model.add(layers.UpSampling2D((2,2)))
# 위 코드 대신 TF에 새로이 추가된 전처리 레이어를 활용할 수 있습니다 (https://www.tensorflow.org/tutorials/images/data_augmentation)
model.add(layers.experimental.preprocessing.Resizing(200, 200)) 

model.add(conv_base) # 사전 학습된 ResNet-50을 통해 Feature를 추출해냅니다.

model.add(layers.Flatten())

model.add(layers.Dense(128, activation=None))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.5))

model.add(layers.Dense(64, activation=None))
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.5))

model.add(layers.Dense(10, activation='softmax'))
model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=2e-5), 
              loss=keras.losses.sparse_categorical_crossentropy, 
              metrics=[keras.metrics.sparse_categorical_accuracy])

# Colab GPU 기준으로 1.5시간 가량 소요됩니다.
history = model.fit(train_images, train_labels, epochs=5, batch_size=20, validation_split=0.3)
result = model.evaluate(test_images, test_labels)

print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])
print()
print(model.summary())

acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']

x_len = np.arange(len(acc))

plt.plot(x_len, acc, marker='.', c='blue', label="Train-set Acc.")
plt.plot(x_len, val_acc, marker='.', c='red', label="Validation-set Acc.")

plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('Accuracy')
plt.show()

loss = history.history['loss']
val_loss = history.history['val_loss']

x_len = np.arange(len(acc))

plt.plot(x_len, loss, marker='.', c='blue', label="Train-set loss.")
plt.plot(x_len, val_loss, marker='.', c='red', label="Validation-set loss.")

plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('Cross-entropy')
plt.show()
model.save('transfer_resnet50.h5')
# del model
    
# model = tf.keras.models.load_model('transfer_resnet50.h5')
# predictions = model.predict(test_images)
# print(predictions)