'Keras.NET usabilty

yI would like to use CNN in my .NET application for image classification. I found this perfect example on SciSharp github:https://github.com/SciSharp/SciSharp-Stack-Examples/blob/master/src/TensorFlowNET.Examples/ImageProcessing/ImageClassificationKeras.cs I created simple NET6.0 console application and put example into it but have a lot of issues. Here is exact implementation of the code:

using System.Collections.Generic;
using Tensorflow;
using Tensorflow.Keras;
using static Tensorflow.Binding;
using static Tensorflow.KerasApi;
using Tensorflow.Keras.Utils;
using System.IO;
using Tensorflow.Keras.Engine;

namespace TensorFlowNET.Examples
{
/// <summary>
/// This tutorial shows how to classify images of flowers.
/// https://www.tensorflow.org/tutorials/images/classification
/// </summary>
public class ImageClassificationKeras
{
    int batch_size = 32;
    int epochs = 3;
    Shape img_dim = (180, 180);
    IDatasetV2 train_ds, val_ds;
    Model model;

    public bool Run()
    {
        tf.enable_eager_execution();

        PrepareData();
        BuildModel();
        Train();
        model.save("D:\\test");
        return true;
    }

    public void BuildModel()
    {
        int num_classes = 5;
        // var normalization_layer = tf.keras.layers.Rescaling(1.0f / 255);
        var layers = keras.layers;
        model = keras.Sequential(new List<ILayer>
        {
            layers.Rescaling(1.0f / 255, input_shape: (img_dim.dims[0], img_dim.dims[1], 3)),
            layers.Conv2D(16, 3, padding: "same", activation: keras.activations.Relu),
            layers.MaxPooling2D(),
            /*layers.Conv2D(32, 3, padding: "same", activation: "relu"),
            layers.MaxPooling2D(),
            layers.Conv2D(64, 3, padding: "same", activation: "relu"),
            layers.MaxPooling2D(),*/
            layers.Flatten(),
            layers.Dense(128, activation: keras.activations.Relu),
            layers.Dense(num_classes)
        });

        model.compile(optimizer: keras.optimizers.Adam(),
            loss: keras.losses.SparseCategoricalCrossentropy(from_logits: true),
            metrics: new[] { "accuracy" });

        model.summary();
    }

    public void Train()
    {
        model.fit(train_ds, validation_data: val_ds, epochs: epochs);
    }

    public void PrepareData()
    {
        string fileName = "flower_photos.tgz";
        string url = $"https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz";
        string data_dir = Path.Combine(Path.GetTempPath(), "flower_photos");
        Web.Download(url, data_dir, fileName);
        Compress.ExtractTGZ(Path.Join(data_dir, fileName), data_dir);
        data_dir = Path.Combine(data_dir, "flower_photos");

        train_ds = keras.preprocessing.image_dataset_from_directory(data_dir,
            validation_split: 0.2f,
            subset: "training",
            seed: 123,
            image_size: img_dim,
            batch_size: batch_size);

        val_ds = keras.preprocessing.image_dataset_from_directory(data_dir,
            validation_split: 0.2f,
            subset: "validation",
            seed: 123,
            image_size: img_dim,
            batch_size: batch_size);

        train_ds = train_ds.shuffle(1000).prefetch(buffer_size: -1);
        val_ds = val_ds.prefetch(buffer_size: -1);
    }
}

}

  1. The first issue occures inside PrepareData(). Variables train_ds.class_names and val_ds.class_names should contain string array with subdirectories names, but they stay null all the time.

  2. training does not improve accuracy. Here you can see console output of the training procedure begining: [enter image description here][1]. Accuracy column finishes the training with value 0.1757, which is almost the same like at the training start.

  3. save method on model does not store anything. The parameter is a path into existing empty directory;

It looks very strange, what Am I doing wrong?

Thank you



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source