import matplotlib.pyplot as plt
import numpy as np
import matplotlib.image as mpimg
import scipy.ndimage.filters as sci_filter
from scipy.ndimage import imread
from scipy import ndimage
import scipy
from PIL import Image
import pandas as pd
%matplotlib inline
При работа със снимки обаче моделите нарастват много бързо:
K
.img = Image.open('image.jpg')
img.thumbnail((512, 288), Image.ANTIALIAS)
img = np.array(img.convert('LA'))[:,:,0]
img = img / 255
def plot_gray(img):
plt.figure(figsize=(10,18))
plt.imshow(img, cmap = plt.get_cmap('gray'))
plot_gray(img)
k = np.ones((5,5))
k = k / np.dot(*k.shape)
print(k)
blurred = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(blurred)
k = np.array([[0, -1, 0],
[-1,14,-1],
[0, -1, 0]])
sharpen = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(sharpen)
k = np.array([[1.,0.,-1.],
[0.,0.,0.],
[-1.,0.,1.]])
edge1 = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(edge1)
k = np.array([[0.,1.,0.],
[1.,-4.,1.],
[0.,1.,0.]])
edge2 = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(edge2)
k = np.array([[-1.,-1.,-1.],
[-1.,8.,-1.],
[-1.,-1.,-1.]])
edge3 = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(edge3)
k = np.array([[-1, 0, 1],
[-3, 0, 3],
[-1, 0, 1],
])
sobel_v = ndimage.convolve(img, k, mode='constant', cval=0.0)
plot_gray(sobel_v / sobel_v.sum())
k = k.T
print(k)
sobel_h = ndimage.convolve(img, k, mode='constant', cval=0.0)
Conv2D
, който използваме за създаване на конволюционни филтри за снимки.¶keras.layers.Conv1D(filters, kernel_size, strides=1, padding='valid', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
filters
- броя на филтрите, които искаме да има в скрития слой.kernel_size
- размер на филрите, например 3
или (3,3)
за 3x3
; 5
или (5,5)
за 5x5
и т.н.Strides
- стъпка на отместване¶1
.Stride 1:
Stride 2: прескача на всеки втори пиксел.
valid
(без padding) и same
(с padding).
3x3
филтър ще има 27
параметъра за 3x3 patch и 3 канала.Има точна формула, чрез която да пресмятаме размера на изходните размери:
$$ O = \frac{( W - K + 2P)}{S} + 1$$
$$ O = \frac{ 32 - 3 + 2*0}{1} + 1 = 30 $$
Padding 1:
$$ O = \frac{ 32 - 3 + 2*1}{1} + 1 = 32 $$
Новия брой филтри си остава винаги 10.
Padding 1 и stride 2:
$$ O = \frac{ 32 - 3 + 2*1}{2} + 1 = 16 $$
SAME
output с филтър 5x5 и stride 1?¶$$ O = \frac{ 32 - 5 + 2*2}{1} + 1 = 32 $$
max-pooling
си имат нормнални градиенти.Flatten
.Flatten
конкатенира каналите в един.import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, Input
from keras.optimizers import Adam
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
plt.figure(figsize=(12,8))
for i in range(10):
plt.subplot(2,5,i+1)
plt.imshow(x_train[i])
model = Sequential()
model.add(Dense(1000, activation='relu', input_shape=(3072,)))
model.add(Dense(500, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer=Adam(0.0001),
metrics=['accuracy'])
model.summary()
model.fit(x_train.reshape(50000, -1), y_train,
batch_size=1024,
epochs=10,
validation_data=(x_test.reshape(10000, -1), y_test))
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', activation='relu',
input_shape=x_train.shape[1:]))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer=Adam(0.0001),
metrics=['accuracy'])
model.summary()
model.fit(x_train, y_train,
batch_size=32,
epochs=10,
validation_data=(x_test, y_test))
print('Using real-time data augmentation.')
# This will do preprocessing and realtime data augmentation:
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
# Compute quantities required for feature-wise normalization
# (std, mean, and principal components if ZCA whitening is applied).
datagen.fit(x_train)
model.fit_generator(datagen.flow(x_train, y_train,
batch_size=256),
epochs=5,
steps_per_epoch=50000/256,
validation_data=(x_test, y_test),
workers=4)
!wget https://d17h27t6h515a5.cloudfront.net/topher/2016/October/580ad86d_train/train.p
!wget https://d17h27t6h515a5.cloudfront.net/topher/2016/October/580ad89e_test/test.p
!wget https://raw.githubusercontent.com/lachezarbozhkov/traffic-signs/master/signnames.csv
# Load pickled data
import pickle
training_file = "train.p"
testing_file = "test.p"
with open(training_file, mode='rb') as f:
train = pickle.load(f)
with open(testing_file, mode='rb') as f:
test = pickle.load(f)
X_train, y_train = train['features'], train['labels']
X_test, y_test = test['features'], test['labels']
train.keys()
y_test
n_train = X_train.shape[0]
n_test = X_test.shape[0]
image_shape = X_train.shape[1:]
n_classes = np.unique(y_train).shape[0]
print("Number of training examples =", n_train)
print("Number of testing examples =", n_test)
print("Image data shape =", image_shape)
print("Number of classes =", n_classes)
signnames = pd.read_csv("signnames.csv", index_col=["ClassId"])
signnames
import math
# Plot 9 random images from train set
def plot_9_singns():
plt.figure(figsize=(14, 14))
for i in range(1, 10):
plt.subplot(3, 3, i)
img = np.random.randint(2, high=n_train)
plt.imshow(X_train[img, :, :, :])
plt.title(signnames.SignName.loc[y_train[img]])
# Plot 1st image from each class
def plot_first_image_each_class():
plt.figure(figsize=(15, 5*math.ceil(n_classes/3)))
n_freq = list(zip(*np.unique(y_train, return_counts=True)))
for i, n_ in enumerate(n_freq):
n, freq = n_
img = np.argmax(y_train == n)
plt.subplot(math.ceil(n_classes/3), 3, i+1)
plt.imshow(X_train[img,:,:,:])
plt.title(signnames.SignName.loc[y_train[img]] + ", count: " + str(freq))
def plot_labels_histogram():
plt.figure(figsize=(14,7))
plt.subplot(1,2,1)
n_freq = np.unique(y_train, return_counts=True)
plt.bar(n_freq[0], n_freq[1])
plt.title("Distribution of different type of signs - Train set")
plt.subplot(1,2,2)
n_freq = np.unique(y_test, return_counts=True)
plt.bar(n_freq[0], n_freq[1])
plt.title("Distribution of different type of signs - Test set")
plot_9_singns()
# plot_first_image_each_class()
plot_labels_histogram()
print(max(y_train))
y_train = keras.utils.to_categorical(y_train, 43)
y_test = keras.utils.to_categorical(y_test, 43)
inputs = Input(shape=(32, 32, 3,))
x = Conv2D(64, 5, padding='same', activation='elu')(inputs)
x = MaxPooling2D()(x)
x = Dropout(0.25)(x)
x = Conv2D(128, 5, padding='same', activation='elu')(x)
x = MaxPooling2D()(x)
x = Dropout(0.25)(x)
x = Conv2D(256, 5, padding='same', activation='elu')(x)
x = MaxPooling2D()(x)
x = Dropout(0.25)(x)
x = Conv2D(512, 5, padding='same', activation='elu')(x)
x = MaxPooling2D()(x)
x = Dropout(0.25)(x)
x = Flatten()(x)
x = Dense(1000, activation='elu')(x)
x = Dropout(0.25)(x)
x = Dense(43, activation='softmax')(x)
model = Model(inputs=inputs, outputs=x)
model.compile(optimizer=Adam(0.0001),
loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train,
batch_size=128,
epochs=10,
validation_data=(X_test, y_test))
import glob
files = glob.glob("signs/*")
print(files)
import os
from scipy import misc
def load_and_resize(f):
image = misc.imread(f, mode="RGB")
image = misc.imresize(image, (32,32))
return image
images = np.array([load_and_resize(f) for f in files])
print(images.shape)
plt.figure(figsize=(14, 28))
for i in range(0, 18):
plt.subplot(6, 3, i+1)
plt.imshow(images[i, :, :, :])
images_predict = images / 255 - 0.5
predictions = model.predict(images_predict)
predictions_ids = np.argmax(predictions, axis=1)
predictions_ids
plt.figure(figsize=(14, 28))
for i in range(0, 18):
plt.subplot(6, 3, i+1)
plt.imshow(images[i, :, :, :])
plt.title("Prediction: " + signnames.ix[predictions_ids[i]]['SignName'])