TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | GitHub'da görüntüle | Not defterini indir | TF Hub modellerine bakın |
Bu not defteri, TensorFlow Hub'dan CropNet modellerini TFDS'den bir veri kümesinde veya kendi mahsul hastalığı saptama veri kümenizde nasıl ince ayar yapacağınızı gösterir.
Olacaksın:
- TFDS manyok veri setini veya kendi verilerinizi yükleyin
- Daha sağlam bir model elde etmek için verileri bilinmeyen (negatif) örneklerle zenginleştirin
- Verilere görüntü büyütmeleri uygulayın
- TF Hub'dan bir CropNet modeli yükleyin ve ince ayar yapın
- Doğrudan Görev Kitaplığı , MLKit veya TFLite ile uygulamanıza dağıtılmaya hazır bir TFLite modelini dışa aktarın
İçe Aktarma ve Bağımlılıklar
Başlamadan önce Model Maker ve TensorFlow Datasets'in en son sürümü gibi ihtiyaç duyulacak bazı bağımlılıkları yüklemeniz gerekir.
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
-yer tutucu2 l10n-yer/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)
İnce ayar yapmak için bir TFDS veri kümesi yükleyin
TFDS'den halka açık Cassava Yaprak Hastalığı veri setini kullanalım.
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
Veya alternatif olarak ince ayar yapmak için kendi verilerinizi yükleyin
Bir TFDS veri seti kullanmak yerine, kendi verileriniz üzerinde de eğitim verebilirsiniz. Bu kod parçacığı, kendi özel veri kümenizi nasıl yükleyeceğinizi gösterir. Verilerin desteklenen yapısı için bu bağlantıya bakın. Burada, halka açık Manyok Yaprak Hastalığı veri seti kullanılarak bir örnek verilmiştir.
# 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)
Tren bölümünden örnekleri görselleştirin
Görüntü örnekleri ve etiketleri için sınıf kimliği ve sınıf adı da dahil olmak üzere veri kümesinden bazı örneklere bakalım.
_ = tfds.show_examples(ds_train, ds_info)
TFDS veri kümelerinden Bilinmeyen örnekler olarak kullanılacak resimler ekleyin
Eğitim veri kümesine ek bilinmeyen (negatif) örnekler ekleyin ve bunlara yeni bir bilinmeyen sınıf etiket numarası atayın. Amaç, pratikte (örneğin sahada) kullanıldığında, beklenmedik bir şey gördüğünde "Bilinmeyen"i tahmin etme seçeneğine sahip bir modele sahip olmaktır.
Aşağıda, ek bilinmeyen görüntüleri örneklemek için kullanılacak veri kümelerinin bir listesini görebilirsiniz. Çeşitliliği artırmak için tamamen farklı 3 veri seti içerir. Bunlardan biri fasulye yaprağı hastalığı veri setidir, böylece model manyok dışındaki hastalıklı bitkilere maruz kalır.
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,
}]
UNKNOWN veri kümeleri de TFDS'den yüklenir.
# 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.'))
tutucu8 l10n-yerAdded 16968 negative examples.Training dataset has now 22624 examples in total.
Büyütme uygula
Tüm resimler için, onları daha çeşitli hale getirmek için, aşağıdaki değişiklikler gibi bazı büyütmeler uygulayacaksınız:
- Parlaklık
- Zıtlık
- Doyma
- renk tonu
- Mahsul
Bu tür büyütmeler, modeli görüntü girdilerindeki değişikliklere karşı daha sağlam hale getirmeye yardımcı olur.
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)
Büyütmeyi uygulamak için Dataset sınıfından map
yöntemini kullanır.
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)
tutucu11 l10n-yerINFO: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
Verileri Model Oluşturucu dostu formata sarın
Bu veri kümesini Model Maker ile kullanmak için ImageClassifierDataLoader sınıfında olmaları gerekir.
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)
Eğitimi çalıştırın
TensorFlow Hub , Transfer Learning için birden fazla modele sahiptir.
Burada birini seçebilir ve daha iyi sonuçlar elde etmek için diğerlerini denemeye devam edebilirsiniz.
Daha fazla model denemek isterseniz bu koleksiyondan ekleyebilirsiniz.
Bir temel model seçin
model_name = 'mobilenet_v3_large_100_224'
map_model_name = {
'cropnet_cassava':
'https://tfhub.dev/google/cropnet/feature_vector/cassava_disease_V1/1',
'cropnet_concat':
'https://tfhub.dev/google/cropnet/feature_vector/concat/1',
'cropnet_imagenet':
'https://tfhub.dev/google/cropnet/feature_vector/imagenet/1',
'mobilenet_v3_large_100_224':
'https://tfhub.dev/google/imagenet/mobilenet_v3_large_100_224/feature_vector/5',
}
model_handle = map_model_name[model_name]
Modele ince ayar yapmak için Model Maker'ı kullanacaksınız. Bu, genel çözümü kolaylaştırır, çünkü modelin eğitiminden sonra da TFLite'a dönüştürülür.
Model Maker, bu dönüşümü mümkün olan en iyi dönüşüm haline getirir ve modeli daha sonra cihaza kolayca yerleştirmek için gerekli tüm bilgilerle birlikte.
Model spesifikasyonu, Model Maker'a hangi temel modeli kullanmak istediğinizi nasıl söylediğinizdir.
image_model_spec = ModelSpec(uri=model_handle)
Buradaki önemli bir ayrıntı, temel modelin eğitim sırasında ince ayarını yapacak olan train_whole_model
ayarıdır. Bu, süreci yavaşlatır ancak nihai modelin doğruluğu daha yüksektir. shuffle
ayarı, modelin verileri, model öğrenimi için en iyi uygulama olan rastgele karıştırılmış bir sırada görmesini sağlar.
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)
tutucu16 l10n-yerINFO: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
Modeli test bölümünde değerlendirin
model.evaluate(test_data)
tutucu18 l10n-yer59/59 [==============================] - 10s 81ms/step - loss: 0.9956 - accuracy: 0.8594 [0.9956456422805786, 0.8594164252281189]
İnce ayarlı modeli daha da iyi anlamak için, karışıklık matrisini analiz etmek iyidir. Bu, bir sınıfın başka bir sınıf olarak ne sıklıkla tahmin edildiğini gösterecektir.
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()
tutucu20 l10n-yerconfusion_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)
Modeli bilinmeyen test verilerine göre değerlendirin
Bu değerlendirmede modelin neredeyse 1 doğrulukta olmasını bekliyoruz. Modelin test edildiği tüm görüntüler normal veri seti ile ilgili değil ve bu nedenle modelin "Bilinmeyen" sınıf etiketini tahmin etmesini bekliyoruz.
model.evaluate(unknown_test_data)
tutucu22 l10n-yer259/259 [==============================] - 36s 127ms/step - loss: 0.6777 - accuracy: 0.9996 [0.677702784538269, 0.9996375441551208]
Karışıklık matrisini yazdırın.
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)
Modeli TFLite ve SavedModel olarak dışa aktarın
Artık eğitilmiş modelleri, cihazda dağıtmak ve TensorFlow'da çıkarım için kullanmak için TFLite ve SavedModel formatlarında dışa aktarabiliriz.
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.tfliteyer tutucu26 l10n-yer
# 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
Sonraki adımlar
Az önce eğittiğiniz model mobil cihazlarda kullanılabilir ve hatta sahada konuşlandırılabilir!
Modeli indirmek için, işbirliğinin sol tarafındaki Dosyalar menüsü için klasör simgesine tıklayın ve indirme seçeneğini seçin.
Burada kullanılan aynı teknik, kullanım durumunuza veya başka herhangi bir görüntü sınıflandırma görevine daha uygun olabilecek diğer bitki hastalıkları görevlerine uygulanabilir. Bir Android uygulamasını takip etmek ve dağıtmak istiyorsanız, bu Android hızlı başlangıç kılavuzuna devam edebilirsiniz.