![]() | ![]() | ![]() | ![]() |
এই টিউটোরিয়ালটি দেখায় যে কীভাবে একটি ডিপ কনভোলিউশনাল জেনারেটাল অ্যাডভারসিয়াল নেটওয়ার্ক (ডিসিজিএএন) ব্যবহার করে হস্তাক্ষর ডিজিটের চিত্র তৈরি করা যায়। কোডটিtf.GradientTape
.tf.GradientTape
প্রশিক্ষণ লুপের সাহায্যে কেরাসtf.GradientTape
এপিআই ব্যবহার করে রচিত।
জিএনএস কি?
জেনারেটর অ্যাডভারসিয়াল নেটওয়ার্ক (জিএএনএস) আজ কম্পিউটার বিজ্ঞানের অন্যতম আকর্ষণীয় ধারণা। দুটি মডেল একসাথে একটি বিদ্বেষমূলক প্রক্রিয়া দ্বারা প্রশিক্ষিত হয়। একজন জেনারেটর ("শিল্পী") এমন চিত্র তৈরি করতে শেখে যা বাস্তব দেখায়, অন্যদিকে বৈষম্যমূলক ("শিল্প সমালোচক") জাল ছাড়াও আসল চিত্রগুলি বলতে শেখে learn
প্রশিক্ষণের সময়, জেনারেটরটি যথাযথ চিত্রগুলি তৈরি করতে ধীরে ধীরে আরও ভাল হয়ে ওঠে, অন্যদিকে বৈষম্যমূলক ব্যক্তি তাদের আলাদা করে বলতে আরও ভাল হয়ে যায়। প্রক্রিয়াটি ভারসাম্যহীন অবস্থায় পৌঁছে যায় যখন বৈষম্যকারী আর বাস্তব চিত্রগুলিকে জাল থেকে আলাদা করতে না পারে।
এই নোটবুকটি এমএনআইএসটি ডেটাশেটে এই প্রক্রিয়াটি দেখায়। নিম্নলিখিত অ্যানিমেশনটি জেনারেটর দ্বারা উত্পাদিত বেশ কয়েকটি চিত্রের চিত্র দেখায় কারণ এটি 50 যুগের জন্য প্রশিক্ষিত হয়েছিল। চিত্রগুলি এলোমেলো শব্দ হিসাবে শুরু হয় এবং সময়ের সাথে সাথে হাতের লিখিত অঙ্কগুলির সাথে সাদৃশ্যপূর্ণ।
জিএএনএস সম্পর্কে আরও জানতে, আমরা এমআইটির ইনট্রো টু ডিপ লার্নিং কোর্সের প্রস্তাব দিই।
সেটআপ
import tensorflow as tf
tf.__version__
'2.3.0'
# To generate GIFs
pip install -q imageio
pip install -q git+https://github.com/tensorflow/docs
import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
from tensorflow.keras import layers
import time
from IPython import display
ডেটাसेट লোড করুন এবং প্রস্তুত করুন
আপনি জেনারেটর এবং বৈষম্যমূলক প্রশিক্ষককে MNIST ডেটাसेट ব্যবহার করবেন। জেনারেটর এমএনআইএসটি ডেটার অনুরূপ হস্তাক্ষর ডিজিট উত্পন্ন করবে।
(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
train_images = (train_images - 127.5) / 127.5 # Normalize the images to [-1, 1]
BUFFER_SIZE = 60000
BATCH_SIZE = 256
# Batch and shuffle the data
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
মডেল তৈরি করুন
জেনারেটর এবং বৈষম্যমূলক উভয়ই কেরাস সিক্যুয়ালিয়াল এপিআই ব্যবহার করে সংজ্ঞায়িত করা হয়।
জেনারেটর
জেনারেটর tf.keras.layers.Conv2DTranspose
(আপসাম্পলিং) স্তর ব্যবহার করে একটি বীজ (এলোমেলো শব্দ) থেকে একটি চিত্র তৈরি করতে। একটি Dense
স্তর দিয়ে শুরু করুন যা এই বীজটিকে ইনপুট হিসাবে গ্রহণ করবে, তারপরে আপনি 28x28x1 এর পছন্দসই চিত্রের আকার না পৌঁছা পর্যন্ত বেশ কয়েকবার উপশম করুন। tf.keras.layers.LeakyReLU
প্রতিটি স্তরের জন্য অ্যাক্টিভেশন লক্ষ্য করুন, tf.keras.layers.LeakyReLU
ব্যবহার করে আউটপুট স্তর ব্যতীত।
def make_generator_model():
model = tf.keras.Sequential()
model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Reshape((7, 7, 256)))
assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size
model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)
return model
একটি চিত্র তৈরি করতে (এখনও প্রশিক্ষণপ্রাপ্ত) জেনারেটরটি ব্যবহার করুন।
generator = make_generator_model()
noise = tf.random.normal([1, 100])
generated_image = generator(noise, training=False)
plt.imshow(generated_image[0, :, :, 0], cmap='gray')
<matplotlib.image.AxesImage at 0x7f2729b9f6d8>
বিভেদকারী
বৈষম্যকারী একটি সিএনএন-ভিত্তিক চিত্র শ্রেণিবদ্ধ।
def make_discriminator_model():
model = tf.keras.Sequential()
model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
input_shape=[28, 28, 1]))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Flatten())
model.add(layers.Dense(1))
return model
উত্পন্ন চিত্রগুলিকে আসল বা নকল হিসাবে শ্রেণিবদ্ধ করতে (এখনও প্রশিক্ষিত না হওয়া) বৈষম্যমূলক ব্যবহার করুন। মডেলটিকে আসল চিত্রগুলির জন্য ইতিবাচক মানগুলি এবং জাল চিত্রগুলির জন্য নেতিবাচক মানগুলি আউটপুট দেওয়ার প্রশিক্ষণ দেওয়া হবে।
discriminator = make_discriminator_model()
decision = discriminator(generated_image)
print (decision)
tf.Tensor([[0.0003284]], shape=(1, 1), dtype=float32)
ক্ষতি এবং অপ্টিমাইজার সংজ্ঞা দিন
উভয় মডেলের জন্য ক্ষতির ফাংশন এবং অপ্টিমাইজার সংজ্ঞায়িত করুন।
# This method returns a helper function to compute cross entropy loss
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
বৈষম্যহীন লোকসান
এই পদ্ধতিটি বৈষম্যমূলক বাস্তব চিত্রগুলিকে জাল থেকে আলাদা করতে কতটা সক্ষম তা প্রমাণ করে। এটি আসল চিত্রগুলিতে বৈষম্যমূলক ভবিষ্যদ্বাণীগুলি 1 এর অ্যারের সাথে তুলনা করে, এবং জাল (উত্পন্ন) চিত্রগুলিতে বৈষম্যমূলক ভবিষ্যদ্বাণীগুলি 0 এর অ্যারের সাথে তুলনা করে।
def discriminator_loss(real_output, fake_output):
real_loss = cross_entropy(tf.ones_like(real_output), real_output)
fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
total_loss = real_loss + fake_loss
return total_loss
জেনারেটর ক্ষতি
জেনারেটরের ক্ষতি বৈষম্যমূলককে ঠকানোর জন্য কতটা সক্ষম হয়েছিল তা পরিমাপ করে। স্বজ্ঞাতভাবে, যদি জেনারেটর ভাল পারফর্ম করে তবে বৈষম্যমূলক ব্যক্তি জাল চিত্রগুলি বাস্তব (বা 1) হিসাবে শ্রেণিবদ্ধ করবে। এখানে, আমরা উত্পন্ন চিত্রগুলিতে বৈষম্যমূলক সিদ্ধান্তগুলি 1s এর অ্যারের সাথে তুলনা করব।
def generator_loss(fake_output):
return cross_entropy(tf.ones_like(fake_output), fake_output)
বৈষম্যকারী এবং জেনারেটর অপ্টিমাইজারগুলি পৃথক, যেহেতু আমরা দুটি নেটওয়ার্ক পৃথকভাবে প্রশিক্ষণ দেব।
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)
চেকপয়েন্টগুলি সংরক্ষণ করুন
এই নোটবুকটি মডেলগুলিকে কীভাবে সংরক্ষণ এবং পুনরুদ্ধার করবেন তাও দেখায়, যা দীর্ঘদিন ধরে চলমান প্রশিক্ষণের কোনও কাজ বাধাগ্রস্ত হওয়ার ক্ষেত্রে সহায়ক হতে পারে।
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
discriminator_optimizer=discriminator_optimizer,
generator=generator,
discriminator=discriminator)
প্রশিক্ষণের লুপটি সংজ্ঞায়িত করুন
EPOCHS = 50
noise_dim = 100
num_examples_to_generate = 16
# We will reuse this seed overtime (so it's easier)
# to visualize progress in the animated GIF)
seed = tf.random.normal([num_examples_to_generate, noise_dim])
প্রশিক্ষণের লুপটি জেনারেটরটিকে ইনপুট হিসাবে একটি এলোমেলো বীজ প্রাপ্তির সাথে শুরু হয়। যে বীজ একটি ইমেজ উত্পাদন করতে ব্যবহৃত হয়। এর পরে বৈষম্যমূলক আসল চিত্রগুলি শ্রেণীবদ্ধ করতে ব্যবহৃত হয় (প্রশিক্ষণের সেট থেকে আঁকা) এবং নকল চিত্রগুলি (জেনারেটর দ্বারা উত্পাদিত)। ক্ষতির পরিমাণ এই মডেলগুলির প্রত্যেকটির জন্য গণনা করা হয়, এবং গ্রেডিয়েন্টগুলি জেনারেটর এবং বৈষম্যমূলক আপডেট করতে ব্যবহৃত হয়।
# Notice the use of `tf.function`
# This annotation causes the function to be "compiled".
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
generated_images = generator(noise, training=True)
real_output = discriminator(images, training=True)
fake_output = discriminator(generated_images, training=True)
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)
gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))
def train(dataset, epochs):
for epoch in range(epochs):
start = time.time()
for image_batch in dataset:
train_step(image_batch)
# Produce images for the GIF as we go
display.clear_output(wait=True)
generate_and_save_images(generator,
epoch + 1,
seed)
# Save the model every 15 epochs
if (epoch + 1) % 15 == 0:
checkpoint.save(file_prefix = checkpoint_prefix)
print ('Time for epoch {} is {} sec'.format(epoch + 1, time.time()-start))
# Generate after the final epoch
display.clear_output(wait=True)
generate_and_save_images(generator,
epochs,
seed)
চিত্রগুলি তৈরি এবং সংরক্ষণ করুন
def generate_and_save_images(model, epoch, test_input):
# Notice `training` is set to False.
# This is so all layers run in inference mode (batchnorm).
predictions = model(test_input, training=False)
fig = plt.figure(figsize=(4,4))
for i in range(predictions.shape[0]):
plt.subplot(4, 4, i+1)
plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
plt.axis('off')
plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
plt.show()
মডেল প্রশিক্ষণ
এক সাথে জেনারেটর এবং বৈষম্যমূলক প্রশিক্ষণ দেওয়ার জন্য উপরের সংজ্ঞায়িত train()
কল করুন। নোট, জিএএনএস প্রশিক্ষণ করা কঠিন হতে পারে। জেনারেটর এবং বৈষম্যকারী একে অপরের উপর শক্তি প্রয়োগ না করা গুরুত্বপূর্ণ (যেমন, তারা একই হারে প্রশিক্ষণ দেয়)।
প্রশিক্ষণের শুরুতে, উত্পন্ন চিত্রগুলি এলোমেলো শব্দের মতো দেখাচ্ছে। প্রশিক্ষণের অগ্রগতির সাথে সাথে উত্পন্ন অঙ্কগুলি ক্রমশ আসল দেখবে। প্রায় 50 টি যুগের পরে, তারা এমএনআইএসটি ডিজিটের অনুরূপ। এটি কল্যাবের ডিফল্ট সেটিংসের সাথে প্রায় এক মিনিট / পর্ব সময় নিতে পারে।
train(train_dataset, EPOCHS)
সর্বশেষ চেকপয়েন্ট পুনরুদ্ধার করুন।
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f2729bc3128>
একটি জিআইএফ তৈরি করুন
# Display a single image using the epoch number
def display_image(epoch_no):
return PIL.Image.open('image_at_epoch_{:04d}.png'.format(epoch_no))
display_image(EPOCHS)
প্রশিক্ষণের সময় সংরক্ষিত চিত্রগুলি ব্যবহার করে একটি অ্যানিমেটেড imageio
তৈরি করতে চিত্রটি ব্যবহার করুন।
anim_file = 'dcgan.gif'
with imageio.get_writer(anim_file, mode='I') as writer:
filenames = glob.glob('image*.png')
filenames = sorted(filenames)
for filename in filenames:
image = imageio.imread(filename)
writer.append_data(image)
image = imageio.imread(filename)
writer.append_data(image)
import tensorflow_docs.vis.embed as embed
embed.embed_file(anim_file)
পরবর্তী পদক্ষেপ
এই টিউটোরিয়ালটি GAN লিখতে এবং প্রশিক্ষণের জন্য প্রয়োজনীয় সম্পূর্ণ কোডটি দেখিয়েছে। পরবর্তী পদক্ষেপ হিসাবে, আপনি অন্য কোনও ডেটাসেটের সাথে পরীক্ষা করতে পছন্দ করতে পারেন, উদাহরণস্বরূপ বড় আকারের সেলিব্রেস ফেসস অ্যাট্রিবিউটস (সেলিব্রে) ডেটাসেট কেগল-এ উপলব্ধ । জিএএনএস সম্পর্কে আরও জানার জন্য আমরা এনআইপিএস ২০১utorial টিউটোরিয়াল: জেনারেটর অ্যাডভারসিয়াল নেটওয়ার্কগুলির প্রস্তাব দিই ।