ডেটাসেট

অনেক মেশিন লার্নিং মডেলে, বিশেষ করে তত্ত্বাবধানে শেখার জন্য, ডেটাসেট প্রশিক্ষণ প্রক্রিয়ার একটি গুরুত্বপূর্ণ অংশ। সুইফট ফর টেনসরফ্লো মডেল রিপোজিটরিতে ডেটাসেট মডিউলের মধ্যে বেশ কিছু সাধারণ ডেটাসেটের জন্য মোড়ক সরবরাহ করে। এই মোড়কগুলি সুইফ্ট-ভিত্তিক মডেলগুলির সাথে সাধারণ ডেটাসেটগুলির ব্যবহার সহজ করে এবং টেনসরফ্লো-এর সাধারণ প্রশিক্ষণ লুপের জন্য সুইফটের সাথে ভালভাবে সংহত করে৷

ডেটাসেট মোড়ক সরবরাহ করা হয়েছে

মডেল সংগ্রহস্থলের মধ্যে এইগুলি বর্তমানে সরবরাহ করা ডেটাসেট মোড়ক:

একটি সুইফ্ট প্রকল্পের মধ্যে এই ডেটাসেট র‍্যাপারগুলির মধ্যে একটি ব্যবহার করতে, আপনার সুইফ্ট লক্ষ্যে নির্ভরতা হিসাবে Datasets যোগ করুন এবং মডিউলটি আমদানি করুন:

import Datasets

বেশিরভাগ ডেটাসেট মোড়কগুলি লেবেলযুক্ত ডেটার এলোমেলোভাবে এলোমেলো ব্যাচ তৈরি করার জন্য ডিজাইন করা হয়েছে। উদাহরণস্বরূপ, CIFAR-10 ডেটাসেট ব্যবহার করার জন্য, আপনি প্রথমে এটি পছন্দসই ব্যাচ আকারের সাথে শুরু করুন:

let dataset = CIFAR10(batchSize: 100)

প্রথম ব্যবহারে, সুইফ্ট ফর টেনসরফ্লো ডেটাসেট র‍্যাপারগুলি স্বয়ংক্রিয়ভাবে আপনার জন্য আসল ডেটাসেট ডাউনলোড করবে, সমস্ত প্রাসঙ্গিক আর্কাইভগুলিকে এক্সট্র্যাক্ট এবং পার্স করবে এবং তারপরে একটি ব্যবহারকারী-স্থানীয় ক্যাশে ডিরেক্টরিতে প্রক্রিয়াকৃত ডেটাসেট সংরক্ষণ করবে৷ একই ডেটাসেটের পরবর্তী ব্যবহার সরাসরি স্থানীয় ক্যাশে থেকে লোড হবে।

এই ডেটাসেট জড়িত একটি ম্যানুয়াল প্রশিক্ষণ লুপ সেট আপ করতে, আপনি নিম্নলিখিত মত কিছু ব্যবহার করবেন:

for (epoch, epochBatches) in dataset.training.prefix(100).enumerated() {
  Context.local.learningPhase = .training
  ...
  for batch in epochBatches {
    let (images, labels) = (batch.data, batch.label)
    ...
  }
}

উপরেরটি 100টি যুগের মাধ্যমে একটি পুনরাবৃত্তিকারী সেট আপ করে ( .prefix(100) ), এবং বর্তমান যুগের সংখ্যাসূচক সূচক এবং সেই যুগটি তৈরি করে এমন এলোমেলো ব্যাচগুলির উপর একটি অলসভাবে ম্যাপ করা ক্রম ফেরত দেয়। প্রতিটি প্রশিক্ষণ যুগের মধ্যে, ব্যাচগুলি পুনরাবৃত্তি করা হয় এবং প্রক্রিয়াকরণের জন্য বের করা হয়। CIFAR10 ডেটাসেট র‍্যাপারের ক্ষেত্রে, প্রতিটি ব্যাচ হল একটি LabeledImage , যা একটি Tensor<Float> প্রদান করে যাতে সেই ব্যাচের সমস্ত ছবি থাকে এবং একটি Tensor<Int32> তাদের মিলিত লেবেল সহ।

CIFAR-10-এর ক্ষেত্রে, পুরো ডেটাসেটটি ছোট এবং এক সময়ে মেমরিতে লোড করা যায়, কিন্তু অন্যান্য বড় ডেটাসেটের জন্য ব্যাচগুলি ডিস্ক থেকে অলসভাবে লোড করা হয় এবং প্রতিটি ব্যাচ যেখানে প্রাপ্ত হয় সেখানে প্রক্রিয়া করা হয়। এটি সেই বৃহত্তর ডেটাসেটের সাথে মেমরির ক্লান্তি রোধ করে।

Epochs API

এই ডেটাসেট র‍্যাপারগুলির বেশিরভাগই একটি ভাগ করা পরিকাঠামোতে নির্মিত যাকে আমরা Epochs API বলেছি৷ Epochs নমনীয় উপাদান সরবরাহ করে যা বিভিন্ন ধরণের ডেটাসেট, পাঠ্য থেকে চিত্র এবং আরও অনেক কিছুকে সমর্থন করার উদ্দেশ্যে।

আপনি যদি নিজের সুইফ্ট ডেটাসেট র‍্যাপার তৈরি করতে চান, তাহলে আপনি সম্ভবত এটি করতে Epochs API ব্যবহার করতে চাইবেন। যাইহোক, সাধারণ ক্ষেত্রে, যেমন ইমেজ শ্রেণীবিভাগ ডেটাসেটগুলির জন্য, আমরা একটি বিদ্যমান ডেটাসেট মোড়কের উপর ভিত্তি করে একটি টেমপ্লেট থেকে শুরু করার এবং আপনার নির্দিষ্ট প্রয়োজন মেটাতে এটি পরিবর্তন করার সুপারিশ করি।

একটি উদাহরণ হিসাবে, আসুন CIFAR-10 ডেটাসেট মোড়ক এবং এটি কীভাবে কাজ করে তা পরীক্ষা করা যাক। প্রশিক্ষণ ডেটাসেটের মূলটি এখানে সংজ্ঞায়িত করা হয়েছে:

let trainingSamples = loadCIFARTrainingFiles(in: localStorageDirectory)
training = TrainingEpochs(samples: trainingSamples, batchSize: batchSize, entropy: entropy)
  .lazy.map { (batches: Batches) -> LazyMapSequence<Batches, LabeledImage> in
    return batches.lazy.map{
      makeBatch(samples: $0, mean: mean, standardDeviation: standardDeviation, device: device)
  }
}

loadCIFARTrainingFiles() ফাংশনের ফলাফল হল প্রশিক্ষণ ডেটাসেটের প্রতিটি চিত্রের জন্য (data: [UInt8], label: Int32) টিপলের একটি অ্যারে। তারপর এটি TrainingEpochs(samples:batchSize:entropy:) কে batchSize ব্যাচ সহ যুগের একটি অসীম ক্রম তৈরি করার জন্য প্রদান করা হয়। আপনি আপনার নিজস্ব র্যান্ডম নম্বর জেনারেটর প্রদান করতে পারেন যেখানে আপনি নির্ধারক ব্যাচিং আচরণ চাইতে পারেন, কিন্তু ডিফল্টরূপে SystemRandomNumberGenerator ব্যবহার করা হয়।

সেখান থেকে, ব্যাচগুলির উপর অলস মানচিত্রগুলি makeBatch(samples:mean:standardDeviation:device:) ফাংশনে শেষ হয়। এটি একটি কাস্টম ফাংশন যেখানে CIFAR-10 ডেটাসেটের জন্য প্রকৃত ইমেজ প্রসেসিং পাইপলাইন অবস্থিত, তাই আসুন এটি একবার দেখে নেওয়া যাক:

fileprivate func makeBatch<BatchSamples: Collection>(
  samples: BatchSamples, mean: Tensor<Float>?, standardDeviation: Tensor<Float>?, device: Device
) -> LabeledImage where BatchSamples.Element == (data: [UInt8], label: Int32) {
  let bytes = samples.lazy.map(\.data).reduce(into: [], +=)
  let images = Tensor<UInt8>(shape: [samples.count, 3, 32, 32], scalars: bytes, on: device)

  var imageTensor = Tensor<Float>(images.transposed(permutation: [0, 2, 3, 1]))
  imageTensor /= 255.0
  if let mean = mean, let standardDeviation = standardDeviation {
    imageTensor = (imageTensor - mean) / standardDeviation
  }

  let labels = Tensor<Int32>(samples.map(\.label), on: device)
  return LabeledImage(data: imageTensor, label: labels)
}

এই ফাংশনের দুটি লাইন ইনকামিং BatchSamples থেকে সমস্ত data বাইটকে একটি Tensor<UInt8> এ সংযুক্ত করে যা কাঁচা CIFAR-10 ডেটাসেটের মধ্যে থাকা চিত্রগুলির বাইট বিন্যাসের সাথে মেলে। এরপরে, আমাদের স্ট্যান্ডার্ড ইমেজ ক্লাসিফিকেশন মডেলগুলিতে প্রত্যাশিতগুলির সাথে মেলে ছবির চ্যানেলগুলিকে পুনরায় সাজানো হয় এবং মডেল ব্যবহারের জন্য চিত্র ডেটাকে Tensor<Float> -এ পুনরায় কাস্ট করা হয়।

ঐচ্ছিক স্বাভাবিককরণ পরামিতিগুলি ইমেজ চ্যানেলের মানগুলিকে আরও সামঞ্জস্য করার জন্য প্রদান করা যেতে পারে, একটি প্রক্রিয়া যা অনেকগুলি চিত্র শ্রেণিবিন্যাসের মডেল প্রশিক্ষণের সময় সাধারণ। নর্মালাইজেশন প্যারামিটার Tensor একবার ডেটাসেট ইনিশিয়ালাইজেশনের সময় তৈরি করা হয় এবং তারপরে একই মান সহ ছোট অস্থায়ী টেনসরগুলির পুনরাবৃত্তি রোধ করার জন্য একটি অপ্টিমাইজেশান হিসাবে makeBatch() এ পাস করা হয়।

অবশেষে, পূর্ণসংখ্যা লেবেলগুলি একটি Tensor<Int32> এ স্থাপন করা হয় এবং চিত্র / লেবেল টেনসর জোড়া একটি LabeledImage এ ফিরে আসে। একটি LabeledImage হল LabeledData এর একটি নির্দিষ্ট কেস, ডেটা এবং লেবেল সহ একটি কাঠামো যা Eppch API এর Collatable প্রোটোকলের সাথে সামঞ্জস্যপূর্ণ।

বিভিন্ন ডেটাসেট প্রকারে Epochs API-এর আরও উদাহরণের জন্য, আপনি মডেল সংগ্রহস্থলের মধ্যে অন্যান্য ডেটাসেট মোড়কগুলি পরীক্ষা করতে পারেন।