TensorFlow Lite operatör sürümleri

Bu belge, TensorFlow Lite'ın op sürüm oluşturma şemasını açıklar. 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 özellikler kullanılmadığı sürece dönüştürücünün yeni sürümü tarafından üretilen yeni bir model dosyasını işlemelidir.
  • İleriye dönük uyumsuzluk algılaması: Eski bir TensorFlow Lite uygulaması, desteklenmeyen bir işlemin yeni bir sürümünü içeren yeni bir modeli okursa, hatayı bildirmelidir.

Örnek: Derinlemesine evrişime genişleme ekleme

Bu belgenin geri kalanı, derinlik yönünde evrişim işlemine genişletme parametrelerinin nasıl ekleneceğini göstererek TFLite'ta op sürüm oluşturmayı açıklar.

Bu belgeyi anlamak için dilatasyon bilgisi gerekli değildir. Dikkat:

  • 2 yeni tamsayı parametresi eklenecek: dilation_width_factor ve dilation_height_factor .
  • Genişletmeyi desteklemeyen eski derinlemesine evrişim çekirdekleri, genişletme faktörlerini 1'e ayarlamaya eşdeğerdir.

FlatBuffer şemasını değiştir

Bir işleme yeni parametreler eklemek için lite/schema/schema.fbs içindeki seçenekler tablosunu değiştirin.

Örneğin, derinlemesine evrişimin seçenekler tablosu şöyle 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 tarafından desteklendiğini belirten yorumlar ekleyin.
  • Yeni uygulama, yeni eklenen parametreler için varsayılan değerleri aldığında, eski uygulama ile tamamen aynı şekilde çalışmalıdır.

Yeni parametreler eklendikten sonra tablo şu şekilde 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ı yeni şema için yeniden oluşturulmalıdır.

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

TensorFlow Lite'da çekirdek uygulaması FlatBuffer tanımından ayrılmıştır. lite/c/builtin_op_data.h parametreyi lite/c/builtin_op_data.h içinde tanımlanan C yapılarından lite/c/builtin_op_data.h .

Orijinal derinlik yönünde 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 başlayarak hangi parametrelerin desteklendiğini belirten açıklamalar ekleyin. Sonuç aşağıda görülmektedir:

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 C yapılarından yeni eklenen parametreleri okumak için çekirdek uygulamasını da değiştirin. Ayrıntılar burada atlanmıştır.

FlatBuffer okuma kodunu değiştirin

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

Yeni parametreleri işlemek için dosyayı aşağıda gösterildiği gibi 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;
}

Burada op sürümünü kontrol etmek gerekli değildir. Yeni uygulama, genişleme faktörlerinin eksik olduğu eski bir model dosyasını okuduğunda, varsayılan değer olarak 1'i kullanacak ve yeni çekirdek, eski çekirdekle tutarlı bir şekilde çalışacaktır.

Çekirdek kaydını değiştir

MutableOpResolver ( lite/mutable_op_resolver.h içinde tanımlanmıştır), op çekirdeklerini kaydetmek için birkaç fonksiyon sağlar. 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 . Bu örnekte, DepthwiseConv2D sürüm 1 ve 2'yi işleyebilen yeni bir op çekirdeği uyguladık, bu yüzden bu satırı değiştirmemiz gerekiyor:

AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D());

için:

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

TFLite işletim sürümünü değiştir

Bir sonraki adım, TFLite'ın operasyonu yürütmek için gereken minimum sürümü doldurmasını sağlamaktır. Bu örnekte, şu anlama gelir:

  • Genişletme faktörlerinin tümü 1 olduğunda sürüm=1'i doldurun.
  • Aksi takdirde sürüm=2'yi doldurun.

Değiştir GetBuiltinOperatorVersion operatör için fonksiyon lite/tools/versioning/op_version.cc durumunda yeni sürümü ekleyerek DepthwiseConv2D :

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üncelleyin

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

Bunu yapmak için lite/tools/versioning/runtime_version.cc yeni bir harita girişi eklemeniz gerekir.

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 içinde tanımlanan geçerli çalışma zamanı sürümüne karşılık gelir.

Delegasyon uygulaması

TensorFlow Lite, operasyonların donanım arka uçlarına devredilmesini sağlayan bir yetkilendirme API'si sağlar. Temsilcinin Prepare işlevinde, sürümün Temsilci 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.
}

Bu, yetkilendirme yalnızca sürüm 1 işlemlerini desteklese bile gereklidir, böylece yetkilendirme, daha yüksek bir sürüm işlemi alırken uyumsuzluğu algılayabilir.