# Modelleri özelleştirme

Transformers modelleri özelleştirilebilir olacak şekilde tasarlanmıştır. Bir modelin kodu, Transformers deposundaki [model](https://github.com/huggingface/transformers/tree/main/src/transformers/models) 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.

> [!TIP]
> Tamamen yeni bir model oluşturuyorsanız, sıfırdan başlamak daha kolay olabilir. Ancak Transformers içindeki mevcut bir modele çok benzer modeller için, aynı yapılandırma ve model sınıfını yeniden kullanmak veya alt sınıflandırmak daha hızlıdır.

Bu kılavuz, bir ResNet modelini nasıl özelleştireceğinizi, [AutoClass](#autoclass) desteğini nasıl etkinleştireceğinizi ve Hub üzerinde nasıl paylaşacağınızı gösterecektir.

## Yapılandırma

[PreTrainedConfig](/docs/transformers/main/tr/main_classes/configuration#transformers.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:

1. Özel bir yapılandırma, [PreTrainedConfig](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig)'in bir alt sınıfı olmalıdır. Bu, özel bir modelin [from_pretrained()](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig.from_pretrained), [save_pretrained()](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained) ve [push_to_hub()](/docs/transformers/main/tr/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub) gibi Transformers modellerinin tüm işlevselliğine sahip olmasını sağlar.
2. [PreTrainedConfig](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig) `__init__` herhangi bir `kwargs` değerini kabul etmeli ve bunlar üst sınıfın `__init__` metoduna iletilmelidir. [PreTrainedConfig](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig), özel yapılandırmanızda ayarlananlardan daha fazla alana sahiptir; bu nedenle bir yapılandırmayı [from_pretrained()](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig.from_pretrained) ile yüklediğinizde, bu alanlar yapılandırmanız tarafından kabul edilmeli ve üst sınıfa iletilmelidir.

> [!TIP]
> Bazı parametrelerin geçerliliğini kontrol etmek faydalıdır. Aşağıdaki örnekte, `block_type` ve `stem_type`'in önceden tanımlanmış değerlerden birine ait olduğunu sağlamak için bir kontrol uygulanmıştır.
>
> [AutoClass](#autoclass) desteğini etkinleştirmek için yapılandırma sınıfına `model_type` ekleyin.

```py
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()](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained) ile özel model klasörünüz olan `custom-resnet` içinde bir JSON dosyası olarak kaydedin.

```py
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](/docs/transformers/main/tr/main_classes/model#transformers.PreTrainedModel) sınıfından türetilir. [PreTrainedConfig](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig) gibi, [PreTrainedModel](/docs/transformers/main/tr/main_classes/model#transformers.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 sözleşmesini izler. Bu, `config` nesnesini alt katmanlara tek tek geçirilen birden çok 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.

> [!TIP]
> [AutoClass](#autoclass) desteğini etkinleştirmek için model sınıfına `config_class` ekleyin.

```py
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.

> [!TIP]
> [AutoClass](#autoclass) desteğini etkinleştirmek için model sınıfına `config_class` ekleyin.

```py
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 döndürmek (`ResnetModelForImageClassification` gibi), özel modeli [Trainer](/docs/transformers/main/tr/main_classes/trainer#transformers.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.

```py
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](https://hf.co/docs/timm/index) kütüphanesinden yükleyin ve ardından bu ağırlıkları [load_state_dict](https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module.load_state_dict) ile özel modele aktarın.

```py
import timm

pretrained_model = timm.create_model("resnet50d", pretrained=True)
resnet50d.model.load_state_dict(pretrained_model.state_dict())
```

## AutoClass

[AutoClass](./models#model-classes) 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](./models#model-classes) API'sine eklemek için [register()](/docs/transformers/main/tr/model_doc/auto#transformers.AutoConfig.register) yöntemini kullanın.

> [!TIP]
> [AutoConfig.register()](/docs/transformers/main/tr/model_doc/auto#transformers.AutoConfig.register) işlevinin ilk argümanı, özel yapılandırma sınıfındaki `model_type` özniteliğiyle eşleşmeli ve `AutoModel.register()` işlevinin ilk argümanı, özel model sınıfının `config_class` değeriyle eşleşmelidir.

```py
from transformers import AutoConfig, AutoModel, AutoModelForImageClassification

AutoConfig.register("resnet", ResnetConfig)
AutoModel.register(ResnetConfig, ResnetModel)
AutoModelForImageClassification.register(ResnetConfig, ResnetModelForImageClassification)
```

Özel model kodunuz artık [AutoClass](#autoclass) API'si ile uyumlu. Kullanıcılar modeli [AutoModel](./model_doc/auto) veya [AutoModelForImageClassification](/docs/transformers/main/tr/model_doc/auto#transformers.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](https://hf.co/models)'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`: `ResnetModel` ve `ResnetModelForImageClassification` sınıflarının kodunu içerir. Bu dosya, diğer dosyalarla aynı dizinde oldukları sürece göreceli içe aktarmalara (relative imports) güvenebilir.

> [!WARNING]
> Bir Transformers model dosyasını kopyalarken, `modeling.py` dosyasının başındaki tüm göreli importları değiştirerek importları Transformers'tan yapın.

- `configuration.py`: `ResnetConfig` için kodu içerir.
- `__init__.py`: Boş olabilir, bu dosya Python'un `resnet_model`'i bir modül olarak kullanılmasına olanak tanır.

```bash
.
└── resnet_model
    ├── __init__.py
    ├── configuration_resnet.py
    └── modeling_resnet.py
```

Modeli paylaşmak için ResNet modelini ve yapılandırmasını içe aktarın.

```py
from resnet_model.configuration_resnet import ResnetConfig
from resnet_model.modeling_resnet import ResnetModel, ResnetModelForImageClassification
```

Model ve yapılandırma dosyalarındaki kodu kopyalayın. AutoClass nesnelerinin [save_pretrained()](/docs/transformers/main/tr/main_classes/model#transformers.PreTrainedModel.save_pretrained) ile kaydedildiğinden emin olmak için [register_for_auto_class()](/docs/transformers/main/tr/main_classes/configuration#transformers.PreTrainedConfig.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.

```py
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.

```json
"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.

```py
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.

```bash
hf auth login
```

```py
from huggingface_hub import notebook_login

notebook_login()
```

Modeli Hub'a yüklemek için modele [push_to_hub()](/docs/transformers/main/tr/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub) çağrısı yapın.

```py
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](https://hf.co/sgugger/custom-resnet50d) içinde Hub'a yüklenmelidir.

Özel bir model, Transformers modelleriyle aynı modelleme kodunu kullanmadığı için yüklemek için [from_pretrained()](/docs/transformers/main/tr/main_classes/model#transformers.PreTrainedModel.from_pretrained) içinde `trust_remote_code=True` parametresini eklemeniz gerekir. Daha fazla bilgi için [özel modelleri yükleme](./models#custom-models) bölümüne bakın.

