Use complex images
Download the neccessary data into the Colab Instance
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip \
-O /tmp/horse-or-human.zip
!wget --no-check-certificate \
https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip \
-O /tmp/validation-horse-or-human.zip
Python中的zipfile模块使用实例 - 简书 (jianshu.com)
import os
import zipfile
local_zip = '/tmp/horse-or-human.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/horse-or-human')
local_zip = '/tmp/validation-horse-or-human.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/validation-horse-or-human')
zip_ref.close()
# Directory with our training horse pictures
train_horse_dir = os.path.join('/tmp/horse-or-human/horses')
# Directory with our training human pictures
train_human_dir = os.path.join('/tmp/horse-or-human/humans')
# Directory with our training horse pictures
validation_horse_dir = os.path.join('/tmp/validation-horse-or-human/horses')
# Directory with our training human pictures
validation_human_dir = os.path.join('/tmp/validation-horse-or-human/humans')
train_horse_names = os.listdir('/tmp/horse-or-human/horses')
print(train_horse_names[:10])
train_human_names = os.listdir('/tmp/horse-or-human/humans')
print(train_human_names[:10])
validation_horse_hames = os.listdir('/tmp/validation-horse-or-human/horses')
print(validation_horse_hames[:10])
validation_human_names = os.listdir('/tmp/validation-horse-or-human/humans')
print(validation_human_names[:10])
Define your model and optimizer
import tensorflow as tf
model = tf.keras.models.Sequential([
# Note the input shape is the desired size of the image with 3 bytes color
# This is the first convolution
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(100, 100, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
# The second convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The third convolution
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fourth convolution
tf.keras.layers.Conv2D(256, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# Flatten the results to feed into a DNN
tf.keras.layers.Flatten(),
# 512 neuron hidden layer
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(256, activation='relu'),
# Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('horses') and 1 for the other ('humans')
tf.keras.layers.Dense(1, activation='sigmoid')
])
print(model.summary())
Output:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 98, 98, 32) 896
max_pooling2d (MaxPooling2D (None, 49, 49, 32) 0
)
conv2d_1 (Conv2D) (None, 47, 47, 64) 18496
max_pooling2d_1 (MaxPooling (None, 23, 23, 64) 0
2D)
conv2d_2 (Conv2D) (None, 21, 21, 128) 73856
max_pooling2d_2 (MaxPooling (None, 10, 10, 128) 0
2D)
conv2d_3 (Conv2D) (None, 8, 8, 256) 295168
max_pooling2d_3 (MaxPooling (None, 4, 4, 256) 0
2D)
flatten (Flatten) (None, 4096) 0
dense (Dense) (None, 512) 2097664
dense_1 (Dense) (None, 256) 131328
dense_2 (Dense) (None, 1) 257
=================================================================
Total params: 2,617,665
Trainable params: 2,617,665
Non-trainable params: 0
_________________________________________________________________
None
from tensorflow.keras.optimizers import RMSprop
optimizer = RMSprop(lr=0.0001)
model.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=['acc'])
Organize your data into Generators
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# All images will be augmented according to whichever lines are uncommented below.
# we can first try without any of the augmentation beyond the rescaling
train_datagen = ImageDataGenerator(
rescale=1./255,
#rotation_range=40,
#width_shift_range=0.2,
#height_shift_range=0.2,
#shear_range=0.2,
#zoom_range=0.2,
#horizontal_flip=True,
#fill_mode='nearest'
)
# Flow training images in batches of 128 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
'/tmp/horse-or-human/', # This is the source directory for training images
target_size=(100, 100), # All images will be resized to 100x100
batch_size=128,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')
validation_datagen = ImageDataGenerator(rescale=1./255)
validation_generator = validation_datagen.flow_from_directory(
'/tmp/validation-horse-or-human',
target_size=(100, 100),
class_mode='binary')
Train your model
history = model.fit(
train_generator,
steps_per_epoch=8,
epochs=100,
verbose=1,
validation_data=validation_generator)
Run your model
import numpy as np
from google.colab import files
from tensorflow.keras import utils
uploaded = files.upload()
for fn in uploaded.keys():
# predicting images
path = '/content/' + fn
img = utils.load_img(path, target_size=(100, 100))
x = utils.img_to_array(img)
x = x / 255.0
x = np.expand_dims(x, axis=0)
image_tensor = np.vstack([x])
classes = model.predict(image_tensor)
print(classes)
print(classes[0])
if classes[0]>0.5:
print(fn + " is a human")
else:
print(fn + " is a horse")
Visualize all of the model layers
import matplotlib.pyplot as plt
import numpy as np
import random
from tensorflow.keras.preprocessing.image import img_to_array, load_img
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# Let's define a new Model that will take an image as input, and will output
# intermediate representations for all layers in the previous model after the first.
successive_outputs = [layer.output for layer in model.layers[1:]]
visualization_model = tf.keras.models.Model(inputs = model.input, outputs = successive_outputs)
# Let's prepare a random input image from the training set.
horse_img_files = [os.path.join(train_horse_dir, f) for f in train_horse_names]
human_img_files = [os.path.join(train_human_dir, f) for f in train_human_names]
img_path = random.choice(horse_img_files + human_img_files)
# uncomment the following line if you want to pick the Xth human file manually
img_path = human_img_files[0]
img = load_img(img_path, target_size=(100, 100)) # this is a PIL image
x = img_to_array(img) # Numpy array with shape (100, 100, 3)
x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 100, 100, 3)
# Rescale by 1/255
x /= 255.0
# Let's run our image through our network, thus obtaining all
# intermediate representations for this image.
successive_feature_maps = visualization_model.predict(x)
# These are the names of the layers, so can have them as part of our plot
layer_names = [layer.name for layer in model.layers]
# Now let's display our representations
for layer_name, feature_map in zip(layer_names, successive_feature_maps):
if len(feature_map.shape) == 4:
# Just do this for the conv / maxpool layers, not the fully-connected layers
n_features = feature_map.shape[-1] # number of features in feature map
n_features = min(n_features,5) # limit to 5 features for easier viewing
# The feature map has shape (1, size, size, n_features)
size = feature_map.shape[1]
# We will tile our images in this matrix
display_grid = np.zeros((size, size * n_features))
for i in range(n_features):
# Postprocess the feature to make it visually palatable
x = feature_map[0, :, :, i]
x -= x.mean()
x /= x.std()
x *= 64
x += 128
x = np.clip(x, 0, 255).astype('uint8')
# We'll tile each filter into this big horizontal grid
display_grid[:, i * size : (i + 1) * size] = x
# Display the grid
scale = 20. / n_features
plt.figure(figsize=(scale * n_features, scale))
plt.title(layer_name)
plt.grid(False)
plt.imshow(display_grid, aspect='auto', cmap='viridis')
Clean up
# Before running the next exercise,
# run the following cell to terminate the kernel and free memory resources
import os, signal
os.kill(os.getpid(), signal.SIGKILL)
TFDS
There’s a lot to learn with TFDS, and it’s a really powerful API. Visit: www.tensorflow.org/datasets to go deeper!
TensorFlow Datasets is a separate install from TensorFlow, so be sure to install it before trying out any samples! If you are using Google Colab, it’s already preinstalled.
If you need to install it, you can do so with a pip command:
pip install tensorflow-datasets
Once it’s installed, you can use it to get access to a dataset with tfds.load , passing it the name of the desired dataset. For example, if you want to use Fashion MNIST, you can use code like this:
import tensorflow as tf
import tensorflow_datasets as tfds
mnist_data = tfds.load("fashion_mnist")
for item in mnist_data:
print(item)
Two very important concepts to learn with TensorFlow Datasets are the Splits API -- that gives you a flexible way of splitting up data into Training, Testing, Validation sets, and Mapping Functions, which allow you to do things like Augmentation. So, for example, you saw how to do Image Augmentation on a generator, but if you’re no longer using generators you’ll need an alternative! TFDS makes it simple with the mapping functions.
Here’s code as an example:
def augmentimages(image, label):
image = tf.cast(image, tf.float32)
image = (image/255)
image = tf.image.random_flip_left_right(image)
return image, label
data = tfds.load('horses_or_humans', split='train', as_supervised=True)
train = data.map(augmentimages)
In this case, tfds.load is used to get the horses or humans dataset. It’s pre-split into a ‘train’ subset with the training data, so you can request that. Then, once you have data, you can call it’s ‘map’ method, passing it a function like ‘AugmentImages’ as shown, and from within there you can do your image augmentation.