মানুষের মধ্যেই সবচেয়ে বেশি ট্রান্সফার লার্নিং ব্যাপারটা লক্ষ্য করা যায়। যেমন, আমরা একটা জিনিস শিখি তবে সেই জিনিসটা যে অন্য কোন কাজে লাগে না সেটা একদম ঠিক নয়। ধরা যাক, এক সময় আমি অংক, অ্যালজেবরা শিখেছি, পাশাপাশি পরিসংখ্যান শিখেছি পরীক্ষায় পাশ করার জন্য। এখন সেই জ্ঞানগুলো ট্রান্সফার হয়েছে মেশিন লার্নিং শিখতে গিয়ে। অংক,অ্যালজেবরা এবং পরিসংখ্যান শেখাটা বৃথা যায়নি। কারণ, আমাকে মেশিন লার্নিং একেবারে কেঁচে গণ্ডূষ করে শুরু করতে হয়নি, কারণ অংক এবং পরিসংখ্যান পাশাপাশি অ্যালজেবরা এই মেশিন লার্নিং শেখার জন্য সাহায্য করেছে। সে কারণেই বলা হয় যদিও একটা কাজের জন্য আমরা কোন কিছু শিখি, দেখা যায় পরে ওই শেখাটা অন্য কাজে লাগছে। এর অর্থ হচ্ছে আমরা অতীতে যা কিছু শিখেছি সেটা এখন কাজে লাগছে নতুন কিছু শিখতে। সেখানে এক ডোমেইন থেকে আরেক ডোমেইনে জ্ঞানটা ট্রান্সফার হচ্ছে।
ছোটবেলায় সাইকেল চালানো শিখেছিলাম বলেই মোটরসাইকেল ধরতে খুব একটা সমস্যা হয়নি। আবার কেউ যদি মোটরসাইকেল চালাতে পারেন তাহলে তার জন্য গাড়ি চালানোর শুরুর ব্যাপারগুলো ধরতে সে রকম সমস্যা হবার কথা না। বাচ্চারা যখন কোন মোবাইল ডিভাইস ব্যবহার করা শেখে, তারা হঠাৎ করে আইপ্যাড পেলে তাদের পুরনো জ্ঞান দিয়েই চালিয়ে নেয় নতুন জিনিস। এর অর্থ হচ্ছে একটার নলেজ আরেকটাতে ট্রান্সফার করা যাচ্ছে। এই একই জিনিস ঘটছে ডিপ লার্নিং এর আরেকটা নতুন ধারণায়। ‘ট্রান্সফার লার্নিং’। একটা কাজে একটা মডেলকে ট্রেইন করা হলে সেটাকে যে পাশাপাশি আর একটা কাজে ব্যবহার করা যাবে না সেটা ঠিক নয়। আমরা একটা ডিপ লার্নিং মডেলকে যদি ‘ইমেজ’ রিলেটেড ব্যাপারে ট্রেনিং করাই, তাহলে ওই কাজের কাছাকাছি আরেকটা কাজে ব্যবহার করা যাবে। ওই দুটো কাজের মধ্যে যত ‘সিমিলারিটি’ আছে ততোই মডেল গুলোর মধ্যে লার্নিং গুলোকে ট্রান্সফার করা সহজ হবে। শুরুতে একটা কাজের জন্য আমরা একদম গোড়া থেকে ট্রেইনিং করলেও পরের কাছাকাছি সেই কাজের জন্য একদম গোড়া থেকে ট্রেনিং করানোর প্রয়োজন নেই। এটাই ট্রান্সফার লার্নিং।
গোড়ার দিকে মেশিন লার্নিং এবং ডিপ লার্নিং অ্যালগরিদমগুলোকে এমনভাবে তৈরি করা হয়েছিল যাতে সে একটা স্পেসিফিক কাজ করতে পারে। আবার এই মডেলগুলোকে একেবারে গোড়া থেকে তৈরি করতে হতো যখন তাদের ফিচার স্পেস ডিস্ট্রিবিউশনে কোন পরিবর্তন আসতো। এখন দেখা যাচ্ছে ফিচার স্পেসে পরিবর্তন আসলেও কাছাকাছি কাজে একটার লার্নিং আরেকটাতে পাঠানো যাচ্ছে। সে কারণে আমরা গত চ্যাপ্টারে আলাপ করেছি ‘প্রি-ট্রেইনড’ মডেল নিয়ে। ‘প্রি-ট্রেইনড’ মডেল হচ্ছে একটা ‘স্টোরকৃত’ বা ‘সেভকৃত’ মডেল যাকে আগেই ট্রেনিং করানো হয়েছিল বিশাল আরেকটা ডাটাসেটের উপর। আমরা সেই মডেলকে অন্য আরেকটা কাজে সরাসরি অথবা ‘ট্রান্সফার লার্নিং’ এর মাধ্যমে আগের মডেলের পুরো বা কিছু অংশ নিয়ে নতুন মডেলকে কাস্টমাইজ করবো। আমাদের ‘প্রি-ট্রেইনড’ মডেল যদি কোটি কোটি ইমেজের উপর ট্রেনিং করানো থাকে, তাহলে সেই মডেলকে দিয়ে নতুন কাজে ওই ছবিগুলোর ‘লার্নিং’ ব্যবহার করা যাবে। ‘ট্রান্সফার লার্নিং’ এর সবচেয়ে বড় ব্যবহার হচ্ছে যখন আমাদের হাতে পর্যাপ্ত ডাটা থাকে না ট্রেনিং করানোর জন্য। সেই জ্ঞানকে নিয়ে আসছি আগের প্রি-ট্রেইনড মডেলের প্রাপ্ত জ্ঞান থেকে।
ধরা যাক আমাদের কাছে একটা ‘প্রি-ট্রেইনড’ মডেল আছে যেগুলো প্রায় ১০০০ ছবি ক্যাটাগরিতে কাজ করেছে। এখন আমার নতুন কাজে যেখানে মাত্র দুটো ছবির ক্যাটাগরি নিয়ে কাজ করছি সেখানে আগের একটা ‘প্রি-ট্রেইনড’ মডেল কোন রকম পরিবর্তন ছাড়াই ব্যবহার করা যায়। আসল কথা হচ্ছে আমাদের ডিপ লার্নিং মডেলগুলো যে ফিচার ম্যাপ তৈরি করে - সেগুলোকে নতুন কাজে আবার গোড়া থেকে ‘ফিচার ম্যাপ’ তৈরি না করে শেষে ক্লাসিফায়ার অংশটুকু ফেলে দিয়ে নতুন ক্লাসিফায়ার যোগ করলেই কাজ হয়ে যায়। মানে একজনের শরীর, আরেকজনের মাথা। মজার কথা, জিনিসটা কাজ করে।
try:# শুধুমাত্র টেন্সর-ফ্লো ২.x ব্যবহার করবো %tensorflow_version 2.xexceptException:passimport tensorflow as tfkeras = tf.keras
TensorFlow 2.x selected.
# কিছু হেল্পার লাইব্রেরি ব্যবহার করছিimport tensorflow as tffrom tensorflow.keras import layersimport tensorflow_datasets as tfdsimport matplotlib.pylab as plt
# টেন্সর-বোর্ড ব্যবহার করছি, এক্সটেনশন এবং লগ ডিরেক্টরি দেখিয়ে দিচ্ছি%load_ext tensorboardLOG_DIR ='./log'
# আগের মতো বিড়াল এবং কুকুরের ডেটাসেট নিয়ে কাজ করছি, দেখে নিন 'গ্লোবাল এভারেজ পুলিং' # বিস্তারিত বলেছি আগের চ্যাপ্টারে, স্প্লিট হচ্ছে ৮০ ট্রেনিং, ১০ ভ্যালিডেশন, ১০ টেস্টসেট শতাংশেsplit = (80,10,10)splits = tfds.Split.TRAIN.subsplit(weighted=split)(cat_train, cat_valid, cat_test), info = tfds.load('cats_vs_dogs', split=list(splits), with_info=True, as_supervised=True)
একটা ‘কনভলিউশনাল নিউরাল’ নেটওয়ার্কে কি আছে? একটা কনভলিউশন বেইজ, আরেকটা ক্লাসিফায়ার হেড। বেশিরভাগ সময় ‘প্রি-ট্রেইনড’ মডেলের কনভলিউশন বেইজ ঠিক রেখে নতুন কাজের নতুন ক্লাসিফায়ার হেড যোগ করলেই ট্রান্সফার লার্নিং এর ব্যবহার দেখতে পারি সহজেই। ট্রান্সফার লার্নিং এর শুরুতেই আমাদের আগের অন্য কাজের জন্য তৈরি মডেলকে ব্যবচ্ছেদ করবো আমরা। তখন বুঝব সেই ‘প্রি-ট্রেইনড’ মডেলের কতটুকু আমরা ‘আনকোরা’ ব্যবহার করব আর কতটুকু নতুন করে ট্রেইন করে নেব সেটা হাতেকলমে দেখবো সামনে।
অনেক গল্প হল, এই মুহূর্তে আমরা একটা ‘প্রি-ট্রেইনড’ মডেলের কিভাবে কাস্টমাইজেশন করব সেটা নিয়ে আলাপ করছি এখানে।
# average_pool = tf.keras.Sequential()# average_pool.add(layers.AveragePooling2D())# average_pool.add(layers.Flatten())# average_pool.add(layers.Dense(1, activation='sigmoid'))# গ্লোবাল এভারেজ পুল, এর কাজ হচ্ছে ফিচারগুলোকে একটা ১২৮০ এলিমেন্ট ভেক্টরে কনভার্ট করবে প্রতিটা ইমেজেaverage_pool = tf.keras.layers.GlobalAveragePooling2D()# একটা করে প্রেডিকশন প্রতিটা ইমেজে, এক্টিভেশন ফাংশন দরকার নেই, যেহেতু পজিটিভ সংখ্যা ১, নেগেটিভ সংখ্যা ০prediction = keras.layers.Dense(1)
১. ‘প্রি-ট্রেইনড’ মডেল থেকে ফিচার এক্সট্রাকশন: আমরা রিপ্রেজেন্টেশন লার্নিং এর মাধ্যমে আগের নেটওয়ার্ক থেকে শিখে সেটা দিয়ে নতুন নেটওয়ার্কের দরকারি ফিচারগুলোকে এক্সট্রাক্ট করব নতুন ডাটা থেকে। এর শেষে আমরা একটা নতুন ক্লাসিফায়ার হেড যোগ করে দেব যাকে ট্রেনিং করালেই বাকি মডেলকে আনকোরা রাখলেও কাজ হয়ে যাবে। এর অর্থ হচ্ছে আমাদের আগের প্রি-ট্রেইনড মডেলকে ব্যবহার করছি নতুন একটা কাজে। আমরা কিন্তু পুরো মডেলকে ট্রেইন করছিনা, শুধুমাত্র দরকারি ক্লাসিফায়ার হেডকে সেই কয়েকটা ক্লাসিফিকেশন কাজের জন্য ট্রেইন করলেই চলছে। পেছনে আগের মডেলের কনভলিউশন বেইজ একই থাকছে। মানে এক নেটওয়ার্ক থেকে কনভলিউশন বেইজ এবং নতুন কাজের নেটওয়ার্ক ক্লাসিফায়ার হেড (নতুন কাজের শেষ অংশ) যোগ করে দিলেই কাজ হয়ে যাবে।
# তিনটা জিনিস যোগ করে মডেল তৈরিstandard_model = tf.keras.Sequential([ head, average_pool, prediction])
# টেন্সরবোর্ড, নতুন পোর্টে%tensorboard --logdir log/ --port=8008
(function() {
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;
document.querySelector("base").href = "https://localhost:8008";
function fixUpTensorboard(root) {
const tftb = root.querySelector("tf-tensorboard");
// Disable the fragment manipulation behavior in Colab. Not
// only is the behavior not useful (as the iframe's location
// is not visible to the user), it causes TensorBoard's usage
// of `window.replace` to navigate away from the page and to
// the `localhost:<port>` URL specified by the base URI, which
// in turn causes the frame to (likely) crash.
tftb.removeAttribute("use-hash");
}
function executeAllScripts(root) {
// When `script` elements are inserted into the DOM by
// assigning to an element's `innerHTML`, the scripts are not
// executed. Thus, we manually re-insert these scripts so that
// TensorBoard can initialize itself.
for (const script of root.querySelectorAll("script")) {
const newScript = document.createElement("script");
newScript.type = script.type;
newScript.textContent = script.textContent;
root.appendChild(newScript);
script.remove();
}
}
function setHeight(root, height) {
// We set the height dynamically after the TensorBoard UI has
// been initialized. This avoids an intermediate state in
// which the container plus the UI become taller than the
// final width and cause the Colab output frame to be
// permanently resized, eventually leading to an empty
// vertical gap below the TensorBoard UI. It's not clear
// exactly what causes this problematic intermediate state,
// but setting the height late seems to fix it.
root.style.height = `${height}px`;
}
const root = document.getElementById("root");
fetch(".")
.then((x) => x.text())
.then((html) => void (root.innerHTML = html))
.then(() => fixUpTensorboard(root))
.then(() => executeAllScripts(root))
.then(() => setHeight(root, 800));
})();
```python # লম্বা টিউটোরিয়াল, একটু মডেল সেভ করে রাখি tl_model.save('cats_dogs_tlearn.h5') ``` ২. প্রি-ট্রেইনড মডেলের ফাইন টিউনিং: পুরনো মডেলের কনভলিউশন বেইজের শুরুর দিকের লেয়ারগুলোকে ‘লক’ করে রেখে নিচের দিকের লেয়ারগুলোকে যদি ‘আনলক’ রাখি, তাহলে ক্লাসিফায়ার হেড এর ট্রেনিং এর সাথে সাথে আনলক লেয়ারগুলোর ট্রেনিং করানো সম্ভব। ফলে প্রি-ট্রেইনড মডেলের শেষের দিকের লেয়ারগুলোকে আমাদের কাজ অনুসারে দরকারি ফাইন টিউনিং করানো সম্ভব। এতে মডেল আমার স্পেসিফিক কাজের জন্য ভালোভাবে কাজ করবে। পরের অংশে আমরা যখন vgg16কে ফাইন টিউনিং করব, তখন ক্লাসিফায়ারের এর সাথে সাথে নিচের দুটো ব্লককে আনলক করে দেব। আমরা বলছি ব্লক ৪ এবং ৫ - যেগুলো আনলক করার ফলে তাদের ওয়েটগুলো আপডেট হবে প্রতি ইপকে, মডেল ট্রেনিং এর সাথে সাথে। নিচের ছবিটা একটু দেখি। এখানে কম্প্লেক্সিটি এড়ানোর জন্য আমরা ‘গ্লোবাল এভারেজ পুলিং’ আর যোগ করছিনা। কোডে সেটা দেখলে বুঝতে পারবেন। এই লেয়ারগুলোর ফিচার ম্যাপ থেকে যে আউটপুট পাব সেটাকে পাঠিয়ে দেব ‘ফ্ল্যাটেন’ লেয়ারে। এরপরের আউটপুট চলে যাবে আমাদের ক্লাসিফায়ারের ‘ডেন্স’ লেয়ারে। ```python # এখন মডেলের ফাইন টিউনিং, ব্লক ৪ এবং ৫ 'আনলক' করে দিলাম tl_model.trainable = True set_trainable = False for layer in vgg.layers: if layer.name in ['block5_conv1', 'block4_conv1']: set_trainable = True if set_trainable: layer.trainable = True else: layer.trainable = False pd.set_option('max_colwidth', -1) layer_vgg2 = [(layer, layer.name, layer.trainable) for layer in vgg.layers] pd.DataFrame(layer_vgg2, columns=['Layer Type', 'Layer Name', 'Layer Trainable']) ```
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Layer Type
Layer Name
Layer Trainable
0
<tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7f240242d710>
input_1
False
1
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24023cfc50>
block1_conv1
False
2
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f23efa09518>
block1_conv2
False
3
<tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f23ef9be7b8>
block1_pool
False
4
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f23ef9be898>
block2_conv1
False
5
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f23ef9d0eb8>
block2_conv2
False
6
<tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f24014d8320>
block2_pool
False
7
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014d8400>
block3_conv1
False
8
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014e3b70>
block3_conv2
False
9
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014f2e48>
block3_conv3
False
10
<tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f2401505fd0>
block3_pool
False
11
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f2401497240>
block4_conv1
True
12
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014a79b0>
block4_conv2
True
13
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014b0c88>
block4_conv3
True
14
<tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f24014c4f60>
block4_pool
True
15
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f2401455630>
block5_conv1
True
16
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f24014677f0>
block5_conv2
True
17
<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7f2401470ac8>
block5_conv3
True
18
<tensorflow.python.keras.layers.pooling.MaxPooling2D object at 0x7f2401483da0>
(function() {
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;
document.querySelector("base").href = "https://localhost:6006";
function fixUpTensorboard(root) {
const tftb = root.querySelector("tf-tensorboard");
// Disable the fragment manipulation behavior in Colab. Not
// only is the behavior not useful (as the iframe's location
// is not visible to the user), it causes TensorBoard's usage
// of `window.replace` to navigate away from the page and to
// the `localhost:<port>` URL specified by the base URI, which
// in turn causes the frame to (likely) crash.
tftb.removeAttribute("use-hash");
}
function executeAllScripts(root) {
// When `script` elements are inserted into the DOM by
// assigning to an element's `innerHTML`, the scripts are not
// executed. Thus, we manually re-insert these scripts so that
// TensorBoard can initialize itself.
for (const script of root.querySelectorAll("script")) {
const newScript = document.createElement("script");
newScript.type = script.type;
newScript.textContent = script.textContent;
root.appendChild(newScript);
script.remove();
}
}
function setHeight(root, height) {
// We set the height dynamically after the TensorBoard UI has
// been initialized. This avoids an intermediate state in
// which the container plus the UI become taller than the
// final width and cause the Colab output frame to be
// permanently resized, eventually leading to an empty
// vertical gap below the TensorBoard UI. It's not clear
// exactly what causes this problematic intermediate state,
// but setting the height late seems to fix it.
root.style.height = `${height}px`;
}
const root = document.getElementById("root");
fetch(".")
.then((x) => x.text())
.then((html) => void (root.innerHTML = html))
.then(() => fixUpTensorboard(root))
.then(() => executeAllScripts(root))
.then(() => setHeight(root, 800));
})();
আমরা আজকে একটা বেইজ মডেল তৈরি করব অক্সফোর্ড ইউনিভার্সিটি’র ভিজ্যুয়াল জিওমেট্রি গ্রূপের vgg16 ডাটাসেট থেকে। এটা একটা প্রি-ট্রেইনড মডেল যা আসলে ‘ইমেজনেট’ নামে একটা বিশাল ডাটাসেট থেকে তৈরি করা। আমরা জানি যে ‘ইমেজনেট’ আসলে ১৪ লক্ষ ছবির একটা ডাটা সেট যার মধ্যে হাজারো ইন্টারনেটের ছবির ১০০০ ক্লাস বা ক্যাটেগরি আছে। এরমধ্যে কি ছবি নেই সেটাই অনেক চিন্তা করে বলতে হবে। আমরা যে ছবি প্রেডিক্ট করবো সেই ছবি ইমেজনেটে আছে কি নেই তার থেকে বড় ব্যাপার হচ্ছে ইমেজনেটকে ব্যবহার করছি ছবির বিভিন্ন ফিচার এক্সট্রাক্ট করার জন্য। চিত্রঃ VGG-16 মডেল, ব্লক দিয়ে এখন আমাদেরকে চিন্তা করতে হবে প্রি-ট্রেইনড মডেল হিসেবে কোন লেয়ারটাকে ব্যবহার করব ফিচার এক্সট্রাকশন এর জন্য। অবশ্যই সবচেয়ে শেষের যে ক্লাসিফিকেশন লেয়ার (সবচেয়ে শুরু’র, কারণ মেশিন লার্নিং মডেলগুলোর ডায়াগ্রাম শুরু হয় নিচ থেকে উপরে) সেটা ফিচার এক্সট্রাকশন এর জন্য ভালো নয়। আমরা শেষের আগের লেয়ারটা ব্যবহার করি আগের লেয়ারের আউটপুটকে ‘ফ্ল্যাটেন’ করার জন্য। তার ঠিক আগের লেয়ার থেকে শুরু করে সবচেয়ে উপরের লেয়ার পর্যন্ত ফিচার এক্সট্রাক্ট করা যায়। ক্লাসিফায়ার লেয়ার এর আগেরটা ফ্ল্যাটেন লেয়ার। আর তার ঠিক আগের আগের লেয়ারটাই স্পেশালাইজড লেয়ার। উপর থেকে নিচ পর্যন্ত আস্তে আস্তে ফিচারগুলো কমপ্লেক্স হতে থাকে বলে শেষের দিকের লেয়ারগুলো স্পেশালাইজড লেয়ার। এই লেয়ারকে বলা হচ্ছে ‘বটলনেক’ লেয়ার। এখানে ‘বটলনেক’ ফিচারগুলো খুবই স্পেসিফিক একটা কাজের জন্য থাকে। আমরা একটা মডেলকে যখন ইনস্ট্যান্সিয়েট করব তখন include_top=False আর্গুমেন্ট দিলেই ক্লাসিফিকেশন লেয়ার থাকবেনা শুরুতে। টপ লেয়ার ছাড়া একটা নেটওয়ার্ক লোড হবে। এটাই ফিচার ‘এক্সট্রাকশন’ এর জন্য সবচেয়ে ভালো অপশন। চিত্রঃ VGG-16 মডেল, ফিচার এক্সট্র্যাক্টর অথবা ফাইন টিউনিং ```python # মডেলের মাথা IMG_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, 3) vgg = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=False, input_shape=IMG_SHAPE) ``` Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5 58892288/58889256 [==============================] - 2s 0us/step ```python # আগের মতো মডেলের শেষ অংশ যোগ করে দিচ্ছি দুটো বাড়তি লেয়ার average_pool = tf.keras.layers.GlobalAveragePooling2D() prediction = keras.layers.Dense(1) ``` আমাদের vgg16 মডেলে ১৩টা কনভলিউশন লেয়ার আছে। এরমধ্যে ৩,৩ কনভলিউশন ফিল্টার এবং দরকারি ম্যাক্স পুলিং লেয়ার আছে ডাউন স্যাম্পলিং এর জন্য। এর মধ্যে দুটো ফুললি কানেক্টেড হিডেন লেয়ার যার ৪০৯৬ নোড ইউনিট আছে প্রতিটা লেয়ারে। এরপরে ১০০০ ইউনিটের ‘ডেন্স লেয়ার’ যা আসলে ১০০০ ক্যাটাগরির ছবির ক্লাসকে আইডেন্টিফাই করছে। আমাদের আসলে শেষের ৩ লেয়ার দরকার পড়ছে না, কারণ নিজেদের ফুললি কানেক্টেড ডেন্স লেয়ার ব্যবহার করব প্রেডিক্ট করতে - যে আসলে ছবিটা একটা কুকুরের না বিড়ালের? আমরা শুরুর পাঁচটা ব্লক নিয়ে ব্যস্ত থাকবো যেগুলো আসলে ফিচার এক্সট্রাকটর হিসেবে ব্যবহার হবে। ছবি দেখুন। আমাদের শুরুর মডেলে যেহেতু শুধুমাত্র ফিচার এক্সট্রাক্ট করব সে কারণে পাঁচটা কনভলিউশন ব্লককে ‘ফ্রিজ’ মানে ‘লক’ করে ফেলব যাতে তাদের ওয়েটগুলো আপডেট হতে না পারে প্রতিটা ইপকের পর। যেহেতু ট্রেনিং এর সময় লেয়ারগুলোর ‘ওয়েট’ দৈব-চয়নের ভিত্তিতে ইনিশিয়ালাইজ হয়, তাই সেই জিনিসটা ব্লকগুলোর আগের শেখা ওয়েটগুলো ভুলিয়ে দিতে পারে। ভুলিয়ে দিতে পারে বলছি ,এ কারণে আগের ট্রেনিংকৃত ফিচার ম্যাপগুলো উল্টাপাল্টা হয়ে যেতে পারে। সে কারণেই পাঁচটা ব্লক, মানে সব ব্লককেই ‘লক’ করে দিচ্ছি। ```python # প্রি-ট্রেইনড মডেলের মাথা ট্রেইন করা যাবে না, একদম লক vgg.trainable = False ``` ```python # দেখি লেয়ারগুলোর অবস্থা, ট্রেইন করা যাবে না import pandas as pd pd.set_option('max_colwidth', -1) layer_vgg = [(layer, layer.name, layer.trainable) for layer in vgg.layers] pd.DataFrame(layer_vgg, columns=['Layer Type', 'Layer Name', 'Layer Trainable']) ```
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}