CIFAR 10 RGB with selected finetuning

Using RGB improves accuracy

In [1]:
import tensorflow as tf
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import glob
from pathlib import Path
%matplotlib inline

Data pipeline

In [2]:
file_path = "datasets/cifar-10-batches-bin/data_batch_*"
train_bins = glob.glob(file_path)


def cifar_dataset(files_list:list) -> tf.data.Dataset:

    data = tf.data.FixedLengthRecordDataset(files_list,1+3*32*32)
    data = data.map(lambda x: tf.decode_raw(x,tf.uint8),num_parallel_calls=4)
    data = data.map(lambda x: (x[1:],tf.expand_dims(x[0],0)),num_parallel_calls=4) 
    data = data.map(lambda x,y: (tf.reshape(x,(3,32,32)),y),num_parallel_calls=4)
    data = data.map(lambda x,y: (tf.transpose(x,(1,2,0)),y),num_parallel_calls=4)
    data = data.map(lambda x,y: (tf.image.convert_image_dtype(x,tf.float32),y),num_parallel_calls=4)
        
    return data
In [3]:
with tf.device('/cpu:0'):
    train_dataset = cifar_dataset(train_bins)
    train_dataset = train_dataset.shuffle(20000)
    train_dataset = train_dataset.repeat(40)
    train_dataset = train_dataset.batch(10)
    train_dataset = train_dataset.prefetch(2)

train_iterator = train_dataset.make_one_shot_iterator()
In [4]:
train_dataset.output_shapes, train_dataset.output_types
Out[4]:
((TensorShape([Dimension(None), Dimension(32), Dimension(32), Dimension(3)]),
  TensorShape([Dimension(None), Dimension(1)])),
 (tf.float32, tf.uint8))

Check input (Restart kernel and dont call this check before training)

In [5]:
im,l = train_iterator.get_next()

with tf.Session() as sess:
    imr,lr = sess.run([im,l])

print(imr.shape)
print(lr.transpose())
plt.imshow(imr[0])
(10, 32, 32, 3)
[[1 5 3 3 5 5 7 0 8 1]]
Out[5]:
<matplotlib.image.AxesImage at 0x7fb654060940>

Store the graph tensors

In [5]:
saver = tf.train.import_meta_graph('models/WT_TRANSFER/wt_transfer_eg.chpt.meta')
In [6]:
features = tf.get_collection('features')[0]
handle = tf.get_collection('handle')[0]
features,handle
Out[6]:
(<tf.Tensor 'Dense_84/Tanh:0' shape=(?, 84) dtype=float32>,
 <tf.Tensor 'Placeholder:0' shape=() dtype=string>)

Check loading

NOTE: We do not have to restore model here, Since we had encoded the weights in the initializer

In [7]:
with tf.Session() as sess:
    #We do not have to restore model here, Since we had encoded the weights in the initializer
    sess.run(tf.global_variables_initializer())
    #Check if the right weights have been loaded
    print(sess.run(tf.get_collection('variables',scope='Conv2/bias')))
    
    hdl = sess.run(train_iterator.string_handle())
    out = sess.run(features,{handle:hdl})
out.shape
[array([-0.14805889,  0.6004731 ,  0.14357984, -0.3337978 , -0.48210445,
       -0.07447348, -0.3848596 , -0.07660984,  0.13621555,  0.2962938 ,
       -0.15078765, -0.14430566,  0.3739807 , -0.3766448 ,  0.60352474,
        0.4924152 ], dtype=float32)]
Out[7]:
(10, 84)

Classifier

In [7]:
classifier = tf.layers.dense(features,10,name="Dense_10")
In [9]:
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(tf.get_collection('variables',scope='Conv2/bias')))
    hdl = sess.run(train_iterator.string_handle())
    print(sess.run(classifier,{handle:hdl}))
[array([-0.14805889,  0.6004731 ,  0.14357984, -0.3337978 , -0.48210445,
       -0.07447348, -0.3848596 , -0.07660984,  0.13621555,  0.2962938 ,
       -0.15078765, -0.14430566,  0.3739807 , -0.3766448 ,  0.60352474,
        0.4924152 ], dtype=float32)]
[[ 2.3488069e-01 -8.2443607e-01 -4.0262529e-01  5.6812119e-01
   1.6834317e+00 -7.4378145e-01  1.4596581e+00  5.8810014e-01
   2.1020987e+00  3.2810912e-01]
 [ 1.6914421e-01 -1.1726081e+00  9.4728291e-02  2.2983912e-01
   2.0852137e+00 -9.8648518e-01  1.5116951e+00  3.2904130e-01
   1.7828474e+00  1.8165329e-01]
 [-1.1638886e-01 -1.3413529e+00  9.3027622e-02  4.1308689e-01
   1.9416277e+00 -8.5523140e-01  1.5127072e+00  3.3934495e-01
   1.4215240e+00  1.8625635e-01]
 [-2.6333117e-01 -1.1884085e+00 -5.8649355e-01  8.7990516e-01
   1.4320683e+00 -6.4558953e-01  1.2166436e+00 -7.1704999e-02
   1.9696487e+00  2.6369381e-01]
 [-6.6933721e-02 -1.8721217e+00 -1.9014776e-03  5.4056621e-01
   1.9147545e+00 -9.8508412e-01  1.6012607e+00 -2.4349251e-01
   1.5207939e+00  3.5045677e-01]
 [-3.1070644e-01 -1.3888136e+00 -3.8346177e-01  8.7691164e-01
   1.6346986e+00 -7.6494324e-01  1.3774996e+00 -3.9963645e-01
   1.9500520e+00  2.2537968e-01]
 [-3.3774745e-01 -1.2526560e+00 -6.0022885e-01  8.2213527e-01
   1.1056736e+00 -2.7196676e-01  8.4350944e-01 -5.3740233e-01
   2.1447763e+00  2.9909003e-01]
 [ 5.5711925e-02 -1.5961704e+00 -2.0618486e-01  5.0729501e-01
   1.8596609e+00 -9.2887700e-01  1.6632142e+00  5.4667443e-02
   1.8389838e+00  4.3509752e-01]
 [-3.6952579e-01 -1.2690077e+00 -9.9337101e-03  5.5675322e-01
   1.9628670e+00 -7.3801631e-01  1.4438782e+00 -4.2300537e-02
   1.8521742e+00  6.2656033e-01]
 [-1.6246265e-01 -9.2887509e-01 -5.5603337e-01  9.6378142e-01
   1.8522435e-01  2.9085901e-01  1.3264940e+00 -1.1849854e+00
   2.9401822e+00  7.2699666e-02]]

Loss and optimizer

In [8]:
label = tf.get_collection('target')[0]

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=tf.one_hot(label,10),logits=classifier))
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

Train

IMPORTANT: Use a new saver and dont mix up with meta graph saver. It wont contain classifier and other tensors created in this graph

In [9]:
!rm models/CIFAR10_rbg/*
In [10]:
#We need a new saver as we have created new variables
saver = tf.train.Saver()

import time

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    hdl = sess.run(train_iterator.string_handle())
    
    start = time.time()
    try:
        i = 1
        tmp = []
        while True:
            i = i+1
            l,_ = sess.run([loss,train],{handle:hdl})
            tmp.append(l)
            if i%5000 == 0:
                avg_loss = np.array(tmp).mean()
                print("Batch: ",i,avg_loss)
                tmp = []
                
    except tf.errors.OutOfRangeError:
        pass
    
    end = time.time()
    elapsed = end-start
    print("Elapsed time : ", elapsed, " s")
    saver.save(sess,'models/CIFAR10_rbg/cifar_model.ckpt')
    
Batch:  5000 1.7460293
Batch:  10000 1.4253856
Batch:  15000 1.318884
Batch:  20000 1.2503136
Batch:  25000 1.2009004
Batch:  30000 1.1596191
Batch:  35000 1.1234559
Batch:  40000 1.0952739
Batch:  45000 1.0666145
Batch:  50000 1.0425783
Batch:  55000 1.0202376
Batch:  60000 0.99888545
Batch:  65000 0.9792681
Batch:  70000 0.95830506
Batch:  75000 0.9405678
Batch:  80000 0.9227281
Batch:  85000 0.9052548
Batch:  90000 0.8875396
Batch:  95000 0.8703296
Batch:  100000 0.85653096
Batch:  105000 0.83980936
Batch:  110000 0.82699376
Batch:  115000 0.81140316
Batch:  120000 0.79666454
Batch:  125000 0.78439045
Batch:  130000 0.769012
Batch:  135000 0.75476575
Batch:  140000 0.741301
Batch:  145000 0.7299393
Batch:  150000 0.7169388
Batch:  155000 0.7016897
Batch:  160000 0.6903341
Batch:  165000 0.67748696
Batch:  170000 0.66823786
Batch:  175000 0.657157
Batch:  180000 0.64173466
Batch:  185000 0.6303167
Batch:  190000 0.6202162
Batch:  195000 0.60806924
Batch:  200000 0.6003759
Elapsed time :  267.226021528244  s

Evaluation

In [11]:
with tf.device('/cpu:0'):
    test_dataset = cifar_dataset(['datasets/cifar-10-batches-bin/test_batch.bin'])
    test_dataset = test_dataset.batch(10)
    test_dataset = test_dataset.prefetch(2)
    
test_iterator = test_dataset.make_one_shot_iterator()
In [12]:
def get_accuracy(predict:'eg: [2,4,1,...]',true: 'eg: [2,4,1,...]') -> int:
    correct_pred = tf.equal(predict,true)
    #We have to cast [True,False,True,...] --> [1,0,1...]
    acc = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
    return acc



with tf.Session() as sess:
    saver.restore(sess,'models/CIFAR10_rbg/cifar_model.ckpt')
    hdl = sess.run(test_iterator.string_handle())
    
    
    #IMPORTANT:
    #Dont place this code inside the loop! This will slow down everything
    acc = get_accuracy(tf.argmax(classifier,axis=1),tf.transpose(tf.argmax(tf.one_hot(label,10),axis=2)))
    
    try:
        i = 0
        acc_list = []
        while True:
            i = i+1
            a = sess.run(acc,{handle:hdl})
            acc_list.append(a)
            if i%100 == 0:
                print(i, "Mean Acc : ", np.array(acc_list).mean())
                acc_list = []
                           
    except tf.errors.OutOfRangeError:
        pass 
INFO:tensorflow:Restoring parameters from models/CIFAR10_rbg/cifar_model.ckpt
100 Mean Acc :  0.605
200 Mean Acc :  0.58
300 Mean Acc :  0.605
400 Mean Acc :  0.59799993
500 Mean Acc :  0.59400004
600 Mean Acc :  0.59199995
700 Mean Acc :  0.571
800 Mean Acc :  0.59
900 Mean Acc :  0.5709999
1000 Mean Acc :  0.582

Serving

In [13]:
Image.open("pics/cifar22.png") #ship - 8
Out[13]:
In [14]:
Image.open("pics/cifar3.png") #automobile - 1
Out[14]:
In [15]:
Image.open("pics/cifar24.png") #automobile - 1
Out[15]:
In [16]:
test_ims_paths = tf.placeholder(tf.string)
serving_data = tf.data.Dataset.from_tensor_slices(test_ims_paths)

def read_img(filepath):
    image_string = tf.read_file(filepath)
    image = tf.image.decode_png(image_string)
    image = tf.image.convert_image_dtype(image,tf.float32)
    #image = tf.image.resize_images(image,(32,32))
    return image
    
serving_data = serving_data.map(lambda x: read_img(x))
serving_data = serving_data.map(lambda x: (x,tf.expand_dims(tf.cast(0,tf.uint8),axis=0)))#To match with iterator
serving_data = serving_data.batch(5)

NOTICE: The tensor shape None matches with the original 32,32

In [17]:
serving_data.output_shapes,serving_data.output_types
Out[17]:
((TensorShape([Dimension(None), Dimension(None), Dimension(None), Dimension(None)]),
  TensorShape([Dimension(None), Dimension(1)])),
 (tf.float32, tf.uint8))
In [18]:
serving_iterator = serving_data.make_initializable_iterator()
In [20]:
with tf.Session() as sess:
    saver.restore(sess,'models/CIFAR10_rbg/cifar_model.ckpt')

    ims_paths = ["pics/cifar22.png","pics/cifar3.png","pics/cifar24.png"]
    hdl,_ = sess.run([serving_iterator.string_handle(),serving_iterator.initializer],{test_ims_paths:ims_paths})
    predictions = tf.argmax(classifier,axis=1)
    out = sess.run(predictions,{handle:hdl})
    print(out) 
INFO:tensorflow:Restoring parameters from models/CIFAR10_rbg/cifar_model.ckpt
[8 0 1]

Summary

1) Restore checkpoint only when you want to use weights in the checkpoint. In this example, we had included the weights as a part of initializers. Hence we did not have to restore chpt before training!

2) Create a new saver to save trained model and dont mess up with the meta graph import saver

3) Do not call the get_next of child iterators when using feedable iterators

4) Using RGB imporves Accuracy