Wednesday, May 12, 2021

 Flowers Dataset - using image_dataset_from_directory

#flowers dataset with some data augmentation


#not so good model with accuracy (both training and validation ) in the range of 
#appox 0.5

# rm -r "/content/flowers"

import tensorflow as tf 
import tensorflow.keras
import os 
import pathlib 
import numpy as np 
import matplotlib.pyplot as plt 


if ( os.path.exists("/content/flowers") == False) : 
  os.mkdir("/content/flowers")
url  = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
flfile = tf.keras.utils.get_file("/content/flowers/flower_photos.tgz" , origin = url, extract  = True)
#NOTE: The tensorflow tutorial currently available at https://www.tensorflow.org/tutorials/images/classification
#(as in 11-May-2021) uses the last parameter as untar = True instead of extract = True above. 
#but untar is deprecated and the documentation recommends to use extract instead of untar.
#further using untat=True causes errorneous behavior also , firstly it doesnt extract the file, secondly
#it saves the ".tgz" file by an extension ".tar.gz" to the file name 
# thus making it "flower_photos.tgz.tar.gz".
print(flfile)
flfile = pathlib.Path(flfile)
print(flfile)

#the following is not required if extract=True is used in get_file
import tarfile 
tfile = tarfile.open(flfile)
tfile.extractall("/content/flowers")
tfile.close()

batch_size = 32 
epochs = 5


train_ds  = tf.keras.preprocessing.image_dataset_from_directory(
    "/content/flowers/flower_photos",
    image_size = ( 180180),
    batch_size = batch_size, 
    subset = "training",
    seed = 123,
    validation_split = 0.2
)


test_ds  = tf.keras.preprocessing.image_dataset_from_directory(
    "/content/flowers/flower_photos",
    image_size = ( 180180),
    batch_size = batch_size, 
    subset = "validation",
    seed = 123,
    validation_split = 0.2
)


data_aug = tf.keras.models.Sequential([
  tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal" , input_shape = (180,180,3)),
  tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
  tf.keras.layers.experimental.preprocessing.RandomZoom(0.2)
])


model = tf.keras.models.Sequential([
    data_aug, 
    tf.keras.layers.Conv2D(163, activation = "relu"),
    #tf.keras.layers.Conv2D(16, 3, activation = "relu" , input_shape = (180,180,3)), 
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(323, activation = "relu"), 
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(643, activation = "relu"), 
    tf.keras.layers.MaxPooling2D(),        
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Flatten(), 
    tf.keras.layers.Dense(512, activation = "relu"),
    tf.keras.layers.Dense(5, activation = "softmax")
])



model.compile(
    optimizer = tf.keras.optimizers.Adam(),
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True), 
    metrics = ["accuracy"]
)

history = model.fit(
    train_ds, 
    validation_data = test_ds, epochs = epochs
)

#Plot the loss and accuracy
plt.figure(figsize = (8,8))

plt.subplot(1,2,1)
plt.plot(range(epochs) , history.history["accuracy"] , "r" , label = "Training Accuracy")
plt.plot(range(epochs) , history.history["val_accuracy"] , "b" , label = "Validation Accuracy")
plt.legend(loc = "upper left")
plt.title("Accuracy")


plt.subplot(1,2,2)
plt.plot(range(epochs) , history.history["loss"] , "r" , label = "Training Loss")
plt.plot(range(epochs) , history.history["val_loss"] , "b" , label = "Validation Loss")
plt.legend(loc = "upper right")
plt.title("Loss")

plt.show()
#Plot the loss and accuracy


#NOTE : Images CANNOT be read like img = test_ds.take(1)[0][0]
#you must use a loop with test_ds.take(x) for that

#prediction on images using the dataset
correct = 0 
incorrect = 0 
i = 0 
images= test_ds.take(1)
plt.figure(figsize=(10,10))
for images, labels in test_ds.take(1):
  print(images.shape)
  for i in range(25):
    ax = plt.subplot(55, i + 1)

    plt.imshow(images[i].numpy().astype("uint8"))
    plt.xticks([])
    plt.yticks([])
    img_arr = tf.keras.preprocessing.image.img_to_array(images[i].numpy().astype("uint8"))
    img_arr = tf.expand_dims(img_arr,0)
    predictions = model.predict(img_arr)
    
    plt.xlabel("P={};A={}".format(np.argmax(predictions[0]) ,labels[i]))
    if (np.argmax(predictions[0]) == labels[i] ) : 
      correct += 1 
    else : 
      incorrect += 1 
    #plt.axis("off")
print ( "correct = {} ; incorrect = {}".format(correct, incorrect))    
#prediction on images using the dataset



#prediction on images by directly reading images from storage
correct = 0 
incorrect = 0 
i = 0 
tulips = os.listdir("/content/flowers/flower_photos/tulips")
tulips_label = 4  #this you wil have to infer from somewhere because labels are not available to you 
                  #when you are directly reading from disk. Mostly the labels are in the order of 
                  #subdirectories, starting with 0. But to confirm, you can plot a few figures using dataset
                  #and infer the label 
plt.figure(figsize=(10,10))
for i in range(25) : 
  img_path = "/content/flowers/flower_photos/tulips/" + tulips[i]

  img = tf.keras.preprocessing.image.load_img(img_path, target_size=(180,180))
  plt.subplot(5,5,i + 1)
  plt.xticks([])
  plt.yticks([])
  plt.imshow(img)
  img_arr = tf.keras.preprocessing.image.img_to_array(img)
  img_arr = tf.expand_dims(img_arr, 0)
  predictions = model.predict(img_arr)
  plt.xlabel("P={};A={}".format(np.argmax(predictions[0]) ,tulips_label))
  if (np.argmax(predictions[0]) == tulips_label) : 
    correct += 1 
  else : 
    incorrect += 1   

print ( "correct = {} ; incorrect = {}".format(correct, incorrect))      
#prediction on images by directly reading images from storage


No comments:

Post a Comment

 using Microsoft.AspNetCore.Mvc; using System.Xml.Linq; using System.Xml.XPath; //<table class="common-table medium js-table js-stre...