# TensorFlow ile Datasets Kullanımı

Bu belge, `datasets` kütüphanesinin TensorFlow ile kullanımına hızlı bir giriş niteliğindedir; odak noktası, veri setlerimizden `tf.Tensor` nesnelerini nasıl elde edeceğimiz ve Hugging Face `Dataset` nesnelerinden `model.fit()` gibi Keras yöntemlerine veri akışını nasıl sağlayacağımızdır.

## Veri seti biçimi

Varsayılan olarak veri kümeleri, tamsayılar, ondalık sayılar, dizeler, listeler gibi standart Python nesneleri döndürür.

Bunun yerine TensorFlow tensörleri almak için veri setinin biçimini `tf` olarak ayarlayabilirsiniz:

```py
>>> from datasets import Dataset
>>> data = [[1, 2],[3, 4]]
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("tf")
>>> ds[0]
{'data': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 2])>}
>>> ds[:2]
{'data': <tf.Tensor: shape=(2, 2), dtype=int64, numpy=
array([[1, 2],
       [3, 4]])>}
```

> [!TIP]
> Bir [Dataset](/docs/datasets/main/tr/package_reference/main_classes#datasets.Dataset) nesnesi, bir Arrow tablosunun sarmalayıcısıdır ve veri setindeki dizilerden TensorFlow tensörlerine hızlı okumalara olanak tanır.

Bu, veri setinizi `Tensor` nesnelerinden oluşan bir sözlüğe dönüştürmek veya ondan TF örneklerini yüklemek için bir üreteç yazmak için faydalı olabilir. Tüm veri setini `Tensor` olarak dönüştürmek istiyorsanız, yalnızca tam veri setini sorgulayın:

```py
>>> ds[:]
{'data': <tf.Tensor: shape=(2, 2), dtype=int64, numpy=
array([[1, 2],
       [3, 4]])>}
```

### N boyutlu diziler

Veri setiniz N boyutlu dizilerden oluşuyorsa, şekil sabit olduğunda varsayılan olarak bunların aynı tensör olarak ele alındığını göreceksiniz:

```py
>>> from datasets import Dataset
>>> data = [[[1, 2],[3, 4]],[[5, 6],[7, 8]]]  # fixed shape
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("tf")
>>> ds[0]
{'data': <tf.Tensor: shape=(2, 2), dtype=int64, numpy=
 array([[1, 2],
        [3, 4]])>}
```

Aksi takdirde, TensorFlow biçimli bir veri seti tek bir tensör yerine `RaggedTensor` çıktısı verir:

```py
>>> from datasets import Dataset
>>> data = [[[1, 2],[3]],[[4, 5, 6],[7, 8]]]  # varying shape
>>> ds = Dataset.from_dict({"data": data})
>>> ds = ds.with_format("torch")
>>> ds[0]
{'data': <tf.RaggedTensor [[1, 2], [3]]>}
```

Ancak bu mantık genellikle yavaş şekil karşılaştırmaları ve veri kopyalamaları gerektirir. Bunu önlemek için `Array` özellik türünü açıkça kullanmalı ve tensörlerinizin şeklini belirtmelisiniz:

```py
>>> from datasets import Dataset, Features, Array2D
>>> data = [[[1, 2],[3, 4]],[[5, 6],[7, 8]]]
>>> features = Features({"data": Array2D(shape=(2, 2), dtype='int32')})
>>> ds = Dataset.from_dict({"data": data}, features=features)
>>> ds = ds.with_format("tf")
>>> ds[0]
{'data': <tf.Tensor: shape=(2, 2), dtype=int64, numpy=
 array([[1, 2],
        [3, 4]])>}
>>> ds[:2]
{'data': <tf.Tensor: shape=(2, 2, 2), dtype=int64, numpy=
 array([[[1, 2],
         [3, 4]],
 
        [[5, 6],
         [7, 8]]])>}
```

### Diğer özellik türleri

[ClassLabel](/docs/datasets/main/tr/package_reference/main_classes#datasets.ClassLabel) verileri doğru şekilde tensörlere dönüştürülür:

```py
>>> from datasets import Dataset, Features, ClassLabel
>>> labels = [0, 0, 1]
>>> features = Features({"label": ClassLabel(names=["negative", "positive"])})
>>> ds = Dataset.from_dict({"label": labels}, features=features) 
>>> ds = ds.with_format("tf")  
>>> ds[:3]
{'label': <tf.Tensor: shape=(3,), dtype=int64, numpy=array([0, 0, 1])>}
```

Dizgiler ve ikili nesneler de desteklenir:

```py
>>> from datasets import Dataset, Features 
>>> text = ["foo", "bar"]
>>> data = [0, 1] 
>>> ds = Dataset.from_dict({"text": text, "data": data})  
>>> ds = ds.with_format("tf") 
>>> ds[:2]
{'text': <tf.Tensor: shape=(2,), dtype=string, numpy=array([b'foo', b'bar'], dtype=object)>,
 'data': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 1])>}
```

Belirli sütunları açıkça biçimlendirip diğer sütunları biçimlendirilmemiş bırakabilirsiniz:

```py
>>> ds = ds.with_format("tf", columns=["data"], output_all_columns=True)
>>> ds[:2]
{'data': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 1])>,
 'text': ['foo', 'bar']}
```

String ve ikili nesneler, PyTorch yalnızca sayıları desteklediği için değiştirilmez.

[Image](/docs/datasets/main/tr/package_reference/main_classes#datasets.Image) ve [Audio](/docs/datasets/main/tr/package_reference/main_classes#datasets.Audio) özellik türleri de desteklenir.

> [!TIP]
> [Image](/docs/datasets/main/tr/package_reference/main_classes#datasets.Image) özellik türünü kullanmak için `vision` ek paketini `pip install datasets[vision]` olarak yüklemeniz gerekir.

```py
>>> from datasets import Dataset, Features, Audio, Image
>>> images = ["path/to/image.png"] * 10
>>> features = Features({"image": Image()})
>>> ds = Dataset.from_dict({"image": images}, features=features) 
>>> ds = ds.with_format("tf")  
>>> ds[0]
{'image': <tf.Tensor: shape=(512, 512, 4), dtype=uint8, numpy=
 array([[[255, 215, 106, 255],
         [255, 215, 106, 255],
         ...,
         [255, 255, 255, 255],
         [255, 255, 255, 255]]], dtype=uint8)>}
>>> ds[:2]
{'image': <tf.Tensor: shape=(2, 512, 512, 4), dtype=uint8, numpy=
 array([[[[255, 215, 106, 255],
          [255, 215, 106, 255],
          ...,
          [255, 255, 255, 255],
          [255, 255, 255, 255]]]], dtype=uint8)>}
```

> [!TIP]
> [Audio](/docs/datasets/main/tr/package_reference/main_classes#datasets.Audio) özellik türünü kullanmak için `audio` ek paketini `pip install datasets[audio]` olarak yüklemeniz gerekir.

```py
>>> from datasets import Dataset, Features, Audio, Image
>>> audio = ["path/to/audio.wav"] * 10
>>> features = Features({"audio": Audio()})
>>> ds = Dataset.from_dict({"audio": audio}, features=features) 
>>> ds = ds.with_format("tf")  
>>> ds[0]["audio"]["array"]
<tf.Tensor: shape=(202311,), dtype=float32, numpy=
array([ 6.1035156e-05,  1.5258789e-05,  1.6784668e-04, ...,
       -1.5258789e-05, -1.5258789e-05,  1.5258789e-05], dtype=float32)>
>>> ds[0]["audio"]["sampling_rate"]
<tf.Tensor: shape=(), dtype=int32, numpy=44100>
```

## Veri yükleme

Veri setinize indeksleme yoluyla bireysel örnekleri ve partileri yükleyebilirsiniz ancak `fit()` ve `predict()` gibi Keras yöntemlerini kullanmak istediğinizde bu yöntem işe yaramaz. Veri setinizden partileri karıştırıp yükleyen ve bu veri üzerinde `fit()` çağrısı yapan bir üreteç fonksiyonu yazabilirsiniz ancak bu gereksiz bir iş yükü gibi görünür. Bunun yerine, veri setinizden veriyi anlık olarak akış halinde kullanmak istiyorsanız, veri setinizi `to_tf_dataset()` yöntemi kullanarak `tf.data.Dataset` nesnesine dönüştürmenizi öneririz.

`tf.data.Dataset` sınıfı geniş bir kullanım senaryosu yelpazesini kapsar - genellikle bellek içindeki Tensor'lerden veya diskteki veya harici depolamadaki dosyaları okumak için bir yükleme işlevi kullanılarak oluşturulur. Veri seti, `map()` yöntemiyle serbestçe dönüştürülebilir veya eğitim için hazır bir veri seti oluşturmak üzere `batch()` ve `shuffle()` gibi yöntemler kullanılabilir. Bu yöntemler, depolanan veriyi hiçbir şekilde değiştirmez - bunun yerine, veri seti üzerinde iterasyon yapıldığında, genellikle model eğitimi veya çıkarım sırasında çalıştırılacak bir veri hattı grafiği oluşturur. Bu, Hugging Face `Dataset` nesnelerinin `map()` yöntemiyle farklıdır; bu yöntem, map işlevini derhal çalıştırır ve yeni veya değiştirilen sütunları kaydeder.

Tüm veri ön işleme hattı `tf.data.Dataset` içinde derlenebildiği için bu yaklaşım, büyük ölçüde paralel ve asenkron veri yükleme ile eğitime olanak tanır. Ancak, grafik derleme gereksinimi bir kısıtlama olabilir; özellikle de genellikle (henüz!) bir TF grafiğinin parçası olarak derlenemeyen Hugging Face tokenizörleri için. Bu nedenle, genellikle veri setini, keyfi Python işlevlerinin kullanılabildiği bir Hugging Face veri seti olarak ön işlemeyi ve ardından eğitim için hazır, toplu (batched) bir veri seti elde etmek üzere `to_tf_dataset()` kullanarak `tf.data.Dataset` biçimine dönüştürmeyi öneririz. Bu yaklaşımın örneklerini görmek için `transformers` kütüphanesine ait [örnekleri](https://github.com/huggingface/transformers/tree/main/examples) veya [defterleri](https://huggingface.co/docs/transformers/notebooks) inceleyebilirsiniz.

### `to_tf_dataset()` kullanma

`to_tf_dataset()` kullanımı basittir. Veri setiniz ön işlemden geçirilip hazır olduğunda, aşağıdaki gibi çağırmanız yeterlidir:

```py
>>> from datasets import Dataset
>>> data = {"inputs": [[1, 2],[3, 4]], "labels": [0, 1]}
>>> ds = Dataset.from_dict(data)
>>> tf_ds = ds.to_tf_dataset(
            columns=["inputs"],
            label_cols=["labels"],
            batch_size=2,
            shuffle=True
            )
```

Burada döndürülen `tf_ds` nesnesi artık eğitim için tamamen hazır ve doğrudan `model.fit()` fonksiyonuna geçirilebilir. Toplu işleme boyutunu (batch size) veri setini oluştururken belirlediğinizi ve bu nedenle `fit()` çağrısında belirtmenize gerek olmadığını unutmayın:

```py
>>> model.fit(tf_ds, epochs=2)
```

Argümanların tam açıklaması için lütfen [to_tf_dataset()](/docs/datasets/main/tr/package_reference/main_classes#datasets.Dataset.to_tf_dataset) belgesine bakın. Birçok durumda, çağrınıza bir `collate_fn` de eklemeniz gerekecektir. Bu, veri setinin birden fazla öğesini alır ve bunları tek bir batch birleştirir. Tüm öğeler aynı uzunluğa sahipse yerleşik varsayılan collator yeterli olacaktır, ancak daha karmaşık görevler için özel bir collator gerekebilir. Özellikle, birçok görevde değişken dizi uzunluklarına sahip örnekler bulunur ve bu durum, batch'leri doğru şekilde doldurabilen bir [data collator](https://huggingface.co/docs/transformers/main/en/main_classes/data_collator) gerektirir. Değişken dizi uzunluklarının çok yaygın olduğu `transformers` NLP [örneklerinde](https://github.com/huggingface/transformers/tree/main/examples) ve [defterlerinde](https://huggingface.co/docs/transformers/notebooks) bunun örneklerini görebilirsiniz.

`to_tf_dataset` ile yüklemenin yavaş olduğunu fark ederseniz, `num_workers` argümanını da kullanabilirsiniz. Bu, verileri paralel olarak yüklemek için birden çok alt süreç başlatır. Bu özellik nispeten yeni ve hâlâ kısmen deneysel niteliktedir - kullanırken herhangi bir hata ile karşılaşırsanız lütfen bir sorun bildirin!

### to_tf_dataset ne zaman kullanılmalı

Dikkatli okuyucu, bu noktada aynı hedefe ulaşmak için iki yaklaşım sunduğumuzu fark etmiş olabilir - TensorFlow modeline veri setinizi geçirmek istiyorsanız, veri setini `.with_format('tf')` kullanarak `Tensor` veya `Tensors` içeren bir `dict` olarak dönüştürebilir ya da `to_tf_dataset()` ile veri setini `tf.data.Dataset` olarak dönüştürebilirsiniz. Bu iki seçeneğin her biri `model.fit()` fonksiyonuna geçirilebilir, peki hangisini seçmelisiniz?

Dikkat edilmesi gereken temel nokta, tüm veri setini `Tensor`'lara dönüştürdüğünüzde bunun statik olduğu ve RAM'e tamamen yüklendiğidir. Bu yöntem basit ve kullanışlıdır ancak aşağıdakilerden herhangi biri geçerliyse, bunun yerine `to_tf_dataset()` kullanmanız gerekir:

- Veri setiniz RAM'e sığmayacak kadar büyük. `to_tf_dataset()` her seferinde yalnızca bir parti (batch) akışlandırır, bu nedenle bu yöntemle çok büyük veri setleri de işlenebilir.
- `dataset.with_transform()` veya `collate_fn` kullanarak rastgele dönüşümler uygulamak istiyorsunuz. Bu, görüntü modelleri eğitirken görüntü artırma veya maskeli dil modelleri eğitirken rastgele maskeleme gibi çeşitli modalitelerde yaygındır. `to_tf_dataset()` kullanıldığında bu dönüşümler bir batch yüklendiği anda uygulanır; bu da aynı örneklerin her yüklendiğinde farklı artırma işlemlerine tabi tutulacağı anlamına gelir. Genellikle istediğiniz şey budur.
- Verileriniz değişken bir boyuta sahip olabilir; örneğin NLP'deki girdi metinleri farklı sayıda token'dan oluşabilir. Değişken boyuta sahip örneklerle bir batch oluşturduğunuzda standart çözüm, daha kısa örnekleri en uzun örneğin uzunluğuna kadar doldurmaktır (padding). Bir veri setinden `to_tf_dataset` ile örnekleri akışa aldığınızda, bu padding işlemini her batch için `collate_fn` üzerinden uygulayabilirsiniz. Ancak bu tür bir veri setini yoğun `Tensor`'lara dönüştürmek istiyorsanız, örnekleri *tüm veri setindeki* en uzun örneğin uzunluğuna kadar doldurmanız gerekir. Bu, devasa miktarda padding'e yol açabilir; bu da bellek israfına neden olur ve modelinizin hızını düşürür.

### Dikkat edilmesi gerekenler ve kısıtlamalar

Şu anda `to_tf_dataset()` her zaman toplu (batched) bir veri seti döndürür - toplu olmayan veri setleri için desteği yakında ekleyeceğiz!

