今日はこのサイトのNeural Networks Crash Tutorial – Keras version (ニューラルネットワーク集中チュートリアル-Keras編)をやる。チュートリアルを始める前に必要なデータをダンロードしてファイルを展開しておく。
!mkdir test1
%download https://btsd.ethz.ch/shareddata/BelgiumTSC/BelgiumTSC_Training.zip
%download https://btsd.ethz.ch/shareddata/BelgiumTSC/BelgiumTSC_Testing.zip
!mkdir BelgiumTrafficSigns
cd BelgiumTrafficSigns
mv ../BelgiumTSC_Training.zip .
!unzip BelgiumTSC_Training.zip
!mv ../BelgiumTSC_Testing.zip .
!unzip BelgiumTSC_Testing.zip
cd ..
スポンサーリンク
Preliminaries¶
import os, skimage.data
def load_data(data_directory):
directories = [d for d in os.listdir(data_directory)
if os.path.isdir(os.path.join(data_directory, d))]
labels = []
images = []
for d in directories:
label_directory = os.path.join(data_directory, d)
file_names = [os.path.join(label_directory, f)
for f in os.listdir(label_directory)
if f.endswith(".ppm")]
for f in file_names:
images.append(skimage.data.imread(f))
labels.append(int(d))
return images, labels
def plot_images(images, labels, color_map = "brg"):
# Get the unique labels
unique_labels = set(labels)
# Initialize the figure
plt.figure(figsize=(20, 20))
# Set a counter
i = 1
# For each unique label,
for label in unique_labels:
# You pick the first image for each label
image = images[labels.index(label)]
# Define 64 subplots
plt.subplot(8, 8, i)
# Don't include axes
plt.axis('off')
# Add a title to each subplot
plt.title("Label {0} ({1})".format(label, labels.count(label)))
# Add 1 to the counter
i += 1
# And you plot this first image
plt.imshow(image, cmap=color_map)
# Show the plot
plt.show()
スポンサーリンク
Load training data¶
次に先程ダウンロードした訓練データをロードする。
train_data_directory = "./BelgiumTrafficSigns/Training"
images, labels = load_data(train_data_directory)
画像がどのように分布しているのかを見るためにラベルのヒストグラムをプロットする。
# Import the `pyplot` module of matplotlib
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = 16, 8
plt.rcParams["font.size"] = "17"
# Make a histogram with 62 bins of the `labels` data
plt.hist(labels, 62)
# Show the plot
plt.show()
いくつかの画像とそれらの形を無作為抽出して確認する。
import random
# Determine the (random) indexes of the images that you want to see
traffic_signs = random.sample(range(len(images)), 4)
# Fill out the subplots with the random images and add shape
for i in range(len(traffic_signs)):
plt.subplot(1, 4, i+1)
plt.axis('off')
plt.imshow(images[traffic_signs[i]])
plt.subplots_adjust(wspace=0.5)
plt.show()
print("shape: {0}".format(images[traffic_signs[i]].shape))
各カテゴリーの最初のサンプルをプロットする。
plt.rcParams["font.size"] = "14"
plot_images(images,labels)
スポンサーリンク
Pre-process images¶
画像を全て同じサイズと解像度にする。
# Import the `transform` module from `skimage`
from skimage import transform
# set desired number of pixels
px = 32
# Rescale the images in the `images` array
simages = [transform.resize(image, (px, px), mode='constant') for image in images]
plot_images(simages,labels)
画像をグレイスケールに変換する。
# Import `rgb2gray` from `skimage.color`
from skimage.color import rgb2gray
# Convert `simages` to grayscale
simagesg = [rgb2gray(img) for img in simages]
plot_images(simagesg, labels, color_map="gray")
# Compare image sizes
print('original = {}, scaled = {}, grayscale = {}'.format(images[0].shape,simages[0].shape,simagesg[0].shape))
スポンサーリンク
Create the neural network model¶
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten, Dropout
import numpy as np
# Convert labels to categorical one-hot encoding
one_hot_labels = keras.utils.to_categorical(labels, num_classes=62)
# Convert images to numpy arrays
data = np.array(simagesg)
data.shape
gmodel = Sequential()
gmodel.add(Flatten(input_shape=data.shape[1:]))
gmodel.add(Dense(62, activation='relu'))
gmodel.add(Dropout(0.5))
gmodel.add(Dense(62, activation='softmax'))
スポンサーリンク
Train the model¶
# Multi-class classification problem
gmodel.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
import tensorflow as tf
session_config = tf.ConfigProto()
session_config.gpu_options.per_process_gpu_memory_fraction = 0.5
# Train the model, iterating on the data in batches of 32 samples
gmodel.fit(data, one_hot_labels, epochs=10, batch_size=32, verbose=1)
スポンサーリンク
Evaluate performance on some samples¶
ここでの目標は訓練がうまくいったかを迅速に評価すること。
完全なモデル検証は、ただ単に訓練データ・セットの標本をいくつか評価する以上のことが要求される。
N = 10
sample_indexes = random.sample(range(len(data)), N)
sample_images = np.array([data[i] for i in sample_indexes])
sample_labels = np.array([labels[i] for i in sample_indexes])
# Run the "correct_pred" operation
predicted = np.array(gmodel.predict_classes(sample_images))
error, = np.nonzero(sample_labels - predicted)
accuracy = 100*(1-error.size/N)
# Print the real and predicted labels
print("Truth: ", sample_labels)
print("Predicted:", predicted, "accuracy = {}%".format(accuracy))
# Display the predictions and the ground truth visually.
fig = plt.figure(figsize=(px, px))
j = 1
for i in range(len(sample_images)):
truth = sample_labels[i]
prediction = predicted[i]
predicted_image = data[labels.index(prediction)]
plt.subplot(10, 2, j)
plt.axis('off')
color='green' if truth == prediction else 'red'
plt.text(40, 10, "Truth: {0}\nPrediction: {1}".format(truth, prediction), fontsize=18, color=color)
plt.imshow(sample_images[i], cmap="gray")
j += 1
plt.subplot(10, 2, j)
plt.axis('off')
plt.imshow(predicted_image, cmap="gray")
j += 1
# Show the plot
plt.show()
スポンサーリンク
Can color improve the results?¶
今度はカラー画像を使ってプロセスを繰り返す。
import numpy as np
# Convert labels to categorical one-hot encoding
one_hot_labels = keras.utils.to_categorical(labels, num_classes=62)
# Convert images to numpy arrays
data = np.array(simages)
data.shape
cmodel = Sequential()
cmodel.add(Flatten(input_shape=data.shape[1:]))
cmodel.add(Dense(62, activation='relu'))
cmodel.add(Dropout(0.5))
cmodel.add(Dense(62, activation='softmax'))
スポンサーリンク
Train the model¶
# Multi-class classification problem
cmodel.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
session_config = tf.ConfigProto()
session_config.gpu_options.per_process_gpu_memory_fraction = 0.5
# Train the model, iterating on the data in batches of 32 samples
cmodel.fit(data, one_hot_labels, epochs=10, batch_size=32, verbose=1)
スポンサーリンク
Evaluate performance on some samples¶
N = 10
sample_indexes = random.sample(range(len(data)), N)
sample_gimages = np.array([simagesg[i] for i in sample_indexes])
sample_cimages = np.array([simages[i] for i in sample_indexes])
sample_labels = np.array([labels[i] for i in sample_indexes])
# Run the "correct_pred" operation
gpredicted = gmodel.predict_classes(sample_gimages)
cpredicted = cmodel.predict_classes(sample_cimages)
gerror, = np.nonzero(sample_labels - gpredicted)
cerror, = np.nonzero(sample_labels - cpredicted)
gaccuracy = 100*(1-gerror.size/N)
caccuracy = 100*(1-cerror.size/N)
# Print the real and predicted labels
print("Truth:", sample_labels)
print("GS: ", gpredicted, "accuracy = {}%".format(gaccuracy))
print("Color:", cpredicted, "accuracy = {}%".format(caccuracy))
# Display the predictions and the ground truth visually.
#fig = plt.figure(figsize=(10, 10))
fig = plt.figure(figsize=(28,28))
j = 1
for i in range(len(sample_images)):
truth = sample_labels[i]
gprediction = gpredicted[i]
cprediction = cpredicted[i]
predicted_gimage = simagesg[labels.index(gprediction)]
predicted_cimage = simages[labels.index(cprediction)]
plt.subplot(10, 3, j)
plt.axis('off')
plt.text(40, 10, "Truth: {}".format(truth),
fontsize=18)
color='green' if truth == gprediction else 'red'
plt.text(40, 15, "GS Prediction: {}".format(gprediction),
fontsize=18, color=color)
color='green' if truth == cprediction else 'red'
plt.text(40, 20, "Color Prediction: {}".format(cprediction),
fontsize=18, color=color)
plt.imshow(sample_cimages[i])
j += 1
plt.subplot(10, 3, j)
plt.axis('off')
plt.imshow(predicted_gimage, cmap="gray")
j += 1
plt.subplot(10, 3, j)
plt.axis('off')
plt.imshow(predicted_cimage)
j += 1
# Show the plot
plt.show()
スポンサーリンク
Can features improve the results?¶
今度は、深層学習で行われることに似た方法でニューラルネットワークに色々な層を足す。
import numpy as np
# Convert labels to categorical one-hot encoding
one_hot_labels = keras.utils.to_categorical(labels, num_classes=62)
# Convert images to numpy arrays
data = np.array(simages)
data.shape
from keras.layers import Flatten, Conv2D, MaxPooling2D
fmodel = Sequential()
# Convolutional neural network to extract features
fmodel.add(Conv2D(32, (3, 3), input_shape=data.shape[1:], activation='relu'))
fmodel.add(MaxPooling2D(pool_size=(2, 2)))
fmodel.add(Conv2D(32, (3, 3), activation='relu'))
fmodel.add(MaxPooling2D(pool_size=(2, 2)))
fmodel.add(Conv2D(32, (3, 3), activation='relu'))
fmodel.add(MaxPooling2D(pool_size=(2, 2)))
# Converts our 3D feature maps to 1D feature vectors
fmodel.add(Flatten())
# Classifier network
fmodel.add(Dense(62, activation='relu'))
fmodel.add(Dropout(0.5))
fmodel.add(Dense(62, activation='softmax'))
Train the model¶
# Multi-class classification problem
fmodel.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
session_config = tf.ConfigProto()
session_config.gpu_options.per_process_gpu_memory_fraction = 0.5
# Train the model, iterating on the data in batches of 32 samples
fmodel.fit(data, one_hot_labels, epochs=10, batch_size=32, verbose=1)
Evaluate performance on some samples¶
sample_indexes = random.sample(range(len(simages)), 10)
sample_gimages = np.array([simagesg[i] for i in sample_indexes])
sample_cimages = np.array([simages[i] for i in sample_indexes])
sample_labels = np.array([labels[i] for i in sample_indexes])
# Run the "correct_pred" operation
gpredicted = gmodel.predict_classes(sample_gimages)
cpredicted = cmodel.predict_classes(sample_cimages)
fpredicted = fmodel.predict_classes(sample_cimages)
gerror, = np.nonzero(sample_labels - gpredicted)
cerror, = np.nonzero(sample_labels - cpredicted)
ferror, = np.nonzero(sample_labels - fpredicted)
gaccuracy = 100*(1-gerror.size/N)
caccuracy = 100*(1-cerror.size/N)
faccuracy = 100*(1-ferror.size/N)
# Print the real and predicted labels
print("Truth:", sample_labels)
print("GS: ", gpredicted, "accuracy = {}%".format(gaccuracy))
print("Color:", cpredicted, "accuracy = {}%".format(caccuracy))
print("DL: ", fpredicted, "accuracy = {}%".format(faccuracy))
# Display the predictions and the ground truth visually.
#fig = plt.figure(figsize=(10, 10))
fig = plt.figure(figsize=(28,28))
j = 1
for i in range(len(sample_images)):
truth = sample_labels[i]
gprediction = gpredicted[i]
cprediction = cpredicted[i]
fprediction = fpredicted[i]
predicted_gimage = simagesg[labels.index(gprediction)]
predicted_cimage = simages[labels.index(cprediction)]
predicted_fimage = simages[labels.index(fprediction)]
plt.subplot(10, 4, j)
plt.axis('off')
plt.text(40, 10, "Truth: {}".format(truth),
fontsize=18)
color='green' if truth == gprediction else 'red'
plt.text(40, 15, "GS Prediction: {}".format(gprediction),
fontsize=18, color=color)
color='green' if truth == cprediction else 'red'
plt.text(40, 20, "Color Prediction: {}".format(cprediction),
fontsize=18, color=color)
color='green' if truth == fprediction else 'red'
plt.text(40, 25, "DL Prediction: {}".format(fprediction),
fontsize=18, color=color)
plt.imshow(sample_cimages[i])
j += 1
plt.subplot(10, 4, j)
plt.axis('off')
plt.imshow(predicted_gimage, cmap="gray")
j += 1
plt.subplot(10, 4, j)
plt.axis('off')
plt.imshow(predicted_cimage)
j += 1
plt.subplot(10, 4, j)
plt.axis('off')
plt.imshow(predicted_fimage)
j += 1
# Show the plot
plt.show()
下のコードは、最初の畳み込み層が処理される後に起こることをそのまま視覚化する。
可視化したい層をインデックスkを変更することで選択できる。
from keras.models import Model
k = 0
intermediate_layer_model = Model(inputs=fmodel.input,
outputs=fmodel.layers[k].output)
intermediate_output = intermediate_layer_model.predict(sample_cimages)
print(intermediate_output.shape)
stacked image(積層画像)として層を可視化する。
import math
M = math.floor(intermediate_output.shape[-1]/3)
N = len(sample_cimages)
print('M = {}, N = {}'.format(M,N))
fig = plt.figure(figsize=(px,px))
for i, img in enumerate(sample_cimages):
plt.subplot(N,M+1,i*(M+1)+1)
plt.imshow(img)
plt.axis('off')
for j in range(M):
#print('i = {}, j = {}, i*(M+1)+j+2 = {}'.format(i,j,i*(M+1)+j+2))
plt.subplot(N,M+1,i*(M+1)+j+2)
plt.imshow((intermediate_output[i,:,:,j:j+3]*255).astype(np.uint8))
plt.axis('off')
plt.show()
flattened image(平坦化画像)として層を視覚化する。
K = intermediate_output.shape[3]
M = np.prod(intermediate_output.shape[1:3])
N = len(sample_cimages)
# print('M = {}, N = {}, K = {}'.format(M,N,K))
fig = plt.figure(figsize=(px,px))
for i, img in enumerate(sample_cimages):
plt.subplot(N,2,i*2+1)
plt.imshow(img)
plt.axis('off')
plt.subplot(N,2,i*2+2)
fimg = np.reshape(intermediate_output[i,:,:,:], [M, K], order = 'C').transpose()
plt.imshow(fimg, cmap='gray')
plt.axis('off')
plt.show()
!pip3 install --upgrade matplotlib
スポンサーリンク
スポンサーリンク