উদ্ভিদ রোগ সনাক্তকরণের জন্য সূক্ষ্ম টিউনিং মডেল

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub এ দেখুন নোটবুক ডাউনলোড করুন TF হাব মডেল দেখুন

এই নোটবুকটি আপনাকে TFDS বা আপনার নিজের ফসলের রোগ সনাক্তকরণ ডেটাসেটের ডেটাসেটে টেনসরফ্লো হাব থেকে ক্রপনেট মডেলগুলিকে কীভাবে সূক্ষ্ম-টিউন করতে হয় তা দেখায়।

আপনি করবেন:

  • TFDS কাসাভা ডেটাসেট বা আপনার নিজের ডেটা লোড করুন
  • আরও শক্তিশালী মডেল পেতে অজানা (নেতিবাচক) উদাহরণ দিয়ে ডেটা সমৃদ্ধ করুন
  • ডেটাতে ইমেজ অগমেন্টেশন প্রয়োগ করুন
  • TF হাব থেকে একটি CropNet মডেল লোড করুন এবং ঠিক করুন
  • একটি TFLite মডেল রপ্তানি করুন, সরাসরি টাস্ক লাইব্রেরি , MLKit বা TFLite এর সাথে আপনার অ্যাপে স্থাপনের জন্য প্রস্তুত

আমদানি এবং নির্ভরতা

শুরু করার আগে, আপনাকে মডেল মেকার এবং টেনসরফ্লো ডেটাসেটের সর্বশেষ সংস্করণের মতো কিছু নির্ভরতা ইনস্টল করতে হবে।

pip install --use-deprecated=legacy-resolver tflite-model-maker
pip install -U tensorflow-datasets
import matplotlib.pyplot as plt
import os
import seaborn as sns

import tensorflow as tf
import tensorflow_datasets as tfds

from tensorflow_examples.lite.model_maker.core.export_format import ExportFormat
from tensorflow_examples.lite.model_maker.core.task import image_preprocessing

from tflite_model_maker import image_classifier
from tflite_model_maker import ImageClassifierDataLoader
from tflite_model_maker.image_classifier import ModelSpec
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_addons/utils/ensure_tf_install.py:67: UserWarning: Tensorflow Addons supports using Python ops for all Tensorflow versions above or equal to 2.5.0 and strictly below 2.8.0 (nightly versions are not supported). 
 The versions of TensorFlow you are currently using is 2.8.0-rc1 and is not supported. 
Some things might work, some things might not.
If you were to encounter a bug, do not file an issue.
If you want to make sure you're using a tested and supported configuration, either change the TensorFlow version or the TensorFlow Addons's version. 
You can find the compatibility matrix in TensorFlow Addon's readme:
https://github.com/tensorflow/addons
  UserWarning,
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/numba/core/errors.py:154: UserWarning: Insufficiently recent colorama version found. Numba requires colorama >= 0.3.9
  warnings.warn(msg)

ফাইন-টিউন চালু করতে একটি TFDS ডেটাসেট লোড করুন

TFDS থেকে সর্বজনীনভাবে উপলব্ধ কাসাভা লিফ ডিজিজ ডেটাসেট ব্যবহার করা যাক।

tfds_name = 'cassava'
(ds_train, ds_validation, ds_test), ds_info = tfds.load(
    name=tfds_name,
    split=['train', 'validation', 'test'],
    with_info=True,
    as_supervised=True)
TFLITE_NAME_PREFIX = tfds_name

অথবা বিকল্পভাবে ফাইন-টিউন চালু করতে আপনার নিজস্ব ডেটা লোড করুন

একটি TFDS ডেটাসেট ব্যবহার করার পরিবর্তে, আপনি নিজের ডেটাতেও প্রশিক্ষণ দিতে পারেন। এই কোড স্নিপেট দেখায় কিভাবে আপনার নিজস্ব কাস্টম ডেটাসেট লোড করতে হয়। ডেটার সমর্থিত কাঠামোর জন্য এই লিঙ্কটি দেখুন। সর্বজনীনভাবে উপলব্ধ কাসাভা লিফ ডিজিজ ডেটাসেট ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে।

# data_root_dir = tf.keras.utils.get_file(
#     'cassavaleafdata.zip',
#     'https://storage.googleapis.com/emcassavadata/cassavaleafdata.zip',
#     extract=True)
# data_root_dir = os.path.splitext(data_root_dir)[0]  # Remove the .zip extension

# builder = tfds.ImageFolder(data_root_dir)

# ds_info = builder.info
# ds_train = builder.as_dataset(split='train', as_supervised=True)
# ds_validation = builder.as_dataset(split='validation', as_supervised=True)
# ds_test = builder.as_dataset(split='test', as_supervised=True)

ট্রেন বিভক্ত থেকে নমুনা কল্পনা করুন

আসুন চিত্রের নমুনা এবং তাদের লেবেলগুলির ক্লাস আইডি এবং ক্লাসের নাম সহ ডেটাসেট থেকে কিছু উদাহরণ দেখে নেওয়া যাক।

_ = tfds.show_examples(ds_train, ds_info)

png

TFDS ডেটাসেট থেকে অজানা উদাহরণ হিসেবে ব্যবহার করার জন্য ছবি যোগ করুন

প্রশিক্ষণ ডেটাসেটে অতিরিক্ত অজানা (নেতিবাচক) উদাহরণ যোগ করুন এবং তাদের জন্য একটি নতুন অজানা ক্লাস লেবেল নম্বর বরাদ্দ করুন। লক্ষ্য হল এমন একটি মডেল থাকা যা অনুশীলনে ব্যবহার করা হলে (যেমন ক্ষেত্রে), অপ্রত্যাশিত কিছু দেখলে "অজানা" ভবিষ্যদ্বাণী করার বিকল্প থাকে।

নীচে আপনি ডেটাসেটের একটি তালিকা দেখতে পারেন যা অতিরিক্ত অজানা চিত্রের নমুনা করতে ব্যবহৃত হবে। এতে বৈচিত্র্য বাড়ানোর জন্য 3টি সম্পূর্ণ ভিন্ন ডেটাসেট রয়েছে। তাদের মধ্যে একটি হল মটরশুটি পাতার রোগের ডেটাসেট, যাতে মডেলটিতে কাসাভা ছাড়া অন্য রোগাক্রান্ত গাছের সংস্পর্শে আসে।

UNKNOWN_TFDS_DATASETS = [{
    'tfds_name': 'imagenet_v2/matched-frequency',
    'train_split': 'test[:80%]',
    'test_split': 'test[80%:]',
    'num_examples_ratio_to_normal': 1.0,
}, {
    'tfds_name': 'oxford_flowers102',
    'train_split': 'train',
    'test_split': 'test',
    'num_examples_ratio_to_normal': 1.0,
}, {
    'tfds_name': 'beans',
    'train_split': 'train',
    'test_split': 'test',
    'num_examples_ratio_to_normal': 1.0,
}]

অজানা ডেটাসেটগুলিও TFDS থেকে লোড করা হয়৷

# Load unknown datasets.
weights = [
    spec['num_examples_ratio_to_normal'] for spec in UNKNOWN_TFDS_DATASETS
]
num_unknown_train_examples = sum(
    int(w * ds_train.cardinality().numpy()) for w in weights)
ds_unknown_train = tf.data.Dataset.sample_from_datasets([
    tfds.load(
        name=spec['tfds_name'], split=spec['train_split'],
        as_supervised=True).repeat(-1) for spec in UNKNOWN_TFDS_DATASETS
], weights).take(num_unknown_train_examples)
ds_unknown_train = ds_unknown_train.apply(
    tf.data.experimental.assert_cardinality(num_unknown_train_examples))
ds_unknown_tests = [
    tfds.load(
        name=spec['tfds_name'], split=spec['test_split'], as_supervised=True)
    for spec in UNKNOWN_TFDS_DATASETS
]
ds_unknown_test = ds_unknown_tests[0]
for ds in ds_unknown_tests[1:]:
  ds_unknown_test = ds_unknown_test.concatenate(ds)

# All examples from the unknown datasets will get a new class label number.
num_normal_classes = len(ds_info.features['label'].names)
unknown_label_value = tf.convert_to_tensor(num_normal_classes, tf.int64)
ds_unknown_train = ds_unknown_train.map(lambda image, _:
                                        (image, unknown_label_value))
ds_unknown_test = ds_unknown_test.map(lambda image, _:
                                      (image, unknown_label_value))

# Merge the normal train dataset with the unknown train dataset.
weights = [
    ds_train.cardinality().numpy(),
    ds_unknown_train.cardinality().numpy()
]
ds_train_with_unknown = tf.data.Dataset.sample_from_datasets(
    [ds_train, ds_unknown_train], [float(w) for w in weights])
ds_train_with_unknown = ds_train_with_unknown.apply(
    tf.data.experimental.assert_cardinality(sum(weights)))

print((f"Added {ds_unknown_train.cardinality().numpy()} negative examples."
       f"Training dataset has now {ds_train_with_unknown.cardinality().numpy()}"
       ' examples in total.'))
Added 16968 negative examples.Training dataset has now 22624 examples in total.

পরিবর্ধন প্রয়োগ করুন

সমস্ত চিত্রের জন্য, সেগুলিকে আরও বৈচিত্র্যময় করতে, আপনি কিছু পরিবর্ধন প্রয়োগ করবেন, যেমন পরিবর্তনগুলি:

  • উজ্জ্বলতা
  • বৈপরীত্য
  • স্যাচুরেশন
  • হিউ
  • ফসল

এই ধরনের পরিবর্ধনগুলি মডেলটিকে ইমেজ ইনপুটগুলির বিভিন্নতার জন্য আরও শক্তিশালী করতে সহায়তা করে।

def random_crop_and_random_augmentations_fn(image):
  # preprocess_for_train does random crop and resize internally.
  image = image_preprocessing.preprocess_for_train(image)
  image = tf.image.random_brightness(image, 0.2)
  image = tf.image.random_contrast(image, 0.5, 2.0)
  image = tf.image.random_saturation(image, 0.75, 1.25)
  image = tf.image.random_hue(image, 0.1)
  return image


def random_crop_fn(image):
  # preprocess_for_train does random crop and resize internally.
  image = image_preprocessing.preprocess_for_train(image)
  return image


def resize_and_center_crop_fn(image):
  image = tf.image.resize(image, (256, 256))
  image = image[16:240, 16:240]
  return image


no_augment_fn = lambda image: image

train_augment_fn = lambda image, label: (
    random_crop_and_random_augmentations_fn(image), label)
eval_augment_fn = lambda image, label: (resize_and_center_crop_fn(image), label)

পরিবর্ধন প্রয়োগ করতে, এটি ডেটাসেট ক্লাস থেকে map পদ্ধতি ব্যবহার করে।

ds_train_with_unknown = ds_train_with_unknown.map(train_augment_fn)
ds_validation = ds_validation.map(eval_augment_fn)
ds_test = ds_test.map(eval_augment_fn)
ds_unknown_test = ds_unknown_test.map(eval_augment_fn)
INFO:tensorflow:Use default resize_bicubic.
INFO:tensorflow:Use default resize_bicubic.
INFO:tensorflow:Use customized resize method bilinear
INFO:tensorflow:Use customized resize method bilinear

মডেল মেকার বন্ধুত্বপূর্ণ বিন্যাসে ডেটা মোড়ানো

মডেল মেকারের সাথে এই ডেটাসেটগুলি ব্যবহার করতে, তাদের একটি ImageClassifierDataLoader ক্লাসে থাকতে হবে।

label_names = ds_info.features['label'].names + ['UNKNOWN']

train_data = ImageClassifierDataLoader(ds_train_with_unknown,
                                       ds_train_with_unknown.cardinality(),
                                       label_names)
validation_data = ImageClassifierDataLoader(ds_validation,
                                            ds_validation.cardinality(),
                                            label_names)
test_data = ImageClassifierDataLoader(ds_test, ds_test.cardinality(),
                                      label_names)
unknown_test_data = ImageClassifierDataLoader(ds_unknown_test,
                                              ds_unknown_test.cardinality(),
                                              label_names)

প্রশিক্ষণ চালান

টেনসরফ্লো হাবের একাধিক মডেল ট্রান্সফার লার্নিংয়ের জন্য উপলব্ধ।

এখানে আপনি একটি বেছে নিতে পারেন এবং আপনি আরও ভাল ফলাফল পাওয়ার চেষ্টা করতে অন্যদের সাথে পরীক্ষা চালিয়ে যেতে পারেন।

আপনি যদি আরও বেশি মডেল চেষ্টা করতে চান, আপনি এই সংগ্রহ থেকে তাদের যোগ করতে পারেন।

একটি বেস মডেল চয়ন করুন

মডেলটি সূক্ষ্ম টিউন করতে, আপনি মডেল মেকার ব্যবহার করবেন। এটি সামগ্রিক সমাধানটিকে সহজ করে তোলে যেহেতু মডেলের প্রশিক্ষণের পরে, এটি এটিকে TFLite-এ রূপান্তরিত করবে।

মডেল মেকার এই রূপান্তরটিকে সর্বোত্তম সম্ভব করে তোলে এবং পরবর্তীতে ডিভাইসে মডেলটিকে সহজেই স্থাপন করার জন্য সমস্ত প্রয়োজনীয় তথ্য সহ।

আপনি মডেল মেকারকে কোন বেস মডেল ব্যবহার করতে চান তা আপনি কীভাবে বলবেন তা হল মডেলের বৈশিষ্ট্য।

image_model_spec = ModelSpec(uri=model_handle)

এখানে একটি গুরুত্বপূর্ণ বিশদটি হল train_whole_model সেট করা যা প্রশিক্ষণের সময় বেস মডেলটিকে সুন্দর করে তুলবে। এটি প্রক্রিয়াটিকে ধীর করে তোলে তবে চূড়ান্ত মডেলটির উচ্চতর নির্ভুলতা রয়েছে। শাফেল সেট করা নিশ্চিত করবে যে মডেলটি shuffle এলোমেলোভাবে ডেটা দেখে যা মডেল শেখার জন্য একটি সর্বোত্তম অনুশীলন।

model = image_classifier.create(
    train_data,
    model_spec=image_model_spec,
    batch_size=128,
    learning_rate=0.03,
    epochs=5,
    shuffle=True,
    train_whole_model=True,
    validation_data=validation_data)
INFO:tensorflow:Retraining the models...
INFO:tensorflow:Retraining the models...
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 hub_keras_layer_v1v2 (HubKe  (None, 1280)             4226432   
 rasLayerV1V2)                                                   
                                                                 
 dropout (Dropout)           (None, 1280)              0         
                                                                 
 dense (Dense)               (None, 6)                 7686      
                                                                 
=================================================================
Total params: 4,234,118
Trainable params: 4,209,718
Non-trainable params: 24,400
_________________________________________________________________
None
Epoch 1/5
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/optimizer_v2/gradient_descent.py:102: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(SGD, self).__init__(name, **kwargs)
176/176 [==============================] - 120s 488ms/step - loss: 0.8874 - accuracy: 0.9148 - val_loss: 1.1721 - val_accuracy: 0.7935
Epoch 2/5
176/176 [==============================] - 84s 444ms/step - loss: 0.7907 - accuracy: 0.9532 - val_loss: 1.0761 - val_accuracy: 0.8100
Epoch 3/5
176/176 [==============================] - 85s 441ms/step - loss: 0.7743 - accuracy: 0.9582 - val_loss: 1.0305 - val_accuracy: 0.8444
Epoch 4/5
176/176 [==============================] - 79s 409ms/step - loss: 0.7653 - accuracy: 0.9611 - val_loss: 1.0166 - val_accuracy: 0.8422
Epoch 5/5
176/176 [==============================] - 75s 402ms/step - loss: 0.7534 - accuracy: 0.9665 - val_loss: 0.9988 - val_accuracy: 0.8555

পরীক্ষা বিভক্ত উপর মডেল মূল্যায়ন

model.evaluate(test_data)
59/59 [==============================] - 10s 81ms/step - loss: 0.9956 - accuracy: 0.8594
[0.9956456422805786, 0.8594164252281189]

সূক্ষ্ম টিউন করা মডেল সম্পর্কে আরও ভাল বোঝার জন্য, বিভ্রান্তি ম্যাট্রিক্স বিশ্লেষণ করা ভাল। এটি দেখাবে কত ঘন ঘন একটি ক্লাস অন্য হিসাবে ভবিষ্যদ্বাণী করা হয়।

def predict_class_label_number(dataset):
  """Runs inference and returns predictions as class label numbers."""
  rev_label_names = {l: i for i, l in enumerate(label_names)}
  return [
      rev_label_names[o[0][0]]
      for o in model.predict_top_k(dataset, batch_size=128)
  ]

def show_confusion_matrix(cm, labels):
  plt.figure(figsize=(10, 8))
  sns.heatmap(cm, xticklabels=labels, yticklabels=labels, 
              annot=True, fmt='g')
  plt.xlabel('Prediction')
  plt.ylabel('Label')
  plt.show()
confusion_mtx = tf.math.confusion_matrix(
    list(ds_test.map(lambda x, y: y)),
    predict_class_label_number(test_data),
    num_classes=len(label_names))

show_confusion_matrix(confusion_mtx, label_names)

png

অজানা পরীক্ষা তথ্য উপর মডেল মূল্যায়ন

এই মূল্যায়নে আমরা আশা করি যে মডেলটির প্রায় 1 এর নির্ভুলতা থাকবে। মডেলটি পরীক্ষা করা সমস্ত চিত্র সাধারণ ডেটাসেটের সাথে সম্পর্কিত নয় এবং তাই আমরা আশা করি যে মডেলটি "অজানা" শ্রেণির লেবেলের পূর্বাভাস দেবে।

model.evaluate(unknown_test_data)
259/259 [==============================] - 36s 127ms/step - loss: 0.6777 - accuracy: 0.9996
[0.677702784538269, 0.9996375441551208]

বিভ্রান্তি ম্যাট্রিক্স প্রিন্ট করুন।

unknown_confusion_mtx = tf.math.confusion_matrix(
    list(ds_unknown_test.map(lambda x, y: y)),
    predict_class_label_number(unknown_test_data),
    num_classes=len(label_names))

show_confusion_matrix(unknown_confusion_mtx, label_names)

png

মডেলটি TFLite এবং SavedModel হিসাবে রপ্তানি করুন

এখন আমরা প্রশিক্ষিত মডেলগুলিকে TFLite এবং SavedModel ফর্ম্যাটে রপ্তানি করতে পারি যাতে ডিভাইসে স্থাপন করা যায় এবং TensorFlow-এ অনুমানের জন্য ব্যবহার করা যায়।

tflite_filename = f'{TFLITE_NAME_PREFIX}_model_{model_name}.tflite'
model.export(export_dir='.', tflite_filename=tflite_filename)
2022-01-26 12:25:57.742415: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmppliqmyki/assets
INFO:tensorflow:Assets written to: /tmp/tmppliqmyki/assets
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/lite/python/convert.py:746: UserWarning: Statistics for quantized inputs were expected, but not specified; continuing anyway.
  warnings.warn("Statistics for quantized inputs were expected, but not "
2022-01-26 12:26:07.247752: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:357] Ignored output_format.
2022-01-26 12:26:07.247806: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored drop_control_dependency.
INFO:tensorflow:Label file is inside the TFLite model with metadata.
fully_quantize: 0, inference_type: 6, input_inference_type: 3, output_inference_type: 3
INFO:tensorflow:Label file is inside the TFLite model with metadata.
INFO:tensorflow:Saving labels in /tmp/tmp_k_gr9mu/labels.txt
INFO:tensorflow:Saving labels in /tmp/tmp_k_gr9mu/labels.txt
INFO:tensorflow:TensorFlow Lite model exported successfully: ./cassava_model_mobilenet_v3_large_100_224.tflite
INFO:tensorflow:TensorFlow Lite model exported successfully: ./cassava_model_mobilenet_v3_large_100_224.tflite
# Export saved model version.
model.export(export_dir='.', export_format=ExportFormat.SAVED_MODEL)
INFO:tensorflow:Assets written to: ./saved_model/assets
INFO:tensorflow:Assets written to: ./saved_model/assets

পরবর্তী পদক্ষেপ

আপনি যে মডেলটি সবেমাত্র প্রশিক্ষিত করেছেন তা মোবাইল ডিভাইসে ব্যবহার করা যেতে পারে এবং এমনকি ক্ষেত্রটিতে স্থাপন করা যেতে পারে!

মডেলটি ডাউনলোড করতে, কোল্যাবের বাম দিকে ফাইল মেনুর ফোল্ডার আইকনে ক্লিক করুন এবং ডাউনলোড বিকল্পটি বেছে নিন।

এখানে ব্যবহৃত একই কৌশলটি অন্যান্য উদ্ভিদ রোগের কাজগুলিতে প্রয়োগ করা যেতে পারে যা আপনার ব্যবহারের ক্ষেত্রে বা অন্য কোনও ধরণের চিত্র শ্রেণিবিন্যাসের কাজের জন্য আরও উপযুক্ত হতে পারে। আপনি যদি একটি অ্যান্ড্রয়েড অ্যাপ অনুসরণ করতে এবং স্থাপন করতে চান, তাহলে আপনি এই অ্যান্ড্রয়েড কুইকস্টার্ট গাইডটি চালিয়ে যেতে পারেন।