TensorFlow.org এ দেখুন | Google Colab-এ চালান | GitHub-এ উৎস দেখুন | নোটবুক ডাউনলোড করুন |
এই টিউটোরিয়ালে, আপনি শিখবেন কিভাবে একটি প্রাক-প্রশিক্ষিত নেটওয়ার্ক থেকে ট্রান্সফার লার্নিং ব্যবহার করে বিড়াল এবং কুকুরের ছবিকে শ্রেণীবদ্ধ করতে হয়।
একটি প্রাক-প্রশিক্ষিত মডেল হল একটি সংরক্ষিত নেটওয়ার্ক যা পূর্বে একটি বৃহৎ ডেটাসেটে, সাধারণত একটি বৃহৎ-স্কেল চিত্র-শ্রেণীবিভাগের কাজে প্রশিক্ষিত ছিল। আপনি হয় পূর্বপ্রশিক্ষিত মডেলটি ব্যবহার করুন বা এই মডেলটিকে একটি নির্দিষ্ট কাজের জন্য কাস্টমাইজ করতে স্থানান্তর শিক্ষা ব্যবহার করুন।
ইমেজ শ্রেণীবিভাগের জন্য স্থানান্তর শেখার পিছনে অন্তর্দৃষ্টি হল যে যদি একটি মডেল একটি বড় এবং সাধারণ যথেষ্ট ডেটাসেটে প্রশিক্ষিত হয়, এই মডেলটি কার্যকরভাবে ভিজ্যুয়াল জগতের একটি জেনেরিক মডেল হিসাবে কাজ করবে। তারপরে আপনি একটি বড় ডেটাসেটে একটি বড় মডেলকে প্রশিক্ষণ দিয়ে শুরু থেকে শুরু না করে এই শেখা বৈশিষ্ট্য মানচিত্রগুলির সুবিধা নিতে পারেন।
এই নোটবুকে, আপনি একটি পূর্বপ্রশিক্ষিত মডেল কাস্টমাইজ করার দুটি উপায় চেষ্টা করবেন:
বৈশিষ্ট্য নিষ্কাশন: নতুন নমুনা থেকে অর্থপূর্ণ বৈশিষ্ট্যগুলি বের করতে পূর্ববর্তী নেটওয়ার্ক দ্বারা শেখা উপস্থাপনা ব্যবহার করুন। আপনি কেবল একটি নতুন শ্রেণীবদ্ধকারী যোগ করুন, যেটিকে স্ক্র্যাচ থেকে প্রশিক্ষিত করা হবে, প্রাক-প্রশিক্ষিত মডেলের উপরে যাতে আপনি ডেটাসেটের জন্য পূর্বে শেখা বৈশিষ্ট্য মানচিত্রগুলিকে পুনরায় ব্যবহার করতে পারেন।
আপনাকে সম্পূর্ণ মডেলটি প্রশিক্ষণের (পুনরায়) প্রয়োজন নেই। বেস কনভোলিউশনাল নেটওয়ার্কে ইতিমধ্যেই এমন বৈশিষ্ট্য রয়েছে যা চিত্রগুলিকে শ্রেণিবদ্ধ করার জন্য সাধারণভাবে উপযোগী। যাইহোক, পূর্বপ্রশিক্ষিত মডেলের চূড়ান্ত, শ্রেণীবিভাগ অংশটি মূল শ্রেণীবিভাগের কাজের জন্য নির্দিষ্ট, এবং পরবর্তীতে মডেলটি প্রশিক্ষণপ্রাপ্ত ক্লাসের সেটের জন্য নির্দিষ্ট।
ফাইন-টিউনিং: হিমায়িত মডেল বেসের কয়েকটি উপরের স্তরগুলিকে আনফ্রিজ করুন এবং নতুন যোগ করা ক্লাসিফায়ার স্তর এবং বেস মডেলের শেষ স্তর উভয়কেই যৌথভাবে প্রশিক্ষণ দিন। এটি আমাদের বেস মডেলের উচ্চ-ক্রম বৈশিষ্ট্য উপস্থাপনাগুলিকে নির্দিষ্ট কাজের জন্য আরও প্রাসঙ্গিক করে তুলতে "সূক্ষ্ম সুর" করতে দেয়।
আপনি সাধারণ মেশিন লার্নিং ওয়ার্কফ্লো অনুসরণ করবেন।
- তথ্য পরীক্ষা এবং বুঝতে
- এই ক্ষেত্রে Keras ImageDataGenerator ব্যবহার করে একটি ইনপুট পাইপলাইন তৈরি করুন
- মডেল রচনা করুন
- পূর্বপ্রশিক্ষিত বেস মডেলে লোড করুন (এবং পূর্বপ্রশিক্ষিত ওজন)
- উপরে শ্রেণীবিন্যাস স্তর স্ট্যাক
- মডেলকে প্রশিক্ষণ দিন
- মডেল মূল্যায়ন
import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf
ডেটা প্রিপ্রসেসিং
ডেটা ডাউনলোড
এই টিউটোরিয়ালে, আপনি বিড়াল এবং কুকুরের কয়েক হাজার ছবি সম্বলিত একটি ডেটাসেট ব্যবহার করবেন। ছবি সম্বলিত একটি জিপ ফাইল ডাউনলোড করুন এবং এক্সট্রাক্ট করুন, তারপর tf.keras.utils.image_dataset_from_directory
ইউটিলিটি ব্যবহার করে প্রশিক্ষণ এবং যাচাইকরণের জন্য একটি tf.data.Dataset
তৈরি করুন। আপনি এই টিউটোরিয়ালে ইমেজ লোড করার বিষয়ে আরও জানতে পারবেন।
_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
train_dir = os.path.join(PATH, 'train')
validation_dir = os.path.join(PATH, 'validation')
BATCH_SIZE = 32
IMG_SIZE = (160, 160)
train_dataset = tf.keras.utils.image_dataset_from_directory(train_dir,
shuffle=True,
batch_size=BATCH_SIZE,
image_size=IMG_SIZE)
Downloading data from https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip 68608000/68606236 [==============================] - 1s 0us/step 68616192/68606236 [==============================] - 1s 0us/step Found 2000 files belonging to 2 classes.
validation_dataset = tf.keras.utils.image_dataset_from_directory(validation_dir,
shuffle=True,
batch_size=BATCH_SIZE,
image_size=IMG_SIZE)
Found 1000 files belonging to 2 classes.
প্রশিক্ষণ সেট থেকে প্রথম নয়টি ছবি এবং লেবেল দেখান:
class_names = train_dataset.class_names
plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
যেহেতু মূল ডেটাসেটে একটি পরীক্ষা সেট নেই, আপনি একটি তৈরি করবেন। এটি করার জন্য, tf.data.experimental.cardinality
ব্যবহার করে বৈধকরণ সেটে কতগুলি ব্যাচ ডেটা উপলব্ধ রয়েছে তা নির্ধারণ করুন, তারপর তাদের 20% একটি পরীক্ষা সেটে নিয়ে যান৷
val_batches = tf.data.experimental.cardinality(validation_dataset)
test_dataset = validation_dataset.take(val_batches // 5)
validation_dataset = validation_dataset.skip(val_batches // 5)
print('Number of validation batches: %d' % tf.data.experimental.cardinality(validation_dataset))
print('Number of test batches: %d' % tf.data.experimental.cardinality(test_dataset))
Number of validation batches: 26 Number of test batches: 6
কর্মক্ষমতা জন্য ডেটাসেট কনফিগার করুন
I/O ব্লক না করেই ডিস্ক থেকে ছবি লোড করতে বাফার করা প্রিফেচিং ব্যবহার করুন। এই পদ্ধতি সম্পর্কে আরও জানতে ডেটা কর্মক্ষমতা নির্দেশিকা দেখুন।
AUTOTUNE = tf.data.AUTOTUNE
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
validation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE)
test_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE)
ডেটা বৃদ্ধি ব্যবহার করুন
যখন আপনার কাছে একটি বড় ইমেজ ডেটাসেট না থাকে, তখন কৃত্রিমভাবে প্রশিক্ষন চিত্রগুলিতে র্যান্ডম, তবুও বাস্তবসম্মত, রূপান্তর প্রয়োগ করে নমুনা বৈচিত্র্য প্রবর্তন করা একটি ভাল অভ্যাস, যেমন ঘূর্ণন এবং অনুভূমিক ফ্লিপিং৷ এটি মডেলটিকে প্রশিক্ষণের ডেটার বিভিন্ন দিকের কাছে তুলে ধরতে এবং অতিরিক্ত ফিটিং কমাতে সাহায্য করে৷ আপনি এই টিউটোরিয়ালে ডেটা বৃদ্ধি সম্পর্কে আরও শিখতে পারেন।
data_augmentation = tf.keras.Sequential([
tf.keras.layers.RandomFlip('horizontal'),
tf.keras.layers.RandomRotation(0.2),
])
আসুন একই ছবিতে বারবার এই স্তরগুলি প্রয়োগ করি এবং ফলাফলটি দেখি।
for image, _ in train_dataset.take(1):
plt.figure(figsize=(10, 10))
first_image = image[0]
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
augmented_image = data_augmentation(tf.expand_dims(first_image, 0))
plt.imshow(augmented_image[0] / 255)
plt.axis('off')
পিক্সেল মান পুনরায় স্কেল করুন
কিছুক্ষণের মধ্যে, আপনি আপনার বেস মডেল হিসাবে ব্যবহারের জন্য tf.keras.applications.MobileNetV2
ডাউনলোড করবেন। এই মডেলটি [-1, 1]
-এ পিক্সেল মান আশা করে, কিন্তু এই মুহুর্তে, আপনার চিত্রগুলির পিক্সেল মানগুলি [0, 255]
-এ রয়েছে। তাদের পুনরায় স্কেল করতে, মডেলের সাথে অন্তর্ভুক্ত প্রিপ্রসেসিং পদ্ধতি ব্যবহার করুন।
preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input
rescale = tf.keras.layers.Rescaling(1./127.5, offset=-1)
প্রাক-প্রশিক্ষিত কনভনেট থেকে বেস মডেল তৈরি করুন
আপনি Google-এ তৈরি MobileNet V2 মডেল থেকে বেস মডেল তৈরি করবেন। এটি ইমেজনেট ডেটাসেটে প্রাক-প্রশিক্ষিত, 1.4M ছবি এবং 1000টি ক্লাস নিয়ে গঠিত একটি বড় ডেটাসেট। ইমেজনেট হল jackfruit
এবং syringe
মতো বিস্তৃত শ্রেণীবিভাগ সহ একটি গবেষণা প্রশিক্ষণ ডেটাসেট। জ্ঞানের এই ভিত্তিটি আমাদের নির্দিষ্ট ডেটাসেট থেকে বিড়াল এবং কুকুরকে শ্রেণিবদ্ধ করতে সাহায্য করবে।
প্রথমে, আপনাকে MobileNet V2 এর কোন স্তরটি বৈশিষ্ট্য নিষ্কাশনের জন্য ব্যবহার করবেন তা বেছে নিতে হবে। একেবারে শেষ শ্রেণীবিন্যাস স্তর ("শীর্ষে", যেহেতু মেশিন লার্নিং মডেলের বেশিরভাগ চিত্র নিচ থেকে উপরে যায়) খুব দরকারী নয়। পরিবর্তে, আপনি ফ্ল্যাটেন অপারেশনের আগে একেবারে শেষ স্তরের উপর নির্ভর করার জন্য সাধারণ অনুশীলন অনুসরণ করবেন। এই স্তরটিকে "বাটলনেক লেয়ার" বলা হয়। অন্তিম/শীর্ষ স্তরের তুলনায় বটলনেক স্তর বৈশিষ্ট্যগুলি আরও সাধারণতা বজায় রাখে।
প্রথমে, ImageNet-এ প্রশিক্ষিত ওজন সহ প্রি-লোড করা একটি MobileNet V2 মডেল ইনস্ট্যান্টিয়েট করুন। Include_top=False আর্গুমেন্ট উল্লেখ করে, আপনি এমন একটি নেটওয়ার্ক লোড করেন যা শীর্ষে শ্রেণীবিভাগের স্তরগুলি অন্তর্ভুক্ত করে না, যা বৈশিষ্ট্য নিষ্কাশনের জন্য আদর্শ।
# Create the base model from the pre-trained model MobileNet V2
IMG_SHAPE = IMG_SIZE + (3,)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
include_top=False,
weights='imagenet')
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_160_no_top.h5 9412608/9406464 [==============================] - 0s 0us/step 9420800/9406464 [==============================] - 0s 0us/step
এই বৈশিষ্ট্য এক্সট্র্যাক্টর প্রতিটি 160x160x3
চিত্রকে 5x5x1280
বৈশিষ্ট্যের ব্লকে রূপান্তর করে। আসুন দেখি এটি চিত্রগুলির একটি উদাহরণ ব্যাচে কী করে:
image_batch, label_batch = next(iter(train_dataset))
feature_batch = base_model(image_batch)
print(feature_batch.shape)
(32, 5, 5, 1280)
বৈশিষ্ট্য নিষ্কাশন
এই ধাপে, আপনি পূর্ববর্তী ধাপ থেকে তৈরি কনভোলিউশনাল বেস হিমায়িত করবেন এবং একটি বৈশিষ্ট্য নিষ্কাশনকারী হিসাবে ব্যবহার করবেন। উপরন্তু, আপনি এটির উপরে একটি শ্রেণীবদ্ধকারী যোগ করুন এবং শীর্ষ-স্তরের শ্রেণীবদ্ধকারীকে প্রশিক্ষণ দিন।
কনভোলিউশনাল বেস হিমায়িত করুন
আপনি মডেলটি সংকলন এবং প্রশিক্ষণের আগে কনভোলিউশনাল বেস হিমায়িত করা গুরুত্বপূর্ণ। ফ্রিজিং (layer.trainable = False সেট করে) প্রশিক্ষণের সময় একটি প্রদত্ত স্তরের ওজনগুলিকে আপডেট করা থেকে বাধা দেয়। MobileNet V2-এ অনেকগুলি স্তর রয়েছে, তাই সম্পূর্ণ মডেলের trainable
পতাকাটিকে False-এ সেট করে সেগুলি সবই স্থবির হয়ে যাবে৷
base_model.trainable = False
ব্যাচ নরমালাইজেশন স্তর সম্পর্কে গুরুত্বপূর্ণ নোট
অনেক মডেলে tf.keras.layers.BatchNormalization
লেয়ার থাকে। এই স্তরটি একটি বিশেষ ক্ষেত্রে এবং সূক্ষ্ম-টিউনিংয়ের প্রসঙ্গে সতর্কতা অবলম্বন করা উচিত, যেমনটি পরে এই টিউটোরিয়ালে দেখানো হয়েছে।
আপনি যখন layer.trainable = False
সেট করেন, তখন ব্যাচ- BatchNormalization
লেয়ার ইনফারেন্স মোডে চলবে এবং এর গড় এবং পরিবর্তনের পরিসংখ্যান আপডেট করবে না।
আপনি যখন ফাইন-টিউনিং করার জন্য ব্যাচ-নরমালাইজেশন লেয়ার ধারণ করে এমন একটি মডেল আনফ্রিজ করবেন, তখন বেস মডেল কল করার সময় training = False
পাস করে আপনার ব্যাচ নরমালাইজেশন লেয়ারগুলিকে ইনফারেন্স মোডে রাখা উচিত। অন্যথায়, অ-প্রশিক্ষণযোগ্য ওজনগুলিতে প্রয়োগ করা আপডেটগুলি মডেলটি যা শিখেছে তা ধ্বংস করবে।
আরো বিস্তারিত জানার জন্য, ট্রান্সফার লার্নিং গাইড দেখুন।
# Let's take a look at the base model architecture
base_model.summary()
Model: "mobilenetv2_1.00_160" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_1 (InputLayer) [(None, 160, 160, 3 0 [] )] Conv1 (Conv2D) (None, 80, 80, 32) 864 ['input_1[0][0]'] bn_Conv1 (BatchNormalization) (None, 80, 80, 32) 128 ['Conv1[0][0]'] Conv1_relu (ReLU) (None, 80, 80, 32) 0 ['bn_Conv1[0][0]'] expanded_conv_depthwise (Depth (None, 80, 80, 32) 288 ['Conv1_relu[0][0]'] wiseConv2D) expanded_conv_depthwise_BN (Ba (None, 80, 80, 32) 128 ['expanded_conv_depthwise[0][0]'] tchNormalization) expanded_conv_depthwise_relu ( (None, 80, 80, 32) 0 ['expanded_conv_depthwise_BN[0][0 ReLU) ]'] expanded_conv_project (Conv2D) (None, 80, 80, 16) 512 ['expanded_conv_depthwise_relu[0] [0]'] expanded_conv_project_BN (Batc (None, 80, 80, 16) 64 ['expanded_conv_project[0][0]'] hNormalization) block_1_expand (Conv2D) (None, 80, 80, 96) 1536 ['expanded_conv_project_BN[0][0]' ] block_1_expand_BN (BatchNormal (None, 80, 80, 96) 384 ['block_1_expand[0][0]'] ization) block_1_expand_relu (ReLU) (None, 80, 80, 96) 0 ['block_1_expand_BN[0][0]'] block_1_pad (ZeroPadding2D) (None, 81, 81, 96) 0 ['block_1_expand_relu[0][0]'] block_1_depthwise (DepthwiseCo (None, 40, 40, 96) 864 ['block_1_pad[0][0]'] nv2D) block_1_depthwise_BN (BatchNor (None, 40, 40, 96) 384 ['block_1_depthwise[0][0]'] malization) block_1_depthwise_relu (ReLU) (None, 40, 40, 96) 0 ['block_1_depthwise_BN[0][0]'] block_1_project (Conv2D) (None, 40, 40, 24) 2304 ['block_1_depthwise_relu[0][0]'] block_1_project_BN (BatchNorma (None, 40, 40, 24) 96 ['block_1_project[0][0]'] lization) block_2_expand (Conv2D) (None, 40, 40, 144) 3456 ['block_1_project_BN[0][0]'] block_2_expand_BN (BatchNormal (None, 40, 40, 144) 576 ['block_2_expand[0][0]'] ization) block_2_expand_relu (ReLU) (None, 40, 40, 144) 0 ['block_2_expand_BN[0][0]'] block_2_depthwise (DepthwiseCo (None, 40, 40, 144) 1296 ['block_2_expand_relu[0][0]'] nv2D) block_2_depthwise_BN (BatchNor (None, 40, 40, 144) 576 ['block_2_depthwise[0][0]'] malization) block_2_depthwise_relu (ReLU) (None, 40, 40, 144) 0 ['block_2_depthwise_BN[0][0]'] block_2_project (Conv2D) (None, 40, 40, 24) 3456 ['block_2_depthwise_relu[0][0]'] block_2_project_BN (BatchNorma (None, 40, 40, 24) 96 ['block_2_project[0][0]'] lization) block_2_add (Add) (None, 40, 40, 24) 0 ['block_1_project_BN[0][0]', 'block_2_project_BN[0][0]'] block_3_expand (Conv2D) (None, 40, 40, 144) 3456 ['block_2_add[0][0]'] block_3_expand_BN (BatchNormal (None, 40, 40, 144) 576 ['block_3_expand[0][0]'] ization) block_3_expand_relu (ReLU) (None, 40, 40, 144) 0 ['block_3_expand_BN[0][0]'] block_3_pad (ZeroPadding2D) (None, 41, 41, 144) 0 ['block_3_expand_relu[0][0]'] block_3_depthwise (DepthwiseCo (None, 20, 20, 144) 1296 ['block_3_pad[0][0]'] nv2D) block_3_depthwise_BN (BatchNor (None, 20, 20, 144) 576 ['block_3_depthwise[0][0]'] malization) block_3_depthwise_relu (ReLU) (None, 20, 20, 144) 0 ['block_3_depthwise_BN[0][0]'] block_3_project (Conv2D) (None, 20, 20, 32) 4608 ['block_3_depthwise_relu[0][0]'] block_3_project_BN (BatchNorma (None, 20, 20, 32) 128 ['block_3_project[0][0]'] lization) block_4_expand (Conv2D) (None, 20, 20, 192) 6144 ['block_3_project_BN[0][0]'] block_4_expand_BN (BatchNormal (None, 20, 20, 192) 768 ['block_4_expand[0][0]'] ization) block_4_expand_relu (ReLU) (None, 20, 20, 192) 0 ['block_4_expand_BN[0][0]'] block_4_depthwise (DepthwiseCo (None, 20, 20, 192) 1728 ['block_4_expand_relu[0][0]'] nv2D) block_4_depthwise_BN (BatchNor (None, 20, 20, 192) 768 ['block_4_depthwise[0][0]'] malization) block_4_depthwise_relu (ReLU) (None, 20, 20, 192) 0 ['block_4_depthwise_BN[0][0]'] block_4_project (Conv2D) (None, 20, 20, 32) 6144 ['block_4_depthwise_relu[0][0]'] block_4_project_BN (BatchNorma (None, 20, 20, 32) 128 ['block_4_project[0][0]'] lization) block_4_add (Add) (None, 20, 20, 32) 0 ['block_3_project_BN[0][0]', 'block_4_project_BN[0][0]'] block_5_expand (Conv2D) (None, 20, 20, 192) 6144 ['block_4_add[0][0]'] block_5_expand_BN (BatchNormal (None, 20, 20, 192) 768 ['block_5_expand[0][0]'] ization) block_5_expand_relu (ReLU) (None, 20, 20, 192) 0 ['block_5_expand_BN[0][0]'] block_5_depthwise (DepthwiseCo (None, 20, 20, 192) 1728 ['block_5_expand_relu[0][0]'] nv2D) block_5_depthwise_BN (BatchNor (None, 20, 20, 192) 768 ['block_5_depthwise[0][0]'] malization) block_5_depthwise_relu (ReLU) (None, 20, 20, 192) 0 ['block_5_depthwise_BN[0][0]'] block_5_project (Conv2D) (None, 20, 20, 32) 6144 ['block_5_depthwise_relu[0][0]'] block_5_project_BN (BatchNorma (None, 20, 20, 32) 128 ['block_5_project[0][0]'] lization) block_5_add (Add) (None, 20, 20, 32) 0 ['block_4_add[0][0]', 'block_5_project_BN[0][0]'] block_6_expand (Conv2D) (None, 20, 20, 192) 6144 ['block_5_add[0][0]'] block_6_expand_BN (BatchNormal (None, 20, 20, 192) 768 ['block_6_expand[0][0]'] ization) block_6_expand_relu (ReLU) (None, 20, 20, 192) 0 ['block_6_expand_BN[0][0]'] block_6_pad (ZeroPadding2D) (None, 21, 21, 192) 0 ['block_6_expand_relu[0][0]'] block_6_depthwise (DepthwiseCo (None, 10, 10, 192) 1728 ['block_6_pad[0][0]'] nv2D) block_6_depthwise_BN (BatchNor (None, 10, 10, 192) 768 ['block_6_depthwise[0][0]'] malization) block_6_depthwise_relu (ReLU) (None, 10, 10, 192) 0 ['block_6_depthwise_BN[0][0]'] block_6_project (Conv2D) (None, 10, 10, 64) 12288 ['block_6_depthwise_relu[0][0]'] block_6_project_BN (BatchNorma (None, 10, 10, 64) 256 ['block_6_project[0][0]'] lization) block_7_expand (Conv2D) (None, 10, 10, 384) 24576 ['block_6_project_BN[0][0]'] block_7_expand_BN (BatchNormal (None, 10, 10, 384) 1536 ['block_7_expand[0][0]'] ization) block_7_expand_relu (ReLU) (None, 10, 10, 384) 0 ['block_7_expand_BN[0][0]'] block_7_depthwise (DepthwiseCo (None, 10, 10, 384) 3456 ['block_7_expand_relu[0][0]'] nv2D) block_7_depthwise_BN (BatchNor (None, 10, 10, 384) 1536 ['block_7_depthwise[0][0]'] malization) block_7_depthwise_relu (ReLU) (None, 10, 10, 384) 0 ['block_7_depthwise_BN[0][0]'] block_7_project (Conv2D) (None, 10, 10, 64) 24576 ['block_7_depthwise_relu[0][0]'] block_7_project_BN (BatchNorma (None, 10, 10, 64) 256 ['block_7_project[0][0]'] lization) block_7_add (Add) (None, 10, 10, 64) 0 ['block_6_project_BN[0][0]', 'block_7_project_BN[0][0]'] block_8_expand (Conv2D) (None, 10, 10, 384) 24576 ['block_7_add[0][0]'] block_8_expand_BN (BatchNormal (None, 10, 10, 384) 1536 ['block_8_expand[0][0]'] ization) block_8_expand_relu (ReLU) (None, 10, 10, 384) 0 ['block_8_expand_BN[0][0]'] block_8_depthwise (DepthwiseCo (None, 10, 10, 384) 3456 ['block_8_expand_relu[0][0]'] nv2D) block_8_depthwise_BN (BatchNor (None, 10, 10, 384) 1536 ['block_8_depthwise[0][0]'] malization) block_8_depthwise_relu (ReLU) (None, 10, 10, 384) 0 ['block_8_depthwise_BN[0][0]'] block_8_project (Conv2D) (None, 10, 10, 64) 24576 ['block_8_depthwise_relu[0][0]'] block_8_project_BN (BatchNorma (None, 10, 10, 64) 256 ['block_8_project[0][0]'] lization) block_8_add (Add) (None, 10, 10, 64) 0 ['block_7_add[0][0]', 'block_8_project_BN[0][0]'] block_9_expand (Conv2D) (None, 10, 10, 384) 24576 ['block_8_add[0][0]'] block_9_expand_BN (BatchNormal (None, 10, 10, 384) 1536 ['block_9_expand[0][0]'] ization) block_9_expand_relu (ReLU) (None, 10, 10, 384) 0 ['block_9_expand_BN[0][0]'] block_9_depthwise (DepthwiseCo (None, 10, 10, 384) 3456 ['block_9_expand_relu[0][0]'] nv2D) block_9_depthwise_BN (BatchNor (None, 10, 10, 384) 1536 ['block_9_depthwise[0][0]'] malization) block_9_depthwise_relu (ReLU) (None, 10, 10, 384) 0 ['block_9_depthwise_BN[0][0]'] block_9_project (Conv2D) (None, 10, 10, 64) 24576 ['block_9_depthwise_relu[0][0]'] block_9_project_BN (BatchNorma (None, 10, 10, 64) 256 ['block_9_project[0][0]'] lization) block_9_add (Add) (None, 10, 10, 64) 0 ['block_8_add[0][0]', 'block_9_project_BN[0][0]'] block_10_expand (Conv2D) (None, 10, 10, 384) 24576 ['block_9_add[0][0]'] block_10_expand_BN (BatchNorma (None, 10, 10, 384) 1536 ['block_10_expand[0][0]'] lization) block_10_expand_relu (ReLU) (None, 10, 10, 384) 0 ['block_10_expand_BN[0][0]'] block_10_depthwise (DepthwiseC (None, 10, 10, 384) 3456 ['block_10_expand_relu[0][0]'] onv2D) block_10_depthwise_BN (BatchNo (None, 10, 10, 384) 1536 ['block_10_depthwise[0][0]'] rmalization) block_10_depthwise_relu (ReLU) (None, 10, 10, 384) 0 ['block_10_depthwise_BN[0][0]'] block_10_project (Conv2D) (None, 10, 10, 96) 36864 ['block_10_depthwise_relu[0][0]'] block_10_project_BN (BatchNorm (None, 10, 10, 96) 384 ['block_10_project[0][0]'] alization) block_11_expand (Conv2D) (None, 10, 10, 576) 55296 ['block_10_project_BN[0][0]'] block_11_expand_BN (BatchNorma (None, 10, 10, 576) 2304 ['block_11_expand[0][0]'] lization) block_11_expand_relu (ReLU) (None, 10, 10, 576) 0 ['block_11_expand_BN[0][0]'] block_11_depthwise (DepthwiseC (None, 10, 10, 576) 5184 ['block_11_expand_relu[0][0]'] onv2D) block_11_depthwise_BN (BatchNo (None, 10, 10, 576) 2304 ['block_11_depthwise[0][0]'] rmalization) block_11_depthwise_relu (ReLU) (None, 10, 10, 576) 0 ['block_11_depthwise_BN[0][0]'] block_11_project (Conv2D) (None, 10, 10, 96) 55296 ['block_11_depthwise_relu[0][0]'] block_11_project_BN (BatchNorm (None, 10, 10, 96) 384 ['block_11_project[0][0]'] alization) block_11_add (Add) (None, 10, 10, 96) 0 ['block_10_project_BN[0][0]', 'block_11_project_BN[0][0]'] block_12_expand (Conv2D) (None, 10, 10, 576) 55296 ['block_11_add[0][0]'] block_12_expand_BN (BatchNorma (None, 10, 10, 576) 2304 ['block_12_expand[0][0]'] lization) block_12_expand_relu (ReLU) (None, 10, 10, 576) 0 ['block_12_expand_BN[0][0]'] block_12_depthwise (DepthwiseC (None, 10, 10, 576) 5184 ['block_12_expand_relu[0][0]'] onv2D) block_12_depthwise_BN (BatchNo (None, 10, 10, 576) 2304 ['block_12_depthwise[0][0]'] rmalization) block_12_depthwise_relu (ReLU) (None, 10, 10, 576) 0 ['block_12_depthwise_BN[0][0]'] block_12_project (Conv2D) (None, 10, 10, 96) 55296 ['block_12_depthwise_relu[0][0]'] block_12_project_BN (BatchNorm (None, 10, 10, 96) 384 ['block_12_project[0][0]'] alization) block_12_add (Add) (None, 10, 10, 96) 0 ['block_11_add[0][0]', 'block_12_project_BN[0][0]'] block_13_expand (Conv2D) (None, 10, 10, 576) 55296 ['block_12_add[0][0]'] block_13_expand_BN (BatchNorma (None, 10, 10, 576) 2304 ['block_13_expand[0][0]'] lization) block_13_expand_relu (ReLU) (None, 10, 10, 576) 0 ['block_13_expand_BN[0][0]'] block_13_pad (ZeroPadding2D) (None, 11, 11, 576) 0 ['block_13_expand_relu[0][0]'] block_13_depthwise (DepthwiseC (None, 5, 5, 576) 5184 ['block_13_pad[0][0]'] onv2D) block_13_depthwise_BN (BatchNo (None, 5, 5, 576) 2304 ['block_13_depthwise[0][0]'] rmalization) block_13_depthwise_relu (ReLU) (None, 5, 5, 576) 0 ['block_13_depthwise_BN[0][0]'] block_13_project (Conv2D) (None, 5, 5, 160) 92160 ['block_13_depthwise_relu[0][0]'] block_13_project_BN (BatchNorm (None, 5, 5, 160) 640 ['block_13_project[0][0]'] alization) block_14_expand (Conv2D) (None, 5, 5, 960) 153600 ['block_13_project_BN[0][0]'] block_14_expand_BN (BatchNorma (None, 5, 5, 960) 3840 ['block_14_expand[0][0]'] lization) block_14_expand_relu (ReLU) (None, 5, 5, 960) 0 ['block_14_expand_BN[0][0]'] block_14_depthwise (DepthwiseC (None, 5, 5, 960) 8640 ['block_14_expand_relu[0][0]'] onv2D) block_14_depthwise_BN (BatchNo (None, 5, 5, 960) 3840 ['block_14_depthwise[0][0]'] rmalization) block_14_depthwise_relu (ReLU) (None, 5, 5, 960) 0 ['block_14_depthwise_BN[0][0]'] block_14_project (Conv2D) (None, 5, 5, 160) 153600 ['block_14_depthwise_relu[0][0]'] block_14_project_BN (BatchNorm (None, 5, 5, 160) 640 ['block_14_project[0][0]'] alization) block_14_add (Add) (None, 5, 5, 160) 0 ['block_13_project_BN[0][0]', 'block_14_project_BN[0][0]'] block_15_expand (Conv2D) (None, 5, 5, 960) 153600 ['block_14_add[0][0]'] block_15_expand_BN (BatchNorma (None, 5, 5, 960) 3840 ['block_15_expand[0][0]'] lization) block_15_expand_relu (ReLU) (None, 5, 5, 960) 0 ['block_15_expand_BN[0][0]'] block_15_depthwise (DepthwiseC (None, 5, 5, 960) 8640 ['block_15_expand_relu[0][0]'] onv2D) block_15_depthwise_BN (BatchNo (None, 5, 5, 960) 3840 ['block_15_depthwise[0][0]'] rmalization) block_15_depthwise_relu (ReLU) (None, 5, 5, 960) 0 ['block_15_depthwise_BN[0][0]'] block_15_project (Conv2D) (None, 5, 5, 160) 153600 ['block_15_depthwise_relu[0][0]'] block_15_project_BN (BatchNorm (None, 5, 5, 160) 640 ['block_15_project[0][0]'] alization) block_15_add (Add) (None, 5, 5, 160) 0 ['block_14_add[0][0]', 'block_15_project_BN[0][0]'] block_16_expand (Conv2D) (None, 5, 5, 960) 153600 ['block_15_add[0][0]'] block_16_expand_BN (BatchNorma (None, 5, 5, 960) 3840 ['block_16_expand[0][0]'] lization) block_16_expand_relu (ReLU) (None, 5, 5, 960) 0 ['block_16_expand_BN[0][0]'] block_16_depthwise (DepthwiseC (None, 5, 5, 960) 8640 ['block_16_expand_relu[0][0]'] onv2D) block_16_depthwise_BN (BatchNo (None, 5, 5, 960) 3840 ['block_16_depthwise[0][0]'] rmalization) block_16_depthwise_relu (ReLU) (None, 5, 5, 960) 0 ['block_16_depthwise_BN[0][0]'] block_16_project (Conv2D) (None, 5, 5, 320) 307200 ['block_16_depthwise_relu[0][0]'] block_16_project_BN (BatchNorm (None, 5, 5, 320) 1280 ['block_16_project[0][0]'] alization) Conv_1 (Conv2D) (None, 5, 5, 1280) 409600 ['block_16_project_BN[0][0]'] Conv_1_bn (BatchNormalization) (None, 5, 5, 1280) 5120 ['Conv_1[0][0]'] out_relu (ReLU) (None, 5, 5, 1280) 0 ['Conv_1_bn[0][0]'] ================================================================================================== Total params: 2,257,984 Trainable params: 0 Non-trainable params: 2,257,984 __________________________________________________________________________________________________
একটি শ্রেণীবিভাগ প্রধান যোগ করুন
বৈশিষ্ট্যগুলির ব্লক থেকে ভবিষ্যদ্বাণী তৈরি করতে, একটি tf.keras.layers.GlobalAveragePooling2D
স্তর ব্যবহার করে প্রতি চিত্র প্রতি একটি একক 1280-এলিমেন্ট ভেক্টরে বৈশিষ্ট্যগুলিকে রূপান্তর করতে স্থানিক 5x5
স্থানিক অবস্থানের উপর গড় করুন৷
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
feature_batch_average = global_average_layer(feature_batch)
print(feature_batch_average.shape)
(32, 1280)
এই বৈশিষ্ট্যগুলিকে প্রতি ছবিতে একটি একক ভবিষ্যদ্বাণীতে রূপান্তর করতে একটি tf.keras.layers.Dense
স্তর প্রয়োগ করুন৷ আপনার এখানে একটি অ্যাক্টিভেশন ফাংশনের প্রয়োজন নেই কারণ এই ভবিষ্যদ্বাণীটিকে একটি logit
বা একটি কাঁচা ভবিষ্যদ্বাণী মান হিসাবে গণ্য করা হবে৷ ধনাত্মক সংখ্যাগুলি ক্লাস 1 ভবিষ্যদ্বাণী করে, নেতিবাচক সংখ্যাগুলি ক্লাস 0 ভবিষ্যদ্বাণী করে৷
prediction_layer = tf.keras.layers.Dense(1)
prediction_batch = prediction_layer(feature_batch_average)
print(prediction_batch.shape)
(32, 1)
কেরাস ফাংশনাল এপিআই ব্যবহার করে ডেটা অগমেন্টেশন, রিস্কেলিং, base_model
এবং ফিচার এক্সট্র্যাক্টর লেয়ারগুলিকে একত্রে চেইন করে একটি মডেল তৈরি করুন। পূর্বে উল্লিখিত হিসাবে, আমাদের মডেলটিতে একটি ব্যাচ- BatchNormalization
লেয়ার রয়েছে বলে training=False
ব্যবহার করুন।
inputs = tf.keras.Input(shape=(160, 160, 3))
x = data_augmentation(inputs)
x = preprocess_input(x)
x = base_model(x, training=False)
x = global_average_layer(x)
x = tf.keras.layers.Dropout(0.2)(x)
outputs = prediction_layer(x)
model = tf.keras.Model(inputs, outputs)
মডেল কম্পাইল করুন
প্রশিক্ষণের আগে মডেলটি কম্পাইল করুন। যেহেতু দুটি শ্রেণী আছে, তাই from_logits=True
সহ tf.keras.losses.BinaryCrossentropy
ক্ষতি ব্যবহার করুন যেহেতু মডেলটি একটি রৈখিক আউটপুট প্রদান করে।
base_learning_rate = 0.0001
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_2 (InputLayer) [(None, 160, 160, 3)] 0 sequential (Sequential) (None, 160, 160, 3) 0 tf.math.truediv (TFOpLambda (None, 160, 160, 3) 0 ) tf.math.subtract (TFOpLambd (None, 160, 160, 3) 0 a) mobilenetv2_1.00_160 (Funct (None, 5, 5, 1280) 2257984 ional) global_average_pooling2d (G (None, 1280) 0 lobalAveragePooling2D) dropout (Dropout) (None, 1280) 0 dense (Dense) (None, 1) 1281 ================================================================= Total params: 2,259,265 Trainable params: 1,281 Non-trainable params: 2,257,984 _________________________________________________________________
মোবাইলনেটের 2.5 মিলিয়ন প্যারামিটার হিমায়িত, কিন্তু ঘন স্তরে 1.2 হাজার প্রশিক্ষণযোগ্য প্যারামিটার রয়েছে। এগুলি দুটি tf.Variable
. পরিবর্তনশীল বস্তুর মধ্যে বিভক্ত, ওজন এবং পক্ষপাত।
len(model.trainable_variables)
2
মডেলকে প্রশিক্ষণ দিন
10টি যুগের জন্য প্রশিক্ষণের পরে, আপনি যাচাইকরণ সেটে ~94% নির্ভুলতা দেখতে পাবেন।
initial_epochs = 10
loss0, accuracy0 = model.evaluate(validation_dataset)
26/26 [==============================] - 2s 16ms/step - loss: 0.7428 - accuracy: 0.5186
print("initial loss: {:.2f}".format(loss0))
print("initial accuracy: {:.2f}".format(accuracy0))
initial loss: 0.74 initial accuracy: 0.52
history = model.fit(train_dataset,
epochs=initial_epochs,
validation_data=validation_dataset)
Epoch 1/10 63/63 [==============================] - 4s 23ms/step - loss: 0.6804 - accuracy: 0.5680 - val_loss: 0.4981 - val_accuracy: 0.7054 Epoch 2/10 63/63 [==============================] - 1s 22ms/step - loss: 0.5044 - accuracy: 0.7170 - val_loss: 0.3598 - val_accuracy: 0.8144 Epoch 3/10 63/63 [==============================] - 1s 21ms/step - loss: 0.4109 - accuracy: 0.7845 - val_loss: 0.2810 - val_accuracy: 0.8861 Epoch 4/10 63/63 [==============================] - 1s 21ms/step - loss: 0.3285 - accuracy: 0.8445 - val_loss: 0.2256 - val_accuracy: 0.9208 Epoch 5/10 63/63 [==============================] - 1s 21ms/step - loss: 0.3108 - accuracy: 0.8555 - val_loss: 0.1986 - val_accuracy: 0.9307 Epoch 6/10 63/63 [==============================] - 1s 21ms/step - loss: 0.2659 - accuracy: 0.8855 - val_loss: 0.1703 - val_accuracy: 0.9418 Epoch 7/10 63/63 [==============================] - 1s 21ms/step - loss: 0.2459 - accuracy: 0.8935 - val_loss: 0.1495 - val_accuracy: 0.9517 Epoch 8/10 63/63 [==============================] - 1s 21ms/step - loss: 0.2315 - accuracy: 0.8950 - val_loss: 0.1454 - val_accuracy: 0.9542 Epoch 9/10 63/63 [==============================] - 1s 21ms/step - loss: 0.2204 - accuracy: 0.9030 - val_loss: 0.1326 - val_accuracy: 0.9592 Epoch 10/10 63/63 [==============================] - 1s 21ms/step - loss: 0.2180 - accuracy: 0.9115 - val_loss: 0.1215 - val_accuracy: 0.9604
শেখার বক্ররেখা
মোবাইলনেটভি2 বেস মডেলটিকে একটি নির্দিষ্ট বৈশিষ্ট্য এক্সট্র্যাক্টর হিসাবে ব্যবহার করার সময় প্রশিক্ষণ এবং বৈধতা নির্ভুলতা/ক্ষতির শেখার বক্ররেখাগুলি একবার দেখে নেওয়া যাক৷
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0,1.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
অল্প পরিমাণে, এটিও কারণ প্রশিক্ষণের মেট্রিকগুলি একটি যুগের জন্য গড় রিপোর্ট করে, যখন বৈধতা মেট্রিকগুলি যুগের পরে মূল্যায়ন করা হয়, তাই বৈধতা মেট্রিকগুলি এমন একটি মডেল দেখতে পায় যা কিছুটা দীর্ঘ প্রশিক্ষিত হয়েছে৷
ফাইন টিউনিং
বৈশিষ্ট্য নিষ্কাশন পরীক্ষায়, আপনি শুধুমাত্র একটি MobileNetV2 বেস মডেলের উপরে কয়েকটি স্তর প্রশিক্ষণ দিচ্ছিলেন৷ প্রশিক্ষণের সময় প্রাক-প্রশিক্ষিত নেটওয়ার্কের ওজন আপডেট করা হয়নি ।
কর্মক্ষমতা আরও বাড়ানোর একটি উপায় হল আপনার যোগ করা ক্লাসিফায়ারের প্রশিক্ষণের পাশাপাশি প্রাক-প্রশিক্ষিত মডেলের উপরের স্তরগুলির ওজনকে প্রশিক্ষণ দেওয়া (বা "সূক্ষ্ম-সুর")। প্রশিক্ষণের প্রক্রিয়াটি ওজনগুলিকে জেনেরিক বৈশিষ্ট্য মানচিত্র থেকে বিশেষভাবে ডেটাসেটের সাথে সম্পর্কিত বৈশিষ্ট্যগুলিতে টিউন করতে বাধ্য করবে।
এছাড়াও, আপনার পুরো মোবাইলনেট মডেলের পরিবর্তে অল্প সংখ্যক শীর্ষ স্তরগুলিকে সূক্ষ্ম-টিউন করার চেষ্টা করা উচিত। বেশিরভাগ কনভোলিউশনাল নেটওয়ার্কে, একটি স্তর যত উপরে, এটি তত বেশি বিশেষায়িত। প্রথম কয়েকটি স্তর খুব সাধারণ এবং সাধারণ বৈশিষ্ট্যগুলি শিখে যা প্রায় সমস্ত ধরণের চিত্রকে সাধারণ করে তোলে। আপনি যত উপরে যাবেন, বৈশিষ্ট্যগুলি ক্রমবর্ধমানভাবে সেই ডেটাসেটের জন্য আরও সুনির্দিষ্ট হচ্ছে যার উপর মডেলটিকে প্রশিক্ষণ দেওয়া হয়েছিল৷ ফাইন-টিউনিং-এর লক্ষ্য হল জেনেরিক লার্নিং ওভাররাইট না করে নতুন ডেটাসেটের সাথে কাজ করার জন্য এই বিশেষ বৈশিষ্ট্যগুলিকে মানিয়ে নেওয়া।
মডেলের উপরের স্তরগুলি আন-ফ্রিজ করুন
আপনাকে যা করতে হবে তা হল base_model
করুন এবং নীচের স্তরগুলিকে অ-প্রশিক্ষণযোগ্য হতে সেট করুন। তারপর, আপনার মডেলটি পুনরায় কম্পাইল করা উচিত (এই পরিবর্তনগুলি কার্যকর হওয়ার জন্য প্রয়োজনীয়), এবং প্রশিক্ষণ পুনরায় শুরু করুন।
base_model.trainable = True
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))
# Fine-tune from this layer onwards
fine_tune_at = 100
# Freeze all the layers before the `fine_tune_at` layer
for layer in base_model.layers[:fine_tune_at]:
layer.trainable = False
Number of layers in the base model: 154
মডেল কম্পাইল করুন
যেহেতু আপনি একটি অনেক বড় মডেলের প্রশিক্ষণ দিচ্ছেন এবং পূর্বপ্রশিক্ষিত ওজনগুলিকে পুনরায় মানিয়ে নিতে চান, তাই এই পর্যায়ে কম শেখার হার ব্যবহার করা গুরুত্বপূর্ণ। অন্যথায়, আপনার মডেল খুব দ্রুত ওভারফিট হতে পারে।
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
optimizer = tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate/10),
metrics=['accuracy'])
model.summary()
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_2 (InputLayer) [(None, 160, 160, 3)] 0 sequential (Sequential) (None, 160, 160, 3) 0 tf.math.truediv (TFOpLambda (None, 160, 160, 3) 0 ) tf.math.subtract (TFOpLambd (None, 160, 160, 3) 0 a) mobilenetv2_1.00_160 (Funct (None, 5, 5, 1280) 2257984 ional) global_average_pooling2d (G (None, 1280) 0 lobalAveragePooling2D) dropout (Dropout) (None, 1280) 0 dense (Dense) (None, 1) 1281 ================================================================= Total params: 2,259,265 Trainable params: 1,862,721 Non-trainable params: 396,544 _________________________________________________________________
len(model.trainable_variables)
56
মডেল প্রশিক্ষণ চালিয়ে যান
আপনি যদি আগে একত্রিত হওয়ার জন্য প্রশিক্ষিত হয়ে থাকেন, তাহলে এই ধাপটি আপনার নির্ভুলতাকে কয়েক শতাংশ পয়েন্ট দ্বারা উন্নত করবে।
fine_tune_epochs = 10
total_epochs = initial_epochs + fine_tune_epochs
history_fine = model.fit(train_dataset,
epochs=total_epochs,
initial_epoch=history.epoch[-1],
validation_data=validation_dataset)
Epoch 10/20 63/63 [==============================] - 7s 40ms/step - loss: 0.1545 - accuracy: 0.9335 - val_loss: 0.0531 - val_accuracy: 0.9864 Epoch 11/20 63/63 [==============================] - 2s 28ms/step - loss: 0.1161 - accuracy: 0.9540 - val_loss: 0.0500 - val_accuracy: 0.9814 Epoch 12/20 63/63 [==============================] - 2s 28ms/step - loss: 0.1125 - accuracy: 0.9525 - val_loss: 0.0379 - val_accuracy: 0.9876 Epoch 13/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0891 - accuracy: 0.9625 - val_loss: 0.0472 - val_accuracy: 0.9889 Epoch 14/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0844 - accuracy: 0.9680 - val_loss: 0.0478 - val_accuracy: 0.9889 Epoch 15/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0857 - accuracy: 0.9645 - val_loss: 0.0354 - val_accuracy: 0.9839 Epoch 16/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0785 - accuracy: 0.9690 - val_loss: 0.0449 - val_accuracy: 0.9864 Epoch 17/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0669 - accuracy: 0.9740 - val_loss: 0.0375 - val_accuracy: 0.9839 Epoch 18/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0701 - accuracy: 0.9695 - val_loss: 0.0324 - val_accuracy: 0.9864 Epoch 19/20 63/63 [==============================] - 2s 28ms/step - loss: 0.0636 - accuracy: 0.9760 - val_loss: 0.0465 - val_accuracy: 0.9790 Epoch 20/20 63/63 [==============================] - 2s 29ms/step - loss: 0.0585 - accuracy: 0.9765 - val_loss: 0.0392 - val_accuracy: 0.9851
MobileNetV2 বেস মডেলের শেষ কয়েকটি স্তরকে ফাইন-টিউনিং করার সময় এবং এর উপরে ক্লাসিফায়ারকে প্রশিক্ষণ দেওয়ার সময় প্রশিক্ষণের শেখার বক্ররেখা এবং বৈধতা নির্ভুলতা/ক্ষতির দিকে নজর দেওয়া যাক। বৈধতা ক্ষতি প্রশিক্ষণের ক্ষতির চেয়ে অনেক বেশি, তাই আপনি কিছু অতিরিক্ত ফিটিং পেতে পারেন।
নতুন প্রশিক্ষণ সেটটি তুলনামূলকভাবে ছোট এবং আসল MobileNetV2 ডেটাসেটের মতো হওয়ায় আপনি কিছুটা ওভারফিটিংও পেতে পারেন।
সূক্ষ্ম টিউনিংয়ের পরে মডেলটি বৈধকরণ সেটে প্রায় 98% নির্ভুলতায় পৌঁছেছে।
acc += history_fine.history['accuracy']
val_acc += history_fine.history['val_accuracy']
loss += history_fine.history['loss']
val_loss += history_fine.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.ylim([0.8, 1])
plt.plot([initial_epochs-1,initial_epochs-1],
plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.ylim([0, 1.0])
plt.plot([initial_epochs-1,initial_epochs-1],
plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
মূল্যায়ন এবং ভবিষ্যদ্বাণী
অবশেষে আপনি পরীক্ষা সেট ব্যবহার করে নতুন ডেটাতে মডেলের কর্মক্ষমতা যাচাই করতে পারেন।
loss, accuracy = model.evaluate(test_dataset)
print('Test accuracy :', accuracy)
6/6 [==============================] - 0s 13ms/step - loss: 0.0281 - accuracy: 0.9948 Test accuracy : 0.9947916865348816
এবং এখন আপনি আপনার পোষা প্রাণী একটি বিড়াল বা কুকুর কিনা ভবিষ্যদ্বাণী করতে এই মডেল ব্যবহার করতে প্রস্তুত.
# Retrieve a batch of images from the test set
image_batch, label_batch = test_dataset.as_numpy_iterator().next()
predictions = model.predict_on_batch(image_batch).flatten()
# Apply a sigmoid since our model returns logits
predictions = tf.nn.sigmoid(predictions)
predictions = tf.where(predictions < 0.5, 0, 1)
print('Predictions:\n', predictions.numpy())
print('Labels:\n', label_batch)
plt.figure(figsize=(10, 10))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image_batch[i].astype("uint8"))
plt.title(class_names[predictions[i]])
plt.axis("off")
Predictions: [0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 0 0 1 1 1 0 0 0 1 0] Labels: [0 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 0 1 0 0 1 1 1 0 0 0 1 0]
সারসংক্ষেপ
বৈশিষ্ট্য নিষ্কাশনের জন্য একটি প্রাক-প্রশিক্ষিত মডেল ব্যবহার করা : একটি ছোট ডেটাসেটের সাথে কাজ করার সময়, একই ডোমেনের একটি বড় ডেটাসেটে প্রশিক্ষিত মডেলের দ্বারা শেখা বৈশিষ্ট্যগুলির সুবিধা নেওয়া একটি সাধারণ অভ্যাস। এটি প্রাক-প্রশিক্ষিত মডেলকে ইনস্ট্যান্টিয়েট করে এবং উপরে একটি সম্পূর্ণ-সংযুক্ত শ্রেণীবিভাগ যোগ করে করা হয়। প্রাক-প্রশিক্ষিত মডেলটি "হিমায়িত" এবং প্রশিক্ষণের সময় শুধুমাত্র ক্লাসিফায়ারের ওজন আপডেট করা হয়। এই ক্ষেত্রে, কনভোলিউশনাল বেস প্রতিটি চিত্রের সাথে যুক্ত সমস্ত বৈশিষ্ট্য বের করে এবং আপনি শুধু একটি শ্রেণীবিভাগকে প্রশিক্ষিত করেছেন যা নিষ্কাশিত বৈশিষ্ট্যগুলির সেটটি দেওয়া চিত্রের শ্রেণি নির্ধারণ করে।
একটি প্রাক-প্রশিক্ষিত মডেল ফাইন-টিউনিং : কর্মক্ষমতা আরও উন্নত করার জন্য, কেউ সূক্ষ্ম-টিউনিংয়ের মাধ্যমে নতুন ডেটাসেটে প্রাক-প্রশিক্ষিত মডেলগুলির শীর্ষ-স্তরের স্তরগুলিকে পুনরায় ব্যবহার করতে চাইতে পারে। এই ক্ষেত্রে, আপনি আপনার ওজনগুলি এমনভাবে টিউন করেছেন যে আপনার মডেল ডেটাসেটের জন্য নির্দিষ্ট উচ্চ-স্তরের বৈশিষ্ট্যগুলি শিখেছে৷ এই কৌশলটি সাধারণত সুপারিশ করা হয় যখন প্রশিক্ষণের ডেটাসেটটি বড় হয় এবং প্রাক-প্রশিক্ষিত মডেলকে প্রশিক্ষণ দেওয়া হয়েছিল এমন মূল ডেটাসেটের সাথে খুব মিল।
আরও জানতে, ট্রান্সফার লার্নিং গাইড দেখুন।
# MIT License
#
# Copyright (c) 2017 François Chollet # IGNORE_COPYRIGHT: cleared by OSS licensing
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.