Beeldgegevensvergroting voor diepgaand leren

Begrijp wat vergroting van beeldgegevens is en hoe u het kunt gebruiken met Keras voor uw deep learning-projecten

Foto door Chris Lawton on Unsplash

Als je ooit hebt geprobeerd beeldherkenning uit te voeren met behulp van deep learning, weet je hoe belangrijk een goede dataset voor training is. Het vinden van voldoende afbeeldingen voor training is echter niet altijd eenvoudig en de nauwkeurigheid van uw model is direct afhankelijk van de kwaliteit van de trainingsgegevens.

Gelukkig zijn er technieken die je kunt gebruiken om de beelddataset die ze gebruiken voor training aan te vullen. Een van de technieken heet vergroting van afbeeldingsgegevens. In dit artikel zal ik bespreken wat vergroting van beeldgegevens is, hoe het werkt, waarom het nuttig is bij deep learning en tot slot hoe u vergroting van beeldgegevens kunt uitvoeren met behulp van de Keras-bibliotheek.

Vergroting van afbeeldingsgegevens is een techniek die maakt nieuwe afbeeldingen van bestaande. Om dat te doen, brengt u enkele kleine wijzigingen aan, zoals het aanpassen van de helderheid van het beeld, of het draaien van het beeld, of het horizontaal of verticaal verschuiven van het onderwerp in het beeld.

Met beeldvergrotingstechnieken kunt u de omvang van uw trainingsset kunstmatig vergroten, waardoor uw model veel meer gegevens voor training krijgt. Hierdoor kunt u de nauwkeurigheid van uw model verbeteren door het vermogen van uw model om nieuwe varianten van uw trainingsgegevens te herkennen te vergroten.

Soorten beeldgegevensvergroting

Beeldvergroting is er in vele vormen, hier zijn enkele van de meest voorkomende: verticale verschuiving, horizontale verschuiving, verticale spiegeling, horizontale spiegeling, rotatie, helderheidsaanpassing en in- en uitzoomen.

Ik zal eerst de verschillende technieken voor beeldvergroting demonstreren met behulp van Python en Keras. Als je het wilt proberen, zorg er dan voor dat je de volgende software en pakketten hebt geรฏnstalleerd:

Nadat Anaconda en TensorFlow zijn geรฏnstalleerd, maakt u een nieuw Jupyter Notebook.

Verticale verschuiving

De eerste beeldvergrotingstechniek die ik wil laten zien is de verticale verschuiving. De verticale verschuiving verschuift het beeld willekeurig verticaal omhoog of omlaag. Voor dit voorbeeld ga ik een afbeelding gebruiken met de naam 747.jpg, in dezelfde map als mijn Jupyter Notebook.

Beeldbron: https://commons.wikimedia.org/wiki/File:Qantas_Boeing_747-438ER_VH-OEI_at_LAX.jpg. Dit bestand is gelicentieerd onder de Creative Commons Naamsvermelding-Gelijk delen 2.0 Generiek licentie.

Het volgende codefragment gebruikt de ImageDataGenerator class in Keras om de afbeelding verticaal te verschuiven.

De ImageDataGenerator class van Keras genereert batches van afbeeldingsgegevens met realtime gegevensvergroting.

#---importeer de modules---
numpy importeren als np
matplotlib.pyplot importeren als plt
van tensorflow.keras.preprocessing.image import load_img
van tensorflow.keras.preprocessing.image import img_to_array
van tensorflow.keras.preprocessing.image import ImageDataGenerator
#--- laad de afbeelding---
image_filename = '747.jpg'
img = load_img(afbeelding_bestandsnaam)
#---converteer de afbeelding naar 3D-array---
afbeeldingsgegevens = img_to_array(img)
#---converteer in een 4-D-array van 1 element van 3D-array dat vertegenwoordigt:
# De afbeelding---
afbeeldingen_gegevens = np.expand_dims (afbeeldingsgegevens, as = 0)
#---generator voor beeldgegevensvergroting maken---
datagen = ImageDataGenerator(width_shift_range=0.2)
#--- bereid de iterator voor; flow() neemt een 4D-array op en geeft terug
# een iterator die een batch afbeeldingen bevat ---
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 5
kolommen = 4
#---plot 5 rijen en 4 kolommen---
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
#---haal de volgende afbeelding in de batch (รฉรฉn afbeelding sinds batch)
# maat is 1) ---
image_batch = treingenerator.next()

#---converteer naar niet-ondertekende gehele getallen om te bekijken---
afbeelding = afbeelding_batch[0].astype('uint8')

#---toon de afbeelding---
assen[r,c].imshow(afbeelding)
#---stel de grootte van de figuur in---
fig.set_size_inches (15,10)

Het bovenstaande codefragment produceert de volgende uitvoer:

Zoals je kunt zien aan de bovenstaande uitvoer, elke keer dat je de . aanroept next() methode uit de train_generator object, krijg je een afbeelding die enigszins is gewijzigd. In het bovenstaande codefragment wordt een nieuwe afbeelding geretourneerd die met 20% is verschoven op basis van de oorspronkelijke afbeeldingshoogte telkens wanneer u de next() methode:

datagen = ImageDataGenerator(width_shift_range=0.2)

Interessant is dat voor deze versie van de ImageDataGenerator (tensorflow.keras.preprocessing.image) klasse, met vermelding van de width_shift_range parameter verschuift de afbeelding verticaal in plaats van horizontaal (wat het gedrag is van de oudereImageDataGeneratorvan het keras.preprocessing.image module). Evenzo, als u wilt dat de afbeelding horizontaal wordt verschoven, moet u de gebruiken height_shift_range parameter (zie volgende paragraaf).

Merk op dat de next() methode zal zo vaak als u wilt een vergrote afbeelding retourneren. In het bovenstaande codefragment hebben we het 20 keer (5 rijen keer 4 kolommen) genoemd.

Horizontale verschuiving

U kunt nu proberen de afbeelding horizontaal te verschuiven met de height_shift_range parameter:

datagen = ImageDataGenerator(height_shift_range=0.2)
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 5
kolommen = 4
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

Het bovenstaande codefragment produceert de volgende uitvoer:

Horizontaal spiegelen

Soms is het zinvol om de afbeelding horizontaal te spiegelen. In het geval van een vliegtuig kan de voorkant van het vliegtuig naar links of naar rechts wijzen:

datagen = ImageDataGenerator(horizontal_flip=Waar)
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 2
kolommen = 2
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

Voor het bovenstaande codefragment is het genereren van vier afbeeldingen goed genoeg, aangezien de voorkant van het vliegtuig naar links of naar rechts kan wijzen:

Onthoud dat het omdraaien willekeurig is (soms krijg je alle vier de originele afbeeldingen en soms krijg je afbeeldingen die horizontaal zijn omgedraaid). Het is waarschijnlijk dat vier bovenstaande afbeeldingen allemaal hetzelfde kunnen zijn. Als dat gebeurt, voert u dat codeblok gewoon opnieuw uit.

Verticaal spiegelen

Net als bij horizontaal spiegelen, kun je ook verticaal spiegelen:

datagen = ImageDataGenerator(vertical_flip=Waar)
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 2
kolommen = 2
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

In het geval van vliegtuigen is het misschien niet zo logisch om ons vliegtuig ondersteboven te draaien! Als u beeldherkenning probeert uit te voeren, is de kans groot dat uw afbeeldingen van vliegtuigen rechtop staan, en dus is het niet zo gebruikelijk om uw model te trainen om omgekeerde vliegtuigen te herkennen. In andere gevallen is verticaal spiegelen heel logisch.

Rotatie

Rotatie, zoals de naam al aangeeft, roteert uw afbeelding. Dit zou erg handig zijn voor ons vliegtuigbeeld. De volgende codefragmenten roteren de afbeelding willekeurig tot 50 graden:

datagen = ImageDataGenerator(rotatiebereik = 50)
train_generator = datagen.flow(images_data)
rijen = 5
kolommen = 4
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

Met rotatie toont de uitvoer de vliegtuigen in de verschillende posities - waarbij de start- en landingsposities worden gesimuleerd:

Helderheid

Een andere augmentatietechniek is het aanpassen van de helderheid van het beeld. Het volgende codefragment stelt een reeks waarden voor helderheidsverschuiving in:

datagen = ImageDataGenerator(helderheid_bereik=[0.15,2.0])
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 5
kolommen = 4
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

De uitvoer bevat een reeks afbeeldingen met verschillende helderheid:

inzoomen

U kunt de afbeeldingen ook in- of uitzoomen:

datagen = ImageDataGenerator(zoom_bereik=[5,0.5])
train_generator = datagen.flow(images_data, batch_size=1)
rijen = 5
kolommen = 4
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

De output toont het beeld in de verschillende zoomverhoudingen:

Merk op dat het zoomen van de afbeeldingen de beeldverhoudingen van de afbeeldingen zal veranderen.

Alle augmentaties combineren

Natuurlijk kunnen alle verschillende augmentatietechnieken die ik tot nu toe heb besproken, worden gecombineerd:

datagen = ImageDataGenerator(width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=Waar,
rotatiebereik = 50,
helderheid_bereik=[0.15,2.0],
zoom_bereik=[5,0.5]
)
train_generator = datagen.flow(images_data, batch_size=1)rijen = 8
kolommen = 8
fig, assen = plt.subplots(rijen,kolommen)
voor r in bereik (rijen):
voor c in bereik (kolommen):
image_batch = treingenerator.next()
afbeelding = afbeelding_batch[0].astype('uint8')
assen[r,c].imshow(afbeelding)
fig.set_size_inches (15,10)

Merk op dat ik verticale flip heb weggelaten omdat dit niet logisch is voor ons voorbeeld.

De uitvoer toont nu de afbeelding met de verschillende toegepaste augmentaties:

De vorige secties toonden de basisprincipes van het vergroten van beeldgegevens en hoe het kan worden toegepast op een enkele afbeelding. Bij deep learning hebben we vaak te maken met een reeks afbeeldingen. Laten we nu eens kijken hoe beeldvergroting kan worden toegepast op een reeks afbeeldingen. Voor illustraties ga ik ervan uit dat in de map die uw Jupyter Notebook bevat, u een Fruit map en de volgende submappen:

Fruit
|__banaan
|__banaan1.jpg
|__banaan2.jpg
|__banaan3.jpg
|__ ...
|__doerian
|__durian1.jpg
|__durian2.jpg
|__durian3.jpg
|__ ...
|__oranje
|__oranje1.jpg
|__oranje2.jpg
|__oranje3.jpg
|__ ...
|__aardbei
|__aardbei1.jpg
|__aardbei2.jpg
|__aardbei3.jpg
|__ ...

Elke submap bevat een reeks afbeeldingen. Bijvoorbeeld de banaan map bevat een aantal afbeeldingen met de naam banaan1.jpg, banaan2.jpg, enzovoort. De naam van de submappen zal dienen als labels voor de verschillende afbeeldingen. Dit betekent dat alle bestanden onder de banaan map bevat afbeeldingen van bananen, enzovoort.

Om een โ€‹โ€‹reeks afbeeldingen van schijf te laden, roept u nu de flow_from_directory() methode van de ImageDataGenerator bijvoorbeeld in plaats van de flow() methode (voor het laden van afbeeldingen uit het geheugen):

train_datagen = ImageDataGenerator(
horizontal_flip=Waar,
vertical_flip=Waar,
rotatiebereik = 50,
)
batch_grootte = 8trein_generator = train_datagen.flow_from_directory(
'./Fruit',
target_size=(224,224),
color_mode='rgb',
batch_size=batch_grootte,
class_mode='categorisch',
shuffle = waar)

Merk op dat ik nu de batch_size t/m 8. Het gebruik van de batchgrootte ziet u binnenkort.

Met behulp van de geretourneerde iterator kan ik de labels voor de verschillende soorten fruit (banaan, durian, sinaasappel en aardbei) vinden:

class_dictionary = trein_generator.class_indices#---maak een woordenboek van labels---
class_dictionary = {waarde:sleutel voor sleutel,waarde in
class_dictionary.items()}
#---converteer het woordenboek naar een lijst---
class_list = [waarde voor _,waarde in class_dictionary.items()]
print(class_lijst)

U ziet de volgende uitvoer:

Er zijn 54 afbeeldingen gevonden die behoren tot 4 klassen.
['banaan', 'durian', 'oranje', 'aardbei']

In totaal zijn er 54 afbeeldingen in 4 mappen. Ook de class_list variabele bevat de lijst met fruit.

Ik zal nu de reeks vergrote afbeeldingen afdrukken die zijn gemaakt door de ImageDataGenerator klas. Ik zal de rijen willekeurig instellen op 10 en voor elke rij wil ik de batch geretourneerde afbeeldingen afdrukken (wat in dit voorbeeld 8 is):

rijen = 10fig, assen = plt.subplots(rijen,batch_grootte)voor r in bereik (rijen):    
#---verkrijg de batch met verbeterde afbeeldingen---
image_batch = treingenerator.next()
#---het aantal geretourneerde afbeeldingen ophalen---
afbeeldingen_count = afbeelding_batch[0].vorm[0]

voor c in bereik (images_count):
#---converteer naar niet-ondertekende gehele getallen om te bekijken---
afbeelding = afbeelding_batch[0][c].astype('uint8')

#---toon de afbeelding---
assen[r,c].imshow(afbeelding)

#---het label van de afbeelding weergeven---
assen[r,c].title.set_text(
class_list[np.argmax(image_batch[1][c])])
#---verbergt de x- en y-ticks---
assen[r,c].set_xticks([])
assen[r,c].set_yticks([])
fig.set_size_inches (15,18)

Aangezien de batch_size is nu ingesteld op 8 (en niet langer 1), de train_generator.next() methode zal je een teruggeven partij van acht vergrote afbeeldingen elke keer dat u het oproept. Het aantal geretourneerde afbeeldingen is gebaseerd op: batch_size die u eerder in de hebt ingesteld flow_from_directory() methode:

train_generator = train_datagen.flow_from_directory(
'./Fruit',
target_size=(224,224),
color_mode='rgb',
batch_size=batch_grootte, # batch_grootte = 8
class_mode='categorisch',
shuffle = waar)

De waarde van de image_batch variabele (geretourneerd door de next() methode) is een tupel van twee elementen:

  • Het eerste element (image_batch[0]) is een array van seriegrootte afbeeldingen (4D-array)
  • Het tweede element (image_batch[1]) bevat de labels voor de afbeeldingen

Het bovenstaande codefragment produceert de volgende uitvoer:

Merk op dat er op de zevende rij twee lege grafieken zijn zonder afbeeldingen. Bedenk dat er in totaal 54 afbeeldingen in de afbeeldingenset zijn, en aangezien elke batch 8 afbeeldingen (per rij) retourneert, zullen de eerste zeven rijen in totaal 54 afbeeldingen (8ร—6 + 6) weergeven. De volgende figuur maakt het duidelijk:

Merk op dat u kunt instellen: rows naar een willekeurig nummer en de ImageDataGenerator class blijft nieuwe augmented afbeeldingen voor je genereren.

Een model bouwen met behulp van transfer learning

U weet nu hoe u de ImageDataGenerator om sets afbeeldingen van schijf te laden voor augmentatie. Maar hoe gebruik je het voor training? Het volgende codefragment laat zien hoe u een deep learning-model kunt bouwen met: overdracht leren.

Transfer learning is een machinale leermethode waarbij een voor een taak ontwikkeld model wordt hergebruikt als uitgangspunt voor een model voor een tweede taak. Transfer learning vermindert de hoeveelheid tijd die u aan training moet besteden.

van tensorflow.keras.models import Model
van tensorflow.keras.applications import VGG16
van tensorflow.keras.layers import Dense, GlobalAveragePooling2D
#---aantal vruchten---
NO_CLASSES = max(train_generator.class_indices.values()) + 1
#---laad het VGG16-model als het basismodel voor training---
base_model = VGG16(include_top=False, input_shape=(224, 224, 3))
#--- onze eigen lagen toevoegen---
x = basismodel.uitvoer
x = GlobalAveragePooling2D()(x)
x = Dicht (1024,activation='relu')(x) # voeg dichte lagen toe dus
# dat het model kan
# leer meer complex
# functies en
# classificeren voor beter
# resultaten.
x = Dicht (1024,activatie='relu')(x) # dichte laag 2
x = Dichte(512,activatie='relu')(x) # dichte laag 3
preds = Dicht (NO_CLASSES,
activatie='softmax')(x) # laatste laag met
# softmax activatie
#---maak een nieuw model met het origineel van het basismodel
# input en de output van het nieuwe model ---
model = Model (invoer = basismodel.invoer, uitvoer = preds)
#---train de eerste 19 lagen niet - 0..18---
voor laag in model.lagen[:19]:
layer.trainable=Niet waar
#--- train de rest van de lagen - vanaf 19---
voor laag in model.lagen[19:]:
layer.trainable=Waar

#---compileer het model---
model.compile(optimizer='Adam',
loss='categorical_crossentropy',
metrics = ['nauwkeurigheid'])

Uitleggen hoe transfer learning werkt, valt buiten het bestek van dit artikel. Ik laat het voor een ander artikel.

De gegenereerde afbeeldingen gebruiken voor training

Als u de vergrote afbeeldingen wilt gebruiken voor training, moet u slagen voor de train_generator in de fit() methode van het model:

#--- train het model---
step_size_train = trein_generator.n // train_generator.batch_size
model.pasvorm(trein_generator,
steps_per_epoch=step_size_train,
tijdperken=15)

De steps_per_epoch parameter betekent in feite hoeveel stappen er in een tijdperk zijn - het is afhankelijk van het aantal afbeeldingen dat je hebt en de batchgrootte die eerder is gedefinieerd. Zet je dit op een hoog getal, dan ben je bezig met repetitieve training. U moet het instellen op basis van deze formule:

aantal afbeeldingen / batchgrootte

In ons voorbeeld hebben we in totaal 54 afbeeldingen. En dus in elk tijdperk, de ImageDataGenerator class transformeert alle 54 afbeeldingen voor training. In elk tijdperk krijgt het model verschillende variaties van de afbeeldingen. Als je 15 tijdperken hebt, worden in totaal 15ร—54 variaties van de afbeeldingen gegenereerd en ingevoerd in het trainingsmodel.

De ImageDataGenerator class stelt uw model in staat om in elk tijdperk nieuwe variaties van de afbeeldingen te ontvangen. Maar onthoud dat het alleen de getransformeerde afbeeldingen retourneert en niet toevoegt aan de set afbeeldingen die u hebt.

Ik hoop dat dit artikel je een goed idee heeft gegeven van waar het bij het vergroten van beeldgegevens om gaat en waarom je ze nodig hebt bij het trainen van je deep learning-modellen. Ik heb het met name gedemonstreerd met behulp van de Keras-module in de TensorFlow-bibliotheek.

Image Data Augmentation for Deep Learning opnieuw gepubliceerd vanuit de bron https://towardsdatascience.com/image-data-augmentation-for-deep-learning-77a87fabd2bf?source=rssโ€”-7f60cf5620c9โ€”4 via https://towardsdatascience.com/feed

<!โ€“

->

Tijdstempel:

Meer van Blockchain-adviseurs