In [1]:
import warnings
warnings.filterwarnings('ignore')
In [2]:
%matplotlib inline
%pylab inline
In [3]:
import matplotlib.pylab as plt
import numpy as np
In [4]:
from distutils.version import StrictVersion
In [5]:
import sklearn
print(sklearn.__version__)
assert StrictVersion(sklearn.__version__ ) >= StrictVersion('0.18.1')
In [6]:
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
print(tf.__version__)
assert StrictVersion(tf.__version__) >= StrictVersion('1.1.0')
In [7]:
# We need keras 2.0.6 or later as this is the version our GPU based system used to create some models
!pip install keras --upgrade
# after installation call Restart & Run All in Kernel menu
In [7]:
import keras
print(keras.__version__)
assert StrictVersion(keras.__version__) >= StrictVersion('2.0.6')
In [9]:
import pandas as pd
print(pd.__version__)
assert StrictVersion(pd.__version__) >= StrictVersion('0.19.0')
In [ ]:
!curl -O https://raw.githubusercontent.com/DJCordhose/speed-limit-signs/master/data/speed-limit-signs.zip
from zipfile import ZipFile
zip = ZipFile(r'speed-limit-signs.zip')
zip.extractall('.')
In [12]:
!ls -l speed-limit-signs
In [13]:
!cat speed-limit-signs/README.md
In [14]:
import os
import skimage.data
import skimage.transform
from keras.utils.np_utils import to_categorical
import numpy as np
def load_data(data_dir, type=".ppm"):
num_categories = 6
# Get all subdirectories of data_dir. Each represents a label.
directories = [d for d in os.listdir(data_dir)
if os.path.isdir(os.path.join(data_dir, d))]
# Loop through the label directories and collect the data in
# two lists, labels and images.
labels = []
images = []
for d in directories:
label_dir = os.path.join(data_dir, d)
file_names = [os.path.join(label_dir, f) for f in os.listdir(label_dir) if f.endswith(type)]
# For each label, load it's images and add them to the images list.
# And add the label number (i.e. directory name) to the labels list.
for f in file_names:
images.append(skimage.data.imread(f))
labels.append(int(d))
images64 = [skimage.transform.resize(image, (64, 64)) for image in images]
return images64, labels
In [15]:
# Load datasets.
ROOT_PATH = "./"
original_dir = os.path.join(ROOT_PATH, "speed-limit-signs")
images, labels = load_data(original_dir, type=".ppm")
In [16]:
import matplotlib
import matplotlib.pyplot as plt
def display_images_and_labels(images, labels):
"""Display the first image of each label."""
unique_labels = set(labels)
plt.figure(figsize=(15, 15))
i = 1
for label in unique_labels:
# Pick the first image for each label.
image = images[labels.index(label)]
plt.subplot(8, 8, i) # A grid of 8 rows x 8 columns
plt.axis('off')
plt.title("Label {0} ({1})".format(label, labels.count(label)))
i += 1
_ = plt.imshow(image)
In [17]:
display_images_and_labels(images, labels)
http://cs231n.github.io/neural-networks-1/#power
http://cs231n.github.io/convolutional-networks/#conv
Nebenbei: Keras.js kann deine Keras-Modelle auch im Browser ausführen
In [18]:
# again a little bit of feature engeneering
y = np.array(labels)
X = np.array(images)
from keras.utils.np_utils import to_categorical
num_categories = 6
y = to_categorical(y, num_categories)
In [68]:
from keras.models import Model
from keras.layers import Dense, Dropout, Flatten, Input
from keras.layers import Convolution2D, MaxPooling2D
# input tensor for a 3-channel 64x64 image
inputs = Input(shape=(64, 64, 3))
# one block of convolutional layers
x = Convolution2D(64, 3, activation='relu', padding='same')(inputs)
x = Convolution2D(64, 3, activation='relu', padding='same')(x)
x = Convolution2D(64, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
# one more block
x = Convolution2D(128, 3, activation='relu', padding='same')(x)
x = Convolution2D(128, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
# one more block
x = Convolution2D(256, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
# softmax activation, 6 categories
predictions = Dense(6, activation='softmax')(x)
In [69]:
model = Model(input=inputs, output=predictions)
model.summary()
In [70]:
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
In [71]:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.9, random_state=42, stratify=y)
In [72]:
X_train.shape, y_train.shape
Out[72]:
In [ ]:
# %time model.fit(X_train, y_train, epochs=50, validation_split=0.3)
%time model.fit(X_train, y_train, epochs=100, validation_split=0.3)
Out[ ]:
Ein solches Modell kann extrem einfach sein und schon dadurch Overfittung verhindern.
Wir verfolgen hier aber eine andere Philosophie: Wir machen das Modell so komplex wie es unsere Hardware zulässt und nutzen eine andere Methode, um Overfitting zu verhindern.
In [74]:
from keras.models import Model
from keras.layers import Dense, Dropout, Activation, Flatten, Input
from keras.layers import Convolution2D, MaxPooling2D
# this is important, try and vary between .4 and .75
drop_out = 0.7
# input tensor for a 3-channel 64x64 image
inputs = Input(shape=(64, 64, 3))
# one block of convolutional layers
x = Convolution2D(64, 3, activation='relu', padding='same')(inputs)
x = Convolution2D(64, 3, activation='relu', padding='same')(x)
x = Convolution2D(64, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Dropout(drop_out)(x)
# one more block
x = Convolution2D(128, 3, activation='relu', padding='same')(x)
x = Convolution2D(128, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Dropout(drop_out)(x)
# one more block
x = Convolution2D(256, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Dropout(drop_out)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(drop_out)(x)
# softmax activation, 6 categories
predictions = Dense(6, activation='softmax')(x)
In [75]:
model = Model(input=inputs, output=predictions)
model.summary()
In [42]:
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
In [43]:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
In [44]:
# https://keras.io/callbacks/#tensorboard
tb_callback = keras.callbacks.TensorBoard(log_dir='./tf_log')
# To start tensorboard
# tensorboard --logdir=/mnt/c/Users/olive/Development/ml/tf_log
# open http://localhost:6006
In [49]:
early_stopping_callback = keras.callbacks.EarlyStopping(monitor='val_loss', patience=100, verbose=1)
In [54]:
checkpoint_callback = keras.callbacks.ModelCheckpoint('./model-checkpoints/weights.epoch-{epoch:02d}-val_loss-{val_loss:.2f}.hdf5');
In [51]:
!rm -r tf_log
In [81]:
# Depends on harware GPU architecture, set as high as possible (this works well on K80)
BATCH_SIZE = 500
In [52]:
# %time model.fit(X_train, y_train, epochs=500, batch_size=BATCH_SIZE, validation_split=0.2, callbacks=[tb_callback, early_stopping_callback])
%time model.fit(X_train, y_train, epochs=500, batch_size=BATCH_SIZE, validation_split=0.2, callbacks=[tb_callback])
# %time model.fit(X_train, y_train, epochs=500, batch_size=BATCH_SIZE, validation_split=0.2)
Out[52]:
In [34]:
model.save('conv-vgg.hdf5')
In [77]:
!ls -lh
In [78]:
# https://transfer.sh/
# Speichert eure Daten für 14 Tage
!curl --upload-file conv-vgg.hdf5 https://transfer.sh/conv-vgg.hdf5
# Vortrainiertes Modell
# loss: 0.0310 - acc: 0.9917 - val_loss: 0.4075 - val_acc: 0.9508
# https://transfer.sh/B1W8e/conv-vgg.hdf5
In [59]:
!ls -lh
In [58]:
!rm conv-vgg.hdf5
In [1]:
# anpassen an aktuelles Modell
# Nachricht an Olli: Liegt auch local auf Ollis Rechner und kann zur Not von da hochgeladen werden (ai/models/conv-vgg.hdf5)
!curl -O https://transfer.sh/B1W8e/conv-vgg.hdf5
In [61]:
!ls -lh
In [79]:
from keras.models import load_model
model = load_model('conv-vgg.hdf5')
In [82]:
train_loss, train_accuracy = model.evaluate(X_train, y_train, batch_size=BATCH_SIZE)
train_loss, train_accuracy
Out[82]:
In [84]:
test_loss, test_accuracy = model.evaluate(X_test, y_test, batch_size=BATCH_SIZE)
test_loss, test_accuracy
Out[84]:
In [86]:
import random
# Pick 10 random images for test data set
random.seed(4) # to make this deterministic
sample_indexes = random.sample(range(len(X_test)), 10)
sample_images = [X_test[i] for i in sample_indexes]
sample_labels = [y_test[i] for i in sample_indexes]
In [88]:
ground_truth = np.argmax(sample_labels, axis=1)
ground_truth
Out[88]:
In [89]:
X_sample = np.array(sample_images)
prediction = model.predict(X_sample)
predicted_categories = np.argmax(prediction, axis=1)
predicted_categories
Out[89]:
In [90]:
# Display the predictions and the ground truth visually.
def display_prediction (images, true_labels, predicted_labels):
fig = plt.figure(figsize=(10, 10))
for i in range(len(true_labels)):
truth = true_labels[i]
prediction = predicted_labels[i]
plt.subplot(5, 2,1+i)
plt.axis('off')
color='green' if truth == prediction else 'red'
plt.text(80, 10, "Truth: {0}\nPrediction: {1}".format(truth, prediction),
fontsize=12, color=color)
plt.imshow(images[i])
In [91]:
display_prediction(sample_images, ground_truth, predicted_categories)