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.
- MNIST
- Fashion-MNIST
- KMNIST
- EMNIST
- QMNIST
- FakeData
- COCO
- LSUN
- ImageFolder
- DatasetFolder
- ImageNet
- CIFAR
- STL10
- SVHN
- PhotoTour
- SBU
- Flickr
- VOC
- Cityscapes
- SBD
- USPS
- Kinetics-400
- HMDB51
- UCF101
- CelebA
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
- airplanes
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/airplanes/image_1.jpg 0 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.