Transformers documentation
Modelleri özelleştirme
Modelleri özelleştirme
Transformers modelleri özelleştirilebilir olacak şekilde tasarlanmıştır. Bir modelin kodu, Transformers deposundaki model alt klasöründe tamamen yer alır. Her klasör bir modeling.py ve bir configuration.py dosyası içerir. Bir modeli özelleştirmeye başlamak için bu dosyaları kopyalayın.
Tamamen yeni bir model oluşturuyorsanız, sıfırdan başlamak daha kolay olabilir. Ancak Transformers'taki mevcut bir modele çok benzer modeller için, aynı yapılandırma ve model sınıfını yeniden kullanmak veya alt sınıf oluşturmak daha hızlıdır.
Bu kılavuz, bir ResNet modelini nasıl özelleştireceğinizi, AutoClass desteğini nasıl etkinleştireceğinizi ve Hub üzerinde nasıl paylaşacağınızı gösterecektir.
Yapılandırma
PreTrainedConfig sınıfı tarafından verilen bir yapılandırma, bir model oluşturmak için gerekli tüm bilgileri içerir. Özel ResNet modelinin özniteliklerini burada yapılandıracaksınız. Farklı öznitelikler, farklı ResNet model türleri verir.
Bir yapılandırmayı özelleştirmek için temel kurallar şunlardır:
- Özel bir yapılandırma, PreTrainedConfig'in bir alt sınıfı olmalıdır. Bu, özel bir modelin from_pretrained(), save_pretrained() ve push_to_hub() gibi bir Transformers modelinin tüm işlevselliğine sahip olmasını sağlar.
- PreTrainedConfig
__init__herhangi birkwargsdeğerini kabul etmeli ve bunlar üst sınıfın__init__metoduna iletilmelidir. PreTrainedConfig, özel yapılandırmanızda ayarlananlardan daha fazla alana sahiptir; bu nedenle bir yapılandırmayı from_pretrained() ile yüklediğinizde, bu alanlar yapılandırmanız tarafından kabul edilmeli ve üst sınıfa iletilmelidir.
Bazı parametrelerin geçerliliğini kontrol etmek faydalıdır. Aşağıdaki örnekte,
block_typevestem_type'in önceden tanımlanmış değerlerden birine ait olduğunu sağlamak için bir kontrol uygulanmıştır.AutoClass desteğini etkinleştirmek için yapılandırma sınıfına
model_typeekleyin.
from transformers import PreTrainedConfig
from typing import List
class ResnetConfig(PreTrainedConfig):
model_type = "resnet"
def __init__(
self,
block_type="bottleneck",
layers: list[int] = [3, 4, 6, 3],
num_classes: int = 1000,
input_channels: int = 3,
cardinality: int = 1,
base_width: int = 64,
stem_width: int = 64,
stem_type: str = "",
avg_down: bool = False,
**kwargs,
):
if block_type not in ["basic", "bottleneck"]:
raise ValueError(f"`block_type` must be 'basic' or bottleneck', got {block_type}.")
if stem_type not in ["", "deep", "deep-tiered"]:
raise ValueError(f"`stem_type` must be '', 'deep' or 'deep-tiered', got {stem_type}.")
self.block_type = block_type
self.layers = layers
self.num_classes = num_classes
self.input_channels = input_channels
self.cardinality = cardinality
self.base_width = base_width
self.stem_width = stem_width
self.stem_type = stem_type
self.avg_down = avg_down
super().__init__(**kwargs)Yapılandırmayı, save_pretrained() ile özel model klasörünüz olan custom-resnet içinde bir JSON dosyası olarak kaydedin.
resnet50d_config = ResnetConfig(block_type="bottleneck", stem_width=32, stem_type="deep", avg_down=True)
resnet50d_config.save_pretrained("custom-resnet")Model
Özel ResNet yapılandırmasıyla artık modeli oluşturabilir ve özelleştirebilirsiniz. Model, temel PreTrainedModel sınıfından türetilir. PreTrainedConfig gibi, PreTrainedModel sınıfından türetmek ve üst sınıfı yapılandırmayla başlatmak, Transformers'ın kaydetme ve yükleme gibi işlevlerini özel modele de taşır.
Transformers modelleri, __init__ metodunda bir config nesnesi kabul etme kuralını izler. Bu, config nesnesini alt katmanlara tek tek geçirilen birden fazla argümana bölmek yerine, tüm config nesnesini modelin alt katmanlarına iletir.
Modelleri bu şekilde yazmak, hiperparametreler için net bir doğruluk kaynağına sahip daha basit kod üretir. Ayrıca, diğer Transformers modellerinden kodu yeniden kullanmayı da kolaylaştırır.
İki ResNet modeli oluşturacaksınız: gizli durumları (hidden states) çıkaran sade bir ResNet modeli ve bir görüntü sınıflandırma başlığına (image classification head) sahip bir ResNet modeli.
Blok türleri ve sınıfları arasında bir eşleme tanımlayın. Diğer her şey, yapılandırma sınıfını ResNet model sınıfına geçirilerek oluşturulur.
AutoClass desteğini etkinleştirmek için model sınıfına
config_classekleyin.
from transformers import PreTrainedModel
from timm.models.resnet import BasicBlock, Bottleneck, ResNet
from .configuration_resnet import ResnetConfig
BLOCK_MAPPING = {"basic": BasicBlock, "bottleneck": Bottleneck}
class ResnetModel(PreTrainedModel):
config_class = ResnetConfig
def __init__(self, config):
super().__init__(config)
block_layer = BLOCK_MAPPING[config.block_type]
self.model = ResNet(
block_layer,
config.layers,
num_classes=config.num_classes,
in_chans=config.input_channels,
cardinality=config.cardinality,
base_width=config.base_width,
stem_width=config.stem_width,
stem_type=config.stem_type,
avg_down=config.avg_down,
)
def forward(self, tensor):
return self.model.forward_features(tensor)Etiketler mevcut ise forward yönteminin, her logit için kaybı hesaplamak üzere yeniden yazılması gerekir. Aksi halde ResNet model sınıfı aynıdır.
AutoClass desteğini etkinleştirmek için model sınıfına
config_classekleyin.
import torch
class ResnetModelForImageClassification(PreTrainedModel):
config_class = ResnetConfig
def __init__(self, config):
super().__init__(config)
block_layer = BLOCK_MAPPING[config.block_type]
self.model = ResNet(
block_layer,
config.layers,
num_classes=config.num_classes,
in_chans=config.input_channels,
cardinality=config.cardinality,
base_width=config.base_width,
stem_width=config.stem_width,
stem_type=config.stem_type,
avg_down=config.avg_down,
)
def forward(self, tensor, labels=None):
logits = self.model(tensor)
if labels is not None:
loss = torch.nn.functional.cross_entropy(logits, labels)
return {"loss": loss, "logits": logits}
return {"logits": logits}Bir model herhangi bir çıktı biçimi döndürebilir. Etiketler mevcut olduğunda kayıpları içeren bir sözlük (örneğin ResnetModelForImageClassification) döndürmek, özel modeli Trainer ile uyumlu hale getirir. Diğer çıktı biçimleri için kendi eğitim döngünüzü oluşturmanız veya eğitim için farklı bir kütüphane kullanmanız gerekir.
Yapılandırmayla özel model sınıfını örnekleyin.
resnet50d = ResnetModelForImageClassification(resnet50d_config)
Bu noktada, modele önceden eğitilmiş ağırlıkları yükleyebilir veya sıfırdan eğitebilirsiniz. Bu kılavuzda, önceden eğitilmiş ağırlıkları yükleyeceksiniz.
Önceden eğitilmiş ağırlıkları timm kütüphanesinden yükleyin ve ardından bu ağırlıkları load_state_dict ile özel modele aktarın.
import timm
pretrained_model = timm.create_model("resnet50d", pretrained=True)
resnet50d.model.load_state_dict(pretrained_model.state_dict())AutoClass
AutoClass API'si, belirli bir model için doğru mimarinin otomatik olarak yüklenmesi için bir kısayoldur. Özel modelinizi yükleyen kullanıcılar için bunu etkinleştirmek kullanışlıdır.
Yapılandırma sınıfında model_type özniteliğinin (mevcut model türlerinden farklı olmalıdır) ve model sınıfında config_class özniteliğinin bulunduğundan emin olun. Özel yapılandırmayı ve modeli AutoClass API'sine eklemek için register() yöntemini kullanın.
AutoConfig.register() işlevinin ilk argümanı, özel yapılandırma sınıfındaki
model_typeözniteliğiyle eşleşmeli veAutoModel.register()işlevinin ilk argümanı, özel model sınıfınınconfig_classdeğeriyle eşleşmelidir.
from transformers import AutoConfig, AutoModel, AutoModelForImageClassification
AutoConfig.register("resnet", ResnetConfig)
AutoModel.register(ResnetConfig, ResnetModel)
AutoModelForImageClassification.register(ResnetConfig, ResnetModelForImageClassification)Özel model kodunuz artık AutoClass API'si ile uyumlu. Kullanıcılar modeli AutoModel veya AutoModelForImageClassification sınıflarıyla yükleyebilir.
Yükle
Diğer kullanıcıların modelinizi kolayca yükleyip kullanabilmesi için özel bir modeli Hub'a yükleyin.
Aşağıda gösterildiği gibi model dizininin doğru yapılandırıldığından emin olun. Dizin şunları içermelidir:
modeling.py:ResnetModelveResnetModelForImageClassificationiçin kodu içerir. Bu dosya, diğer dosyalarla aynı dizinde oldukları sürece göreceli içe aktarmalara güvenebilir.
Bir Transformers model dosyasını kopyalarken,
modeling.pydosyasının başındaki tüm göreli içe aktarmaları, yerine Transformers'tan içe aktarmak için değiştirin.
configuration.py:ResnetConfigiçin kodu içerir.__init__.py: Boş olabilir, bu dosya Python'unresnet_model'i bir modül olarak kullanılmasına olanak tanır.
.
└── resnet_model
├── __init__.py
├── configuration_resnet.py
└── modeling_resnet.pyModeli paylaşmak için ResNet modelini ve yapılandırmasını içe aktarın.
from resnet_model.configuration_resnet import ResnetConfig
from resnet_model.modeling_resnet import ResnetModel, ResnetModelForImageClassificationModel ve yapılandırma dosyalarındaki kodu kopyalayın. AutoClass nesnelerinin save_pretrained() ile kaydedildiğinden emin olmak için register_for_auto_class() metodunu çağırın. Bu işlem, yapılandırma JSON dosyasını AutoClass nesnelerini ve eşlemeyi içerecek şekilde değiştirir.
Bir model için, göreve uygun AutoModelFor sınıfını seçin.
ResnetConfig.register_for_auto_class()
ResnetModel.register_for_auto_class("AutoModel")
ResnetModelForImageClassification.register_for_auto_class("AutoModelForImageClassification")Modelde birden fazla görevi eşlemek için yapılandırma JSON dosyasındaki auto_map alanını doğrudan düzenleyin.
"auto_map": {
"AutoConfig": "<your-repo-name>--<config-name>",
"AutoModel": "<your-repo-name>--<config-name>",
"AutoModelFor<Task>": "<your-repo-name>--<config-name>",
},Yapılandırmayı ve modeli oluşturun ve önceden eğitilmiş ağırlıkları içine yükleyin.
resnet50d_config = ResnetConfig(block_type="bottleneck", stem_width=32, stem_type="deep", avg_down=True)
resnet50d = ResnetModelForImageClassification(resnet50d_config)
pretrained_model = timm.create_model("resnet50d", pretrained=True)
resnet50d.model.load_state_dict(pretrained_model.state_dict())Model artık Hub'a gönderilmeye hazır. Hugging Face hesabınıza komut satırından veya defterden giriş yapın.
hf auth login
from huggingface_hub import notebook_login
notebook_login()Modeli Hub'a yüklemek için modele push_to_hub() çağrısı yapın.
resnet50d.push_to_hub("custom-resnet50d")Önceden eğitilmiş ağırlıklar, yapılandırma, modeling.py ve configuration.py dosyalarının tümü artık ad alanınız altında bir depo içinde Hub'a yüklenmelidir.
Özel bir model, Transformers modelleriyle aynı modelleme kodunu kullanmadığı için yüklemek için from_pretrained() içinde trust_remote_code=True parametresini eklemeniz gerekir. Daha fazla bilgi için özel modelleri yükleme bölümüne bakın.