Önceden Eğitilmiş Modeli Kullanarak Görüntü Sınıflandırma
Bu derste, belirli bir görüntüdeki nesneleri tespit etmek için önceden eğitilmiş bir model kullanmayı öğreneceksiniz. Kullanacaksınsqueezenet Belirli bir görüntüdeki nesneleri büyük bir doğrulukla algılayan ve sınıflandıran önceden eğitilmiş modül.
Yeni aç Juypter notebook ve bu görüntü sınıflandırma uygulamasını geliştirmek için adımları izleyin.
Kitaplıkları İçe Aktarma
İlk olarak, aşağıdaki kodu kullanarak gerekli paketleri içe aktarıyoruz -
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
Sonra, birkaç tane kurduk variables -
INPUT_IMAGE_SIZE = 227
mean = 128
Eğitim için kullanılan görüntüler açıkça çeşitli boyutlarda olacaktır. Doğru eğitim için tüm bu görüntüler sabit bir boyuta dönüştürülmelidir. Aynı şekilde, üretim ortamında tahmin etmek istediğiniz test görüntüleri ve görüntünün de eğitim sırasında kullanılanla aynı boyuta dönüştürülmesi gerekir. Böylece yukarıda adı verilen bir değişken oluşturuyoruzINPUT_IMAGE_SIZE değer sahibi 227. Bu nedenle, tüm görsellerimizi boyuta çevireceğiz227x227 sınıflandırıcımızda kullanmadan önce.
Ayrıca adında bir değişken de beyan ederiz mean değer sahibi 128, daha sonra sınıflandırma sonuçlarını iyileştirmek için kullanılır.
Daha sonra, görüntüyü işlemek için iki işlev geliştireceğiz.
Görüntü işleme
Görüntü işleme iki adımdan oluşur. Birincisi resmi yeniden boyutlandırmak, ikincisi resmi merkezi olarak kırpmaktır. Bu iki adım için, yeniden boyutlandırma ve kırpma için iki işlev yazacağız.
Görüntü Boyutlandırma
İlk olarak, görüntüyü yeniden boyutlandırmak için bir işlev yazacağız. Daha önce de belirtildiği gibi, resmi şu şekilde yeniden boyutlandıracağız:227x227. Öyleyse işlevi tanımlayalımresize aşağıdaki gibi -
def resize(img, input_height, input_width):
Genişliği yüksekliğe bölerek görüntünün en boy oranını elde ederiz.
original_aspect = img.shape[1]/float(img.shape[0])
En-boy oranının 1'den büyük olması görüntünün geniş, yani manzara modunda olduğunu gösterir. Şimdi resim yüksekliğini ayarlıyoruz ve aşağıdaki kodu kullanarak yeniden boyutlandırılmış resmi döndürüyoruz -
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)
En boy oranı ise less than 1, gösterir portrait mode. Şimdi genişliği aşağıdaki kodu kullanarak ayarlıyoruz -
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)
En boy oranı eşitse 1yükseklik / genişlik ayarı yapmıyoruz.
if(original_aspect == 1):
return skimage.transform.resize(img, (input_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
Hızlı başvurunuz için tam işlev kodu aşağıda verilmiştir -
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)
Şimdi görüntünün merkezi etrafında kırpılması için bir fonksiyon yazacağız.
Görüntü Kırpma
Biz ilan ediyoruz crop_image aşağıdaki gibi işlev -
def crop_image(img,cropx,cropy):
Aşağıdaki ifadeyi kullanarak görüntünün boyutlarını çıkarıyoruz -
y,x,c = img.shape
Aşağıdaki iki kod satırını kullanarak görüntü için yeni bir başlangıç noktası oluşturuyoruz -
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
Son olarak, yeni boyutlara sahip bir görüntü nesnesi oluşturarak kırpılmış görüntüyü döndürüyoruz -
return img[starty:starty+cropy,startx:startx+cropx]
Hızlı referansınız için tüm işlev kodu aşağıda verilmiştir -
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]
Şimdi bu fonksiyonları test etmek için kod yazacağız.
Görüntü işleniyor
İlk olarak, bir görüntü dosyasını içine kopyalayın. images proje dizininizdeki alt klasör. tree.jpgdosya projeye kopyalanır. Aşağıdaki Python kodu görüntüyü yükler ve konsolda görüntüler -
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')
Çıktı aşağıdaki gibidir -
Orijinal görüntünün boyutunun 600 x 960. Bunu şu spesifikasyonumuza göre yeniden boyutlandırmamız gerekiyor:227 x 227. Daha önce tanımladığımızresizeişlevi bu işi yapar.
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')
Çıktı aşağıda verildiği gibidir -
Şimdi görüntü boyutunun 227 x 363. Bunu kırpmalıyız227 x 227algoritmamızın son akışı için. Bu amaçla önceden tanımlanmış kırpma fonksiyonunu diyoruz.
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')
Aşağıda kodun çıktısı belirtilmiştir -
Bu noktada, resmin boyutu 227 x 227ve sonraki işlemler için hazırdır. Şimdi üç rengi üç farklı bölgeye çıkarmak için görüntü eksenlerini değiştiriyoruz.
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
Aşağıda verilen çıktıdır -
CHW Image Shape: (3, 227, 227)
Son eksenin artık dizideki ilk boyut haline geldiğine dikkat edin. Şimdi aşağıdaki kodu kullanarak üç kanalı çizeceğiz -
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))
Çıktı aşağıda belirtilmiştir -
Son olarak, görüntü üzerinde dönüştürme gibi bazı ek işlemler yapıyoruz. Red Green Blue -e Blue Green Red (RGB to BGR), daha iyi sonuçlar için ortalamayı kaldırma ve aşağıdaki üç kod satırını kullanarak parti boyutu ekseni ekleme -
# 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)
Bu noktada, resmin içinde NCHW formatve ağımıza beslenmeye hazır. Ardından, önceden eğitilmiş model dosyalarımızı yükleyeceğiz ve yukarıdaki resmi tahmin için ona besleyeceğiz.
İşlenmiş Görüntüdeki Nesneleri Tahmin Etme
İlk önce, init ve predict Caffe'nin önceden eğitilmiş modellerinde tanımlanan ağlar.
Model Dosya Yollarını Ayarlama
Önceki tartışmamızdan hatırlayın, tüm önceden eğitilmiş modeller modelsKlasör. Bu klasöre giden yolu aşağıdaki gibi belirledik -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
Yolu kurduk init_net protobuf dosyası squeezenet aşağıdaki gibi model -
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
Aynı şekilde, predict_net protobuf aşağıdaki gibidir -
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
Teşhis amacıyla iki yolu yazdırıyoruz -
print(INIT_NET)
print(PREDICT_NET)
Çıktıyla birlikte yukarıdaki kod, hızlı referansınız için burada verilmiştir -
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)
Çıktı aşağıda belirtilmiştir -
/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
Sonra, bir tahminci oluşturacağız.
Tahmin Oluşturma
Model dosyalarını aşağıdaki iki ifadeyi kullanarak okuyoruz -
with open(INIT_NET, "rb") as f:
init_net = f.read()
with open(PREDICT_NET, "rb") as f:
predict_net = f.read()
Tahmin edici, iki dosyaya işaretçilerin parametreler olarak iletilmesiyle oluşturulur. Predictor işlevi.
p = workspace.Predictor(init_net, predict_net)
pnesne, herhangi bir görüntüdeki nesneleri tahmin etmek için kullanılan tahmin edicidir. Her giriş görüntüsünün, daha önce yaptığımız gibi NCHW formatında olması gerektiğini unutmayın.tree.jpg dosya.
Nesneleri Tahmin Etme
Belirli bir görüntüdeki nesneleri tahmin etmek önemsizdir - sadece tek bir komut satırını çalıştırmak. Biz ararızrun yöntemi predictor belirli bir görüntüde bir nesne algılaması için nesne.
results = p.run({'data': img})
Tahmin sonuçları artık şurada mevcuttur: results Okunabilirliğimiz için bir diziye dönüştürdüğümüz nesne.
results = np.asarray(results)
Anlayışınız için dizinin boyutlarını aşağıdaki ifadeyi kullanarak yazdırın -
print("results shape: ", results.shape)
Çıktı aşağıda gösterildiği gibidir -
results shape: (1, 1, 1000, 1, 1)
Şimdi gereksiz ekseni kaldıracağız -
preds = np.squeeze(results)
En üstteki tahmin artık şu şekilde alınabilir: max değer preds dizi.
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
Çıktı aşağıdaki gibidir -
Prediction: 984
Confidence: 0.89235985
Gördüğünüz gibi, model bir indeks değerine sahip bir nesneyi tahmin etti 984 ile 89%güven. 984'ün indeksi, ne tür bir nesnenin algılandığını anlamada bize pek bir anlam ifade etmiyor. İndeks değerini kullanarak nesnenin dizgeli ismini almamız gerekir. Modelin, karşılık gelen indeks değerleriyle birlikte tanıdığı nesne türleri, bir github havuzunda mevcuttur.
Şimdi 984 indeks değerine sahip nesnemizin adını nasıl alacağımızı göreceğiz.
Sonuçların Kısaltılması
Github havuzuna aşağıdaki gibi bir URL nesnesi oluşturuyoruz -
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac0
71eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
URL'nin içeriğini okuyoruz -
response = urllib2.urlopen(codes)
Yanıt, tüm kodların ve açıklamalarının bir listesini içerecektir. Ne içerdiğini anlamanız için aşağıda yanıtın birkaç satırı gösterilmektedir -
5: 'electric ray, crampfish, numbfish, torpedo',
6: 'stingray',
7: 'cock',
8: 'hen',
9: 'ostrich, Struthio camelus',
10: 'brambling, Fringilla montifringilla',
Şimdi 984'ün istediğimiz kodunu bulmak için tüm diziyi yineliyoruz. for aşağıdaki gibi döngü -
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")
Kodu çalıştırdığınızda, aşağıdaki çıktıyı göreceksiniz -
Model predicts rapeseed with 0.89235985 confidence
Şimdi modeli başka bir görüntü üzerinde deneyebilirsiniz.
Farklı Bir Görüntüyü Tahmin Etmek
Başka bir görüntüyü tahmin etmek için, görüntü dosyasını imagesproje dizininizin klasörü. Bu, daha öncetree.jpgdosya saklanır. Koddaki görüntü dosyasının adını değiştirin. Aşağıda gösterildiği gibi yalnızca bir değişiklik gereklidir
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
Orijinal resim ve tahmin sonucu aşağıda gösterilmektedir -
Çıktı aşağıda belirtilmiştir -
Model predicts pretzel with 0.99999976 confidence
Gördüğünüz gibi, önceden eğitilmiş model, belirli bir görüntüdeki nesneleri büyük bir doğrulukla algılayabilir.
Tam Kaynak
Belirli bir görüntüde nesne tespiti için önceden eğitilmiş bir model kullanan yukarıdaki kodun tam kaynağı, hızlı referansınız için burada belirtilmiştir -
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")
Bu zamana kadar, veri kümenizdeki tahminleri yapmak için önceden eğitilmiş bir modeli nasıl kullanacağınızı biliyorsunuz.
Sırada ne var? neural network (NN) mimariler Caffe2ve bunları veri kümenizde eğitin. Şimdi önemsiz bir tek katmanlı NN'nin nasıl oluşturulacağını öğreneceğiz.