97% dan yuqori aniqlik bilan rasm tasniflagichini qanday qurish mumkin

Muvaffaqiyat uchun aniq va to'liq reja

Qanday qilib kompyuterni rasmga qarashni va uni gul sifatida to'g'ri aniqlashni o'rgatasiz? Qanday qilib kompyuterga gul tasvirini ko'rishni o'rgatasiz va keyin u qanday tur ekanligini bilmasangiz ham u qanday gul turini aniq aytasiz?

Sizga ko'rsatay!

Ushbu maqola sizni PyTorch yordamida tasvirlar tasniflagichini yaratish asoslari bilan tanishtiradi. Siz telefoningiz ilovasida shunga o'xshash narsani kamerangiz ko'rib turgan gulning nomini aytib berishni tasavvur qilishingiz mumkin. Agar xohlasangiz, ushbu klassifikatorni o'qitib, o'zingizning ilovangizda foydalanish uchun eksport qilishingiz mumkin.

Bu erdan nima qilishingiz butunlay sizga va sizning tasavvuringizga bog'liq.

Men ushbu maqolani hamma uchun yangi bo'lgan va boshlash uchun joy qidiradigan har bir kishi uchun ushbu maqolani birlashtirdim. Ushbu ma'lumotni olish, uni takomillashtirish va uni o'zingiz qilishingiz kerak.

Agar siz daftarni ko'rmoqchi bo'lsangiz, uni shu erdan topishingiz mumkin.

Ushbu PyTorch rasm tasniflagichi Udacity dasturi uchun yakuniy loyiha sifatida qurilganligi sababli, kod Udacity-dan olingan kodni oladi va bu o'z navbatida rasmiy PyTorch hujjatlariga asoslanadi. Udacity shuningdek, yorliqlarni xaritalash uchun JSON faylini taqdim etdi. Ushbu faylni ushbu GitHub repo-da topish mumkin.

Gullar to'g'risidagi ma'lumotlar to'plami haqida ma'lumotni bu erda topishingiz mumkin. Ma'lumotlar to'plamida 102 ta gul sinflarining har biri uchun alohida papka mavjud. Har bir gul raqam sifatida belgilanadi va raqamlangan har bir katalogda bir nechta .jpg fayllar bo'ladi.

Qani boshladik!

Enni Spratt surati Unsplash-da

Bu mening protsessorim har qanday oqilona vaqtni ishlata oladigan katta ma'lumotlardan foydalanadigan neyron tarmoq bo'lgani uchun men Google Colab-da rasmlar tasniflagichini o'rnatdim. Colab haqiqatan ham ajoyib, chunki u bepul GPU ta'minlaydi. (Agar siz Colab bilan tanishgan bo'lsangiz, ushbu maqolani Google Colab-dan boshlashni ko'rib chiqing!)

Men Colab-dan foydalanayotganligim sababli PyTorch-ni import qilishni boshlashim kerak edi. Agar siz Colab-dan foydalanmasangiz, buni qilishingiz shart emas.

*** YANGILASH! (01/29) *** Colab endi mahalliy PyTorch-ni qo'llab-quvvatlamoqda !!! Quyidagi kodni ishlatishingiz shart emas, lekin agar kimdir biron bir muammoga duch kelsa, men uni qoldiraman!

# Google Colab-dan foydalanayotgan bo'lsangiz, PyTorch-ni import qiling
# http://pytorch.org/
Os.path-dan import mavjud
wheel.pep425tag dan import get_abbr_impl, get_impl_ver, get_abi_tag
platforma = '{} {} - {}' formati (get_abbr_impl (), get_impl_ver (), get_abi_tag ())
cuda_output =! ldconfig -p | grep cudart.so | sed -e '/ .* \. \ ([0-9] * \) \. \ ([0-9] * \) $ / cu \ 1 \ 2 / '
accelerator = cuda_output [0] mavjud bo'lsa ('/ dev / nvidia0') else 'cpu'
! pip o'rnatish -q http://download.pytorch.org/whl/{accelerator}/torch-0.4.1-{platform}-linux_x86_64.whl mash'alasi
import mash'alasi

Keyin, yostiq bilan (masalan, Kolabda bug ') muammoga duch kelganimdan so'ng, men oldinga yugurib chiqdim:

import PIL
bosib chiqarish (PIL.PILLOW_VERSION)

Agar siz 5.3.0 dan pastroq narsani olgan bo'lsangiz, "Ish vaqti" ostidagi ochiladigan menyudan "Ish vaqtini qayta boshlash" -ni tanlang va ushbu katakni yana ishga tushiring. Siz borishingiz kerak!

Ushbu loyiha uchun GPU-dan foydalanishni xohlaysiz, bu Colab-ni o'rnatish juda oddiy. Siz shunchaki "ish vaqti" ochiladigan menyusiga o'tasiz, "ish vaqti turini o'zgartirish" -ni tanlang, so'ng apparat tezlatgichining ochiladigan menyusida "GPU" -ni tanlang!

Keyin men yugurishni yaxshi ko'raman

train_on_gpu = mash'al.cuda.is_available ()
agar train_on_gpu:
    chop etish ('Bummer! CPU bo'yicha o'qitish ...')
yana:
    print ('Siz borganingiz yaxshi! GPU bo'yicha o'qitish ...')

shunchaki uning ishlashiga ishonch hosil qilish uchun. Keyin choping

qurilma = torch.device (agar torch.cuda.is_available () "" cpu "bo'lsa)" cuda: 0 ")

qurilmani aniqlash uchun.

Shundan so'ng, fayllarni import qiling. Buni amalga oshirishning bir qancha usullari mavjud, agar sizning ma'lumotlar bazangiz shu erda saqlangan bo'lsa, Google Drive-ni o'rnatish juda oson. Garchi men buni eng foydali echim deb topmagan bo'lsam ham, buni juda oson va foydaliroq bo'lganim uchun, quyida aytib o'taman.

google.colab import diskidan
drive.mount ('/ content / gdrive')

Keyin siz havolani ko'rasiz, ustiga bosing, kirishga ruxsat bering, ochilgan kodni nusxa oling, maydonga qo'ying, Enter ni bosing va siz borishingiz yaxshi! Agar chap tomondagi yon oynada drayvingizni ko'rmasangiz, shunchaki "yangilash" tugmachasini bosing va u paydo bo'lishi kerak.

(Hujayrani ishga tushiring, havolani bosing, sahifadagi kodni ko'chiring, maydonga qo'ying, Enter tugmasini bosing va drayvingizni muvaffaqiyatli o'rnatganingizda buni ko'rasiz):

Bu juda ham oson!

Ammo, agar siz ZIP-fayllarning umumiy havolasini yuklab olmoqchi bo'lsangiz (ushbu loyiha uchun bu osonroq va tezroq bo'ladi), siz quyidagilarni ishlatishingiz mumkin:

! wget
! ochish

Masalan:

! wget -cq https://s3.amazonaws.com/content.udacity-data.com/courses/nd188/flower_data.zip
! unzip -qq gul_data.zip

Bu sizga bir necha soniya ichida Udacity-ning gullari haqidagi ma'lumotlarni beradi!

(Agar siz kichkina fayllarni yuklayotgan bo'lsangiz, ularni shunchaki oddiy kod bilan to'g'ridan-to'g'ri yuklashingiz mumkin. Ammo, agar xohlasangiz, ekranning chap tomoniga o'tishingiz va agar kerak bo'lmasa "fayllarni yuklash" tugmachasini bosishingiz mumkin. Mahalliy faylni ushlash uchun oddiy kodni ishlatgan kabi his eting.)

Ma'lumotlarni yuklaganimdan so'ng, men foydalanmoqchi bo'lgan kutubxonalarni olib keldim.

% matplotlib chizig'i
% config InlineBackend.figure_format = 'retina'
import vaqti
import json
nusxasini import qilish
matplotlib.pyplot-ni plt sifatida import qilish
sns sifatida dengiz shimoli importi
numpy ni np sifatida import qilish
import PIL
PIL import Image-dan
to'plamlardan OrderedDict import qiling
import mash'alasi
mash'al import nn, optim
torch.optim import lr_scheduler-dan
mash'al.autograd importidan o'zgaruvchan
import mash'alasi
mash'aladan import ma'lumotlar to'plamlari, modellar, transformatsiyalar
torch.utils.data.sampler-dan SubsetRandomSampler-ni import qilish
torch.nn ni nn sifatida import qiling
F sifatida import torch.nn.funktsional

Keyingi ma'lumotlar o'zgartiriladi! Siz dasturingiz iloji boricha ko'proq ma'lumotga ega bo'lishi uchun mashg'ulotlar to'plamida bir nechta turli xil o'zgarishlarni ishlatganingizga ishonch hosil qilishni xohlaysiz. Siz burilgan, burilgan va kesilgan rasmlarga o'rgatish orqali yanada mustahkam modelni yaratishingiz mumkin.

Tasvir qiymatlarini bizning tarmog'imizga o'tkazmasdan oldin ularni normalizatsiya qilish uchun standart sapmalar ta'minlanganligini anglatadi, ammo ularni tasvir tsenzuralarining turli o'lchamlari o'rtacha va standart og'ish qiymatlarini ko'rib chiqish orqali ham topish mumkin. Rasmiy hujjatlar bu erda juda foydali!

Tasvirlar tasniflagichi uchun men buni oddiy holda saqladim:

data_transforms = {
    "poezd": o'zgartiradi. Yozing ([
        o'zgartiradi. RandomRotation (30),
        transforms.RandomResizedCrop (224),
        transforms.RandomHorizontalFlip (),
        transforms.ToTensor (),
        o'zgartiring.Normalize ([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'valid': transforms.Compose (([
        transformatsiyaResize (256),
        o'zgartiradi.CenterCrop (224),
        transforms.ToTensor (),
        o'zgartiring.Normalize ([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ])
}
# Ma'lumotlar to'plamini ImageFolder-ga yuklang
image_datasets = {x: ma'lumotlar to'plamlari.ImageFolder (os.path.join (data_dir, x),
                                          data_transforms [x])
                  x uchun ['train', 'valid']}
# Tasvir ma'lumotlari to'plamlari va poezd shakllaridan foydalanib, dataloaderlarni aniqlang
batch_size = 64
dataloaders = {x: torch.utils.data.DataLoader (rasm_datasets [x], batch_size = batch_size,
                                             aralashtirish = To'g'ri, num_workers = 4)
              x uchun ['train', 'valid']}
class_names = image_datasets ['train']. darslari
['train', 'valid']} dagi x uchun ma'lumotlar_sizes = {x: len (image_datasets [x])
class_names = image_datasets ['train']. darslari

Yuqorida ko'rib turganingizdek, men yuqoridagi kodda to'plam hajmini, ma'lumotlarni yuklovchilarni va sinf nomlarini ham aniqladim.

Ma'lumotlarga juda tez qarash va qurilmani tekshirish uchun men yugurdim:

bosib chiqarish (database_sizes)
chop etish (qurilma)
{'train': 6552, 'valid': 818}
cuda: 0

Keyinchalik, yorliq raqami va haqiqiy gul nomidan xaritani bajarishimiz kerak. Udacity ushbu xaritani tuzish uchun JSON faylini taqdim etdi.

ochiq ('cat_to_name.json', 'r') kabi f:
    cat_to_name = json.load (f)

Ma'lumot yuklovchini sinab ko'rish uchun:

rasmlar, teglar = keyingi (iter (dataloaders ['train'])))
rand_idx = np.random.randint (len (rasmlar))
# Chop etish (rand_idx)
chop etish ("yorliq: {}, sinf: {}, nomi: {}". format (yorliqlar [rand_idx] .item (),
                                               class_names [yorliqlar [rand_idx] .item ()],
                                               cat_to_name [class_names [yorliqlar [rand_idx] .item ()]]))

Endi u yanada qiziqarli bo'lishni boshlaydi! So'nggi bir necha yil ichida bir qator modellar kompyuter ko'rish muammolarida qayta foydalanish uchun ko'pchiligimizga qaraganda ancha malakali odamlar tomonidan yaratilgan. PyTorch oldindan tayyorlangan modellarni yuklashni va ularga qurishni osonlashtiradi, aynan biz ushbu loyiha uchun qiladigan ishimiz. Modelni tanlash butunlay sizga bog'liq!

ResNet, AlexNet va VGG kabi eng mashhur oldindan tayyorlangan ba'zi modellar ImageNet Challenge-dan kelib chiqadi. Ushbu oldindan tayyorlangan modellar boshqalarga bunday katta hajmdagi kompyuter quvvatiga, sabr-toqat va vaqtga ehtiyoj sezmasdan kompyuterni ko'rishda zamonaviy natijalarni tezda olishga imkon beradi. Men aslida DenseNet bilan juda yaxshi natijalarga erishdim va DenseNet161-dan foydalanishga qaror qildim, bu menga nisbatan juda tez natijalar berdi.

Buni tezda ishga tushirish orqali o'rnatishingiz mumkin

model = Model.densenet161 (oldindan = To'g'ri)

lekin o'zingizga model, optimizator va rejalashtiruvchini tanlash qiziqarli bo'lishi mumkin. Arxitekturada tanlovni o'rnatish uchun yugurib chiqing

model_name = 'densenet' #vgg
agar model_name == 'densenet':
    model = Model.densenet161 (oldindan = To'g'ri)
    num_in_feature = 2208
    bosib chiqarish (model)
elif model_name == 'vgg':
    model = Model.vgg19 (oldindan = To'g'ri)
    num_in_feature = 25088
    bosib chiqarish (model.classifier)
yana:
    bosib chiqarish ("Noma'lum model, iltimos 'densenet' yoki 'vgg'" ni tanlang)

bu sizga alternativ modelni tezda o'rnatishga imkon beradi.

Shundan so'ng, siz uchun mos keladigan parametrlardan foydalanib, tasniflagichni qurishni boshlashingiz mumkin. Men oldinga borib, qurdim

model.parametrlari () uchun parametr uchun:
    param.requires_grad = Noto'g'ri
def build_classifier (num_in_feature, hidden_layers, num_out_feature):
   
    tasniflagich = nn.Sequential ()
    agar hidden_layers == Yo'q:
        klassifikator.add_module ('fc0', nn.Learear (num_in_feature, 102))
    yana:
        layer_sizes = zip (yashirin_ o'yinchilar [: - 1], yashirin_ o'yinchilar [1:])
        klassifikator.add_module ('fc0', nn.Learear (num_in_feature, hidden_layers [0]))
        tasniflagich.add_module ('relu0', nn.ReLU ())
        klassifikator.add_module ('drop0', nn.Dropout (.6))
        tasniflagich.add_module ('relu1', nn.ReLU ())
        klassifikator.add_module ('drop1', nn.Dropout (.5))
        uchun, (h1, h2) sonlar ichida (layer_sizes):
            tasniflagich.add_modul ('fc' + str (i + 1), nn.Learear (h1, h2))
            klassifikator.add_module ('relu' + str (i + 1), nn.ReLU ())
            klassifikator.add_module ('tomchi' + str (i + 1), nn.Dropout (.5))
        klassifikator.add_module ('chiqish', nn.Linear (hidden_layers [-1], num_out_feature))
        
    qaytish klassifikatori

bu men foydalanadigan yashirin qatlamlar sonini o'zgartirishning oson yo'li va shuningdek, o'qish tezligini sozlash imkonini beradi. O'zingizning modelingizni yaxshiroq aniqlash uchun qo'shimcha ReLU va ochiladigan qatlamlarni qo'shishga qaror qilishingiz mumkin.

Keyinchalik, tasniflagichingiz parametrlarini o'qitishga harakat qiling. Men bu erda faqat tasniflovchi parametrlarini o'qitganimga ishonch hosil qilishga qaror qildim, bu erda parametr parametrlari muzlatilgan. Siz o'zingizning optimizatoringiz, mezoningiz va rejalashtiruvchingiz bilan xohlaganingizcha ijodiy narsalarni olishingiz mumkin. Mezon - bu modeldagi moslikni baholash uchun ishlatiladigan usul, optimizator - vaznlarni yangilash uchun ishlatiladigan optimallashtirish usuli va rejalashtiruvchi optimallashtirish jarayonida ishlatiladigan o'rganish tezligi va qadam hajmini sozlash uchun turli xil usullarni taqdim etadi.

Sizga eng yaxshi natija beradigan narsani ko'rish uchun iloji boricha ko'proq variant va birikmalardan foydalaning. Barcha rasmiy hujjatlarni bu erda ko'rishingiz mumkin. Men buni ko'rib chiqishni va foydalanmoqchi bo'lgan narsalar to'g'risida o'zingizning qaroringizni qabul qilishni maslahat beraman. Siz bu erda cheksiz ko'p imkoniyatlarga ega emassiz, lekin siz o'ynashni boshlaganingizda, xuddi shunday his etasiz!

hidden_layers = Yo'q
tasniflagich = tuzish_klassifikator (raqamlar_infeatrlari, yashirin_ o'yinchi, 102)
bosib chiqarish (klassifikator)
# Faqat tasniflagich parametrlarini o'rgating, xususiyat parametrlari muzlatilgan
agar model_name == 'densenet':
    model.classifier = klassifikator
    mezon = nn.CrossEntropyLoss ()
    optimizer = optim.Adadelta (model.parameter ())
    sched = optim.lr_scheduler.StepLR (optimizator, step_size = 4)
elif model_name == 'vgg':
    model.classifier = klassifikator
    mezon = nn.NLLLoss ()
    optimizator = optim.Adam (model.classifier.parameter (), lr = 0.0001)
    sched = lr_scheduler.StepLR (optimizator, step_size = 4, gamma = 0.1)
yana:
    o'tish

Endi sizning modelingizni mashq qilish vaqti keldi.

# Https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html dan moslashtirildi
def train_model (model, mezon, optimizator, jadval, raqam_epochs = 5):
    beri = vaqt.time ()
best_model_wts = copy.deepcopy (model.state_dict ())
    best_acc = 0.0
davrlar davri uchun (num_epochs):
        bosib chiqarish ('Davr {} / {}'. format (davr + 1, raqamlar ro'yxati))
        bosib chiqarish ('-' * 10)
# Har bir davr o'quv va tekshirish bosqichiga ega
        ['poezd', 'valid'] bosqichi uchun:
            agar faza == 'poezd':
                model.train () # Modelni o'qitish rejimiga qo'ying
            yana:
                model.eval () # rejimni baholash uchun modelni o'rnating
yugurish_loss = 0.0
            yugurish_corrects = 0
# Ma'lumotni takrorlash.
            ma'lumotlar, dataloaderlarda yorliqlar uchun [faza]:
                kirish = kirish.to (qurilma)
                teglar = labels.to (qurilma)
Nol parametr parametrlari
                optimizer.zero_grad ()
# Oldinga
                # iz tarixi faqat poezdda bo'lsa
                torch.set_grad_enabled bilan (faza == 'poezd'):
                    natijalar = model (kirishlar)
                    _, prededs = mash'al.max (chiqishlar, 1)
                    yo'qotish = mezon (natijalar, yorliqlar)
# Orqaga + optimallashtirish faqat o'quv bosqichida bo'lsa
                    agar faza == 'poezd':
                        # jadval.step ()
                        loss.backward ()
                        
                        optimizer.step ()
# Statistika
                run_loss + = loss.item () * kirish.size (0)
                run_corrects + = mash'al.sum (preds == labels.data)
epoch_loss = ishlayotgan_loss / ma'lumotlar_sizes [faza]
            epoch_acc = yugurish_corrects.double () / database_sizes [bosqich]
chop etish ('{} Yo'qotishlar: {: .4f} Acc: {: .4f}'. formati (
                faza, epox_loss, epoch_acc))
# Modelni chuqur nusxalash
            agar faza == 'to'g'ri' va epoch_acc> best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy (model.state_dict ())
bosib chiqarish ()
time_elapsed = time.time () - beri
    chop etish ('{: .0f} m {: .0f} s'.format-da o'qitish tugallandi (
        vaqtning vaqti // 60, vaqtning vaqti% 60))
    chop etish ('Best val Acc: {: 4f}'. format (best_acc))
# Eng yaxshi model og'irliklarini yuklang
    model.load_state_dict (eng yaxshi_model_wts)
    
    qaytish modeli
davrlar = 30
model.to (qurilma)
model = train_model (model, mezon, optimizator, jadval, davrlar)

Men o'z davrlarimni osongina kuzatib borishni va shuningdek, mening modelim ishlayotgan vaqtni kuzatishni istadim. Yuqoridagi kod ikkalasini ham o'z ichiga oladi va natijalar juda yaxshi! Siz ko'rishingiz mumkinki, model tez o'rganmoqda va 7-davr tomonidan tekshiruv to'plamidagi aniqlik 95% dan oshdi!

Davr 1/30
----------
poezd yo'qotish: 2.4793 Acc: 0.4791
yaroqsiz yo'qotish: 0.9688 Acc: 0.8191

Davr 2/30
----------
poezd halokati: 0.8288 Acc: 0.8378
yaroqsiz yo'qotish: 0.4714 Acc: 0.9010

3/30 asr
----------
poezd halokati: 0.5191 Acc: 0.8890
yaroqsiz yo'qotish: 0.3197 Acc: 0.9181

Davr 4/30
----------
poezd halokati: 0.4064 Acc: 0.9095
yaroqsiz yo'qotish: 0.2975 Acc: 0.9169

5/30 davr
----------
poezd yo'qotish: 0.3401 Acc: 0.9214
yaroqsiz yo'qotish: 0.2486 Acc: 0.9401

6/30-asr
----------
poezd halokati: 0.3111 Acc: 0.9303
haqiqiy yo'qotish: 0.2153 Acc: 0.9487

Davr 7/30
----------
poezd halokati: 0.2987 Acc: 0.9298
yaroqli yo'qotish: 0.1969 Acc: 0.9584
...
67 m 43 soniyada mashg'ulot tugadi
Eng yaxshi val Acc: 0.973105

Ushbu kodni Google Colab-da GPU bilan ishlash bir soatcha vaqtni olganligini ko'rishingiz mumkin.

Endi baholash vaqti keldi

model.eval ()
aniqlik = 0
ma'lumotlar, dataloaderlar uchun yorliqlar uchun ['valid']:
    kirishlar, teglar = kirishlar.to (qurilma), teglar.to (qurilma)
    natijalar = model (kirishlar)
    
    # Ehtimol eng yuqori sinf bizning taxmin qilingan sinfimizdir
    tenglik = (labels.data == outputs.max (1) [1])
# Aniqlik = barcha taxminlarga bo'lingan to'g'ri prognozlar soni
    aniqlik + = tenglik.type_as (mash'al.FloatTensor ()). o'rtacha ()
    
chop etish ("Sinov aniqligi: {: .3f}". format (aniqlik / len (dataloaders ['valid'])))
Sinov aniqligi: 0.973

Nazorat punktini saqlash juda muhimdir

model.class_to_idx = image_datasets ['train']. class_to_idx
nazorat nuqtasi = {'input_size': 2208,
              'output_size': 102,
              "davrlar": davrlar,
              'batch_size': 64,
              'model': modellar.densenet161 (oldindan = To'g'ri),
              'tasniflovchi': klassifikator,
              'rejalashtiruvchi': jadval,
              'optimizer': optimizer.state_dict (),
              'state_dict': model.state_dict (),
              'class_to_idx': model.class_to_idx
             }
   
mash'al.save (nazorat nuqtasi, 'nazorat nuqtasi.pth')

Siz barcha parametrlarni saqlashingiz shart emas, lekin men ularni shu erda misol qilib keltiraman. Ushbu nazorat punkti oldindan tayyorlangan densenet161 arxitekturasi bilan modelni saqlab qoladi, ammo agar siz o'zingizning nazorat nuqtangizni ikkita tanlovli variant bilan saqlamoqchi bo'lsangiz, siz albatta buni amalga oshirishingiz mumkin. Kirish hajmi va modelini oddiygina sozlang.

Endi siz nazorat punktingizni yuklay olasiz. Agar siz loyihangizni Udacity ish joyiga yuborsangiz, narsalar biroz qiyinlashishi mumkin. Nazorat punktingizdagi yukni bartaraf etishda ba'zi yordamlar.

Siz tugmachalarni tekshirish orqali tekshirishingiz mumkin

ckpt = torch.load ('nazorat nuqtasi.pth')
ckpt.keys ()

Keyin modelingizni yuklang va qayta yarating!

def load_checkpoint (filepath):
    nazorat nuqtasi = mash'al.load (filepath)
    model = nazorat nuqtasi ['model']
    model.classifier = nazorat nuqtasi ['klassifikator']
    model.load_state_dict (nazorat nuqtasi ['state_dict'])
    model.class_to_idx = nazorat nuqtasi ['class_to_idx']
    optimizer = nazorat nuqtasi ['optimizer']
    davrlar = nazorat nuqtasi ['davrlar']
    
    model.parametrlari () uchun parametr uchun:
        param.requires_grad = Noto'g'ri
        
    qaytish modeli, nazorat nuqtasi ['class_to_idx']
model, class_to_idx = load_checkpoint ('checkpoint.pth')

Davom etishni xohlaysizmi? Tasvirlarni qayta ishlash va tasniflash uchun inferatsiya qilish yaxshi fikr. Oldinga o'tib, rasm yo'lingizni aniqlang va rasmni oching:

image_path = 'gul_data / valid / 102 / image_08006.jpg'
img = Image.open (image_path)

Tasviringizni qayta ishlang va qayta ishlangan rasmga qarang:

def process_image (rasm):
    '' 'PyTorch modeli uchun PIL tasvirini tarozi, kesish va normalizatsiya qilish,
        Numpy massivini qaytaradi
    '' '
    # PyTorch modelida foydalanish uchun PIL tasvirini qayta ishlang
    # tensor.numpy (). transpozitsiya (1, 2, 0)
    preprocess = transforms.Compose (([
        transformatsiyaResize (256),
        o'zgartiradi.CenterCrop (224),
        transforms.ToTensor (),
        o'zgartiring.Normalize (o'rtacha = [0.485, 0.456, 0.406],
                             std = [0.229, 0.224, 0.225])
    ])
    rasm = oldindan ishlov berish (rasm)
    rasmni qaytarish
def imshow (rasm, ax = yo'q, sarlavha = yo'q):
    "" "Tensor uchun namoyish." ""
    agar bolta yo'q bo'lsa:
        fig, ax = plt.subplots ()
    
    # PyTorch tensorlari rang kanali birinchi o'lchov deb taxmin qiladi
    # lekin matplotlib uchinchi o'lchovni qabul qiladi
    image = image.numpy (). transpozitsiya ((1, 2, 0))
    
    # Qayta ishlashni bekor qiling
    o'rtacha = np.array ([0.485, 0.456, 0.406])
    std = np.array ([0.229, 0.224, 0.225])
    image = std * rasm + o'rtacha
    
    # Tasvirni 0 dan 1 gacha kesish kerak yoki aks etganda shovqin paydo bo'ladi
    rasm = np.clip (rasm, 0, 1)
    
    ax.imshow (rasm)
    
    qaytish boltasi
Image.open ('gul_data / valid / 102 / image_08006.jpg') tasvir sifatida:
    plt.imshow (rasm)
model.class_to_idx = image_datasets ['train']. class_to_idx

Bashorat qilish uchun funktsiyani yarating:

def predict2 (image_ath, model, topk = 5):
    '' 'Ta'lim chuqur chuqurlashtirilgan modelidan foydalangan holda rasm sinfini (yoki sinflarini) oldindan aytib bering.
    '' '
    
    # Tasvir faylidan sinfni bashorat qilish uchun kodni kiriting
    img = Image.open (image_path)
    img = process_image (img)
    
    # 2D tasvirni 1D vektorga aylantirish
    img = np.expand_dims (img, 0)
    
    
    img = mash'al.from_numpy (img)
    
    model.eval ()
    kirishlar = O'zgaruvchan (img) .to (qurilma)
    logits = model.forward (kirishlar)
    
    ps = F.softmax (jurnallar, dim = 1)
    topk = ps.cpu (). topk (topk)
    
    qaytish (e.data.numpy (). siqish (). tolist () top uchun e uchun)

Rasmlar to'g'ri formatda bo'lgandan so'ng, siz o'zingizning modelingiz bilan bashorat qilish uchun funktsiyani yozishingiz mumkin. Umumiy amaliyotlardan biri bu eng yuqori 5 sinfni (odatda top-KK deb nomlanadi) bashorat qilishdir. Sinf ehtimolini hisoblashni xohlaysiz, keyin KK ning eng katta qiymatlarini topasiz.

Tensorning eng katta KK qiymatlarini olish uchun k.topk () dan foydalaning. Ushbu usul eng yuqori k ehtimolliklarni ham, sinflarga mos keladigan ehtimollik ko'rsatkichlarini ham qaytaradi. Ushbu indekslardan siz sinfga qo'shgan klass_to_idx-dan foydalanib haqiqiy ma'lumot yorliqlariga yoki ma'lumotlarni yuklashda foydalangan rasm papkasidan o'zgartirishingiz kerak. Lug'atni o'zgartirganingizga ishonch hosil qiling, shunda siz indeksdan sinfga xaritani olasiz.

Ushbu usul rasmga va modelning tekshiruv punktiga borishi kerak, keyin ehtimolliklar va sinflarni qaytarishi kerak.

img_path = 'gul_data / valid / 18 / image_04252.jpg'
probellar, sinflar = bashorat2 (img_path, model.to (qurilma))
bosib chiqarish
chop etish (sinflar)
gullar_nameslari = [mushuk_tosh nomlari [sinfdagi ismlar [e]] sinflar uchun e
chop etish (gul_ nomlari)

Mening modelim qanday ishlashidan mamnunman!

[0.9999195337295532, 1.4087702766119037e-05, 1.3897360986447893e-05, 1.1400215043977369e-05, 6.098791800468462e-06]
[12, 86, 7, 88, 40]
['peruvian nilufar', 'cho'l atirguli', 'qirol proteya', 'magnoliya', 'qilich nilufari']

Asosan, men ko'rsatgan rasm Peru zambilidir, deyarli 100%. Ko'rishni xohlaysizmi? Grafikadagi grafikadagi eng yaxshi beshta sinf uchun ehtimolliklarni kiritish uchun matplotlib-dan foydalanib ko'ring:

def view_classify (img_path, prob, sinflar, xaritalash):
    '' 'Tasvirni ko'rish funktsiyasi va oldindan taxmin qilingan sinflar.
    '' '
    image = Image.open (img_path)
anjir, (ax1, ax2) = plt.subplots (figsize = (6,10), ncols = 1, uyalar = 2)
    gul_nomasi = xaritalash [img_path.split ('/') [- 2]]
    ax1.set_title (gul_ nomi)
    ax1.imshow (rasm)
    ax1.axis ("o'chirilgan")
    
    y_pos = np.arange (len (prob))
    ax2.barh (y_pos, prob, align = 'center')
    ax2.set_yticks (y_pos)
    ax2.set_yticklabels (gul_ nomlari)
    ax2.invert_yaxis () # teglar yuqoridan pastgacha o'qiladi
    ax2.set_title ('Sinfning ehtimolligi')
view_classify (img_path, zondlar, sinflar, cat_to_name)

Siz shunga o'xshash narsani ko'rishingiz kerak:

Aytishim kerak, men bundan juda mamnunman! Sizning taxminlaringiz turli xil rasmlarga qanchalik yaqin ekanligini ko'rish uchun boshqa bir nechta rasmlarni sinab ko'rishni tavsiya etaman.

Endi o'zingizning modelingizni yaratish vaqti keldi va quyida qanday javob berilganligini menga ayting!

Pez Gonzalez surati Unsplash-da

Siz chuqur o'rganish yoki mashinani o'rganish modelini tugatdingizmi, lekin bundan keyin nima qilish kerakligini bilmayapsizmi? Nega uni internetga joylashtirmaysiz?

O'zingizning modelingizni u erda ko'ring, shunda hamma uni ko'rishi mumkin!

Flask yordamida mashinangizni o'rganish modelini qanday o'rnatishni o'rganish uchun ushbu maqolani ko'rib chiqing!