Jak používat přenosové učení a jemné doladění v Kerasu a Tensorflowu k vybudování systému rozpoznávání obrázků a klasifikaci (téměř) jakéhokoli objektu

Příklad obrázků z datového souboru CompCars (163 značek automobilů, 1713 modelů automobilů)
Jděte přímo do kódu na GitHubu zde!

V posledním příspěvku jsem se zabýval tím, jak používat Keras k rozpoznání kterékoli z 1000 kategorií objektů ve výzvě vizuální rozpoznávání ImageNet. Kategorie, které máme v úmyslu předpovídat, však v tomto seznamu nejsou častěji.

Co tedy dělat, když chceme klasifikovat mezi různými modely slunečních brýlí? nebo boty? nebo výrazy obličeje? nebo různé modely aut? nebo různé typy plicních chorob v rentgenových snímcích?

V tomto příspěvku vám ukážu, jak pomocí přenosu učení a jemného doladění identifikovat jakékoli přizpůsobitelné kategorie objektů! Pro shrnutí uvádíme následující řady příspěvků na blogu:

  1. Vytvořte systém rozpoznávání obrázků pro 1000 každodenních kategorií objektů (ImageNet ILSVRC) pomocí Keras a TensorFlow
  2. Vytvořte systém rozpoznávání obrázků pro všechny přizpůsobitelné kategorie objektů pomocí učení přenosu a doladění v Keras a TensorFlow (tento příspěvek)
  3. Sestavte systém detekce objektů v reálném čase pro stovky kategorií každodenních objektů (PASCAL VOC, COCO)
  4. Vytvořte webovou službu pro jakýkoli systém rozpoznávání obrázků nebo detekce objektů

Proč používat přenosné učení / jemné ladění?

Je dobře známo, že konvoluční sítě vyžadují na trénink značné množství dat a zdrojů. Například model ImageNet ILSVRC byl trénován na 1,2 milionu obrázků v průběhu 2–3 týdnů na více GPU.

Stalo se normou, nikoliv výjimkou, pro vědce i odborníky, kteří používají přenosové učení a jemné doladění, to znamená, že přenáší síťová závaží vyškolená na předchozí úkol, jako je ImageNet, na nový úkol.

A dělá to úžasně dobře! Razavian et al (2014) ukázal, že pouhým využitím funkcí extrahovaných pomocí hmotností z modelu vyškoleného na ImageNet ILSVRC dosáhli nejmodernějšího výkonu nebo téměř nejmodernějšího výkonu na velké škále počítačového vidění úkoly.

Můžeme použít dva přístupy:

  1. Přenosové učení: vezměte ConvNet, který byl předběžně vyškolen na ImageNet, odstraňte poslední plně připojenou vrstvu, pak zbytek zbytku ConvNet považujte za extraktor funkcí nového datového souboru. Jakmile rozbalíte funkce pro všechny obrázky, vyškolte klasifikátor pro nový datový soubor.
  2. Jemné doladění: vyměňte a přeškolte klasifikátor v horní části sítě ConvNet a také vylaďte závaží předem vyškolené sítě pomocí zpětné propagace.

Které použít?

Váš výběr přístupu ovlivní dva hlavní faktory:

  1. Velikost vaší sady dat
  2. Podobnost vašeho datového souboru s předem vyškoleným datovým souborem (obvykle ImageNet)
Převzato z http://cs231n.github.io/

* měli byste také experimentovat s tréninkem od nuly.

Obrázek nahoře a odrážky níže popisují některé obecné rady, kdy zvolit, který přístup.

  • Podobný a malý datový soubor: vyhněte se přeplnění tím, že nedokonale vyladíte váhy na malém datovém souboru, a pomocí extrahovaných funkcí z nejvyšších úrovní ConvNet využijte podobnosti datového souboru.
  • Jiný a malý datový soubor: vyhněte se přeplňování tím, že nedokonale vyladíte váhy na malém datovém souboru, a využívejte extrahované funkce z nižších úrovní ConvNet, které jsou zobecnitelnější.
  • Podobné a velké datové soubory: s velkým datovým souborem můžeme váhy doladit s menší šancí na přeplnění tréninkových dat.
  • Jiný a velký datový soubor: s velkým datovým souborem můžeme znovu vyladit váhy s menší šancí na přeplnění.

Zvětšení dat

Výkonným a běžným nástrojem pro zvýšení velikosti datové sady a zobecnění modelu je rozšíření dat. Ve skutečnosti každá soutěž vyhrávající ConvNet využívá rozšíření dat. Zvětšení dat je v podstatě proces umělého zvětšení velikosti vašeho souboru dat pomocí transformací.

Většina knihoven s hlubokým učením má připravené funkce pro typické transformace. Úkolem našeho systému rozpoznávání obrázků je rozhodnout, které transformace mají smysl pro vaše data (například rentgenové snímky by se pravděpodobně neměly otáčet o více než 45 stupňů, protože by to znamenalo chybu v získávání obrázků krok).

Zvětšení dat pomocí horizontálního převrácení a náhodného oříznutí

Příklad transformací: Jitter pixelů, rotace, střih, náhodné oříznutí, horizontální převrácení, protažení, korekce čočky.

Přeneste učení a dolaďte implementaci

Jděte přímo do kódu na GitHubu zde!

Příprava dat

Ukázkové obrázky z datového souboru Kaggle's Cat vs Dog

Jako náš příklad použijeme datový soubor Kaggle's Dogs vs Cats a takto nastavíme svá data pomocí adresáře školení a adresáře validace:

train_dir /
  Pes/
  kočka/
val_dir /
  Pes/
  kočka/

Implementace

Začněme přípravou našich generátorů dat:

train_datagen = ImageDataGenerator (
    preprocessing_function = preprocess_input,
    rotace = 30,
    width_shift_range = 0,2,
    height_shift_range = 0,2,
    shear_range = 0,2,
    zoom_range = 0,2,
    horizontal_flip = True
)
test_datagen = ImageDataGenerator (
    preprocessing_function = preprocess_input,
    rotace = 30,
    width_shift_range = 0,2,
    height_shift_range = 0,2,
    shear_range = 0,2,
    zoom_range = 0,2,
    horizontal_flip = True
)
train_generator = train_datagen.flow_from_directory (
  args.train_dir,
  target_size = (IM_WIDTH, IM_HEIGHT),
  batch_size = batch_size,
)
validation_generator = test_datagen.flow_from_directory (
  args.val_dir,
  target_size = (IM_WIDTH, IM_HEIGHT),
  batch_size = batch_size,
)

Připomeňme z předchozího blogového příspěvku na rozpoznávání obrázků důležitost kroku předzpracování. Toto je nastaveno preprocessing_function = preprocess_input, kde preprocess_input je z modulu keras.applications.inception_v3.

Rozsahy signálů pro rotaci, řazení, stříhání, přiblížení a překlopení pro jejich příslušné transformace zvětšení dat.

Dále vytvoříme instanci sítě InceptionV3 z modulu keras.applications.

base_model = InceptionV3 (weights = 'imagenet', include_top = False)

Použijeme flag include_top = False, abychom vynechali hmotnosti poslední plně připojené vrstvy, protože to je specifické pro soutěž ImageNet, ze které byly váhy dříve trénovány. Přidáme a inicializujeme novou poslední vrstvu:

def add_new_last_layer (base_model, nb_classes):
  "" "Přidejte do vrstvy poslední vrstvu
  Args:
    base_model: model keras s výjimkou top
    nb_classes: # tříd
  Návraty:
    nový model keras s poslední vrstvou
  "" "
  x = base_model.output
  x = GlobalAveragePooling2D () (x)
  x = hustá (FC_SIZE, aktivace = 'relu') (x)
  předpovědi = hustá (nb_classes, Activation = 'softmax') (x)
  model = model (vstup = základní_model.vstup, výstup = předpovědi)
  návratový model

GlobalA BeverPooling2D převádí txorový výstup MxNxC na tenzor 1xC, kde C je # kanálů.

Poté přidáme plně připojenou hustou vrstvu o velikosti 1024 a funkci softmax na výstupu, abychom stlačili hodnoty mezi [0,1].

V tomto programu ukážu přenosové učení i jemné doladění. Můžete použít jeden nebo oba, pokud chcete.

  1. Přenosové učení: Zmrazte vše kromě předposlední vrstvy a přecvičte poslední vrstvu Hustá
  2. Doladění: zmrazte spodní konvoluční vrstvy a přeškolte více vrstev

Obě tyto činnosti zajistí v tomto pořadí stabilnější a důslednější školení. Je tomu tak proto, že velké aktualizace gradientu spouštěné náhodně inicializovanými váhami by mohly zničit naučené hmotnosti v konvoluční základně, pokud nejsou zmrazené. Jakmile se poslední vrstva stabilizuje (přenosové učení), pak přejdeme na přeškolení více vrstev (jemné doladění).

Přenos učení

def setup_to_transfer_learn (model, základní_model):
  Zmrazit všechny vrstvy a zkompilovat model „“ “
  pro vrstvu v base_model.layers:
    layer.trainable = False
  model.compile (optimizer = 'rmsprop',
                loss = 'categoryorical_crossentropy',
                metrics = ['správnost'])

Doladit

def setup_to_finetune (model):
   „“ „Zmrazte dolní část NB_IV3_LAYERS a přeškolte zbývající vrchol
      vrstvy.
   poznámka: NB_IV3_LAYERS odpovídá prvním 2 počátečním blokům v
         inceptionv3 architecture
   Args:
     model: keras model
   "" "
   pro vrstvu v model.layers [: NB_IV3_LAYERS_TO_FREEZE]:
      layer.trainable = False
   pro vrstvu v model.layers [NB_IV3_LAYERS_TO_FREEZE:]:
      layer.trainable = True
   model.compile (optimalizátor = SGD (lr = 0,0001, hybnost = 0,9),
                 loss ='ategorical_crossentropy ')

Při jemném doladění je důležité snížit rychlost učení ve srovnání s mírou, která byla použita při tréninku od nuly (lr = 0,0001), jinak by optimalizace mohla destabilizovat a ztráty se odklonit.

Výcvik

Nyní jsme všichni připraveni na trénink. Použijte fit_generator jak pro učení přenosu, tak pro jemné doladění.

history = model.fit_generator (
  train_generator,
  samples_per_epoch = nb_train_samples,
  nb_epoch = nb_epoch,
  validation_data = validation_generator,
  nb_val_samples = nb_val_samples,
  class_weight = 'auto'
)
model.save (args.output_model_file)

K tréninku použijeme instanci Amazon EC2 g2.2xlarge. Pokud nejste obeznámeni s AWS, podívejte se na tento tutoriál (namísto použití předepsaného AMI vyhledejte v AMI komunity „hluboké učení“ - pro tento příspěvek jsem použil ami-638c1eo3in v USA-West-Oregon).

Pomocí objektu historie můžeme vykreslit přesnost a ztrátu školení

def plot_training (historie):
  acc = history.history ['acc']
  val_acc = history.history ['val_acc']
  loss = history.history ['loss']
  val_loss = history.history ['val_loss']
  epochy = rozsah (len (acc))
  
  plt.plot (epochy, acc, 'r.')
  plt.plot (epochy, val_acc, 'r')
  plt.title („Přesnost školení a validace“)
  
  plt.figure ()
  plt.plot (epochy, ztráta, 'r.')
  plt.plot (epochy, val_loss, 'r-')
  plt.title („Ztráta ze školení a validace“)
  plt.show ()

Předpověď

Nyní, když máme uložený soubor keras.model, můžeme upravit stejnou funkci predikce (), kterou jsme napsali v posledním blogovém příspěvku, a předpovídat třídu místního obrazového souboru nebo libovolného souboru prostřednictvím webové adresy URL. Pokladna github pro celý program.

python Prediction.py - image pes.001.jpg - model dc.model
python předpověď.py --image_url https://goo.gl/Xws7Tp - model dc.model

Jsme hotovi!

Jako příklad jsem trénoval model v datasetu psů proti kočkám pomocí 24 000 obrázků pro výcvik a 1 000 obrázků pro ověření pro 2 epochy. I po pouhých 2 epochách je výkon docela vysoký:

Protokol metriky po 2 epochách
Stáhněte si trénovaný model zde *

* model kompatibilní s kerami == 1.2.2

Příklady

python předpověď.py --image_url https://goo.gl/Xws7Tp - model dc.model

python předpověď.py --image_url https://goo.gl/6TRUol - model dc.model

Zůstaňte naladěni na další příspěvek v řadě:

  1. Vytvořte systém rozpoznávání obrázků pro 1000 každodenních kategorií objektů (ImageNet ILSVRC) pomocí Keras a TensorFlow
  2. Vytvořte systém rozpoznávání obrázků pro všechny přizpůsobitelné kategorie objektů pomocí učení přenosu a doladění v Keras a TensorFlow (tento příspěvek)
  3. Sestavte systém detekce objektů v reálném čase pro stovky kategorií každodenních objektů (PASCAL VOC, COCO)
  4. Vytvořte webovou službu pro jakýkoli systém rozpoznávání obrázků nebo detekce objektů

Pokud máte nějaké dotazy, kontaktujte mě na adrese greg.ht.chu@gmail.com nebo mi napište na LinkedIn!

Pokud se vám to líbilo, klikněte na ikonu ❤