সিএনএন ব্যবহার করে লাইন ফলোয়ার রোবট
এই টিউটোরিয়ালে আমরা কীভাবে একটি লাইন অনুসরণকারী রোবট তৈরি করতে শিখব। যদিও, নিজের মধ্যে এই ধারণাটি বেশ পুরানো হওয়ায় সেখানে প্রচুর লাইন ফলোয়ার টিউটোরিয়াল রয়েছে। তবে, আমরা এখানে কনভলিউশনাল নিউরাল নেটওয়ার্ক (সিএনএন) ব্যবহার করে কীভাবে লাইনটি সনাক্ত করতে হবে তা শিখব। মূলত, আমরা আমাদের রাস্পবেরি পাই ক্যামেরা ব্যবহার করে একটি পূর্বনির্ধারিত ব্যবধানে কয়েকটি সিরিজ চিত্রগুলি ক্যাপচার করব, তারপরে আমরা আমাদের রোবোটটি যেদিকে এগিয়ে, ডান বা বাম দিকে এগিয়ে যেতে হবে সেদিকে ভবিষ্যদ্বাণী করতে একটি প্রাক-প্রশিক্ষিত সিএনএন ব্যবহার করব। এই টিউটোরিয়ালটির জন্য আপনার নিম্নলিখিত বিষয়গুলির প্রয়োজন হবে: -
- রাস্পবেরি পাই বোর্ড,
- পাই ক্যামেরা,
- জাম্পারের তারগুলি
- চ্যাসি, মোটর, টায়ার
- মোটর নিয়ন্ত্রণ আইসি (L293d)
আমি ধরে নিচ্ছি যে আপনি আপনার রাস্পবেরি পাই এর জিপিআইও পিন ব্যবহার করে মোটরগুলি কীভাবে নিয়ন্ত্রণ করবেন তা আপনি ইতিমধ্যে সচেতন। আপনি যদি আপনার দক্ষতাটি সামান্য একটু বাড়িয়ে নিতে চান তবে আমার আগের টিউটোরিয়ালটি দেখুন । এছাড়াও, আরও এগিয়ে যাওয়ার আগে আপনার পাইতে টেনস্রফ্লো ১.১ রয়েছে এবং ওপেন সিভি ইনস্টল করা আছে তা নিশ্চিত করুন।
আমি এই টিউটোরিয়ালটি তিনটি বিভাগে বিভক্ত করব: -
- সিএনএন-এর জন্য চিত্রগুলি ক্যাপচার করুন।
- সিএনএন প্রশিক্ষণ
- রাস্পবেরি পিআই এ সিএনএন স্থাপন করুন
সিএনএন-এর জন্য চিত্রগুলি ক্যাপচার করুন
আমাদের সিএনএন প্রশিক্ষণের জন্য আমাদের তিনটি শর্তের অর্থাত্ এগিয়ে, বাম এবং ডানগুলির জন্য তিনটি চিত্রের প্রয়োজন। একবার আমরা আমাদের সিএনএনকে প্রশিক্ষণ দিলে রোবটটি কোন দিকে চলেছে তা অনুমান করতে সক্ষম হবে এবং তারপরে আমরা সেই অনুযায়ী সংশোধনমূলক ব্যবস্থা নিতে পারি। উদাহরণস্বরূপ, যদি লাইনের বাম দিকে ঘুরতে থাকে, সিএনএন ভবিষ্যদ্বাণী করবে যে রোবটটি লাইনের সাথে সম্পর্কিত ডানদিকে চলেছে এবং সুতরাং, আমাদের এটি বাম দিকে সরানো উচিত।

বিভিন্ন পদ্ধতিতে আপনি সিএনএন প্রশিক্ষণের জন্য ডেটা সেট তৈরি করতে পারেন। আমার ক্ষেত্রে, আমি প্রথমে একটি ট্র্যাক তৈরি করেছি। তারপরে, আমি .5 সেকেন্ডের ব্যবধানে চিত্রের একটি সিরিজ ক্যাপচারের জন্য নীচে উল্লিখিত কোডটি ব্যবহার করেছি। তারপরে আপনি ট্র্যাকের বিভিন্ন অবস্থানে রোবটটি রাখুন এবং কয়েকটি সিরিজ চিত্রগুলি ক্যাপচার করুন। উদাহরণস্বরূপ, প্রথম চিত্রটিতে, আমি রোবটটি এমনভাবে রেখেছি যাতে আমি সিএনএনকে সনাক্ত করতে চাই যে রোবটটি বাম দিকে যেতে পারে। একইভাবে আপনি ট্র্যাকের বিভিন্ন অবস্থানে এই প্রক্রিয়াটি পুনরাবৃত্তি করেন। একবার হয়ে গেলে আপনি এগিয়ে এবং সঠিক দিকনির্দেশের জন্য এই প্রক্রিয়াটি পুনরাবৃত্তি করতে পারেন। একবার আপনি তিনটি দিকের জন্য চিত্রগুলি ক্যাপচার করার পরে, যথাক্রমে সামনের দিকে, বাম এবং ডানদিকে আলাদা আলাদা ফোল্ডারে রাখুন।
# import the necessary packages from picamera.array import PiRGBArray from picamera import PiCamera import time import cv2 # initialize the camera and grab a reference to the raw camera capture camera = PiCamera() camera.resolution = (640, 480) # set the resolution camera.framerate = 32 # set the frame rate rawCapture = PiRGBArray(camera, size=(640, 480)) # allow the camera to warm up time.sleep(0.1) # capture frames from the camera start = 1for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): # grab the raw NumPy array representing the image, then initialize the timestamp and occupied/unoccupied text image = frame.array # show the frame cv2.imshow("Frame", image) key = cv2.waitKey(1) & 0xFF cv2.imwrite(str(start) + ".jpg", image) start = start + 1 # clear the stream in preparation for the next frame rawCapture.truncate(0) # if the `q` key was pressed, break from the loop if key == ord("q"): break time.sleep(.5)
সিএনএন প্রশিক্ষণ
আপনি সিএনএনকে হয় রাস্পবেরি পিআই নিজেই বা অন্য একটি আরও শক্তিশালী সিস্টেমে প্রশিক্ষণ দিতে পারেন এবং তারপরে প্রশিক্ষিত মডেলটি সংরক্ষণ করতে পারেন যা পাই পড়তে পারে। ক্যাপচার হওয়া চিত্রগুলিতে আপনার সিএনএনকে প্রশিক্ষণের জন্য কোডটি নীচে দেওয়া হয়েছে।
প্রথমে আমরা প্রয়োজনীয় গ্রন্থাগারগুলি আমদানি করি।
# import the necessary packages
from keras.models import Sequential
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, Flatten, Dense
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing.image import img_to_array
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from imutils import paths
import numpy as np
import argparse
import random
import cv2
import os
import matplotlib
from keras.models import Sequential
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, Flatten, Dense
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing.image import img_to_array
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from imutils import paths
import numpy as np
import argparse
import random
import cv2
import os
import matplotlib
তারপরে আমরা একটি শ্রেণি সংজ্ঞায়িত করি
LeNet
যা একটি সিএনএন তৈরি করতে ব্যবহৃত হতে পারে। এখানে আপনি দেখতে পারেন এই শ্রেণীর একটি ফাংশন আছে build
যা গ্রহণ আর্গুমেন্ট width
, height
, depth
, এবং classes
। প্রস্থ এবং উচ্চতা চিত্রের প্রস্থ এবং উচ্চতার সমান হওয়া উচিত যা আপনি সিএনএন-এ ইনপুট হিসাবে ব্যবহার করবেন। আমার ক্ষেত্রে আমি 28x28 চিত্র ব্যবহার করছিলাম, সুতরাং প্রস্থ এবং উচ্চতা উভয়ই 28 টি গ্রহণযোগ্যভাবে হয়। গভীরতা ইনপুট চিত্রে চ্যানেলের সংখ্যা নির্ধারণ করে। একরঙার জন্য গভীরতা 1 এবং আরজিবি এর জন্য 3। ক্লাসগুলি সিএনএন সনাক্ত করতে চাইলে বিভিন্ন ধরণের চিত্রের সংজ্ঞা দেয়। আমাদের ক্ষেত্রে আমরা তিন ধরণের চিত্রের মধ্যে পার্থক্য করতে চাই - ফরোয়ার্ড, বাম এবং ডান।class LeNet: @staticmethod def build(width, height, depth, classes): # initialize the model model = Sequential() inputShape = (height, width, depth)# first set of CONV => RELU => POOL layers model.add(Conv2D(20, (5, 5), padding="same", input_shape=inputShape)) model.add(Activation("relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# second set of CONV => RELU => POOL layers model.add(Conv2D(50, (5, 5), padding="same")) model.add(Activation("relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# first (and only) set of FC => RELU layers model.add(Flatten()) model.add(Dense(500)) model.add(Activation("relu"))# softmax classifier model.add(Dense(classes)) model.add(Activation("softmax"))# return the constructed network architecture return model
আপনি যখন
build
ফাংশনটি কল করবেন তখন এটি দুটি কনভোলসাল স্তর এবং একটি দুটি ঘন স্তর সহ একটি নিউরাল নেটওয়ার্ক সংজ্ঞায়িত করবে। কেউ এই স্তরগুলির পরামিতিগুলির সাথে পরীক্ষা করতে পারেন, বা এমনকি মডেলের যথার্থতা উন্নত করতে অতিরিক্ত স্তর যুক্ত করতে পারেন। এরপরে, যেখানে আপনার প্রশিক্ষণ চিত্রের ফোল্ডার উপস্থিত রয়েছে সেই পথটি সরবরাহ করুন। আপনি অবশ্যই তিনটি ফোল্ডার ফরোয়ার্ড, বাম এবং ডানদিক তৈরি করতে হবে এবং উপরের ক্যাপচারযুক্ত চিত্রগুলি সংশ্লিষ্ট ফোল্ডারে রেখে দিতে হবে।dataset = '/home/pi/Desktop/tutorials/raspberry/trainImages/' # please change this path # initialize the data and labels print("[INFO] loading images...") data = [] labels = [] # grab the image paths and randomly shuffle them imagePaths = sorted(list(paths.list_images(dataset))) random.seed(42) random.shuffle(imagePaths)# loop over the input images for imagePath in imagePaths: # load the image, pre-process it, and store it in the data list image = cv2.imread(imagePath) image = cv2.resize(image, (28, 28)) image = img_to_array(image) data.append(image)# extract the class label from the image path and update the # labels list label = imagePath.split(os.path.sep)[-2] print(label) if label == 'forward': label = 0 elif label == 'right': label = 1 else: label =2 labels.append(label)
উপরের কোডটি তখন উপ-ফোল্ডারগুলিতে উপস্থিত তালিকার
imagePaths
স্টোরগুলিতে উপস্থিত প্রতিটি চিত্রের পথ ধরে এবং সেগুলি বদলে দেয়। মডেলটি প্রশিক্ষণ দেওয়ার সময় এলোমেলোভাবে প্রতিটি ক্লাসের ডেটা সরবরাহ করার জন্য শ্যাফেল করা প্রয়োজন। এরপরে, প্রতিটি চিত্রের পরে পড়া, পুনরায় আকার দেওয়া, নাম্পার অ্যারে রূপান্তরিত এবং এতে সংরক্ষণ করা হয় data
। এখন আমাদের প্রতিটি চিত্রের জন্য একটি লেবেলও নির্ধারণ করতে হবে। এর জন্য আমরা প্রতিটি চিত্রের চিত্রের পথ থেকে ফোল্ডারের নামটি বের করি। তারপরে, আমরা তুলনা করি যদি ফোল্ডারের নাম 'ফরোয়ার্ড' হয় তবে আমরা 0 এর লেবেল বরাদ্দ করি Similarly একইভাবে 1 এবং 2 এর লেবেল ফোল্ডারে 'ডান' এবং 'বামে' উপস্থিত চিত্রগুলিকে বরাদ্দ করা হয়। এ কারণেই সাব-ফোল্ডার তৈরি করা এবং একই রকম চিত্রগুলি বিভিন্ন ফোল্ডারে স্থাপন করা প্রয়োজন।# scale the raw pixel intensities to the range [0, 1] data = np.array(data, dtype="float") / 255.0 labels = np.array(labels) # partition the data into training and testing splits using 75% of # the data for training and the remaining 25% for testing (trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25, random_state=42)# convert the labels from integers to vectors trainY = to_categorical(trainY, num_classes=3) testY = to_categorical(testY, num_classes=3)
এরপরে, চিত্রগুলি স্বাভাবিক করা হয় যাতে প্রতিটি পিক্সেলের মান 0 এবং 1 এর মধ্যে হয় Then তারপরে, চিত্রগুলি মডেলটির কার্যকারিতা যাচাই করার জন্য প্রশিক্ষণ এবং পরীক্ষার জন্য বিভাগে বিভক্ত হয়। পরবর্তী পদক্ষেপগুলিতে আমরা লেনেট ক্লাস ব্যবহার করে মডেলটি তৈরি করি, প্রশিক্ষণ ডেটাতে মডেলটিকে প্রশিক্ষণ দিন এবং তারপরে প্রশিক্ষিত ডেটা সংরক্ষণ করি।
# initialize the number of epochs to train for, initial learning rate, # and batch size EPOCHS = 15 INIT_LR = 1e-3 BS = 32# initialize the model print("[INFO] compiling model...") model = LeNet.build(width=28, height=28, depth=3, classes=3) opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS) model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"]) # train the network print("[INFO] training network...") H = model.fit(trainX, trainY, batch_size=BS, validation_data=(testX, testY),# steps_per_epoch=len(trainX) // BS, epochs=EPOCHS, verbose=1) # save the model to disk print("[INFO] serializing network...") model.save("model")
সিএনএন মোতায়েন করুন
একবার আমরা আমাদের মডেলকে প্রশিক্ষণ দিলে, আমরা এটি আমাদের পাইতে স্থাপন করতে পারি। সিএনএন থেকে ভবিষ্যদ্বাণী করে রোবটের দিকনির্দেশনা নিয়ন্ত্রণের জন্য আপনি নীচে উল্লিখিত কোডটি ব্যবহার করতে পারেন। প্রথমে আমরা প্রয়োজনীয় গ্রন্থাগার আমদানি করে শুরু করি। এখানে আমরা
motor_control.py
ফাইলটিও ব্যবহার করছি যা আপনি আমার আগের টিউটোরিয়ালে খুঁজে পেতে পারেন।
# import the necessary packages
from keras.preprocessing.image import img_to_array
from keras.models import load_model
import numpy as np
import cv2, time, sys, imutils, argparse
import RPi.GPIO as GPIO
from picamera.array import PiRGBArray
from picamera import PiCamera
import motor_control as mc
from keras.preprocessing.image import img_to_array
from keras.models import load_model
import numpy as np
import cv2, time, sys, imutils, argparse
import RPi.GPIO as GPIO
from picamera.array import PiRGBArray
from picamera import PiCamera
import motor_control as mc
এরপরে, রাস্পবেরিপির পিনগুলি সংজ্ঞায়িত করুন যা আপনি মোটরগুলি নিয়ন্ত্রণ করতে ব্যবহার করবেন।
GPIO.setmode(GPIO.BCM)#choose the GPIO pins for mptor control fwd1 = 23 # pin 16 bwd1 = 24 #pin 18 fwd2 = 16 # pin 36 bwd2 = 20 # pin 38# declare selected pin as output pin GPIO.setup(fwd1, GPIO.OUT) GPIO.setup(bwd1, GPIO.OUT) GPIO.setup(fwd2, GPIO.OUT) GPIO.setup(bwd2, GPIO.OUT)
এর পরে, আমরা একটি ফাংশন সংজ্ঞায়িত করি
control_robot
যা মডেল থেকে ভবিষ্যদ্বাণী ভিত্তিক রোবটের দিক নিয়ন্ত্রণ করবে।
#function to control direction of robot based on prediction from CNN
def control_robot(image):
prediction = np.argmax(model.predict(image))
if prediction == 0:
print("forward")
mc.forward()
elif prediction == 2:
print("left")
mc.left()
else:
print("right")
mc.right()
def control_robot(image):
prediction = np.argmax(model.predict(image))
if prediction == 0:
print("forward")
mc.forward()
elif prediction == 2:
print("left")
mc.left()
else:
print("right")
mc.right()
এরপরে, আমরা ক্যামেরাটি শুরু করব এবং পূর্বনির্ধারিত বিরতিতে চিত্রগুলি দখল শুরু করব। এই চিত্রটির প্রত্যেকটি প্রাক-প্রক্রিয়াজাতকরণের মতো
আমরা প্রশিক্ষণের চিত্রগুলির জন্য করেছি। তারপরে এই চিত্রগুলি ফাংশনে পৌঁছে
control_robot
যা রোবটের দিকনির্দেশকে নিয়ন্ত্রণ করে।model = load_model("model")if __name__ == "__main__":
try:
mc.stop()
# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
# allow the camera to warmup
time.sleep(0.1)
# capture frames from the camerafor frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# grab the raw NumPy array representing the image, then initialize the timestamp
# and occupied/unoccupied text
image = frame.array
# show the frame
key = cv2.waitKey(1) & 0xFF image = cv2.resize(image, (28, 28))
image = img_to_array(image)
image = np.array(image, dtype="float") / 255.0
image = image.reshape(-1, 28, 28, 3)
#cv2.imshow("Frame", image[0]) control_robot(image) # clear the stream in preparation for the next frame
rawCapture.truncate(0) except KeyboardInterrupt:
mc.stop()
GPIO.cleanup()
sys.exit()
যদি সবকিছু ঠিকঠাক হয়, আপনি যখন আপনার রাস্পবেরি পাইতে এই কোডটি চালাবেন তখন আপনি একটি অনুরূপ ফলাফল দেখতে সক্ষম
হবেন।

আমি আশা করি আপনি টিউটোরিয়ালটি উপভোগ করেছেন। মন্তব্য এবং জিজ্ঞাসা জিজ্ঞাসা বা কিছু পরামর্শ দিতে নির্দ্বিধায়। আমি এখানে বেস হিসাবে ব্যবহার করেছি রাস্পবেরিপিতে তাঁর আশ্চর্যজনক টিউটোরিয়ালগুলির জন্য অ্যাড্রিয়ান রোজব্রোককে একটি বিশাল ধন্যবাদ। তার ওয়েবসাইট চেকআউট করুন ।
0 comments:
Post a Comment