2

How do i save an image classification model as .pb file and its label.txt by using Keras And Tensorflow in order to use this two files on android.i have a code for beginning and the code is only save .pb file but not label.txt

I have already done the hole thing but not label.txt here is the code

import pandas as pd 
import numpy as np
import warnings
warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import keras
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout,Activation
from keras.optimizers import Adam
from keras.callbacks import TensorBoard
from keras.layers.core import Lambda
from keras.optimizers import Adam
import keras 
import keras.backend as k
import tensorflow as tf
from tensorflow.python.framework import graph_util
print(keras.__version__)
print(tf.__version__)
import os
train_df = pd.read_csv('fashionmnist/fashion-mnist_train.csv',sep=',')
test_df = pd.read_csv('fashionmnist/fashion-mnist_test.csv',sep=',')


train_data =np.array(train_df,dtype = 'float32')
test_data = np.array(test_df,dtype = 'float32')
x_train = train_data[:,1:]/255
y_train = train_data[:,0]
x_test = train_data[:,1:]/255
y_test = train_data[:,0]
x_train,x_validate,y_train,y_validate=train_test_split(x_train,y_train,test_size = 0.2,random_state = 12345)
image = x_train[50,:].reshape((28,28))
plt.imshow(image)
plt.show()

image_rows =28
image_cols= 28
batch_size =100
image_shape =(image_rows,image_cols,1)



x_train = x_train.reshape(x_train.shape[0],*image_shape)
x_test = x_test.reshape(x_test.shape[0],*image_shape)
x_validate = x_validate.reshape(x_validate.shape[0],*image_shape)


def build_network(is_training=True):
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=image_shape,  padding='same',name="1_conv"))
    model.add(Activation('relu'))
    model.add(Conv2D(32, (3, 3), padding='same',name="2_conv"))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2),name="1_pool"))

    model.add(Conv2D(64, (3, 3), padding='same',name="3_conv"))
    model.add(Activation('relu'))
    model.add(Conv2D(64,(3, 3), padding='same',name="4_conv"))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2),name="2_pool"))

    model.add(Conv2D(128,(3, 3),padding='same',name="5_conv"))
    model.add(Activation('relu'))
    model.add(Conv2D(128, (3, 3),padding='same',name="6_conv"))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2),name="3_pool"))

    model.add(Conv2D(256,(3, 3), padding='same',name="7_conv"))
    model.add(Activation('relu'))
    model.add(Conv2D(256, (3, 3), padding='same',name="8_conv"))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2),name="4_pool"))

    model.add(Flatten())
    model.add(Dense(512,name="fc_1"))
    model.add(Activation('relu'))


    if (is_training):
        #model.add(Dense(512, activation='relu'))
        #model.add(Dropout(0.5, name="drop_1"))
        model.add(Lambda(lambda x:k.dropout(x,level=0.5),name="drop_1"))



    model.add(Dense(10,name="fc_2"))
    model.add(Activation('softmax',name="class_result"))
    #model.summary()
    return model


    tf.reset_default_graph()
sess = tf.Session()
k.set_session(sess)
model=build_network()

history_dict = {}
model.compile(loss='sparse_categorical_crossentropy',optimizer = Adam(),metrics=['accuracy'])




class TFCheckpointCallback(keras.callbacks.Callback):
    def __init__(self,saver,sess):
        self.saver=saver
        self.sess=sess

    def on_epoch_end(self,epoch,log=None):
        self.saver.save(self.sess,'fMnist/ckpt',global_step=epoch)


tf_saver= tf.train.Saver(max_to_keep=2)
checkpoint_callback= TFCheckpointCallback(tf_saver,sess)
%time
tf_graph=sess.graph
tf.train.write_graph(tf_graph.as_graph_def(),'freeze','fm_graph.pdtxt',as_text=True)
%time
history = model.fit(x_train,
                    y_train,
                    batch_size=batch_size,
                    epochs=50,
                    callbacks=[checkpoint_callback],
                    shuffle=True,
                    verbose=1,
                    validation_data=(x_validate,y_validate)
                   )

sess.close()


model_folder='fMnist/'
def prepare_graph_for_freezing(model_folder):
    model=build_network(is_training=False)
    checkpoint=tf.train.get_checkpoint_state(model_folder)
    input_checkpoint=checkpoint.model_checkpoint_path
    saver=tf.train.Saver()
    with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:
        k.set_session(sess)
        saver.restore(sess,input_checkpoint)
        tf.gfile.MakeDirs(model_folder+'freeze')
        saver.save(sess,model_folder + 'freeze/ckpt',global_step=0)


def freeze_graph(model_folder):
    checkpoint =tf.train.get_checkpoint_state(model_folder)
    print(model_folder+'freeze/')
    input_checkpoint = checkpoint.model_checkpoint_path
    absolut_model_folder="/".join(input_checkpoint.split('/')[:-1])
    output_graph=absolut_model_folder + "/fm_freazen_model.pb"
    print(output_graph)
    output_node_name = "class_result/Softmax"
    clear_devices = True
    new_saver=  tf.train.import_meta_graph(input_checkpoint + '.meta',clear_devices=clear_devices)

    graph = tf.get_default_graph()
    input_graph_def = graph.as_graph_def()


    with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess2:
        print(input_checkpoint)
        new_saver.restore(sess2,input_checkpoint)

        output_graph_def=graph_util.convert_variables_to_constants(
        sess2,
        input_graph_def,
        output_node_name.split(","))

        with tf.gfile.GFile(output_graph,"wb") as f:
            f.write(output_graph_def.SerializeToString())
        print("%d ops in the final graph."% len(output_graph_def.node))
tf.reset_default_graph()
prepare_graph_for_freezing("freeze/")
freeze_graph("freeze/")

I got checkpoints and .pb file

but I don't have label.txt file

haptomee
  • 59
  • 10

1 Answers1

1

As far as Image Classification is concerned on Android, I recommend you to use TensorFlow Lite instead of using the protocol buffers directly.

First you need to convert the Keras model ( .h5 ) to a TensorFlow Lite model (.tflite ).

converter = tf.lite.TFLiteConverter.from_keras_model_file( 'model.h5' )
tflite_buffer = converter.convert()
open( 'tflite_model.tflite' , 'wb' ).write( tflite_buffer )

The model is ready to be loaded on Android. To check the input and output dtype and shape, refer this file.

Now on Android, first add the TensorFlow Lite dependency in the build.gradle.

dependencies {
...
   implementation 'org.tensorflow:tensorflow-lite:1.13.1'
...
}

Now we load the model as a MappedByteBuffer object.

@Throws(IOException::class)

private fun loadModelFile(): MappedByteBuffer {
    val MODEL_ASSETS_PATH = "model.tflite"
    val assetFileDescriptor = assets.openFd(MODEL_ASSETS_PATH)
    val fileInputStream = FileInputStream(assetFileDescriptor.getFileDescriptor())
    val fileChannel = fileInputStream.getChannel()
    val startoffset = assetFileDescriptor.getStartOffset()
    val declaredLength = assetFileDescriptor.getDeclaredLength()
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startoffset, declaredLength)
}

Using the interpreter.run() method, we produce a inference given some input. See this file. This file contains methods for resizing the Bitmap using Bitmap.createScaledBitmap method and also converting it to a float[][]

val interpreter = Interpreter( loadModelFile() )
val inputs : Array<FloatArray> = arrayOf( some_input_image. )
val outputs : Array<FloatArray> = arrayOf( floatArrayOf( 0.0f , 0.0f ) )
interpreter.run( inputs , outputs )
val output = outputs[0]

That's all. TFLite is much faster than TensorFlow Mobile.

Note: TF Lite supports only a few number of ops. Since, ops related with CNNs are fully supported, we can use TFLite for image classification in Android and iOS too.

Tips:

  1. For a reduced size of the .tflite file, use the post_training_quantize flag while converting the model in Python.

    converter = tf.lite.TFLiteConverter.from_keras_model_file( 'model.h5' )
    converter.post_training_quantize = True
    tflite_buffer = converter.convert()
    open( 'tflite_model.tflite' , 'wb' ).write( tflite_buffer )
    
  2. Also, try using the Firebase MLKit for hosting custom models in Firebase.

  3. I have created a number of apps which classify images and text using TF.

https://github.com/shubham0204/Spam_Classification_Android_Demo

https://github.com/shubham0204/Skinly_for_Melanoma

Shubham Panchal
  • 4,061
  • 2
  • 11
  • 36
  • For labels.txt, you can place the file in the assets folder of the app and read it. – Shubham Panchal Jun 05 '19 at 02:59
  • sir thank you for your best explanation but the point is how do i get label.txt file (how do i write that text file) for that model .I have 178 class and I train the network with those 178 folders image data(class) each of therm are labeled properly and each class's have 5000 images. – haptomee Jun 05 '19 at 09:35
  • @haptomee Have you been able to find a way on how to get the label.txt, I'm finding it really hard to get the label.txt. – Ibrahim Dec 25 '19 at 12:17