In [2]:
%cd /home/ubuntu/statefarm
from theano.sandbox import cuda
cuda.use('gpu0')
%matplotlib inline
from __future__ import print_function, division
path = "/home/ubuntu/statefarm/"
#path = '/home/ubuntu/statefarm/sample/'
import utils; reload(utils)
from utils import *
from IPython.display import FileLink
import skimage
from skimage import exposure, io
#import cv2
import glob
import matplotlib.image as mpimg
#from imutils.object_detection import non_max_suppression
In [3]:
%%bash
cut -f 1 -d ',' driver_imgs_list.csv | grep -v subject | uniq -c
lines=$(expr `wc -l driver_imgs_list.csv | cut -f 1 -d ' '` - 1)
echo "Got ${lines} pics"
fastai's statefarm has 3478 pics in validation set and 18946 in training, so let's get something close to that
In [4]:
import csv
import os
to_get = set(['p081','p075', 'p072', 'p066', 'p064'])
with open('driver_imgs_list.csv') as f:
next(f)
for line in csv.reader(f):
if line[0] in to_get:
if os.path.exists('train/%s/%s' %(line[1], line[2])):
os.popen('mv train/%s/%s valid/%s/%s'%(line[1], line[2], line[1], line[2]))
import glob
print('Training has', len(glob.glob('train/*/*jpg')))
print('Validation has', len(glob.glob('valid/*/*jpg')))
In [5]:
batch_size = 64
gen_t = image.ImageDataGenerator(rotation_range=15, height_shift_range=0.05,
shear_range=0.1, channel_shift_range=20, width_shift_range=0.1)
trn_batches = get_batches(path+'train', gen_t, batch_size=batch_size)
val_batches = get_batches(path+'valid', batch_size=batch_size*2, shuffle=False)
In [6]:
from vgg16bn import Vgg16BN
model = vgg_ft_bn(10)
In [7]:
model.compile(optimizer=Adam(1e-3),
loss='categorical_crossentropy', metrics=['accuracy'])
In [8]:
model.fit_generator(trn_batches, trn_batches.N, nb_epoch=3, validation_data=val_batches,
nb_val_samples=val_batches.N)
Out[8]:
In [9]:
model.optimizer.lr = 1e-5
model.fit_generator(trn_batches, trn_batches.N, nb_epoch=3, validation_data=val_batches,
nb_val_samples=val_batches.N)
Out[9]:
In [10]:
last_conv_idx = [i for i,l in enumerate(model.layers) if type(l) is Convolution2D][-1]
conv_layers = model.layers[:last_conv_idx+1]
In [11]:
conv_model = Sequential(conv_layers)
In [12]:
trn_batches = get_batches(path+'train', gen_t, batch_size=batch_size, shuffle=False)
conv_feat = conv_model.predict_generator(trn_batches, trn_batches.nb_sample)
conv_val_feat = conv_model.predict_generator(val_batches, val_batches.nb_sample)
In [13]:
save_array(path+'results/conv_val_feat.dat', conv_val_feat)
save_array(path+'results/conv_feat.dat', conv_feat)
#print(type(conv_feat))
conv_feat = load_array(path+'results/conv_feat.dat')
conv_val_feat = load_array(path+'results/conv_val_feat.dat')
print(type(conv_feat))
In [14]:
#print(conv_layers[-1].output_shape)
def get_bn_layers(p):
return [
MaxPooling2D(input_shape=conv_layers[-1].output_shape[1:]),
Flatten(),
Dropout(p),
Dense(512, activation='relu'),
BatchNormalization(),
Dropout(p),
Dense(512, activation='relu'),
BatchNormalization(),
Dropout(p),
Dense(10, activation='softmax')
]
In [15]:
p = 0.8
In [16]:
(val_classes, trn_classes, val_labels, trn_labels,
val_filenames, filenames, test_filenames) = get_classes(path)
In [17]:
bn_model = Sequential(get_bn_layers(p))
bn_model.compile(Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
In [18]:
bn_model.fit(conv_feat, trn_labels, batch_size=batch_size, nb_epoch=1,
validation_data=(conv_val_feat, val_labels))
Out[18]:
In [19]:
bn_model.optimizer.lr = 1e-7
bn_model.fit(conv_feat, trn_labels, batch_size=batch_size, nb_epoch=7,
validation_data=(conv_val_feat, val_labels))
Out[19]:
In [20]:
test_batches = get_batches(path+'test', batch_size=batch_size, shuffle=False, class_mode=None)
In [21]:
conv_test_feat = conv_model.predict_generator(test_batches, test_batches.nb_sample)
That took forever (one hour? didn't time it perfectly)
In [22]:
preds = bn_model.predict(conv_test_feat, batch_size=batch_size*2)
subm = do_clip(preds,0.93)
In [23]:
subm_name = path+'results/subm.gz'
In [24]:
classes = sorted(trn_batches.class_indices, key=trn_batches.class_indices.get)
In [25]:
submission = pd.DataFrame(subm, columns=classes)
submission.insert(0, 'img', [a[4:] for a in test_filenames])
submission.head()
submission.to_csv(subm_name, index=False, compression='gzip')
In [26]:
from IPython.display import FileLink
FileLink(subm_name)
Out[26]:
In [27]:
bn_model.save_weights(path+'models/bn_model.h5')
bn_model.load_weights(path+'models/bn_model.h5')
In [28]:
bn_feat = bn_model.predict(conv_feat, batch_size=batch_size)
bn_val_feat = bn_model.predict(conv_val_feat, batch_size=batch_size)
Let's try something else - can I look at what the model predicts for the training set?
Let's have a look at the images with a 'bad' maximum probability, around 50% - how many training pictures do we have with bad probabilities?
In [29]:
np.max(bn_feat[:,1])
Out[29]:
Give me all training pictures that don't have a class 'probability' above 90%
In [30]:
np.where(np.amax(bn_feat, axis=1) < 0.9)
Out[30]:
In [53]:
def check_training_picture(bn_feat, filenames, number):
print(bn_feat[number,:])
print(filenames[number])
plt.imshow(mpimg.imread('train/' + filenames[number]))
In [54]:
check_training_picture(bn_feat, filenames, 22)
This is marked as class0 -
c0: normal driving
c1: texting - right
c2: talking on the phone - right
c3: texting - left
c4: talking on the phone - left
c5: operating the radio
c6: drinking
c7: reaching behind
c8: hair and makeup
c9: talking to passenger
That hand is probably confusing, but it's mostly the correct class.
In [55]:
check_training_picture(bn_feat, filenames, 45)
This doesn't have any 'good' class, everything is low, which is weird - could be the not-straight head angle, but who knows. I just realised that some pictures have a blue tape-like thing on the driver window (see above and below), some pictures don't have that sheet, which is probably confusing.
In [56]:
check_training_picture(bn_feat, filenames, 17421)
This is marked as 'talking to passenger', but it may as well be c0, driving normally.
In [32]:
to_remove = np.where(np.amax(bn_feat, axis=1) < 0.9)[0]
print(len(to_remove))
print(1580./18587*100)
1580 pictures are 'weird', which is not that much compared to our 18587 pictures (roughly 8.5%)
In [38]:
to_remove_files = set([filenames[index] for index in to_remove])
list(to_remove_files)[:5]
out = open('weird_files.txt', 'w')
for f in to_remove_files:
out.write('%s\n'%f)
In [5]:
print(path)
%pwd
to_remove_files = [x.rstrip() for x in open('/home/ubuntu/statefarm/train/weird_files.txt')]
len(to_remove_files)
to_remove_files[:5]
Out[5]:
In [4]:
%%bash
mkdir weird_ones
mkdir weird_ones/train
for i in {0..9}; do mkdir /home/ubuntu/statefarm/weird_ones/train/c${i}; done
In [13]:
%cd /home/ubuntu/statefarm/train
for l in glob.glob('*/*jpg'):
if l in to_remove_files:
os.popen('mv %s ../weird_ones/train/%s'%(l, l))
In [14]:
%%bash
find . -type f | wc -l
OK we removed the weird ones.
In [15]:
path = "/home/ubuntu/statefarm/"
In [16]:
batch_size = 64
gen_t = image.ImageDataGenerator(rotation_range=15, height_shift_range=0.05,
shear_range=0.1, channel_shift_range=20, width_shift_range=0.1)
trn_batches = get_batches(path+'train', gen_t, batch_size=batch_size)
val_batches = get_batches(path+'valid', batch_size=batch_size*2, shuffle=False)
In [17]:
from vgg16bn import Vgg16BN
model = vgg_ft_bn(10)
In [18]:
model.compile(optimizer=Adam(1e-3),
loss='categorical_crossentropy', metrics=['accuracy'])
In [19]:
model.fit_generator(trn_batches, trn_batches.N, nb_epoch=3, validation_data=val_batches,
nb_val_samples=val_batches.N)
Out[19]:
In [20]:
model.optimizer.lr = 1e-5
model.fit_generator(trn_batches, trn_batches.N, nb_epoch=3, validation_data=val_batches,
nb_val_samples=val_batches.N)
Out[20]:
In [21]:
last_conv_idx = [i for i,l in enumerate(model.layers) if type(l) is Convolution2D][-1]
conv_layers = model.layers[:last_conv_idx+1]
In [22]:
conv_model = Sequential(conv_layers)
In [23]:
trn_batches = get_batches(path+'train', gen_t, batch_size=batch_size, shuffle=False)
conv_feat = conv_model.predict_generator(trn_batches, trn_batches.nb_sample)
conv_val_feat = conv_model.predict_generator(val_batches, val_batches.nb_sample)
In [24]:
#print(conv_layers[-1].output_shape)
def get_bn_layers(p):
return [
MaxPooling2D(input_shape=conv_layers[-1].output_shape[1:]),
Flatten(),
Dropout(p),
Dense(512, activation='relu'),
BatchNormalization(),
Dropout(p),
Dense(512, activation='relu'),
BatchNormalization(),
Dropout(p),
Dense(10, activation='softmax')
]
In [25]:
p = 0.8
In [26]:
(val_classes, trn_classes, val_labels, trn_labels,
val_filenames, filenames, test_filenames) = get_classes(path)
In [27]:
bn_model = Sequential(get_bn_layers(p))
bn_model.compile(Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
In [28]:
bn_model.fit(conv_feat, trn_labels, batch_size=batch_size, nb_epoch=1,
validation_data=(conv_val_feat, val_labels))
Out[28]:
In [29]:
bn_model.optimizer.lr = 1e-5
bn_model.fit(conv_feat, trn_labels, batch_size=batch_size, nb_epoch=7,
validation_data=(conv_val_feat, val_labels))
Out[29]:
In [30]:
bn_model.optimizer.lr = 1e-7
bn_model.fit(conv_feat, trn_labels, batch_size=batch_size, nb_epoch=7,
validation_data=(conv_val_feat, val_labels))
Out[30]:
In [31]:
test_batches = get_batches(path+'test', batch_size=batch_size, shuffle=False, class_mode=None)
In [32]:
conv_test_feat = conv_model.predict_generator(test_batches, test_batches.nb_sample)
That took forever (one hour? didn't time it perfectly)
In [33]:
preds = bn_model.predict(conv_test_feat, batch_size=batch_size*2)
subm = do_clip(preds,0.93)
In [34]:
subm_name = path+'results/subm_woweird.gz'
In [35]:
classes = sorted(trn_batches.class_indices, key=trn_batches.class_indices.get)
In [36]:
submission = pd.DataFrame(subm, columns=classes)
submission.insert(0, 'img', [a[4:] for a in test_filenames])
submission.head()
submission.to_csv(subm_name, index=False, compression='gzip')
In [37]:
from IPython.display import FileLink
FileLink(subm_name)
Out[37]:
In [45]:
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
img = glob.glob('train/*/*jpg')[100]
img = cv2.imread(img)
(rects, weights) = hog.detectMultiScale(img, winStride=(4, 4), padding=(8, 8), scale=1.05)
for (x, y, w, h) in rects:
cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)
rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs=None, overlapThresh=0.5)
for (xA, yA, xB, yB) in pick:
cv2.rectangle(img, (xA, yA), (xB, yB), (0, 255, 0), 2)
#plt.imshow(img)
#cv2.imshow('hi', img)
img.save('test.png')
In [ ]: