PYTORCH C++ İLE DERİN ÖĞRENME -2: Veri Yükleme

Herkese merhabalar. Serinin ikinci bölümünde veri yükleme işlemi yapacağız. Pytorch kütüphanesinde gömülü olan birçok veri seti bulunmaktadır. İlk kısımda olarak bu veri setleri yüklemeyi öğreneceğiz. İkinci kısım olarak Kendi oluşturduğumuz veri setlerini yüklemeyi öğrenceğiz.

Kodlara ve dosyalara, yazının sonunda bulunan github hesabıma girerek ulaşabilirsiniz.

Pytorch C++ yüklemediyseniz aşağıdaki serinin ilk bölümüne giderek kurulum işlemlerine buradan ulaşabilirsiniz:

Proje için CMakeLists.txt dosyası ve C++ uzantılı dosya oluşturmamız gerekmektedir.

CMakeLists.txt ve Pytorch_giris.cpp Dosyası Oluşturmak

ilk önce proje klasörü oluşturuyoruz.

$ mkdir Pytorch_2

mkdir komutu ile klasör oluşturuldu.

$ cd Pytorch_2/

Komut ile klasörün içerisine giriyoruz.

$ touch CMakeLists.txt

Komut ile CMakeLists.txt dosyası oluşturuldu.

$ touch Pytorch_2.cpp

Komut ile Pytorch_2.cpp dosyası oluşturuldu.

CMakeLists.txt Dosyasına Eklenecekler

CMakeLists.txt dosyasının içerisine giriyoruz.

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(Pytorch_giris)

find_package(Torch REQUIRED)

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(Pytorch_2)

find_package(Torch REQUIRED)

add_executable(pytorch Pytorch_2.cpp)
target_link_libraries(Pytorch_2 "${TORCH_LIBRARIES}")
set_property(TARGET Pytorch_2 PROPERTY CXX_STANDARD 14)

Yazıları CMakeLists.txt dosyasına ekliyoruz ve kaydediyoruz.

Pytorch_giris.cpp Dosyasına Eklenecekler

Hazır Veri Setlerini Yüklemek

C ++ ön ucu, Python gibi, güçlü bir paralel veri yükleyici ile birlikte gelir. Bu veri yükleyici, bir veri kümesinden (kendiniz tanımlayabileceğiniz) veri gruplarını okuyabilir ve birçok yapılandırma düğmesi sağlar.

auto dataset = torch::data::datasets::MNIST("./mnist")
    .map(torch::data::transforms::Normalize<>(0.5, 0.5))
    .map(torch::data::transforms::Stack<>());

torch::data::datasets fonksiyonu altında Pytorch kütüphanesine gömülü birçok veri setleri bulunmaktadır. Bu fonksiyon ile veri setlerini projenize tanımlayabilirsiniz. Bu kısımda projeye yüklenecek veri setini seciyoruz. Diğer parametreler ile bu veri setlerini yüklemeden önce üzerlerinde değişiklik yapabilmekteyiz.

.map(torch::data::transforms::Normalize<>(0.5, 0.5)) fonksiyonu ile veri setinde bulunan resimler üzerinde normalizasyon işlemi yapılabilmektedir. Bu normalizasyon ile resim piksel değerlerini -1 +1 değerleri arasında normalize edebilmekteyiz. Normalizasyon ile matematiksel işlem yükünü azaltıp daha hızlı sonuçlar alabilmekteyiz. Ayrıca piksellerin sayısal üstünlüğün özellik haritasında etkisi olmadığı için bu işlem yapılamtadır.

.map(torch::data::transforms::Stack<>()); fonksiyonu ile bir grup tensörü alan ve onları ilk boyut boyunca tek bir tensöre yığan yığın harmanlamasını uygularız

Veri setini tanımladıktan sonra tanımlanan veri seti projeye yüklenecektir.

auto data_loader = torch::data::make_data_loader(
    std::move(dataset),
    torch::data::DataLoaderOptions().batch_size(kBatchSize).workers(2));

Verileri yukarıdaki fonksiyon ile yükleyebiliriz. Yüklerken yığın boyutunu belirleyebiliriz. Yığın boyutu ile sistemi zorlamamak ve modelin hızlı çalışmasını sağlamak amacıyla verileri bir anda değil yığın şeklinde verebilmeteyiz.

struct DataLoaderOptions {
  DataLoaderOptions() = default;
      : batch_size_(batch_size) {}

  TORCH_ARG(size_t, batch_size) = 1;
  TORCH_ARG(size_t, workers) = 0;
  TORCH_ARG(optional<size_t>, max_jobs);
  TORCH_ARG(optional<std::chrono::milliseconds>, timeout);
  TORCH_ARG(bool, enforce_ordering) = true;
  TORCH_ARG(bool, drop_last) = false;

Yukarıdaki fonksiyonda tanımlandığı gibi torch::data::DataLoaderOptions() fonksiyonu ile veri setini nasıl yükleneceği seçilebilmektedir.

for (torch::data::Example<>& batch : *data_loader) {
  std::cout << "Batch size: " << batch.data.size(0) << " | Labels: ";
  for (int64_t i = 0; i < batch.data.size(0); ++i) {
    std::cout << batch.target[i].item<int64_t>() << " ";
  }
  std::cout << std::endl;
}

Yüklenen veri setinin içeriğinde resimler veya resimlerin piksel değerleri bulunmaktadır. İkinci olarak bu resimlerin etiketleri bulunkatadır. Yukarıdaki kod bloğu ile bu etiketlerin çıktısını konsol üzerinden alabilmeteyiz.

Pytorch kütüphanesinde python programlama dili ile kullanılabilen veri setleri C++ programlama dili ile torch kütüphanesinde kullanılabilmektedir. Kullanılabilen veri setleri aşağıdadır.

Oluşturulan Veri Setlerini Yüklemek

Torch kütüphanesine gömülü olmayan, kendi oluşturduğunuz veri setlerini torch kütüphanesi ile yükleyebilirsiniz. Bu kısımda kendi oluşturduğunuz veri setleri nasıl yükleneceği anlatılacaktır.

Veri setinin bulunduğu klasörün içeriği aşagıdaki gibi olmalıdır.

  • Dataset
    • airplanes
      • images
    • motorcycle
      • images

Veri seti için info.txt dosyası oluşturmamız gerekmektedir. Dosyanın içeriği aşağıdaki gibi olmalıdır.

  • info.txt
    • Dataset/airplanes/image_1.jpg 0 train
      Dataset/airplanes/image_2.jpg 0 train
      Dataset/airplanes/image_3.jpg 0 train
      Dataset/airplanes/image_4.jpg 0 train
      Dataset/airplanes/image_5.jpg 0 train
      Dataset/motorcycle/image_6.jpg 1 train
      Dataset/motorcycle/image_7.jpg 1 train
      Dataset/motorcycle/image_8.jpg 1 train
      Dataset/motorcycle/image_9.jpg 1 train
      Dataset/motorcycle/image_10.jpg 1 train

Dataset dosya ismi / sınıf dosya ismi / resim ismi / sınıf (sayı olarak) / train-validation-test (kullanım amacı).

class CustomDataset : public torch::data::datasets::Dataset<CustomDataset> {
  using Example = torch::data::Example<>;

 CustomDataset(const Data& data) : data(data) {}

  Example get(size_t index) {
    std::string path = options.datasetPath + data[index].first;
    auto mat = cv::imread(path);
    assert(!mat.empty());

    cv::resize(mat, mat, cv::Size(options.image_size, options.image_size));
    std::vector<cv::Mat> channels(3);
    cv::split(mat, channels);

    auto R = torch::from_blob(
        channels[2].ptr(),
        {options.image_size, options.image_size},
        torch::kUInt8);
    auto G = torch::from_blob(
        channels[1].ptr(),
        {options.image_size, options.image_size},
        torch::kUInt8);
    auto B = torch::from_blob(
        channels[0].ptr(),
        {options.image_size, options.image_size},
        torch::kUInt8);

    auto tdata = torch::cat({R, G, B})
                     .view({3, options.image_size, options.image_size})
                     .to(torch::kFloat);
    auto tlabel = torch::from_blob(&data[index].second, {1}, torch::kLong);
    return {tdata, tlabel};
  }

  torch::optional<size_t> size() const {
    return data.size();
  }
};

std::pair<Data, Data> readInfo() {
  Data train, test;

  std::ifstream stream(options.infoFilePath);
  assert(stream.is_open());

  long label;
  std::string path, type;

while (true) {
    stream >> path >> label >> type;

    if (type == "train")
      train.push_back(std::make_pair(path, label));
    else
      assert(false);

    if (stream.eof())
      break;
  }

Yukarıdaki kod bloğu ile veri setini yüklemek için gerekli fonksiyonlar oluşturuldu. Bu fonksyionları projeleriniz için uygulayabilirsiniz. Başka projelerde kod üzerinde değişiklik yapmadan kullanılabilmektedir .

 if (torch::cuda::is_available())
    options.device = torch::kCUDA;
  std::cout << "Running on: "
            << (options.device == torch::kCUDA ? "CUDA" : "CPU") << std::endl;

Yukarıdaki kod bloğu ile GPU ya sahip ekran kartınız var ise GPU yu kullanarak işlemlerinizi yapabilirsiniz. Eğer GPU destekleyen ekran kartına sahip değilseniz CPU kullanarak işlemleri gerçekleştirebilirsiniz.

auto train_set =
      CustomDataset(data.first).map(torch::data::transforms::Stack<>());
  auto train_size = train_set.size().value();
  auto train_loader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
          std::move(train_set), options.train_batch_size);

Yukarıdaki kod bloğu ile oluşturduğumuz veri setini tanımlamış ve projemize başarı ile yüklemiş oluyoruz.

Serinin ikinci bölümünde 1. kısımda torch kütüphanesine gömülü hazır veri setlerini projemize tanımlamış ve yüklemiş olduk. 2. kısımda kendi oluşturduğumuz veri setini tanımlamış ve yüklemiş bulunmaktayız. Serinin sonraki bölümünde projemize entegre ettiğimiz veri setini eğitip test etmeyi yapacağız.

Serinin sonraki bölümlerinde görüşmek dileğiyle.

Hazır veri setini tanımlama ve yükleme işlemlerini yaptığımız kodlara buradan ulaşabilirsiniz.

Kendi oluşturduğumuz veri setini tanımlama ve yükleme işlemlerini yaptığımız kodlara buradan ulaşabilirsiniz.

Kaynakça

Yazar Hakkında
Toplam 15 yazı
Abdullah Enes Doruk
Abdullah Enes Doruk
Bursa Teknik Üniversitesi Elektrik Elektronik Mühendisliği Bölümü öğrencisi. İlgilendiği alanlar; Görüntü işleme, Sürücüsüz Araçlar, Derin Öğrenme.Abdullah Enes Doruk
Yorumlar (Yorum yapılmamış)

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

×

Bir Şeyler Ara