TensorFlow Lite operatör sürümleri

Bu belgede, TensorFlow Lite'ın işlem sürümü oluşturma şeması açıklanmaktadır. Op sürümü oluşturma, geliştiricilerin mevcut işlemlere yeni işlevler ve parametreler eklemesine olanak tanır. Ayrıca, aşağıdakileri garanti eder:

  • Geriye dönük uyumluluk: Yeni TensorFlow Lite uygulaması, eski bir model dosyasını işlemelidir.
  • İleriye dönük uyumluluk: Eski TensorFlow Lite uygulaması, yeni özellik kullanılmadığı sürece dönüştürücünün yeni sürümü tarafından oluşturulan yeni bir model dosyasını işleyebilmelidir.
  • Yönlendirme uyumsuzluğu algılama: Eski bir TensorFlow Lite uygulaması, desteklenmeyen bir işlemin yeni bir sürümünü içeren yeni bir model okuyorsa hatayı bildirmelidir.

Örnek: Derinlemesine konvolüsyona genişleme ekleme

Bu belgenin geri kalanında, derinlik kıvrım işlemine genişleme parametrelerinin nasıl ekleneceği gösterilmektedir.

Bu belgeyi anlamak için genişleme hakkında bilgi sahibi olmanız gerekmez. Unutmayın:

  • 2 yeni tam sayı parametresi eklenecek: dilation_width_factor ve dilation_height_factor.
  • Genişlemeyi desteklemeyen eski derinlik konvolüsyon çekirdekleri, genişleme faktörlerini 1'e ayarlamakla eşdeğerdir.

FlatBuffer şemasını değiştirin

Bir işleme yeni parametreler eklemek için lite/schema/schema.fbs bölümünden seçenekler tablosunu değiştirin.

Örneğin, derinlikli evrişimi gösteren seçenekler tablosu aşağıdaki gibi görünür:

table DepthwiseConv2DOptions {
  padding:Padding;
  stride_w:int;
  stride_h:int;
  depth_multiplier:int;
  fused_activation_function:ActivationFunctionType;
}

Yeni parametreler eklerken:

  • Hangi parametrelerin hangi sürümün desteklediğini belirten yorumlar ekleyin.
  • Yeni uygulama, yeni eklenen parametreler için varsayılan değerleri aldığında, eski uygulamayla tam olarak aynı şekilde çalışmalıdır.

Yeni parametreler eklendikten sonra tablo aşağıdaki gibi olacaktır:

table DepthwiseConv2DOptions {
  // Parameters for DepthwiseConv version 1 or above.
  padding:Padding;
  stride_w:int;
  stride_h:int;
  depth_multiplier:int;
  fused_activation_function:ActivationFunctionType;
  // Parameters for DepthwiseConv version 2 or above.
  dilation_w_factor:int = 1;
  dilation_h_factor:int = 1;
}

lite/schema/schema_generated.h dosyasının yeni şema için yeniden oluşturulması gerekir.

C yapılarını ve çekirdek uygulamasını değiştirme

TensorFlow Lite'ta çekirdek uygulaması FlatBuffer tanımından ayrılır. Çekirdekler, parametreyi lite/c/builtin_op_data.h içinde tanımlanan C yapılarından okur.

Orijinal derinlikli evrişim parametresi aşağıdaki gibidir:

typedef struct {
  TfLitePadding padding;
  int stride_width;
  int stride_height;
  int depth_multiplier;
  TfLiteFusedActivation activation;
} TfLiteDepthwiseConvParams;

FlatBuffer şemasında olduğu gibi, hangi sürümden itibaren hangi parametrelerin desteklendiğini belirten yorumlar ekleyin. Sonuç aşağıda gösterilmiştir:

typedef struct {
  // Parameters for DepthwiseConv version 1 or above.
  TfLitePadding padding;
  int stride_width;
  int stride_height;
  int depth_multiplier;
  TfLiteFusedActivation activation;
  // Parameters for DepthwiseConv version 2 or above.
  int dilation_width_factor;
  int dilation_height_factor;
} TfLiteDepthwiseConvParams;

Lütfen yeni eklenen parametreleri C yapılarından okumak için çekirdek uygulamasını da değiştirin. Burada ayrıntılara yer verilmemiştir.

FlatBuffer okuma kodunu değiştirme

FlatBuffer okuma ve C yapısı oluşturma mantığı lite/core/api/flatbuffer_conversions.cc içindedir.

Dosyayı, aşağıda gösterildiği gibi yeni parametreleri işleyecek şekilde güncelleyin:

TfLiteStatus ParseDepthwiseConv2D(const Operator* op,
                                  ErrorReporter* error_reporter,
                                  BuiltinDataAllocator* allocator,
                                  void** builtin_data) {
  CheckParsePointerParams(op, error_reporter, allocator, builtin_data);

  SafeBuiltinDataAllocator safe_allocator(allocator);

  std::unique_ptr<TfLiteDepthwiseConvParams,
                  SafeBuiltinDataAllocator::BuiltinDataDeleter>
      params = safe_allocator.Allocate<TfLiteDepthwiseConvParams>();
  TF_LITE_ENSURE(error_reporter, params != nullptr);

  const DepthwiseConv2DOptions* schema_params =
      op->builtin_options_as_DepthwiseConv2DOptions();

  if (schema_params != nullptr) {
    params->padding = ConvertPadding(schema_params->padding());
    params->stride_width = schema_params->stride_w();
    params->stride_height = schema_params->stride_h();
    params->depth_multiplier = schema_params->depth_multiplier();
    params->activation =
        ConvertActivation(schema_params->fused_activation_function());

    params->dilation_width_factor = schema_params->dilation_w_factor();
    params->dilation_height_factor = schema_params->dilation_h_factor();
  }

  *builtin_data = params.release();
  return kTfLiteOk;
}

Operasyon sürümünü buradan kontrol etmeniz gerekmez. Yeni uygulama, genişletme faktörlerinin eksik olduğu eski bir model dosyasını okuduğunda, varsayılan değer olarak 1 kullanılır ve yeni çekirdek eski çekirdekle tutarlı şekilde çalışır.

Çekirdek kaydını değiştirme

MutableOpresolver (lite/mutable_op_resolver.h'da tanımlanır), işlem çekirdeklerini kaydetmek için birkaç işlev sunar. Minimum ve maksimum sürüm varsayılan olarak 1'dir:

void AddBuiltin(tflite::BuiltinOperator op, TfLiteRegistration* registration,
                int min_version = 1, int max_version = 1);
void AddCustom(const char* name, TfLiteRegistration* registration,
               int min_version = 1, int max_version = 1);

Yerleşik işlemler lite/kernels/register.cc bölgesinde kayıtlı. Bu örnekte, DepthwiseConv2D sürüm 1 ve 2'yi işleyebilen yeni bir işlem çekirdeği uyguladık. Bu nedenle şu satırı değiştirmemiz gerekiyor:

AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D());

karşılaştırma yapılacak öğe:

AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D(),
             /* min_version = */ 1,
             /* max_version = */ 2);

TFLite işlem sürümünü değiştirme

Sonraki adım, TFLite'ın, işletim sistemini çalıştırmak için gereken minimum sürümü doldurmasını sağlamaktır. Bu örnekte bunun anlamı şudur:

  • Genişleme faktörlerinin tamamı 1 olduğunda sürüm=1'i doldurun.
  • Aksi takdirde version=2 değerini doldurun.

DepthwiseConv2D nesnesine yeni sürümü ekleyerek lite/tools/versioning/op_version.cc içindeki operatör için GetBuiltinOperatorVersion işlevini değiştirin:

case BuiltinOperator_DEPTHWISE_CONV_2D:
  auto depthwise_conv_params =
      reinterpret_cast<TfLiteDepthwiseConvParams*>(op_sig.builtin_data);
  TFLITE_DCHECK(depthwise_conv_params != nullptr);
  if (depthwise_conv_params->dilation_width_factor != 1 ||
       depthwise_conv_params->dilation_height_factor != 1) {
    return 2;
  }
  return 1;

Operatör sürüm haritasını güncelleme

Son adım, yeni sürüm bilgisini operatör sürüm haritasına eklemektir. Bu sürüm haritasına göre modelin gerekli minimum çalışma zamanı sürümünü oluşturmamız gerektiğinden bu adım gereklidir.

Bunun için lite/tools/versioning/runtime_version.cc uygulamasına yeni bir harita girişi eklemeniz gerekiyor.

Bu örnekte, op_version_map içine aşağıdaki girişi eklemeniz gerekir:

{ {BuiltinOperator_DEPTHWISE_CONV_2D, 2}, %CURRENT_RUNTIME_VERSION%}

Burada %CURRENT_RUNTIME_VERSION%, tensorflow/core/public/version.h dosyasında tanımlanan mevcut çalışma zamanı sürümüne karşılık gelir.

Yetki uygulaması

TensorFlow Lite, donanım arka uçlarına işlem yetkisi vermeye olanak tanıyan bir yetkilendirme API'si sunar. Yetki verilmiş kullanıcının Prepare işlevinde, sürümün Yetki kodundaki her düğüm için desteklenip desteklenmediğini kontrol edin.

const int kMaxVersion = 1;
TfLiteNode* node;
TfLiteRegistration* registration = nullptr;
TF_LITE_ENSURE_STATUS(context->GetNodeAndRegistration(context, node_index, &node, &registration));

if (registration->version > kMaxVersion) {
  // Reject the node if the version isn't supported.
}

Yetkilendirme yalnızca sürüm 1 işlemlerini destekliyor olsa bile bu gereklidir. Bu nedenle, yetki daha yüksek sürüm işlemi alırken uyumsuzluğu algılayabilir.