Murat ERDEM - Personal Research Blog




TensorFlow Model Training and Object Recognition With Flutter

October 24, 2020

Bu yazımızda flutter tflite paketini kullanarak resimler üzerinde nesne tanıma yapacak ve bu çalışmada kullanılan modelleri kendi istediğimiz şekilde nasıl eğitebileceğimize değineceğiz.

Yapay zeka konusunda çok fazla zaman geçirmiş birisi değilim ancak siber güvenlik alanında çalışmaya başlamadan önce bir süre makine öğrenmesi, görüntü işleme, model eğitme, GANs gibi konularda küçük çalışmalarım olmuştu. Bu yazıda ise o günlerden edindiğim tecrübeler ve son zamanlarda sıklıkla karşılaştığım tflite ile flutter üzerinde yapılan projeleri incelediğimde ve konu ile ilgili yaptığım araştırmalarda elde ettiğim bilgileri paylaşacağım.

Projenin son halini github repomda paylaşacağım buradan elde edebilirsiniz

Model Eğitmek

Öncelikle bir görüntüdeki nesneleri tanıyabilmek için eğitilmiş bir modele ihtiyacımız vardır. Hazır modelleri burada indirebilirsiniz yada kendi modelinizi eğitmek için buradan repoyu indirebilirsiniz. İndirme işleminden sonra gerekli kurulumları yapmak gerekiyor bunu aşağıdaki komut ile yapabilirsiniz.

       
    
        pip3 install -r requirements.txt
    

Burada repo içerisini incelersek data klasörünü görebilirsiniz burada bizim modeli eğiteceğimiz veriler tutulmaktadır. Bu dizin içerisindeki raw klasörüne yüksek çözünürlükteki resimleri atmamız gerekmekte. Örnek olarak resimlerdeki yüzleri tanıyan bir model eğitmek istersek içerisinde insan yüzlerinin olduğu resimleri buraya atmalıyız. Daha sonra bu resimleri yeniden boyutlandırmamız gerekmekte. Bu modelin daha kolay eğitilmesine yardımcı olacaktır. 800 x 600 piksel boyutunda yüksek çözünürlükte ve jpg formatında bu resimleri yeniden düzenleyerek aynı dizindeki image/train dizinine kayıt ediyoruz. Images altında bulunan train dizini modelimizin öğrenme sırasında kullanacağı data setlerin bulunduğu dizindir, test klasörü ise model eğitildikten sonra doğruluk oranı için kendini test edeceği dizindir. Örnek olarak 1000 adet resim varsa elimizde bunun 200 kadarını test dizinine kalanlarını da train dizinine koyabiliriz. Eğer model eğitildikten sonra doğruluk oranı istenilenden düşük ise veri sayısını arttırmak doğruluk oranını yükseltecektir. Bu resimlerin üzerindeki yüzlerin olduğu kısımları eğitime başlamadan önce etiketlememiz gerekmekte. Bunun için LabelImg tool kullanılabilir.

Modelimizin Eğitilmesi kısmında ise ciddi bir donanım gerekmekte genel olarak daha hızlı işlem yapabildiği için GPU kullanılarak eğitilmektedir. Ancak google tarafından sunulan google colab hizmeti ile kendi sisteminizi meşgul etmek yerine google sunucuları üzerinde modelinizi eğitebilirsiniz. Bunuda github yada drive üzerine modelinizi ve data setlerinizi yükleyerek yapabilirsiniz. Bunun nasıl yapıldığı ile ilgili detaylı bilgiye buradan ulaşabilirsiniz.

Model eğitmek genelde uzun bir işlemdir yapay zeka ile ilgilenen arkadaşlarım uyumadan önce eğitimi başlatıp uyanınca sonuçlarına bakıyorlar size de bu yöntemi tavsiye edebilirim.

Tflite Model Elde Etmek

Modelimizi çalıştırdıktan sonra resimler üzerinde bazı algoritmalar uygulayarak öğrenmesini tamamlayacaktır. İstenilen seviyede bir doğruluk oranına sahipse bunu mobil uygulamalarda kullanabilmek için tflite modeline dönüştürmemiz gerekmekte bunun bir kaç farklı yolu vardır. bunlardan ilki aşağıdaki komutları sırası ile çalıştırmaktır.

       
    
        !python /content/models/research/object_detection/export_tflite_ssd_graph.py — pipeline_config_path {pipeline_fname} — trained_checkpoint_prefix “/content/models/research/training/model.ckpt-1000” — output_directory “/content/object_detection_demo/” — add_postprocessing_op True — max_detections 10
    

Bu komut modelimizi tflite modeline dönüştürecektir. Daha sonra aşağıdaki komut ile TACO toolu üzerinden modelimizi optimize etmek gerekmektedir bu komut resimler üzerinde 300×300 piksellik bir düzenleme yapmaktadır.

    
        !toco \
        — graph_def_file=”/content/object_detection_demo/tflite_graph.pb” \
        — output_file=”/content/object_detection_demo/detect.tflite” \
        — input_shapes=1,300,300,3 \
        — input_arrays=normalized_input_image_tensor \
        — output_arrays=’TFLite_Detection_PostProcess’,’TFLite_Detection_PostProcess:1',’TFLite_Detection_PostProcess:2',’TFLite_Detection_PostProcess:3' \
        — inference_type=FLOAT \
        — allow_custom_ops
    

Bir başka tflite modeli elde etme yöntemi SavedModel kullanmaktır bunu nasıl elde edeceğimizi dokümanlarından bakabilirisiniz. SavedModel elde ettikten sonra aşağıdaki kod ile tflite modelimizi elde edebiliriz.

    
        import tensorflow as tf

        # Convert the model
        converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) # path to the SavedModel directory
        tflite_model = converter.convert()

        # Save the model.
        with open('model.tflite', 'wb') as f:
        f.write(tflite_model)
    

Terminal üzerinden de aşağıdaki komutu kullanabiliriz.

    
        tflite_convert \
        --saved_model_dir=/tmp/mobilenet_saved_model \
        --output_file=/tmp/mobilenet.tflite
    

Tflite Paketinin Projeye Dahil Edilmesi

Buradan sonra Flutter kısmına geçiş yapıyoruz. Flutterde modelleri kullanabilmek için öncelikle tflite paketinin kurulumunu yapmamız gerekmekte kurulum için pubspec.yaml dosyasına aşağıdaki eklemeyi yapıp “flutter pup get” komutunu çalıştırmamız yeterli.

    
        dependencies:
            tflite: ^1.1.1
    

Bu kurulum sırasında asıl dikkat etmemiz gereken nokta ise android\app\build.gradle dosyasında android içerisine aşağıdaki kod parçasını eklememiz. Bu eklemeyi yapmazsak zip file yada compress file gibi bir hata almaktayız.

    
        aaptOptions {
            noCompress 'tflite'
            noCompress 'lite'
        }
    

Bu proje için gerekli bir başka paket ise image picker. Bunuda aşağıdaki gibi ekleme yaparak dahil edebiliriz projemize.

    
        dependencies:
            tflite: ^1.1.1
            image_picker: ^0.6.7+12
    

Modelin Projeye Dahil Edilmesi

Gerekli kurulumlardan sonra uygulamamız ilk yüklendiği sırada oluşturmuş olduğumuz modeli de yüklemek için initState kısmında çağrılacak aşağıdaki fonksiyonu kullanabiliriz.

    
        loadModel() async {
            await Tflite.loadModel(
                model: "assets/ssd_mobilenet.tflite",
                labels: "assets/ssd_mobilenet.txt",
                numThreads: 5);
          }
    

Burada modelimi ve lable dosyasını assets dizinine ekledim bunu uygulama her yüklendiğinde otomatik olarak çalıştıracağı için model her seferinde projeme dahil edilecektir.

Yukarıdaki fonksiyonun çalışması için aşağıdaki kütüphaneyi ilgili sayfaya import etmemiz gerekmekte.

    
        import 'package:tflite/tflite.dart';
    
(Açılış Sayfası)

Tflite Model Kullanmak

Modelimizi projemize dahil ettikten sonra onu kullanmak için aşağıdaki gibi detectObjectOnImage fonksiyonuna ihtiyacımız var.

    
        detectObject(File image) async {
            var recognitions = await Tflite.detectObjectOnImage(
                path: image.path,
                // required
                model: "SSDMobileNet",
                imageMean: 127.5,
                imageStd: 127.5,
                threshold: 0.4,
                numResultsPerClass: 2,
                asynch: true
                );
            print(recognitions[0]);
            setState(() {
              output = recognitions;
            });
          }
    

Burada yazmış olduğumuz fonksiyonda Image Picker plugini ile seçmiş olduğumuz resmin dosya yolunu parametre olarak alıyor ve ilgili resim üzerinde tarama yaparak resimde bulunan nesnenin etiketini, doğruluk oranını ve konumunu çıktı olarak veriyor.

    
        {
            rect: {
                w: 0.994217038154602, 
                x: 0.0, h: 0.919082522392273, 
                y: 0.07482728362083435
            }, 
            confidenceInClass: 0.6875, 
            detectedClass: person
        }
    

Bu verilere göre kullanıcıya ekranda nasıl görünmesini istiyorsak düzenleyip verebiliriz. Uygulama kapatılırken ise dispose fonksiyonunu aşağıdaki gibi düzenleyerek modelimizi kapatabiliriz.

    
        @override
        void dispose() {
            Tflite.close();
            super.dispose();
        }
    

Yararlı Kaynaklar

  1. https://github.com/tzutalin/labelImg
  2. http://tzutalin.github.io/labelImg/
  3. https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/toco
  4. https://github.com/harshilpatel312/open-images-downloader
  5. https://colab.research.google.com/notebooks/intro.ipynb
  6. https://tfhub.dev/s?deployment-format=lite&subtype=module,placeholder
  7. https://medium.com/@ayyucekizrak/adım-adım-google-colab-ücretsiz-tpu-kullanımı-621dc6e5487d
  8. https://www.tensorflow.org/lite/convert
  9. https://www.tensorflow.org/guide/saved_model
  10. https://github.com/Tony607/object_detection_demo
  11. https://medium.com/datadriveninvestor/how-to-train-your-own-custom-model-with-tensorflow-object-detection-api-and-deploy-it-into-android-aeacab7fa76f
  12. https://github.com/tensorflow/models/tree/master/community
  13. https://pub.dev/packages/tflite
  14. https://pub.dev/packages/image_picker