How do I generate a class_labels.txt in Keras for usage in a CoreML model? - swift

I have been trying to create an IOS App using coreML, I have trained a convolutional neural network in Keras, when I use CoreMLTools to transform this model to a CoreML model it shows that the output is a multidimensional array, but I want it to be a class probability. How do I generate a .txt file with the class labels in Keras?
This is the code I use to generate a coreML model:
import coremltools
coreml_model = coremltools.converters.keras.convert(
"chars74kV3.0.h5", class_labels = "class_labels.txt", image_input_names= ['input'], input_names=['input'], image_scale=255.)
coreml_model.author = 'Thijs van der Heijden'
coreml_model.license = 'MIT'
coreml_model.description = 'A basic Deep Convolutional Neural Network to classify handwritten letters.'
coreml_model.input_description['input'] = 'A 64x64 pixel Image'
coreml_model.save('chars74k.mlmodel')

The class_labels.txt file should just be a plain text file with one label per line, in order of the classes in your training set. For example,
dog
cat
person
would be your label file for a three-class network where class 0 was "dog", class 1 was "cat", and class 2 was "person". If this is a public classification dataset, you should have that information with the dataset, and if it's your own you'll just have to create such a mapping file. You'd have to do this anyway to associate class numbers with values.

Related

Interclass and Intraclass classification structure of CNN

I am working on a inter-class and intra-class classification problem with one CNN such as first there is two classes Cat and Dog than in Cat there is a classification three different breeds of cats and in Dog there are 5 different breeds dogs.
I haven't tried the coding yet just working on feasibility if that works.
My question is what will be the feasible design for this kind of problem.
I am thinking to design for the training, first CNN-1 network that will differentiate cat and dog and gather the image data of all the training images. After the separation of cat and dog, CNN-2 and CNN-3 will train these images further for each breed of dog and cat. I am just not sure how the testing will work in this situation.
I have approached a similar problem previously in Python. Hopefully this is helpful and you can come up with an alternative implementation in Matlab if that is what you are using.
After all was said and done, I landed on a single model for all predictions. For your purpose you could have one binary output for dog vs. cat, another multi-class output for the dog breeds, and another multi-class output for the cat breeds.
Using Tensorflow, I created a mask for the irrelevant classes. For example, if the image was of a cat, then all of the dog breeds are irrelevant and they should not impact model training for that example. This required a customized TF Dataset (that converted 0's to -1 for the mask) and a customized loss function that returned 0 error when the mask was present for that example.
Finally for the training process. Specific to your question, you will have to create custom accuracy functions that can handle the mask values how you want them to, but otherwise this part of the process should be standard. It was best practice to evenly spread out the classes among the training data but they can all be trained together.
If you google "Multi-Task Training" you can find additional resources for this problem.
Here are some code snips if you are interested:
For the customize TF dataset that masked irrelevant labels...
# Replace 0's with -1 for mask when there aren't any labels
def produce_mask(features):
for filt, tensor in features.items():
if "target" in filt:
condition = tf.equal(tf.math.reduce_sum(tensor), 0)
features[filt] = tf.where(condition, tf.ones_like(tensor) * -1, tensor)
return features
def create_dataset(filepath, batch_size=10):
...
# **** This is where the mask was applied to the dataset
dataset = dataset.map(produce_mask, num_parallel_calls=cpu_count())
...
return parsed_features
Custom loss function. I was using binary-crossentropy because my problem was multi-label. You will likely want to adapt this to categorical-crossentropy.
# Custom loss function
def masked_binary_crossentropy(y_true, y_pred):
mask = backend.cast(backend.not_equal(y_true, -1), backend.floatx())
return backend.binary_crossentropy(y_true * mask, y_pred * mask)
Then for the custom accuracy metrics. I was using top-k accuracy, you may need to modify for your purposes, but this will give you the general idea. When comparing this to the loss function, instead of converting all to 0, which would over-inflate the accuracy, this function filters those values out entirely. That works because the outputs are measured individually, so each output (binary, cat breed, dog breed) would have a different accuracy measure filtered only to the relevant examples.
backend is keras backend.
def top_5_acc(y_true, y_pred, k=5):
mask = backend.cast(backend.not_equal(y_true, -1), tf.bool)
mask = tf.math.reduce_any(mask, axis=1)
masked_true = tf.boolean_mask(y_true, mask)
masked_pred = tf.boolean_mask(y_pred, mask)
return top_k_categorical_accuracy(masked_true, masked_pred, k)
Edit
No, in the scenario I described above there is only one model and it is trained with all of the data together. There are 3 outputs to the single model. The mask is a major part of this as it allows the network to only adjust weights that are relevant to the example. If the image was a cat, then the dog breed prediction does not result in loss.

How to Divide Drone Images dataset into Train & Test and Valid Parts for Faster R CNN in Matlab2018b

I have 297 Grayscale images and I would Like Divide Them into 3 parts (train-test and validation).
Ofcourse, I wrote some sample codes for example following codes from MathWorks (Object Detection Using Faster R-CNN Deep Learning)
% Split data into a training and test set.
idx = floor(0.6 * height(vehicleDataset));
trainingData = vehicleDataset(1:idx,:);
testData = vehicleDataset(idx:end,:);
But Matlab 2018a show the following error
Error:"Undefined function 'height' for input arguments of type
'struct'."
I would like to detect objects in images using "Faster R CNN" method and determine their locations in images.
Suppose your images are saved in the path "C:\Users\Student\Desktop\myImages"
First, create an imageDataStore object to manage a collection of image files.
datapath = "C:\Users\Student\Desktop\myImages";
imds = imageDatastore(datapath);%You may look at documentation for customizations.
[trainds,testds,valds] = splitEachLabel(imds,.6,.2);%Lets say 60% data for training, 20% for testing and 20% for validation
Now you have train data in the variable trainds and test data in the variable testds.
You can retrieve each images using readimage, say 5th image from train set as;
im = readimage(trainds,5);

How to combine 2 trained models in Keras

I want to to concatenate the last layer before the output of 2 trained models and have a new model that uses the merged layer to give predictions. below is the relevant parts of my code:
model1 = load_model("model1_location.model")
model2 = load_model("model1_location.model")
merged_model = Sequential(name='merged_model')
merged_model.add(merge([model1.layers[-1],model2.layers[-1]]))
merged_model.add(Dense(3, activation='softmax'))
The above code gives the following error:
ValueError: Layer merge_2 was called with an input that isn't a symbolic tensor. Received type: <class 'keras.layers.core.Dense'>.
What is the correct way to combine those models, Alternatively how do I get a symbolic tensor from a layer?
you need to get the output attribute like so:
merged_model.add(merge([model1.layers[-1].output, model2.layers[-1].output]))

Keras - use part of the input at later stage in sequential model

I'm training a CNN. My input is an image and a few metadata. I'd like to train a CNN that only looks at the image in the convolutional stages, and then uses the output of the convolutional stages and the metadata in the final dense layers.
metadata -----------------
|-> dense -> output
image -> Convolutions -
How can I do this with Keras? Can I feed input that has not a rectangular shape?
For instance if the image is (255, 255, 3) and the metadata (10) how would this work?
I've found this issue that seems related but I don't get how they split the input and merge the second part with the intermediate output later on.
You need to use the Functional API with a multi-input model.
An example could be:
from keras.layers import Input, Conv1D, Dense, concatenate
#Image data
conv_input = Input(shape=conv_input_shape)
conv_output = Conv1D(nfilters,kernel_shape)(conv_input)
#Metadata
metadata_input = Input(shape=metadata_shape)
#Merge and add dense layer
merge_layer = concatenate([metadata_input, conv_output])
main_output = Dense(dense_size)(merge_layer)
# Define model with two inputs
model = Model(inputs=[conv_input, metadata_input], outputs=[main_output])
Hope this helps!

How to clasify an unlabelled dataset with a newly trained NaiveBayes classifier in Weka

I have an unlabeled dataset that I want to classify with my newly trained classifier using NaiveBayes classification in Weka. So actually when in the Classify mode in weka if i give the option Supplied Test set, then it accepts the test set only if it is labelled and evaluates and gives the accuracy.
But what I want is to train it using a train.csv or train.arff file and then give it a new unseen and unlabelled test.csv or test.arff file and classify it and give it labels depending on classes in the training file. But if I provide an unlabelled file as test file to wweka it gives:
ERROR: Train and Test set not compatible
Sample format of my Train and test files are as below:
Train.csv file:
article story .......hockey class
1 0 ...... 0 politics
0 0 .......1 sports
.
.
.
.
. sports
and Test.csv file:
article story .......hockey class
0 1 ...... 0
1 0 .......1
.
.
.
.
.
So how do I classify an unlabelled dataset in Weka using NaiveBayes classifier??
It seems you are missing the class label. Weka requires training and test set to have the exact same attributes in the same order. Now there are two cases:
You know the classes of your test set
The performance is calculated by comparing the actual class labels with the predicted ones. You need to supply the class labels in your test set like you did in your training set.
You DON'T know the classes of your test set
To calculate a performance, Weka needs to compare the predicted classes with the actual classes. If you don't have the actual classes, you cannot calculate the performance. You can only predict classes.
You have to add a class label with missing values for your test instances if you just want prediction.
Even if your test set is labelled, Weka will not see it at first stage. It will use the classifier you developed with training data and then will apply the classifier on the test set you supply. The classifier then predicts each instance class and Weka then keeps track of a correct or incorrect classification. So, what you are doing here is exactly what you are trying to achieve. The error is telling that the training and test sets are not compatible because I believe you have removed the "class" label from the test set. Don't worry. Keep it as it is and the accuracy you are getting from Weka is the actual performance of the classifier. Hope that helps.
you cant leave it all empty, you need to set at least one each class label on the class field (as some kind of "clue" for the weka)
article story .......hockey class
0 1 ...... 0 politics
1 0 .......1 sport
1 1 .......1 ?
1 1 .......1 ?
the two first row will provide weka an example of the prediction class. Then you can predict as much as instance with no class (?) using your trained model