Skip to content

Commit 21d8b23

Browse files
committed
Added Tutorial Hvass-Labs#9
1 parent f03ade9 commit 21d8b23

File tree

4 files changed

+232
-214
lines changed

4 files changed

+232
-214
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ inception/
77
checkpoints/
88
checkpoints*
99
logs/
10+
summary/
1011

1112
# PyCharm
1213
.idea/

08_Transfer_Learning.ipynb

Lines changed: 181 additions & 171 deletions
Large diffs are not rendered by default.

cifar10.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import numpy as np
3636
import pickle
3737
import download
38+
from dataset import one_hot_encoded
3839

3940
########################################################################
4041

@@ -149,15 +150,6 @@ def _load_data(filename):
149150
return images, cls
150151

151152

152-
def _one_hot_encoded(cls):
153-
"""
154-
Generate the One-Hot encoded class-labels from an array of integers.
155-
Returns a 2-dim array of shape: [image_number, num_classes]
156-
"""
157-
158-
return np.eye(num_classes)[cls]
159-
160-
161153
########################################################################
162154
# Public functions that you may call to download the data-set from
163155
# the internet and load the data into memory.
@@ -225,7 +217,7 @@ def load_training_data():
225217
# The begin-index for the next batch is the current end-index.
226218
begin = end
227219

228-
return images, cls, _one_hot_encoded(cls)
220+
return images, cls, one_hot_encoded(class_numbers=cls, num_classes=num_classes)
229221

230222

231223
def load_test_data():
@@ -237,6 +229,6 @@ def load_test_data():
237229

238230
images, cls = _load_data(filename="test_batch")
239231

240-
return images, cls, _one_hot_encoded(cls)
232+
return images, cls, one_hot_encoded(class_numbers=cls, num_classes=num_classes)
241233

242234
########################################################################

inception.py

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import numpy as np
5858
import tensorflow as tf
5959
import download
60+
from cache import cache
6061
import os
6162
import sys
6263

@@ -306,6 +307,22 @@ def close(self):
306307

307308
self.session.close()
308309

310+
def _write_summary(self, logdir='summary/'):
311+
"""
312+
Write graph to summary-file so it can be shown in TensorBoard.
313+
314+
This function is used for debugging and may be changed or removed in the future.
315+
316+
:param logdir:
317+
Directory for writing the summary-files.
318+
319+
:return:
320+
Nothing.
321+
"""
322+
323+
writer = tf.train.SummaryWriter(logdir=logdir, graph=self.graph)
324+
writer.close()
325+
309326
@staticmethod
310327
def _create_feed_dict(image_path=None, image=None):
311328
"""
@@ -476,7 +493,7 @@ def transfer_values(self, image_path=None, image=None):
476493
# Batch-processing.
477494

478495

479-
def process_images(fn, images):
496+
def process_images(fn, images=None, image_paths=None):
480497
"""
481498
Call the function fn() for each image, e.g. transfer_values() from
482499
the Inception model above. All the results are concatenated and returned.
@@ -487,19 +504,28 @@ def process_images(fn, images):
487504
:param images:
488505
List of images to process.
489506
507+
:param image_paths:
508+
List of file-paths for the images to process.
509+
490510
:return:
491511
Numpy array with the results.
492512
"""
493513

514+
# Are we using images or image_paths?
515+
using_images = images is not None
516+
494517
# Number of images.
495-
num_images = len(images)
518+
if using_images:
519+
num_images = len(images)
520+
else:
521+
num_images = len(image_paths)
496522

497523
# Pre-allocate list for the results.
498524
# This holds references to other arrays. Initially the references are None.
499525
result = [None] * num_images
500526

501527
# For each input image.
502-
for i, image in enumerate(images):
528+
for i in range(num_images):
503529
# Status-message. Note the \r which means the line should overwrite itself.
504530
msg = "\r- Processing image: {0:>6} / {1}".format(i+1, num_images)
505531

@@ -508,7 +534,10 @@ def process_images(fn, images):
508534
sys.stdout.flush()
509535

510536
# Process the image and store the result for later use.
511-
result[i] = fn(image=image)
537+
if using_images:
538+
result[i] = fn(image=images[i])
539+
else:
540+
result[i] = fn(image_path=image_paths[i])
512541

513542
# Print newline.
514543
print()
@@ -522,7 +551,7 @@ def process_images(fn, images):
522551
########################################################################
523552

524553

525-
def transfer_values_cache(file_path, images, model=None):
554+
def transfer_values_cache(cache_path, model, images=None, image_paths=None):
526555
"""
527556
This function either loads the transfer-values if they have
528557
already been calculated, otherwise it calculates the values
@@ -534,44 +563,30 @@ def transfer_values_cache(file_path, images, model=None):
534563
535564
See Tutorial #08 for an example on how to use this function.
536565
537-
:param file_path:
566+
:param cache_path:
538567
File containing the cached transfer-values for the images.
539568
569+
:param model:
570+
Instance of the Inception model.
571+
540572
:param images:
541573
4-dim array with images. [image_number, height, width, colour_channel]
542574
543-
:param model:
544-
Instance of the Inception-class above. If None then
545-
a new instance will be created if necessary.
575+
:param image_paths:
576+
Array of file-paths for images (must be jpeg-format).
546577
547578
:return:
548579
The transfer-values from the Inception model for those images.
549580
"""
550581

551-
# If the cache-file exists.
552-
if os.path.exists(file_path):
553-
# Load the transfer-values from the file.
554-
with open(file_path, mode='rb') as file:
555-
transfer_values = np.load(file)
582+
# Helper-function for processing the images if the cache-file does not exist.
583+
# This is needed because we cannot supply both fn=process_images
584+
# and fn=model.transfer_values to the cache()-function.
585+
def fn():
586+
return process_images(fn=model.transfer_values, images=images, image_paths=image_paths)
556587

557-
print("- Transfer-values loaded from cache-file.")
558-
else:
559-
# Otherwise calculate the transfer-values for all the images and save them.
560-
561-
if model is None:
562-
# Create an instance of the Inception-model if None is supplied.
563-
# This takes about a second to execute.
564-
# The object instance could be re-used across multiple calls of this
565-
# function, but this is a tiny part of the overall time-usage.
566-
model = Inception()
567-
568-
# Calculate the transfer-values of the Inception model for the given images.
569-
transfer_values = process_images(fn=model.transfer_values,
570-
images=images)
571-
572-
# Save the transfer-values to a file.
573-
with open(file_path, mode='wb') as file:
574-
np.save(file, transfer_values)
588+
# Read the transfer-values from a cache-file, or calculate them if the file does not exist.
589+
transfer_values = cache(cache_path=cache_path, fn=fn)
575590

576591
return transfer_values
577592

0 commit comments

Comments
 (0)