प्री-प्रशिक्षित मॉडल का उपयोग करके छवि वर्गीकरण
इस पाठ में, आप किसी दिए गए चित्र में वस्तुओं का पता लगाने के लिए पूर्व-प्रशिक्षित मॉडल का उपयोग करना सीखेंगे। आप उपयोग करेंगेsqueezenet पूर्व-प्रशिक्षित मॉड्यूल जो किसी दिए गए चित्र में बड़ी सटीकता के साथ वस्तुओं का पता लगाता है और उनका वर्गीकरण करता है।
एक नया खोलें Juypter notebook और इस छवि वर्गीकरण अनुप्रयोग को विकसित करने के लिए चरणों का पालन करें।
पुस्तकालयों का आयात करना
सबसे पहले, हम नीचे दिए गए कोड का उपयोग करके आवश्यक पैकेज आयात करते हैं -
from caffe2.proto import caffe2_pb2
from caffe2.python import core, workspace, models
import numpy as np
import skimage.io
import skimage.transform
from matplotlib import pyplot
import os
import urllib.request as urllib2
import operator
अगला, हमने कुछ सेट किए variables -
INPUT_IMAGE_SIZE = 227
mean = 128
प्रशिक्षण के लिए उपयोग की जाने वाली छवियां स्पष्ट रूप से विभिन्न आकारों की होंगी। इन सभी छवियों को सटीक प्रशिक्षण के लिए निश्चित आकार में परिवर्तित किया जाना चाहिए। इसी तरह, परीक्षण की छवियां और वह छवि जिसे आप उत्पादन वातावरण में भविष्यवाणी करना चाहते हैं, उसे भी आकार में परिवर्तित करना होगा, उसी तरह जो प्रशिक्षण के दौरान उपयोग किया जाता है। इस प्रकार, हम ऊपर एक चर बनाते हैंINPUT_IMAGE_SIZE मान होना 227। इसलिए, हम अपनी सभी छवियों को आकार में बदल देंगे227x227 हमारे वर्गीकरण में इसका उपयोग करने से पहले।
हम एक चर भी घोषित करते हैं mean मान होना 128, जिसका उपयोग बाद में वर्गीकरण परिणामों में सुधार के लिए किया जाता है।
अगला, हम छवि को संसाधित करने के लिए दो फ़ंक्शन विकसित करेंगे।
इमेज प्रोसेसिंग
इमेज प्रोसेसिंग में दो चरण होते हैं। पहला एक छवि का आकार बदलने के लिए है, और दूसरा एक छवि को केन्द्रित करना है। इन दो चरणों के लिए, हम आकार बदलने और क्रॉप करने के लिए दो कार्य लिखेंगे।
छवि का आकार बदलना
सबसे पहले, हम छवि को आकार देने के लिए एक फ़ंक्शन लिखेंगे। जैसा कि पहले कहा गया था, हम छवि का आकार बदल देंगे227x227। तो चलिए फंक्शन को परिभाषित करते हैंresize निम्नानुसार है -
def resize(img, input_height, input_width):
हम ऊंचाई द्वारा चौड़ाई को विभाजित करके छवि के पहलू अनुपात को प्राप्त करते हैं।
original_aspect = img.shape[1]/float(img.shape[0])
यदि पहलू अनुपात 1 से अधिक है, तो यह इंगित करता है कि छवि व्यापक है, यह कहना है कि यह परिदृश्य मोड में है। अब हम छवि की ऊँचाई को समायोजित करते हैं और निम्न कोड का उपयोग करके पुन: आकार की छवि को लौटाते हैं -
if(original_aspect>1):
new_height = int(original_aspect * input_height)
return skimage.transform.resize(img, (input_width,
new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
यदि पहलू अनुपात है less than 1, यह इंगित करता है portrait mode। अब हम निम्नलिखित कोड का उपयोग करके चौड़ाई समायोजित करते हैं -
if(original_aspect<1):
new_width = int(input_width/original_aspect)
return skimage.transform.resize(img, (new_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
यदि पहलू अनुपात बराबर होता है 1, हम कोई ऊँचाई / चौड़ाई समायोजन नहीं करते हैं।
if(original_aspect == 1):
return skimage.transform.resize(img, (input_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
पूरा फ़ंक्शन कोड आपके त्वरित संदर्भ के लिए नीचे दिया गया है -
def resize(img, input_height, input_width):
original_aspect = img.shape[1]/float(img.shape[0])
if(original_aspect>1):
new_height = int(original_aspect * input_height)
return skimage.transform.resize(img, (input_width,
new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
if(original_aspect<1):
new_width = int(input_width/original_aspect)
return skimage.transform.resize(img, (new_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
if(original_aspect == 1):
return skimage.transform.resize(img, (input_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
अब हम इसके केंद्र के आस-पास के चित्र को क्रॉप करने के लिए एक फंक्शन लिखेंगे।
इमेज क्रॉपिंग
हम घोषणा करते हैं crop_image कार्य निम्नानुसार है -
def crop_image(img,cropx,cropy):
हम निम्नलिखित कथन का उपयोग करके छवि के आयामों को निकालते हैं -
y,x,c = img.shape
हम कोड की निम्नलिखित दो पंक्तियों का उपयोग करके छवि के लिए एक नया प्रारंभिक बिंदु बनाते हैं -
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
अंत में, हम नए आयामों के साथ एक इमेज ऑब्जेक्ट बनाकर क्रॉप की गई इमेज को वापस करते हैं -
return img[starty:starty+cropy,startx:startx+cropx]
संपूर्ण फ़ंक्शन कोड आपके त्वरित संदर्भ के लिए नीचे दिया गया है -
def crop_image(img,cropx,cropy):
y,x,c = img.shape
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
return img[starty:starty+cropy,startx:startx+cropx]
अब, हम इन कार्यों का परीक्षण करने के लिए कोड लिखेंगे।
प्रसंस्करण छवि
सबसे पहले, एक छवि फ़ाइल की प्रतिलिपि बनाएँ images आपके प्रोजेक्ट निर्देशिका के भीतर सबफ़ोल्डर। tree.jpgफ़ाइल को प्रोजेक्ट में कॉपी किया गया है। निम्नलिखित पायथन कोड छवि को लोड करता है और इसे कंसोल पर प्रदर्शित करता है -
img = skimage.img_as_float(skimage.io.imread("images/tree.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')
आउटपुट इस प्रकार है -
ध्यान दें कि मूल छवि का आकार है 600 x 960। हमें इसे अपने विनिर्देशन के अनुसार बदलना होगा227 x 227। हमारे पहले से परिभाषित फोनresizeकार्य यह काम करता है।
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')
आउटपुट नीचे दिया गया है -
ध्यान दें कि अब छवि का आकार है 227 x 363। हमें इसकी फसल की जरूरत है227 x 227हमारे एल्गोरिथ्म को अंतिम फ़ीड के लिए। हम इस उद्देश्य के लिए पहले से परिभाषित फसल कार्य कहते हैं।
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')
नीचे दिए गए कोड का उत्पादन है -
इस बिंदु पर, छवि आकार की है 227 x 227और आगे की प्रक्रिया के लिए तैयार है। अब हम तीन अलग-अलग क्षेत्रों में तीन रंगों को निकालने के लिए छवि कुल्हाड़ियों को स्वैप करते हैं।
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
नीचे दिया गया आउटपुट है -
CHW Image Shape: (3, 227, 227)
ध्यान दें कि अंतिम अक्ष अब सरणी में पहला आयाम बन गया है। अब हम निम्नलिखित कोड का उपयोग करके तीन चैनलों की साजिश करेंगे -
pyplot.figure()
for i in range(3):
pyplot.subplot(1, 3, i+1)
pyplot.imshow(img[i])
pyplot.axis('off')
pyplot.title('RGB channel %d' % (i+1))
उत्पादन नीचे बताया गया है -
अंत में, हम छवि पर कुछ अतिरिक्त प्रसंस्करण करते हैं जैसे कि परिवर्तित करना Red Green Blue सेवा Blue Green Red (RGB to BGR), बेहतर परिणाम के लिए माध्य निकालना और कोड की निम्नलिखित तीन पंक्तियों का उपयोग करके बैच आकार अक्ष को जोड़ना -
# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)
इस बिंदु पर, आपकी छवि अंदर है NCHW formatऔर हमारे नेटवर्क में खिलाने के लिए तैयार है। अगला, हम अपनी पूर्व-प्रशिक्षित मॉडल फ़ाइलों को लोड करेंगे और भविष्यवाणी के लिए उपरोक्त छवि को इसमें फीड करेंगे।
प्रोसेस्ड इमेज में ऑब्जेक्ट्स की भविष्यवाणी करना
हम पहले के लिए पथ सेटअप करते हैं init तथा predict कैफ़े के पूर्व प्रशिक्षित मॉडल में परिभाषित नेटवर्क।
मॉडल फ़ाइल पथ सेट करना
हमारी पिछली चर्चा से याद रखें, सभी पूर्व-प्रशिक्षित मॉडल में स्थापित हैं modelsफ़ोल्डर। हमने इस फ़ोल्डर का पथ निम्नानुसार सेट किया है -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
हमने रास्ता तय किया init_net की protobuf फ़ाइल squeezenet मॉडल निम्नानुसार है -
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
इसी तरह, हम रास्ता तय करते हैं predict_net प्रोटोबॉफ़ निम्नानुसार है -
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
हम निदान के उद्देश्य के लिए दो रास्ते प्रिंट करते हैं -
print(INIT_NET)
print(PREDICT_NET)
आउटपुट के साथ उपरोक्त कोड आपके त्वरित संदर्भ के लिए यहां दिया गया है -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
उत्पादन का उल्लेख नीचे दिया गया है -
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb
अगला, हम एक भविष्यवक्ता बनाएंगे।
प्रिडिक्टर बनाना
हम निम्नलिखित दो कथनों का उपयोग करके मॉडल फ़ाइलों को पढ़ते हैं -
with open(INIT_NET, "rb") as f:
init_net = f.read()
with open(PREDICT_NET, "rb") as f:
predict_net = f.read()
भविष्य कहनेवाला दो फाइलों के मापदंडों के रूप में संकेत से गुजरता है Predictor समारोह।
p = workspace.Predictor(init_net, predict_net)
pऑब्जेक्ट भविष्यवक्ता है, जो किसी भी छवि में वस्तुओं की भविष्यवाणी करने के लिए उपयोग किया जाता है। ध्यान दें कि प्रत्येक इनपुट छवि एनसीएचडब्ल्यू प्रारूप में होनी चाहिए, जैसा कि हमने पहले हमारे लिए किया हैtree.jpg फ़ाइल।
वस्तुओं की भविष्यवाणी करना
किसी दिए गए चित्र में वस्तुओं का अनुमान लगाना तुच्छ है - केवल कमांड की एक पंक्ति को निष्पादित करना। हम फोन करते हैंrun पर विधि predictor किसी दिए गए चित्र में एक वस्तु का पता लगाने के लिए वस्तु।
results = p.run({'data': img})
भविष्यवाणी परिणाम अब में उपलब्ध हैं results ऑब्जेक्ट, जिसे हम अपनी पठनीयता के लिए एक सरणी में परिवर्तित करते हैं।
results = np.asarray(results)
निम्नलिखित कथन का उपयोग करके अपनी समझ के लिए सरणी के आयामों को प्रिंट करें -
print("results shape: ", results.shape)
आउटपुट नीचे दिखाया गया है -
results shape: (1, 1, 1000, 1, 1)
अब हम अनावश्यक अक्ष को हटा देंगे -
preds = np.squeeze(results)
सबसे ऊपरी भविष्यवाणी को अब ले जाकर प्राप्त किया जा सकता है max में मूल्य preds सरणी।
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
आउटपुट इस प्रकार है -
Prediction: 984
Confidence: 0.89235985
जैसा कि आप देखते हैं कि मॉडल ने एक इंडेक्स वैल्यू वाली एक वस्तु की भविष्यवाणी की है 984 साथ में 89%आत्मविश्वास। 984 के सूचकांक को समझने में हमें कोई मतलब नहीं है कि किस तरह की वस्तु का पता लगाया गया है। हमें इसके सूचकांक मूल्य का उपयोग करके ऑब्जेक्ट के लिए कड़ा नाम प्राप्त करने की आवश्यकता है। मॉडल जिस तरह की वस्तुओं को उनके संबंधित सूचकांक मूल्यों के साथ पहचानता है, वह एक जीथब रिपॉजिटरी पर उपलब्ध है।
अब, हम देखेंगे कि 984 के इंडेक्स वैल्यू वाले हमारे ऑब्जेक्ट के लिए नाम कैसे पुनः प्राप्त करें।
स्ट्रिंग परिणाम
हम निम्नानुसार github रिपॉजिटरी के लिए एक URL ऑब्जेक्ट बनाते हैं -
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac0
71eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
हम URL की सामग्री पढ़ते हैं -
response = urllib2.urlopen(codes)
प्रतिक्रिया में सभी कोड और उसके विवरणों की एक सूची होगी। प्रतिक्रिया की कुछ लाइनें आपकी समझ के लिए नीचे दिखाई गई हैं कि इसमें क्या है -
5: 'electric ray, crampfish, numbfish, torpedo',
6: 'stingray',
7: 'cock',
8: 'hen',
9: 'ostrich, Struthio camelus',
10: 'brambling, Fringilla montifringilla',
अब हम एक का उपयोग कर 984 के हमारे वांछित कोड का पता लगाने के लिए पूरे सरणी को पुन: व्यवस्थित करते हैं for पाश इस प्रकार है -
for line in response:
mystring = line.decode('ascii')
code, result = mystring.partition(":")[::2]
code = code.strip()
result = result.replace("'", "")
if (code == str(curr_pred)):
name = result.split(",")[0][1:]
print("Model predicts", name, "with", curr_conf, "confidence")
जब आप कोड चलाते हैं, तो आपको निम्न आउटपुट दिखाई देंगे -
Model predicts rapeseed with 0.89235985 confidence
अब आप किसी अन्य छवि पर मॉडल आज़मा सकते हैं।
एक अलग छवि की भविष्यवाणी
किसी अन्य छवि की भविष्यवाणी करने के लिए, बस छवि फ़ाइल को इसमें कॉपी करें imagesआपके प्रोजेक्ट डायरेक्टरी का फोल्डर। यह वह निर्देशिका है जिसमें हमारे पहलेtree.jpgफ़ाइल संग्रहीत है। कोड में छवि फ़ाइल का नाम बदलें। नीचे दिखाए गए अनुसार केवल एक परिवर्तन आवश्यक है
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
मूल चित्र और भविष्यवाणी परिणाम नीचे दिखाए गए हैं -
उत्पादन का उल्लेख नीचे दिया गया है -
Model predicts pretzel with 0.99999976 confidence
जैसा कि आप देखते हैं कि पूर्व-प्रशिक्षित मॉडल किसी दिए गए चित्र में बड़ी सटीकता के साथ वस्तुओं का पता लगाने में सक्षम है।
पूर्ण स्रोत
उपरोक्त कोड के लिए पूर्ण स्रोत जो किसी दिए गए चित्र में ऑब्जेक्ट डिटेक्शन के लिए एक पूर्व-प्रशिक्षित मॉडल का उपयोग करता है, आपके त्वरित संदर्भ के लिए यहां उल्लेख किया गया है -
def crop_image(img,cropx,cropy):
y,x,c = img.shape
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
return img[starty:starty+cropy,startx:startx+cropx]
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
pyplot.figure()
for i in range(3):
pyplot.subplot(1, 3, i+1)
pyplot.imshow(img[i])
pyplot.axis('off')
pyplot.title('RGB channel %d' % (i+1))
# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
with open(INIT_NET, "rb") as f:
init_net = f.read()
with open(PREDICT_NET, "rb") as f:
predict_net = f.read()
p = workspace.Predictor(init_net, predict_net)
results = p.run({'data': img})
results = np.asarray(results)
print("results shape: ", results.shape)
preds = np.squeeze(results)
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac071eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
response = urllib2.urlopen(codes)
for line in response:
mystring = line.decode('ascii')
code, result = mystring.partition(":")[::2]
code = code.strip()
result = result.replace("'", "")
if (code == str(curr_pred)):
name = result.split(",")[0][1:]
print("Model predicts", name, "with", curr_conf, "confidence")
इस समय तक, आप जानते हैं कि अपने डेटासेट पर भविष्यवाणियाँ करने के लिए पूर्व-प्रशिक्षित मॉडल का उपयोग कैसे करें।
आगे यह जानने के लिए है कि आपको कैसे परिभाषित करना है neural network (NN) में आर्किटेक्चर Caffe2और उन्हें आपके डेटासेट पर प्रशिक्षित करें। अब हम सीखेंगे कि एक तुच्छ सिंगल लेयर NN कैसे बनाया जाता है।