In this notebook, some template code has already been provided for you, and you will need to implement additional functionality to successfully complete this project. You will not need to modify the included code beyond what is requested. Sections that begin with '(IMPLEMENTATION)' in the header indicate that the following block of code will require additional functionality which you must provide. Instructions will be provided for each section, and the specifics of the implementation are marked in the code block with a 'TODO' statement. Please be sure to read the instructions carefully!
Note: Once you have completed all of the code implementations, you need to finalize your work by exporting the iPython Notebook as an HTML document. Before exporting the notebook to html, all of the code cells need to have been run so that reviewers can see the final implementation and output. You can then export the notebook by using the menu above and navigating to \n", "File -> Download as -> HTML (.html). Include the finished document along with this notebook as your submission.
In addition to implementing code, there will be questions that you must answer which relate to the project and your implementation. Each section where you will answer a question is preceded by a 'Question X' header. Carefully read each question and provide thorough answers in the following text boxes that begin with 'Answer:'. Your project submission will be evaluated based on your answers to each of the questions and the implementation you provide.
Note: Code and Markdown cells can be executed using the Shift + Enter keyboard shortcut. Markdown cells can be edited by double-clicking the cell to enter edit mode.
The rubric contains optional "Stand Out Suggestions" for enhancing the project beyond the minimum requirements. If you decide to pursue the "Stand Out Suggestions", you should include the code in this IPython notebook.
In this notebook, you will make the first steps towards developing an algorithm that could be used as part of a mobile or web app. At the end of this project, your code will accept any user-supplied image as input. If a dog is detected in the image, it will provide an estimate of the dog's breed. If a human is detected, it will provide an estimate of the dog breed that is most resembling. The image below displays potential sample output of your finished project (... but we expect that each student's algorithm will behave differently!).
In this real-world setting, you will need to piece together a series of models to perform different tasks; for instance, the algorithm that detects humans in an image will be different from the CNN that infers dog breed. There are many points of possible failure, and no perfect algorithm exists. Your imperfect solution will nonetheless create a fun user experience!
We break the notebook into separate steps. Feel free to use the links below to navigate the notebook.
In the code cell below, we import a dataset of dog images. We populate a few variables through the use of the load_files
function from the scikit-learn library:
train_files
, valid_files
, test_files
- numpy arrays containing file paths to imagestrain_targets
, valid_targets
, test_targets
- numpy arrays containing onehot-encoded classification labels dog_names
- list of string-valued dog breed names for translating labelsfrom sklearn.datasets import load_files
from keras.utils import np_utils
import numpy as np
from glob import glob
# define function to load train, test, and validation datasets
def load_dataset(path):
data = load_files(path)
dog_files = np.array(data['filenames'])
dog_targets = np_utils.to_categorical(np.array(data['target']), 133)
return dog_files, dog_targets
# load train, test, and validation datasets
train_files, train_targets = load_dataset('dogImages/train')
valid_files, valid_targets = load_dataset('dogImages/valid')
test_files, test_targets = load_dataset('dogImages/test')
# load list of dog names
dog_names = [item[20:-1] for item in sorted(glob("dogImages/train/*/"))]
# print statistics about the dataset
print('There are %d total dog categories.' % len(dog_names))
print('There are %s total dog images.\n' % len(np.hstack([train_files, valid_files, test_files])))
print('There are %d training dog images.' % len(train_files))
print('There are %d validation dog images.' % len(valid_files))
print('There are %d test dog images.'% len(test_files))
In the code cell below, we import a dataset of human images, where the file paths are stored in the numpy array human_files
.
import random
random.seed(8675309)
# load filenames in shuffled human dataset
human_files = np.array(glob("lfw/*/*"))
random.shuffle(human_files)
# print statistics about the dataset
print('There are %d total human images.' % len(human_files))
We use OpenCV's implementation of Haar feature-based cascade classifiers to detect human faces in images. OpenCV provides many pre-trained face detectors, stored as XML files on github. We have downloaded one of these detectors and stored it in the haarcascades
directory.
In the next code cell, we demonstrate how to use this detector to find human faces in a sample image.
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# extract pre-trained face detector
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt.xml')
# load color (BGR) image
img = cv2.imread(human_files[3])
# convert BGR image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find faces in image
faces = face_cascade.detectMultiScale(gray)
# print number of faces detected in the image
print('Number of faces detected:', len(faces))
# get bounding box for each detected face
for (x,y,w,h) in faces:
# add bounding box to color image
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
Before using any of the face detectors, it is standard procedure to convert the images to grayscale. The detectMultiScale
function executes the classifier stored in face_cascade
and takes the grayscale image as a parameter.
In the above code, faces
is a numpy array of detected faces, where each row corresponds to a detected face. Each detected face is a 1D array with four entries that specifies the bounding box of the detected face. The first two entries in the array (extracted in the above code as x
and y
) specify the horizontal and vertical positions of the top left corner of the bounding box. The last two entries in the array (extracted here as w
and h
) specify the width and height of the box.
We can use this procedure to write a function that returns True
if a human face is detected in an image and False
otherwise. This function, aptly named face_detector
, takes a string-valued file path to an image as input and appears in the code block below.
# returns "True" if face is detected in image stored at img_path
def face_detector(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
return len(faces) > 0
Question 1: Use the code cell below to test the performance of the face_detector
function.
human_files
have a detected human face? dog_files
have a detected human face?  You will see that our algorithm falls short of this goal, but still gives acceptable performance. We extract the file paths for the first 100 images from each of the datasets and store them in the numpy arrays human_files_short
and dog_files_short
.
Answer:
human_files_short = human_files[:100]
dog_files_short = train_files[:100]
# Do NOT modify the code above this line.
## TODO: Test the performance of the face_detector algorithm
human_faces_list = []
dog_faces_list = []
human_counter_t = 0
dog_counter_t = 0
human_counter_f = 0
dog_counter_f = 0
#Tests performance of human_files on face detection algorithm
for i in range(100):
human_faces_list.append(face_detector(human_files_short[i]))
if (human_faces_list[i]==True):
human_counter_t+=1
elif (human_faces_list[i]==False):
human_counter_f+=1
for i in range(100):
dog_faces_list.append(face_detector(dog_files_short[i]))
if (dog_faces_list[i]==True):
dog_counter_t+=1
elif (dog_faces_list[i]==False):
dog_counter_f+=1
print("{}% of the first 100 images in human_files have detected a human face".format(human_counter_t/(len(human_files_short))*100))
print("{}% of the first 100 images in dog_files have detected a human face".format(dog_counter_t/(len(dog_files_short))*100))
#1. 98% of the first 100 images of the human_files_short are accurately predicting a human face.
#2. 11% of human faces are detected in the dog_files_short file using the face_detector algorithm
Question 2: This algorithmic choice necessitates that we communicate to the user that we accept human images only when they provide a clear view of a face (otherwise, we risk having unneccessarily frustrated users!). In your opinion, is this a reasonable expectation to pose on the user? If not, can you think of a way to detect humans in images that does not necessitate an image with a clearly presented face?
Answer:
We suggest the face detector from OpenCV as a potential way to detect human images in your algorithm, but you are free to explore other approaches, especially approaches that make use of deep learning :). Please use the code cell below to design and test your own face detection algorithm. If you decide to pursue this optional task, report performance on each of the datasets.
#Question 2:
#Not a reasonable request.
#Users would be upset and frustrated and eventually another competitor with more dedication will win them over.
## (Optional) TODO: Report the performance of another
## face detection algorithm on the LFW dataset
### Feel free to use as many code cells as needed.
import cv2
# extract pre-trained face detector
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
smile_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_smile.xml')
#Couldn't find the .xml files =( #
#left_ear_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_mcs_leftear_alt.xml')
#right_ear_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_mcs_rightear_alt.xml')
# returns "True" if face is detected in image stored at img_path
human_files_short = human_files[:100]
dog_files_short = train_files[:100]
def face_detector_2(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
eyes = eye_cascade.detectMultiScale(gray)
smile = smile_cascade.detectMultiScale(gray)
if (len(faces)+len(eyes)+len(smile) > 1) :
return True, len(faces)+len(eyes)+len(smile)
## TODO: Test the performance of the face_detector algorithm
human_faces_list = []
dog_faces_list = []
human_counter_t = 0
dog_counter_t = 0
human_counter_f = 0
dog_counter_f = 0
face_detector_2(human_files_short[1])
faces = face_cascade.detectMultiScale(gray)
eyes = eye_cascade.detectMultiScale(gray)
smile = smile_cascade.detectMultiScale(gray)
img = cv2.imread(human_files_short[2])
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
for (x,y,w,h) in faces:
# add bounding box to color image
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
for (sx,sy,sw,sh) in smile:
cv2.rectangle(roi_color,(sx,sy),(sx+sw,sy+sh),(255,255,0),2)
# display the image, along with bounding box
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(cv_rgb)
plt.show()
print('Number of faces detected:', len(faces))
print('Number of eyes detected:', len(eyes))
print('Number of smiles detected:', len(smile))
# find faces in image
img2 = cv2.imread(dog_files_short[1])
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
faces2 = face_cascade.detectMultiScale(gray)
# print number of faces detected in the image
# get bounding box for each detected face
for (x,y,w,h) in faces2:
# add bounding box to color image
cv2.rectangle(img2,(x,y),(x+w,y+h),(255,0,255),2)
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
print('Number of faces detected:', len(faces2))
In this section, we use a pre-trained ResNet-50 model to detect dogs in images. Our first line of code downloads the ResNet-50 model, along with weights that have been trained on ImageNet, a very large, very popular dataset used for image classification and other vision tasks. ImageNet contains over 10 million URLs, each linking to an image containing an object from one of 1000 categories. Given an image, this pre-trained ResNet-50 model returns a prediction (derived from the available categories in ImageNet) for the object that is contained in the image.
from keras.applications.resnet50 import ResNet50
# define ResNet50 model
ResNet50_model = ResNet50(weights='imagenet')
When using TensorFlow as backend, Keras CNNs require a 4D array (which we'll also refer to as a 4D tensor) as input, with shape
$$ (\text{nb_samples}, \text{rows}, \text{columns}, \text{channels}), $$
where nb_samples
corresponds to the total number of images (or samples), and rows
, columns
, and channels
correspond to the number of rows, columns, and channels for each image, respectively.
The path_to_tensor
function below takes a string-valued file path to a color image as input and returns a 4D tensor suitable for supplying to a Keras CNN. The function first loads the image and resizes it to a square image that is $224 \times 224$ pixels. Next, the image is converted to an array, which is then resized to a 4D tensor. In this case, since we are working with color images, each image has three channels. Likewise, since we are processing a single image (or sample), the returned tensor will always have shape
$$ (1, 224, 224, 3). $$
The paths_to_tensor
function takes a numpy array of string-valued image paths as input and returns a 4D tensor with shape
$$ (\text{nb_samples}, 224, 224, 3). $$
Here, nb_samples
is the number of samples, or number of images, in the supplied array of image paths. It is best to think of nb_samples
as the number of 3D tensors (where each 3D tensor corresponds to a different image) in your dataset!
from keras.preprocessing import image
from tqdm import tqdm
def path_to_tensor(img_path):
# loads RGB image as PIL.Image.Image type
img = image.load_img(img_path, target_size=(224, 224))
# convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
x = image.img_to_array(img)
# convert 3D tensor to 4D tensor with shape (1, 224, 224, 3) and return 4D tensor
return np.expand_dims(x, axis=0)
def paths_to_tensor(img_paths):
list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
Getting the 4D tensor ready for ResNet-50, and for any other pre-trained model in Keras, requires some additional processing. First, the RGB image is converted to BGR by reordering the channels. All pre-trained models have the additional normalization step that the mean pixel (expressed in RGB as $[103.939, 116.779, 123.68]$ and calculated from all pixels in all images in ImageNet) must be subtracted from every pixel in each image. This is implemented in the imported function preprocess_input
. If you're curious, you can check the code for preprocess_input
here.
Now that we have a way to format our image for supplying to ResNet-50, we are now ready to use the model to extract the predictions. This is accomplished with the predict
method, which returns an array whose $i$-th entry is the model's predicted probability that the image belongs to the $i$-th ImageNet category. This is implemented in the ResNet50_predict_labels
function below.
By taking the argmax of the predicted probability vector, we obtain an integer corresponding to the model's predicted object class, which we can identify with an object category through the use of this dictionary.
from keras.applications.resnet50 import preprocess_input, decode_predictions
def ResNet50_predict_labels(img_path):
# returns prediction vector for image located at img_path
img = preprocess_input(path_to_tensor(img_path))
return np.argmax(ResNet50_model.predict(img))
While looking at the dictionary, you will notice that the categories corresponding to dogs appear in an uninterrupted sequence and correspond to dictionary keys 151-268, inclusive, to include all categories from 'Chihuahua'
to 'Mexican hairless'
. Thus, in order to check to see if an image is predicted to contain a dog by the pre-trained ResNet-50 model, we need only check if the ResNet50_predict_labels
function above returns a value between 151 and 268 (inclusive).
We use these ideas to complete the dog_detector
function below, which returns True
if a dog is detected in an image (and False
if not).
### returns "True" if a dog is detected in the image stored at img_path
def dog_detector(img_path):
prediction = ResNet50_predict_labels(img_path)
return ((prediction <= 268) & (prediction >= 151))
Question 3: Use the code cell below to test the performance of your dog_detector
function.
human_files_short
have a detected dog? dog_files_short
have a detected dog?Answer:
### TODO: Test the performance of the dog_detector function
### on the images in human_files_short and dog_files_short.
human_files_short = human_files[:100]
dog_files_short = train_files[:100]
# Do NOT modify the code above this line.
## TODO: Test the performance of the face_detector algorithm
human_faces_list = []
dog_faces_list = []
human_counter_t = 0
dog_counter_t = 0
human_counter_f = 0
dog_counter_f = 0
#Tests performance of human_files on face detection algorithm
for i in range(len(human_files_short)):
human_faces_list.append(dog_detector(human_files_short[i]))
if (human_faces_list[i]==True):
human_counter_t+=1
elif (human_faces_list[i]==False):
human_counter_f+=1
for i in range(len(dog_files_short)):
dog_faces_list.append(dog_detector(dog_files_short[i]))
if (dog_faces_list[i]==True):
dog_counter_t+=1
elif (dog_faces_list[i]==False):
dog_counter_f+=1
print("{}% of the first 100 images in human_files have detected a dog using ResNet Dog Detector".format(human_counter_t/(len(human_files_short))*100))
print("{}% of the first 100 images in dog_files have detected a dog using ResNet Dog Detector".format(dog_counter_t/(len(dog_files_short))*100))
#1. 98% of the first 100 images of the human_files_short are accurately predicting a human face.
#2. 11% of human faces are detected in the dog_files_short file using the face_detector algorithm
Now that we have functions for detecting humans and dogs in images, we need a way to predict breed from images. In this step, you will create a CNN that classifies dog breeds. You must create your CNN from scratch (so, you can't use transfer learning yet!), and you must attain a test accuracy of at least 1%. In Step 5 of this notebook, you will have the opportunity to use transfer learning to create a CNN that attains greatly improved accuracy.
Be careful with adding too many trainable layers! More parameters means longer training, which means you are more likely to need a GPU to accelerate the training process. Thankfully, Keras provides a handy estimate of the time that each epoch is likely to take; you can extrapolate this estimate to figure out how long it will take for your algorithm to train.
We mention that the task of assigning breed to dogs from images is considered exceptionally challenging. To see why, consider that even a human would have great difficulty in distinguishing between a Brittany and a Welsh Springer Spaniel.
| Brittany | Welsh Springer Spaniel |
|---|---|
It is not difficult to find other dog breed pairs with minimal inter-class variation (for instance, Curly-Coated Retrievers and American Water Spaniels).
| Curly-Coated Retriever | American Water Spaniel |
|---|---|
Likewise, recall that labradors come in yellow, chocolate, and black. Your vision-based algorithm will have to conquer this high intra-class variation to determine how to classify all of these different shades as the same breed.
| Yellow Labrador | Chocolate Labrador | Black Labrador |
|---|---|---|
We also mention that random chance presents an exceptionally low bar: setting aside the fact that the classes are slightly imabalanced, a random guess will provide a correct answer roughly 1 in 133 times, which corresponds to an accuracy of less than 1%.
Remember that the practice is far ahead of the theory in deep learning. Experiment with many different architectures, and trust your intuition. And, of course, have fun!
We rescale the images by dividing every pixel in every image by 255.
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
# pre-process the data for Keras
train_tensors = paths_to_tensor(train_files).astype('float32')/255
valid_tensors = paths_to_tensor(valid_files).astype('float32')/255
test_tensors = paths_to_tensor(test_files).astype('float32')/255
train_tensors.shape
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
model.summary()
We have imported some Python modules to get you started, but feel free to import as many modules as you need. If you end up getting stuck, here's a hint that specifies a model that trains relatively fast on CPU and attains >1% test accuracy in 5 epochs:
Question 4: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. If you chose to use the hinted architecture above, describe why you think that CNN architecture should work well for the image classification task.
Answer:
#Question 4: In general, CNN architectures work better when they are given more filters (depth) to extract nontrivial
#features from the input data. Here, I followed a similar structure provided above, and believed it would be an effective
#architecture because it is incrementally increasing the number of filters in the network, while reducing noise across each layer
#with a max pooling function, and decreasing the height & width of the dataset at each layer. This allows the neural
#network to identify the most important features in a given image. With the last MLP layer, after flattening the output of
#CNN architecture, our model can find correlations and estimate a probabiliy that an input is one of the class outputs.
#With 133 MLPs, this provides enough hidden layer units to approximate the input's complexity (given that there are 50,176 inputs into the last layer )
from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequential
model = Sequential()
### TODO: Define your architecture.
model.add(Conv2D(16, (2,2), strides=(1,1), padding='same', input_shape=train_tensors.shape[1:], activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))
model.add(Conv2D(32,(4,4), strides=(1,1), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))
model.add(Conv2D(64,(2,2), strides=(1,1), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='same'))
#model.add(GlobalAveragePooling2D())
model.add(Flatten())
model.add(Dense(133,activation='softmax'))
model.summary()
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
from keras.callbacks import ModelCheckpoint
### TODO: specify the number of epochs that you would like to use to train the model.
epochs = 5
### Do NOT modify the code below this line.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.from_scratch.hdf5',
verbose=1, save_best_only=True)
model.fit(train_tensors, train_targets,
validation_data=(valid_tensors, valid_targets),
epochs=epochs, batch_size=20, callbacks=[checkpointer], verbose=1)
model.load_weights('saved_models/weights.best.from_scratch.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 1%.
# get index of predicted dog breed for each image in test set
dog_breed_predictions = [np.argmax(model.predict(np.expand_dims(tensor, axis=0))) for tensor in test_tensors]
# report test accuracy
test_accuracy = 100*np.sum(np.array(dog_breed_predictions)==np.argmax(test_targets, axis=1))/len(dog_breed_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
bottleneck_features = np.load('bottleneck_features/DogVGG16Data.npz')
train_VGG16 = bottleneck_features['train']
valid_VGG16 = bottleneck_features['valid']
test_VGG16 = bottleneck_features['test']
The model uses the the pre-trained VGG-16 model as a fixed feature extractor, where the last convolutional output of VGG-16 is fed as input to our model. We only add a global average pooling layer and a fully connected layer, where the latter contains one node for each dog category and is equipped with a softmax.
VGG16_model = Sequential()
VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:]))
VGG16_model.add(Dense(133, activation='softmax'))
VGG16_model.summary()
VGG16_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.VGG16.hdf5',
verbose=1, save_best_only=True)
VGG16_model.fit(train_VGG16, train_targets,
validation_data=(valid_VGG16, valid_targets),
epochs=20, batch_size=20, callbacks=[checkpointer], verbose=1)
VGG16_model.load_weights('saved_models/weights.best.VGG16.hdf5')
Now, we can use the CNN to test how well it identifies breed within our test dataset of dog images. We print the test accuracy below.
# get index of predicted dog breed for each image in test set
VGG16_predictions = [np.argmax(VGG16_model.predict(np.expand_dims(feature, axis=0))) for feature in test_VGG16]
# report test accuracy
test_accuracy = 100*np.sum(np.array(VGG16_predictions)==np.argmax(test_targets, axis=1))/len(VGG16_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
from extract_bottleneck_features import *
def VGG16_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_VGG16(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = VGG16_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
You will now use transfer learning to create a CNN that can identify dog breed from images. Your CNN must attain at least 60% accuracy on the test set.
In Step 4, we used transfer learning to create a CNN using VGG-16 bottleneck features. In this section, you must use the bottleneck features from a different pre-trained model. To make things easier for you, we have pre-computed the features for all of the networks that are currently available in Keras:
The files are encoded as such:
Dog{network}Data.npz
where {network}
, in the above filename, can be one of VGG19
, Resnet50
, InceptionV3
, or Xception
. Pick one of the above architectures, download the corresponding bottleneck features, and store the downloaded file in the bottleneck_features/
folder in the repository.
In the code block below, extract the bottleneck features corresponding to the train, test, and validation sets by running the following:
bottleneck_features = np.load('bottleneck_features/Dog{network}Data.npz')
train_{network} = bottleneck_features['train']
valid_{network} = bottleneck_features['valid']
test_{network} = bottleneck_features['test']
### TODO: Obtain bottleneck features from another pre-trained CNN.
bottleneck_features=np.load('bottleneck_features/DogResnet50Data.npz')
#np.load('bottleneck_features/DogVGG16Data.npz')
train_Resnet50 = bottleneck_features['train']
valid_Resnet50 = bottleneck_features['valid']
test_Resnet50 = bottleneck_features['test']
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
<your model's name>.summary()
Question 5: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. Describe why you think the architecture is suitable for the current problem.
Answer:
#Question 5: Resnet50 is a trained CNN on Imagenet. Instead of training my own network, I leveraged transfer learning to extract
#the best features and connected a last MLP layer to correlate the Resnet50 architecture to my unique dataset. I added a global average ppooling layer
#in order to pass this output into a MLP. These last MLP ensures the RESNET50 features appply to my dataset.
#This works because the data we are working with is relatively similar to the one that Resnet50 was trained on
#(Imagenet). They are both related to images. Resnet extracted higher-order features from Imagenet and applies it
#to our particular image classifcation problem below, making it suitable for our current problem.
### TODO: Define your architecture.
Resnet50_model=Sequential()
Resnet50_model.add(GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:]))
Resnet50_model.add(Dense(133, activation='softmax'))
Resnet50_model.summary()
### TODO: Compile the model.
Resnet50_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
### TODO: Train the model.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.Resnet50.hdf5',
verbose=1, save_best_only=True)
Resnet50_model.fit(train_Resnet50, train_targets,
validation_data=(valid_Resnet50, valid_targets),
epochs=200, batch_size=20, callbacks=[checkpointer], verbose=1)
### TODO: Load the model weights with the best validation loss.
Resnet50_model.load_weights('saved_models/weights.best.Resnet50.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 60%.
### TODO: Calculate classification accuracy on the test dataset.
# get index of predicted dog breed for each image in test set
Resnet50_predictions = [np.argmax(Resnet50_model.predict(np.expand_dims(feature, axis=0))) for feature in test_Resnet50]
# report test accuracy
test_accuracy = 100*np.sum(np.array(Resnet50_predictions)==np.argmax(test_targets, axis=1))/len(Resnet50_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
Write a function that takes an image path as input and returns the dog breed (Affenpinscher
, Afghan_hound
, etc) that is predicted by your model.
Similar to the analogous function in Step 5, your function should have three steps:
dog_names
array defined in Step 0 of this notebook to return the corresponding breed.The functions to extract the bottleneck features can be found in extract_bottleneck_features.py
, and they have been imported in an earlier code cell. To obtain the bottleneck features corresponding to your chosen CNN architecture, you need to use the function
extract_{network}
where {network}
, in the above filename, should be one of VGG19
, Resnet50
, InceptionV3
, or Xception
.
### TODO: Write a function that takes a path to an image as input
### and returns the dog breed that is predicted by the model.
from extract_bottleneck_features import *
def Resnet50_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = Resnet50_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
Write an algorithm that accepts a file path to an image and first determines whether the image contains a human, dog, or neither. Then,
You are welcome to write your own functions for detecting humans and dogs in images, but feel free to use the face_detector
and dog_detector
functions developed above. You are required to use your CNN from Step 5 to predict dog breed.
Some sample output for our algorithm is provided below, but feel free to design your own user experience!
### TODO: Write your algorithm.
### Feel free to use as many code cells as needed.
def detector(img_path):
if (face_detector(img_path)==True):
x=Resnet50_predict_breed(img_path)
elif (face_detector(img_path)==False):
x=Resnet50_predict_breed(img_path)
elif(dog_detector(img_path)==True):
x=Resnet50_predict_breed(img_path)
else:
print('error')
img = cv2.imread(img_path)
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
print('You look most like a {}'.format(x))
In this section, you will take your new algorithm for a spin! What kind of dog does the algorithm think that you look like? If you have a dog, does it predict your dog's breed accurately? If you have a cat, does it mistakenly think that your cat is a dog?
Test your algorithm at least six images on your computer. Feel free to use any images you like. Use at least two human and two dog images.
Question 6: Is the output better than you expected :) ? Or worse :( ? Provide at least three possible points of improvement for your algorithm.
Answer:
## TODO: Execute your algorithm from Step 6 on
## at least 6 images on your computer.
## Feel free to use as many code cells as needed.
detector('ImagesforDLDogClassifier/Rottweiler.jpg')
detector('ImagesforDLDogClassifier/pitbull.jpg')
detector('ImagesforDLDogClassifier/Alejandra_Lievano.jpg')
detector('ImagesforDLDogClassifier/Carlos Lievano.jpg')
detector('ImagesforDLDogClassifier/Adrian_Lievano_Headshot_02_06_18.JPG')
detector('ImagesforDLDogClassifier/Daniel_Lievano.jpg')
detector('ImagesforDLDogClassifier/Eric_Ondarza.jpg')
detector('ImagesforDLDogClassifier/Gabriel_lievano.png')
detector('ImagesforDLDogClassifier/Olga_Lievano.jpg')
detector('ImagesforDLDogClassifier/Ozzy_headshot.jpg')
#Question 6: Output is slightly worse than I expected.
#If I were to improve the algorithm, I'd
#(1.) implement data augmentation, to avoid translational or rotational defects to the assignment of labels,
#(2.) increase the number of CNN layers and MLP during the transfer learning process of our model,
#(3.) Get more data on each of the dog breeds; i think that was a major reason why the algorithm didn't perform better. We had maybe 4 images per dog breed.


You have so many ways to install the Ruby and the Rails gems.
I’ll talk here about my preferred one: The RVM. Is a CLI which allows you to easily install, manage and work with multiple ruby environments. In this way, this tool makes the installation step pretty easy.
This step-by-step works well on Ubuntu distro, but will work fine in any Linux distro.
You can append “–ruby –rails” to install the latest versions from these. But we will try another approach:
Run rvm list known
to discover the current rubies available. Actually, the current version is 2.2-head.
Run rvm install 2.2-head
. It will install the Ruby 2.2 and all dependencies.
Run rvm use 2.2-head --default
. To set 2.2 as default version.
Now install the Rails: gem install rails
.
Now you have Ruby and Rails on latest verions available in your machine. Congratulations!
MongoDB is the NoSQL Database layer that we will use in our application.
Congratulations! Now you have Rails and MongoDB installed on the best way!
In the next topic, i will explain about generating a new application with Rails console and with MongoDB as default ORM.
Thanks for you attention, Cheers.


Davis Cup: Great Britain captain Leon Smith to mull over Andy Murray decision for Germany quarter-final tie
"Andy is not going to be difficult to get recalling on what needs to be done"
Captain Leon Smith will mull over whether or not to pick Andy Murray for Great Britain's Davis Cup quarter-final tie against Germany in Madrid on Friday evening.
Jamie Murray and Neal Skupski were Great Britain's heroes once again as a team missing Andy Murray defeated Kazakhstan to set up a quarter-final against Germany.
The former world No 1 ground out a dramatic victory over Dutchman Tallon Griekspoor in nearly three hours on Wednesday but was far from his best, and admitted afterwards that he was carrying extra weight and was not feeling good about his game.
Davis Cup quarter-final line-up
| Serbia | vs | Russia |
| Australia | vs | Canada |
| Great Britain | vs | Germany |
| Argentina | vs | Spain |
Smith and his players can look forward to a last-eight tie against Germany that on paper appears very tight.
There will be plenty to mull over selection-wise although Kyle Edmund has surely booked his spot in the side along with the doubles pair, leaving Smith to decide whether to recall Andy Murray ahead of Dan Evans.
Smith admitted there will be no miracle return to peak fitness, saying: "It's not going to change huge amounts. But it's important after five weeks of not playing any competitive tennis that you play a match.
"It wasn't his ideal match at all, but it was a match nonetheless, and that gets you going again. And Andy is not going to be difficult to get recalling on what needs to be done.
"It's probably quite a good thing it's a later start tomorrow. We can talk about it tomorrow, see how things are going, obviously do some practice, see how things feel, and then we can make a decision."
Germany do not possess any star names but have two strong singles options in the hugely-experienced Philipp Kohlschreiber and fast-rising Jan-Lennard Struff, while doubles pair Kevin Krawietz and Andreas Mies are the French Open champions.
Jamie Murray said: "We're really excited to be playing them in the quarter-finals. I don't think our guys will hold any fear to play them, and likewise. I think it's going to be a very evenly-matched tie."
Check our news, reports and reaction from all major tennis events by following us on skysports.com/tennis, our app for mobile devices or our Twitter account @skysportstennis.


Use this link to share the graph:
Comments, feedback, criticism, or suggestions, I'd love to hear from you! You can leave a comment on my blog or email me.


Hardwood Furniture made in the midwest
Hedge House is an independent furniture company focused on functional design and understated silhouettes. Every piece of furniture is made to order and handcrafted by local artisans.
- ★
- ★
- ★
- ★
- ★
Click here to read what our customers have to say.


Browser support
SVG sprite requires browser support for SVG fragment identifiers feature. This feature is currenty widely supported among all major web browsers, covering approximately 83.68% users.
Detailed browser support breakdown:
| Browser | Version |
|---|---|
| IE | 11 |
| Edge | 16 , 17 |
| Firefox | 58 , 59, 60, 61 |
| Safari | 11 , 11.1, Technology Preview |
| iOS Safari | 11.3 |
| Chrome | 63, 64, 65 , 66, 67, 68 |
| Chrome for Android | 64 |
| UC Browser for Android | 11.8 |
| Samsung Internet | 6.2 |


A <google-calendar-list> looks like this:
<google-calendar-list>
A <google-calendar-busy> looks like this:
<google-calendar-busy>


Annoying
Appealing
Boring
Clear
Compelling
Complex
Confusing
Cutting edge
Dated
Difficult
Disruptive
Distracting
Dull
Easy to use
Effective
Efficient
Effortless
Empowering
Engaging
Exceptional
Familiar
Fast
Flexible
Fresh
Friendly
Frustrating
Gets in the way
Hard to Use
Helpful
High quality
Impressive
Ineffective
Innovative
Inspiring
Intimidating
Intuitive
Inviting
Irrelevant
Old
Ordinary
Organized
Overwhelming
Patronizing
Poor quality
Powerful
Responsive
Rigid
Satisfying
Slow
Time-consuming
Time-Saving
Too Technical
Unapproachable
Unattractive
Uncontrollable
Understandable
Undesirable
Unpredictable
Usable
Useful
Valuable


| Package | Description |
|---|---|
| org.threeten.bp |
The main API for dates, times, instants, and durations.
|
| org.threeten.bp.chrono |
Support for calendar systems other than the default ISO.
|
| Modifier and Type | Method and Description |
|---|---|
static Clock |
Clock.fixed(Instant fixedInstant,
ZoneId zone)
Obtains a clock that always returns the same instant.
|
static Clock |
Clock.offset(Clock baseClock,
Duration offsetDuration)
Obtains a clock that returns instants from the specified clock with the
specified duration added
|
static Clock |
Clock.system(ZoneId zone)
Obtains a clock that returns the current instant using best available
system clock.
|
static Clock |
Clock.systemDefaultZone()
Obtains a clock that returns the current instant using the best available
system clock, converting to date and time using the default time-zone.
|
static Clock |
Clock.systemUTC()
Obtains a clock that returns the current instant using the best available
system clock, converting to date and time using the UTC time-zone.
|
static Clock |
Clock.tick(Clock baseClock,
Duration tickDuration)
Obtains a clock that returns instants from the specified clock truncated
to the nearest occurrence of the specified duration.
|
static Clock |
Clock.tickMinutes(ZoneId zone)
Obtains a clock that returns the current instant ticking in whole minutes
using best available system clock.
|
static Clock |
Clock.tickSeconds(ZoneId zone)
Obtains a clock that returns the current instant ticking in whole seconds
using best available system clock.
|
abstract Clock |
Clock.withZone(ZoneId zone)
Returns a copy of this clock with a different time-zone.
|
| Modifier and Type | Method and Description |
|---|---|
static ZonedDateTime |
ZonedDateTime.now(Clock clock)
Obtains the current date-time from the specified clock.
|
static YearMonth |
YearMonth.now(Clock clock)
Obtains the current year-month from the specified clock.
|
static Year |
Year.now(Clock clock)
Obtains the current year from the specified clock.
|
static OffsetTime |
OffsetTime.now(Clock clock)
Obtains the current time from the specified clock.
|
static OffsetDateTime |
OffsetDateTime.now(Clock clock)
Obtains the current date-time from the specified clock.
|
static MonthDay |
MonthDay.now(Clock clock)
Obtains the current month-day from the specified clock.
|
static LocalTime |
LocalTime.now(Clock clock)
Obtains the current time from the specified clock.
|
static LocalDateTime |
LocalDateTime.now(Clock clock)
Obtains the current date-time from the specified clock.
|
static LocalDate |
LocalDate.now(Clock clock)
Obtains the current date from the specified clock.
|
static Instant |
Instant.now(Clock clock)
Obtains the current instant from the specified clock.
|
static Clock |
Clock.offset(Clock baseClock,
Duration offsetDuration)
Obtains a clock that returns instants from the specified clock with the
specified duration added
|
static Clock |
Clock.tick(Clock baseClock,
Duration tickDuration)
Obtains a clock that returns instants from the specified clock truncated
to the nearest occurrence of the specified duration.
|
| Modifier and Type | Method and Description |
|---|---|
ThaiBuddhistDate |
ThaiBuddhistChronology.dateNow(Clock clock) |
MinguoDate |
MinguoChronology.dateNow(Clock clock) |
JapaneseDate |
JapaneseChronology.dateNow(Clock clock) |
LocalDate |
IsoChronology.dateNow(Clock clock)
Obtains the current ISO local date from the specified clock.
|
HijrahDate |
HijrahChronology.dateNow(Clock clock) |
ChronoLocalDate |
Chronology.dateNow(Clock clock)
Obtains the current local date in this chronology from the specified clock.
|
static ThaiBuddhistDate |
ThaiBuddhistDate.now(Clock clock)
Obtains the current
ThaiBuddhistDate from the specified clock. |
static MinguoDate |
MinguoDate.now(Clock clock)
Obtains the current
MinguoDate from the specified clock. |
static JapaneseDate |
JapaneseDate.now(Clock clock)
Obtains the current
JapaneseDate from the specified clock. |
static HijrahDate |
HijrahDate.now(Clock clock)
Obtains the current
HijrahDate of the Islamic Umm Al-Qura calendar
from the specified clock. |
Copyright © 2007–2017 ThreeTen.org. All rights reserved.


Presentation installation notes
This presentation was authored using Markdown. The website is produce with standard Unix commands and three open source utilities I wrote–
- findfile locates the files needed to build site and presentation
- md2slides converts a single markdown file into a series of HTML pages that serve as slides.
- shorthand converts the markdown applying templating for the website
This these are all available you should be able to run the Makefile and
build your own copy of the website.


--- layout: post title: Episode 042 | /\ndy Hunt - Pragmatic and Awesome link: http://traffic.libsyn.com/developeronfire/DeveloperOnFire-42-AndyHunt.mp3 length: 65011712 speaker: Dave Rael duration: '01:08:24' subtitle: 'Developer On Fire: Andy Hunt' guest_name: Andy Hunt image: /assets/images/AndyHunt.png guest_blog: http://toolshed.com/ guest_twitter: PragmaticAndy disqus_url: http://developeronfire.com/Podcast/Episodes/ndy-hunt-pragmatic-and-awesome episode_number: 42 redirect_from: - "/42/" - "/042/" - "/0042/" - "/ndy-hunt-pragmatic-and-awesome/" - "/Andy-Hunt/" - "/AndyHunt/" - "/Podcast/Episodes/42/" - "/Podcast/Episodes/042/" - "/Podcast/Episodes/0042/" - "/Podcast/Episodes/ndy-hunt-pragmatic-and-awesome/" - "/Podcast/Episodes/Andy-Hunt/" - "/Podcast/Episodes/AndyHunt/" guid: http://developeronfire.com:80/Podcast/Episodes/ndy-hunt-pragmatic-and-awesome ---
Andy Hunt is an author and publisher, avid musician, and sometimes woodworker. When not making noise or firewood he occasionally speaks at conferences. He has been active in the field of software development since before the @ sign. He co-authored The Pragmatic Programmer with Dave as well as seven other titles, was an author of the Agile Manifesto, and tweets random bits about code, life, and zen at @PragmaticAndy.
1. Determine the context
2. Always ask why
3. Interact with the people who know


Popular Searches
Rappers huh. You got it
We've all been there
One for screeching vocals and bludgeoning beats


Decimals - Fraction Converter
Made by Rishi Vaka 7C
For science fair
Click the button for further instructions
Click me for further instructions
≈


--- layout: page title: About Me description: This is what I do. background: '/img/AboutMe.jpg' ---
I am a data science leader in tech space with 15+ years of Data Science & Analytics experience. My areas of expertise include and not limited to Sales & Marketing, Life Sciences and CPG industries.
I graduated with Bachelor in Finance, Mathematics and Economics from Saint Elizabeth's College. My heart was set on working on Wall Street after graduation. However, the universe had other plans. I graduated during the Recession and jobs in finance industry were hard to come by, especially for recent college graduates. I ended up taking a job in Technical Data Management at Cadbury Adams. Over there I met a statistican who inspired me to go back to graduate school for a degree in Applied Mathematics and the rest is history. Since then I have worked at a diverse set of companies ranging from start ups to Fortune 500 companies.
In my spare time, I love to travel, garden and hike.


What Cannot Be Represented by Bits? (Uncountable Sets)
Schedule Reminders: Problem Set 1 is due this Friday (4:19pm). See the schedule for updated office hours.
Here is Cantor’s original proof (in German, but the math is universal, so somewhat understandable even without knowing German):
Georg Cantor, Ueber eine elementare Frage der Mannigfaltigkeitslehre. Published in Jahresbericht der Deutschen Mathematiker-Vereinigung, Volume 1, 1891. (About this Scan)
Its only a bit over 2 pages long, and its easy to see Cantor’s answer to the ``Is 0 a Natural Number?’’ question without understanding any German. Google translates the title as On an elementary question of the theory of manifolds.
Barrow’s The Infinite Book has chapter on the sad life of Georg Cantor: The Madness of Georg Cantor.
We went through the proof that the binary strings are uncountable pretty quickly, and this is definitely a mind-blowing result. If you are not bothered by this result, its probably because you aren’t thinking about things deeply enough. Some other recommended presentations of these topics include:
-
Vi Hart video’s on Proof some infinities are bigger than other infinities and How many kinds of infinity are there? (sample youtube comment: watching this makes me feel like i’ve just taken the red pill and the blue pill, crushed them into a single, purple powder and snorted it).
-
Numberphile’s, Infinity is bigger than you think.
-
You can also see how Prof. Mahmoody and I covered this in cs2102 over these three classes (which overlaps a fair bit with what we’ve done in cs3102, but with more detail and examples): Class 17: Infinite Sets [Video], Class 18: Spooky Infinities [Video], Class 19: Reviewing Infinities [Video].


GLIB-COMPILE-SCHEM(1) User Commands GLIB-COMPILE-SCHEM(1) NAME glib-compile-schemas - GSettings schema compiler SYNOPSIS glib-compile-schemas [option...] {directory} DESCRIPTION glib-compile-schemas compiles all the GSettings XML schema files in directory into a binary file with the name gschemas.compiled that can be used by GSettings. The XML schema files must have the filename extension .gschema.xml. For a detailed description of the XML file format, see the GSettings documentation. At runtime, GSettings looks for schemas in the glib-2.0/schemas subdirectories of all directories specified in the XDG_DATA_DIRS environment variable. The usual location to install schema files is /usr/share/glib-2.0/schemas. In addition to schema files, glib-compile-schemas reads 'vendor override' files, which are key files that can override default values for keys in the schemas. The group names in the key files are the schema id, and the values are written in serialized GVariant form. Vendor override files must have the filename extension .gschema.override. By convention, vendor override files begin with nn_ where nn is a number from 00 to 99. Higher numbered files have higher priority (eg: if the same override is made in a file numbered 10 and then again in a file numbered 20, the override from 20 will take precedence). Options -h, --help Print help and exit --targetdir=TARGETDIR Store gschemas.compiled in TARGETDIR instead of directory. --dry-run Don't write gschemas.compiled. This option can be used to check .gschema.xml sources for errors. --allow-any-name Do not enforce restrictions on key names. Note that this option is purely to facility the transition from GConf, and will be removed at some time in the future. SEE ALSO User Commands 07/14/2012 GLIB-COMPILE-SCHEM(1)


Mississippi Democrat Mike Espy Launches 2020 Senate Run
by ERIK DE LA GARZA(CN) – Democrat Mike Espy on Tuesday announced his run for the Mississippi Senate seat he sought in a tight special election last year, setting up a potential 2020 rematch with Republican Cindy Hyde-Smith, who was dogged by controversy for a remark expressing a willingness to attend a public hanging.
Espy, 65, rose to national prominence after being elected the state’s first African-American congressman in 1986, before going on to serve as secretary of agriculture under President Bill Clinton. He said in a video announcing his candidacy Tuesday that he was running for the U.S. Senate because progress in Mississippi “is still too slow.”
“And we can’t continue the change we need if we have a senator who openly laughs about public hangings and makes statements supporting voter suppression. Cindy Hyde-Smith is hurting Mississippi, our progress and our reputation,” Espy said in the nearly three-minute video.
Hyde-Smith, a former state agriculture commissioner appointed to fill the late Senator Thad Cochran’s seat on an interim basis, defeated Espy by nearly 8 percentage points in the 2018 special election, becoming Mississippi’s first woman elected to Congress.
She had been expected to easily cruise to victory in the conservative state that President Donald Trump carried by 18 points in 2016, but allegations of racism shifted focus to her background and the state’s own history of racial discrimination and lynching.
The controversy ignited after a video surfaced showing Hyde-Smith joking about her willingness to attend a public hanging, telling a crowd about a political supporter: “If he invited me to a public hanging, I’d be on the front row.”
She later apologized, but Espy’s campaign seized the opportunity to turn the remarks into momentum. He received last-minute support from prominent Democratic figures and national fundraising groups pumping enthusiasm and cash into the tighter-than-expected race.
But even help from President Barack Obama wasn’t enough to mobilize Democratic voters to push Espy across the finish line. Mississippi has not elected a Democrat to the U.S. Senate since 1982 and has never elected a black senator since the Reconstruction Era after the Civil War.
“We came so close in 2018. Join me, this time we’ll do it,” Espy said in his video.
Hyde-Smith said in a statement Tuesday afternoon that she looks forward to the race.
“As the 2020 campaign approaches, I look forward to discussing once again with Mississippi voters our vision for the best ways to move our state and country forward,” she said. “I’m proud to have helped lead efforts to transform our federal courts with conservative judges, improve border security, continue modernizing our military, and pass pro-growth policies that have created new jobs and better wages.”
Trump endorsed Hyde-Smith’s reelection bid on Twitter in July.
She is serving out the remainder of Cochran’s term through 2021. Cochran resigned in April 2018 due to health issues, and passed away this year.
Copyright © 2019 courthousenews.com


---
layout: post
title: 'Indiana Jones and the Kingdom of the Crystal Skull: The Abridged Script'
date: '2008-06-20T22:19:03+01:00'
tags: []
tumblr_url: http://backlog.robbevan.com/post/39207372/indiana-jones-and-the-kingdom-of-the-crystal
---
Indiana Jones and the Kingdom of the Crystal Skull: The Abridged Script


In this notebook, some template code has already been provided for you, and you will need to implement additional functionality to successfully complete this project. You will not need to modify the included code beyond what is requested. Sections that begin with '(IMPLEMENTATION)' in the header indicate that the following block of code will require additional functionality which you must provide. Instructions will be provided for each section, and the specifics of the implementation are marked in the code block with a 'TODO' statement. Please be sure to read the instructions carefully!
Note: Once you have completed all of the code implementations, you need to finalize your work by exporting the iPython Notebook as an HTML document. Before exporting the notebook to html, all of the code cells need to have been run so that reviewers can see the final implementation and output. You can then export the notebook by using the menu above and navigating to \n", "File -> Download as -> HTML (.html). Include the finished document along with this notebook as your submission.
In addition to implementing code, there will be questions that you must answer which relate to the project and your implementation. Each section where you will answer a question is preceded by a 'Question X' header. Carefully read each question and provide thorough answers in the following text boxes that begin with 'Answer:'. Your project submission will be evaluated based on your answers to each of the questions and the implementation you provide.
Note: Code and Markdown cells can be executed using the Shift + Enter keyboard shortcut. Markdown cells can be edited by double-clicking the cell to enter edit mode.
The rubric contains optional "Stand Out Suggestions" for enhancing the project beyond the minimum requirements. If you decide to pursue the "Stand Out Suggestions", you should include the code in this IPython notebook.
In this notebook, you will make the first steps towards developing an algorithm that could be used as part of a mobile or web app. At the end of this project, your code will accept any user-supplied image as input. If a dog is detected in the image, it will provide an estimate of the dog's breed. If a human is detected, it will provide an estimate of the dog breed that is most resembling. The image below displays potential sample output of your finished project (... but we expect that each student's algorithm will behave differently!).
In this real-world setting, you will need to piece together a series of models to perform different tasks; for instance, the algorithm that detects humans in an image will be different from the CNN that infers dog breed. There are many points of possible failure, and no perfect algorithm exists. Your imperfect solution will nonetheless create a fun user experience!
We break the notebook into separate steps. Feel free to use the links below to navigate the notebook.
In the code cell below, we import a dataset of dog images. We populate a few variables through the use of the load_files
function from the scikit-learn library:
train_files
, valid_files
, test_files
- numpy arrays containing file paths to imagestrain_targets
, valid_targets
, test_targets
- numpy arrays containing onehot-encoded classification labels dog_names
- list of string-valued dog breed names for translating labelsfrom sklearn.datasets import load_files
from keras.utils import np_utils
import numpy as np
from glob import glob
# define function to load train, test, and validation datasets
def load_dataset(path):
data = load_files(path)
dog_files = np.array(data['filenames'])
dog_targets = np_utils.to_categorical(np.array(data['target']), 133)
return dog_files, dog_targets
# load train, test, and validation datasets
train_files, train_targets = load_dataset('dogImages/train')
valid_files, valid_targets = load_dataset('dogImages/valid')
test_files, test_targets = load_dataset('dogImages/test')
# load list of dog names
dog_names = [item[20:-1] for item in sorted(glob("dogImages/train/*/"))]
# print statistics about the dataset
print('There are %d total dog categories.' % len(dog_names))
print('There are %s total dog images.\n' % len(np.hstack([train_files, valid_files, test_files])))
print('There are %d training dog images.' % len(train_files))
print('There are %d validation dog images.' % len(valid_files))
print('There are %d test dog images.'% len(test_files))
In the code cell below, we import a dataset of human images, where the file paths are stored in the numpy array human_files
.
import random
random.seed(8675309)
# load filenames in shuffled human dataset
human_files = np.array(glob("lfw/*/*"))
random.shuffle(human_files)
# print statistics about the dataset
print('There are %d total human images.' % len(human_files))
We use OpenCV's implementation of Haar feature-based cascade classifiers to detect human faces in images. OpenCV provides many pre-trained face detectors, stored as XML files on github. We have downloaded one of these detectors and stored it in the haarcascades
directory.
In the next code cell, we demonstrate how to use this detector to find human faces in a sample image.
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# extract pre-trained face detector
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt.xml')
# load color (BGR) image
img = cv2.imread(human_files[3])
# convert BGR image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find faces in image
faces = face_cascade.detectMultiScale(gray)
# print number of faces detected in the image
print('Number of faces detected:', len(faces))
# get bounding box for each detected face
for (x,y,w,h) in faces:
# add bounding box to color image
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# convert BGR image to RGB for plotting
cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# display the image, along with bounding box
plt.imshow(cv_rgb)
plt.show()
Before using any of the face detectors, it is standard procedure to convert the images to grayscale. The detectMultiScale
function executes the classifier stored in face_cascade
and takes the grayscale image as a parameter.
In the above code, faces
is a numpy array of detected faces, where each row corresponds to a detected face. Each detected face is a 1D array with four entries that specifies the bounding box of the detected face. The first two entries in the array (extracted in the above code as x
and y
) specify the horizontal and vertical positions of the top left corner of the bounding box. The last two entries in the array (extracted here as w
and h
) specify the width and height of the box.
We can use this procedure to write a function that returns True
if a human face is detected in an image and False
otherwise. This function, aptly named face_detector
, takes a string-valued file path to an image as input and appears in the code block below.
# returns "True" if face is detected in image stored at img_path
def face_detector(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
return len(faces) > 0
Question 1: Use the code cell below to test the performance of the face_detector
function.
human_files
have a detected human face? dog_files
have a detected human face?  You will see that our algorithm falls short of this goal, but still gives acceptable performance. We extract the file paths for the first 100 images from each of the datasets and store them in the numpy arrays human_files_short
and dog_files_short
.
Answer:
human_files_short = human_files[:100]
dog_files_short = train_files[:100]
# Do NOT modify the code above this line.
## TODO: Test the performance of the face_detector algorithm
## on the images in human_files_short and dog_files_short.
human_hit = 0
dog_hit = 0
for item in human_files_short:
if face_detector(item):
human_hit += 1
for item in dog_files_short:
if face_detector(item):
dog_hit += 1
print("Human detection %s"%(human_hit*100/100))
print("Dog detection %s"%(dog_hit*100/100))
Question 2: This algorithmic choice necessitates that we communicate to the user that we accept human images only when they provide a clear view of a face (otherwise, we risk having unneccessarily frustrated users!). In your opinion, is this a reasonable expectation to pose on the user? If not, can you think of a way to detect humans in images that does not necessitate an image with a clearly presented face?
Answer: Usually images are not perfect, and asking for users to upload severl times is not a good approach. My suggestion is to use deep learning models which can scan different parts of each images, and, with a properly size of examples is able to identify images that is not so clear. In the other hand, we can do some preprocessing steps using visual computing, to adjust color, britghness, size, cropping, etc. Delegate to deep learning models to discover everything will require too many effort, time and tunning.
We suggest the face detector from OpenCV as a potential way to detect human images in your algorithm, but you are free to explore other approaches, especially approaches that make use of deep learning :). Please use the code cell below to design and test your own face detection algorithm. If you decide to pursue this optional task, report performance on each of the datasets.
## (Optional) TODO: Report the performance of another
## face detection algorithm on the LFW dataset
### Feel free to use as many code cells as needed.
# The Face Recognition library from https://github.com/ageitgey/face_recognition it is a
# good alternative from OpenCV that uses Deep Learning.
from PIL import Image
import face_recognition
from matplotlib import pyplot as plt
# Load the jpg file into a numpy array
image_face = face_recognition.load_image_file(human_files[0])
# Find all the faces in the image using the default HOG-based model.
# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.
face_locations = face_recognition.face_locations(image_face)
print("Detected {} face(s) in this image.".format(len(face_locations)))
for face_location in face_locations:
# Print the location of each face in this image
top, right, bottom, left = face_location
print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
# You can access the actual face itself like this:
face_image = image_face[top:bottom, left:right]
plt.imshow(face_image)
plt.suptitle('Face Detected')
plt.show()
plt.imshow(image_face)
plt.suptitle('Original Picutre')
plt.show()
In this section, we use a pre-trained ResNet-50 model to detect dogs in images. Our first line of code downloads the ResNet-50 model, along with weights that have been trained on ImageNet, a very large, very popular dataset used for image classification and other vision tasks. ImageNet contains over 10 million URLs, each linking to an image containing an object from one of 1000 categories. Given an image, this pre-trained ResNet-50 model returns a prediction (derived from the available categories in ImageNet) for the object that is contained in the image.
from keras.applications.resnet50 import ResNet50
# define ResNet50 model
ResNet50_model = ResNet50(weights='imagenet')
When using TensorFlow as backend, Keras CNNs require a 4D array (which we'll also refer to as a 4D tensor) as input, with shape
$$ (\text{nb_samples}, \text{rows}, \text{columns}, \text{channels}), $$where nb_samples
corresponds to the total number of images (or samples), and rows
, columns
, and channels
correspond to the number of rows, columns, and channels for each image, respectively.
The path_to_tensor
function below takes a string-valued file path to a color image as input and returns a 4D tensor suitable for supplying to a Keras CNN. The function first loads the image and resizes it to a square image that is $224 \times 224$ pixels. Next, the image is converted to an array, which is then resized to a 4D tensor. In this case, since we are working with color images, each image has three channels. Likewise, since we are processing a single image (or sample), the returned tensor will always have shape
The paths_to_tensor
function takes a numpy array of string-valued image paths as input and returns a 4D tensor with shape
Here, nb_samples
is the number of samples, or number of images, in the supplied array of image paths. It is best to think of nb_samples
as the number of 3D tensors (where each 3D tensor corresponds to a different image) in your dataset!
from keras.preprocessing import image
from tqdm import tqdm
def path_to_tensor(img_path):
# loads RGB image as PIL.Image.Image type
img = image.load_img(img_path, target_size=(224, 224))
# convert PIL.Image.Image type to 3D tensor with shape (224, 224, 3)
x = image.img_to_array(img)
# convert 3D tensor to 4D tensor with shape (1, 224, 224, 3) and return 4D tensor
return np.expand_dims(x, axis=0)
def paths_to_tensor(img_paths):
list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
Getting the 4D tensor ready for ResNet-50, and for any other pre-trained model in Keras, requires some additional processing. First, the RGB image is converted to BGR by reordering the channels. All pre-trained models have the additional normalization step that the mean pixel (expressed in RGB as $[103.939, 116.779, 123.68]$ and calculated from all pixels in all images in ImageNet) must be subtracted from every pixel in each image. This is implemented in the imported function preprocess_input
. If you're curious, you can check the code for preprocess_input
here.
Now that we have a way to format our image for supplying to ResNet-50, we are now ready to use the model to extract the predictions. This is accomplished with the predict
method, which returns an array whose $i$-th entry is the model's predicted probability that the image belongs to the $i$-th ImageNet category. This is implemented in the ResNet50_predict_labels
function below.
By taking the argmax of the predicted probability vector, we obtain an integer corresponding to the model's predicted object class, which we can identify with an object category through the use of this dictionary.
from keras.applications.resnet50 import preprocess_input, decode_predictions
def ResNet50_predict_labels(img_path):
# returns prediction vector for image located at img_path
img = preprocess_input(path_to_tensor(img_path))
return np.argmax(ResNet50_model.predict(img))
While looking at the dictionary, you will notice that the categories corresponding to dogs appear in an uninterrupted sequence and correspond to dictionary keys 151-268, inclusive, to include all categories from 'Chihuahua'
to 'Mexican hairless'
. Thus, in order to check to see if an image is predicted to contain a dog by the pre-trained ResNet-50 model, we need only check if the ResNet50_predict_labels
function above returns a value between 151 and 268 (inclusive).
We use these ideas to complete the dog_detector
function below, which returns True
if a dog is detected in an image (and False
if not).
### returns "True" if a dog is detected in the image stored at img_path
def dog_detector(img_path):
prediction = ResNet50_predict_labels(img_path)
return ((prediction <= 268) & (prediction >= 151))
Question 3: Use the code cell below to test the performance of your dog_detector
function.
human_files_short
have a detected dog? dog_files_short
have a detected dog?Answer:
### TODO: Test the performance of the dog_detector function
### on the images in human_files_short and dog_files_short.
human_hit = 0
dog_hit = 0
for item in human_files_short:
if dog_detector(item):
human_hit += 1
for item in dog_files_short:
if dog_detector(item):
dog_hit += 1
print("Human detection %s"%(human_hit*100/100))
print("Dog detection %s"%(dog_hit*100/100))
Now that we have functions for detecting humans and dogs in images, we need a way to predict breed from images. In this step, you will create a CNN that classifies dog breeds. You must create your CNN from scratch (so, you can't use transfer learning yet!), and you must attain a test accuracy of at least 1%. In Step 5 of this notebook, you will have the opportunity to use transfer learning to create a CNN that attains greatly improved accuracy.
Be careful with adding too many trainable layers! More parameters means longer training, which means you are more likely to need a GPU to accelerate the training process. Thankfully, Keras provides a handy estimate of the time that each epoch is likely to take; you can extrapolate this estimate to figure out how long it will take for your algorithm to train.
We mention that the task of assigning breed to dogs from images is considered exceptionally challenging. To see why, consider that even a human would have great difficulty in distinguishing between a Brittany and a Welsh Springer Spaniel.
| Brittany | Welsh Springer Spaniel |
|---|---|
It is not difficult to find other dog breed pairs with minimal inter-class variation (for instance, Curly-Coated Retrievers and American Water Spaniels).
| Curly-Coated Retriever | American Water Spaniel |
|---|---|
Likewise, recall that labradors come in yellow, chocolate, and black. Your vision-based algorithm will have to conquer this high intra-class variation to determine how to classify all of these different shades as the same breed.
| Yellow Labrador | Chocolate Labrador | Black Labrador |
|---|---|---|
We also mention that random chance presents an exceptionally low bar: setting aside the fact that the classes are slightly imabalanced, a random guess will provide a correct answer roughly 1 in 133 times, which corresponds to an accuracy of less than 1%.
Remember that the practice is far ahead of the theory in deep learning. Experiment with many different architectures, and trust your intuition. And, of course, have fun!
We rescale the images by dividing every pixel in every image by 255.
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
# pre-process the data for Keras
train_tensors = paths_to_tensor(train_files).astype('float32')/255
valid_tensors = paths_to_tensor(valid_files).astype('float32')/255
test_tensors = paths_to_tensor(test_files).astype('float32')/255
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
model.summary()
We have imported some Python modules to get you started, but feel free to import as many modules as you need. If you end up getting stuck, here's a hint that specifies a model that trains relatively fast on CPU and attains >1% test accuracy in 5 epochs:
Question 4: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. If you chose to use the hinted architecture above, describe why you think that CNN architecture should work well for the image classification task.
It was choosen a set of layers with different filters in order to try to understand better each image and extract usefull features to be able to classifify properly. Using more layers the trainig and classificiation stages could spend time, so we need to balance this choice.
Answer:
from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequential
model = Sequential()
### TODO: Define your architecture.
model.add(Conv2D(filters=8, kernel_size=2, padding="same", activation="relu", input_shape=(224, 224, 3)))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=16, kernel_size=2, padding="same", activation="relu"))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=32, kernel_size=2, padding="same", activation="relu"))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding="same", activation="relu"))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=128, kernel_size=2, padding="same", activation="relu"))
model.add(MaxPooling2D(pool_size=2))
model.add(Flatten())
model.add(Dense(300, activation="relu"))
model.add(Dense(133, activation="softmax"))
model.summary()
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
from keras.callbacks import ModelCheckpoint
from keras.callbacks import EarlyStopping
early_stopping_monitor = EarlyStopping(patience=2)
### TODO: specify the number of epochs that you would like to use to train the model.
epochs = 5
### Do NOT modify the code below this line.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.from_scratch.hdf5',
verbose=1, save_best_only=True)
model.fit(train_tensors, train_targets,
validation_data=(valid_tensors, valid_targets),
epochs=epochs, batch_size=20, callbacks=[checkpointer, early_stopping_monitor], verbose=1)
model.load_weights('saved_models/weights.best.from_scratch.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 1%.
# get index of predicted dog breed for each image in test set
dog_breed_predictions = [np.argmax(model.predict(np.expand_dims(tensor, axis=0))) for tensor in test_tensors]
# report test accuracy
test_accuracy = 100*np.sum(np.array(dog_breed_predictions)==np.argmax(test_targets, axis=1))/len(dog_breed_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
bottleneck_features = np.load('bottleneck_features/DogVGG16Data.npz')
train_VGG16 = bottleneck_features['train']
valid_VGG16 = bottleneck_features['valid']
test_VGG16 = bottleneck_features['test']
The model uses the the pre-trained VGG-16 model as a fixed feature extractor, where the last convolutional output of VGG-16 is fed as input to our model. We only add a global average pooling layer and a fully connected layer, where the latter contains one node for each dog category and is equipped with a softmax.
VGG16_model = Sequential()
VGG16_model.add(GlobalAveragePooling2D(input_shape=train_VGG16.shape[1:]))
VGG16_model.add(Dense(133, activation='softmax'))
VGG16_model.summary()
VGG16_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.VGG16.hdf5',
verbose=1, save_best_only=True)
VGG16_model.fit(train_VGG16, train_targets,
validation_data=(valid_VGG16, valid_targets),
epochs=20, batch_size=20, callbacks=[checkpointer], verbose=1)
VGG16_model.load_weights('saved_models/weights.best.VGG16.hdf5')
Now, we can use the CNN to test how well it identifies breed within our test dataset of dog images. We print the test accuracy below.
# get index of predicted dog breed for each image in test set
VGG16_predictions = [np.argmax(VGG16_model.predict(np.expand_dims(feature, axis=0))) for feature in test_VGG16]
# report test accuracy
test_accuracy = 100*np.sum(np.array(VGG16_predictions)==np.argmax(test_targets, axis=1))/len(VGG16_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
from extract_bottleneck_features import *
def VGG16_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_VGG16(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = VGG16_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)]
You will now use transfer learning to create a CNN that can identify dog breed from images. Your CNN must attain at least 60% accuracy on the test set.
In Step 4, we used transfer learning to create a CNN using VGG-16 bottleneck features. In this section, you must use the bottleneck features from a different pre-trained model. To make things easier for you, we have pre-computed the features for all of the networks that are currently available in Keras:
The files are encoded as such:
Dog{network}Data.npz
where {network}
, in the above filename, can be one of VGG19
, Resnet50
, InceptionV3
, or Xception
. Pick one of the above architectures, download the corresponding bottleneck features, and store the downloaded file in the bottleneck_features/
folder in the repository.
In the code block below, extract the bottleneck features corresponding to the train, test, and validation sets by running the following:
bottleneck_features = np.load('bottleneck_features/Dog{network}Data.npz')
train_{network} = bottleneck_features['train']
valid_{network} = bottleneck_features['valid']
test_{network} = bottleneck_features['test']
### TODO: Obtain bottleneck features from another pre-trained CNN.
bottleneck_features = np.load('bottleneck_features/DogResnet50Data.npz')
train_Resnet50 = bottleneck_features['train']
valid_Resnet50 = bottleneck_features['valid']
test_Resnet50 = bottleneck_features['test']
Create a CNN to classify dog breed. At the end of your code cell block, summarize the layers of your model by executing the line:
<your model's name>.summary()
Question 5: Outline the steps you took to get to your final CNN architecture and your reasoning at each step. Describe why you think the architecture is suitable for the current problem.
Answer:
This pre-trained model does not require more layers, just a global average for the input layer and dense with softmax activation for probabilities of each class, as result
### TODO: Define your architecture.
Resnet50_model = Sequential()
Resnet50_model.add(GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:]))
Resnet50_model.add(Dense(133, activation='softmax'))
Resnet50_model.summary()
### TODO: Compile the model.
Resnet50_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
Train your model in the code cell below. Use model checkpointing to save the model that attains the best validation loss.
You are welcome to augment the training data, but this is not a requirement.
### TODO: Train the model.
checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.Resnet50.hdf5',
verbose=1, save_best_only=True)
Resnet50_model.fit(train_Resnet50, train_targets,
validation_data=(valid_Resnet50, valid_targets),
epochs=40, batch_size=20, callbacks=[checkpointer], verbose=1)
### TODO: Load the model weights with the best validation loss.
Resnet50_model.load_weights('saved_models/weights.best.Resnet50.hdf5')
Try out your model on the test dataset of dog images. Ensure that your test accuracy is greater than 60%.
### TODO: Calculate classification accuracy on the test dataset.
# get index of predicted dog breed for each image in test set
Resnet50_predictions = [np.argmax(Resnet50_model.predict(np.expand_dims(feature, axis=0))) for feature in test_Resnet50]
# report test accuracy
test_accuracy = 100*np.sum(np.array(Resnet50_predictions)==np.argmax(test_targets, axis=1))/len(Resnet50_predictions)
print('Test accuracy: %.4f%%' % test_accuracy)
Write a function that takes an image path as input and returns the dog breed (Affenpinscher
, Afghan_hound
, etc) that is predicted by your model.
Similar to the analogous function in Step 5, your function should have three steps:
dog_names
array defined in Step 0 of this notebook to return the corresponding breed.The functions to extract the bottleneck features can be found in extract_bottleneck_features.py
, and they have been imported in an earlier code cell. To obtain the bottleneck features corresponding to your chosen CNN architecture, you need to use the function
extract_{network}
where {network}
, in the above filename, should be one of VGG19
, Resnet50
, InceptionV3
, or Xception
.
### TODO: Write a function that takes a path to an image as input
### and returns the dog breed that is predicted by the model.
def Resnet50_predict_breed(img_path):
# extract bottleneck features
bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))
# obtain predicted vector
predicted_vector = Resnet50_model.predict(bottleneck_feature)
# return dog breed that is predicted by the model
return dog_names[np.argmax(predicted_vector)], np.max(predicted_vector)
Write an algorithm that accepts a file path to an image and first determines whether the image contains a human, dog, or neither. Then,
You are welcome to write your own functions for detecting humans and dogs in images, but feel free to use the face_detector
and dog_detector
functions developed above. You are required to use your CNN from Step 5 to predict dog breed.
Some sample output for our algorithm is provided below, but feel free to design your own user experience!
### TODO: Write your algorithm.
### Feel free to use as many code cells as needed.
def detect_image(img):
image_face = face_recognition.load_image_file(img)
face_locations = face_recognition.face_locations(image_face, model="cnn")
if len(face_locations) > 0:
return "human"
else:
race, prob = Resnet50_predict_breed(img)
if prob >0.3:
return race + "(" + str(prob) + ")"
else:
return "neither"
In this section, you will take your new algorithm for a spin! What kind of dog does the algorithm think that you look like? If you have a dog, does it predict your dog's breed accurately? If you have a cat, does it mistakenly think that your cat is a dog?
Test your algorithm at least six images on your computer. Feel free to use any images you like. Use at least two human and two dog images.
Question 6: Is the output better than you expected :) ? Or worse :( ? Provide at least three possible points of improvement for your algorithm.
Answer: The output was really good to deal with human or dog images. But, with a small set of random images, due to some patterns of colors there were some misclassifications. Investing time to study other pre-trained model is possible to evaluate new classifiers, or create a new one based on images that could be used on the process.
import glob
def load_dataset_random(path):
files = dirlist = glob.glob(path)
return files
random_files = load_dataset_random('randomImages/*')
## TODO: Execute your algorithm from Step 6 on
## at least 6 images on your computer.
## Feel free to use as many code cells as needed.
human_files_short = sorted(human_files)[:10]
dog_files_short = sorted(test_files)[:10]
samples = np.concatenate([human_files_short, dog_files_short, random_files])
random.shuffle(samples)
for item in samples:
result = detect_image(item)
img = cv2.imread(item)
plt.imshow(img)
plt.title(result)
plt.show()


This div can be selected
This div can be selected
This div can be selected
This div can be selected
This div can be selected
This div can be selected


Simscape Multibody Parts Library
This library provides examples of parameterized parts Simscape Multibody. They simplify the assembly of mechanisms. Listed below are example models showing their use.
Library
Overview of Library
Overview of Gear Assemblies
Open the Simscape Multibody Parts Library
|
Extrusion Examples
1. Circular Extrusion Assembly: Model, Documentation
2. Box Extrusion Assembly: Model, Documentation
3. Elliptical Tube Assembly: Model, Documentation
|
Gear Examples
1. Common Gear Assembly Testrig: Model, Documentation
2. Planetary Gear Testrig: Model, Documentation
3. Bevel Gear Assembly Testrig: Model, Documentation
4. Double Bevel Gear Assembly Testrig: Model, Documentation
5. Four-Sided Bevel Gear Assembly Testrig: Model, Documentation
6. Rack and Pinion Assembly Testrig: Model, Documentation
7. Worm Gear Assembly Testrig: Model, Documentation
8. Worm Gear Constraints with CAD Parts: Model, Documentation
9. Lead Screw Actuation Torque: Model, Documentation
10. Lead Screw with Friction: Model, Documentation
11. Open Differential: Model, Documentation
|
Linkage Examples
1. Four Bar Linkage: Model, Documentation
2. Slider-Crank Linkage: Model, Documentation
3. Five-Bar Linkage Stamping Mechanism: Model, Documentation
|
Pulley Examples
1. Three Connected Pulleys: Model, Documentation
2. Cable-Driven XY Table with Cross Base: Model, Documentation
|
Applications
1. Water Powered Lift: Model, Documentation
2. Linear Transport System: Model, Documentation
Copyright 2017-2023 The MathWorks™, Inc.


Blind Draft
Create a Flight
Use the buttons in the section below to add a blank input field for each beer being served. Then, add the beer names in the order you are serving them.
Only create as many text fields as you need.
Use the buttons in the section below to add a blank input field for each beer being served. Then, add the beer names in the order you are serving them.
Only create as many text fields as you need.


--- layout: jsdoc title: "Class: CacheExpiration" jsdocNav: - Modules: - workbox-background-sync - workbox-broadcast-cache-update - workbox-build - workbox-cache-expiration - workbox-cacheable-response - workbox-google-analytics - workbox-precaching - workbox-routing - workbox-runtime-caching - workbox-sw ---
The CacheExpiration
class allows you define an expiration and / or
limit on the responses cached.
const cacheExpiration = new workbox.cacheExpiration.CacheExpiration({
maxEntries: 2,
maxAgeSeconds: 10,
});
Creates a new CacheExpiration
instance, which is used to remove entries
from a Cache
once certain criteria—max number of entries, age of entry, or both—is met.
| Parameters |
|
|---|
Expires entries, both based on the the maximum age and the maximum number of entries, depending on how this instance is configured.
A mutex is used to ensure that there is only one copy of this asynchronous
method running at a time. If another request to this method is made while
it's already running, then the now
timestamp associated with that request
is saved and used to recursively trigger the method after the asynchronous
operations are complete.
cacheExpiration.expireEntries({
cacheName: 'example-cache-name'
});
| Parameters |
|
|||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns |
Promise
Resolves when the cache expiration has been performed. |
Checks whether a Response
is fresh, based on the Response
's
Date
header and the configured maxAgeSeconds
.
If maxAgeSeconds
or the Date
header is not set then it will
default to returning true
.
expirationPlugin.isResponseFresh({
cachedResponse: responseFromCache
});
| Parameters |
|
|||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns |
boolean
Either the |
Updates the timestamp stored in IndexedDB for url
to be equal to now
.
expirationPlugin.updateTimestamp({
cacheName: 'example-cache-name',
url: '/example-url'
});
| Parameters |
|
|---|


use FSM branch AND then build as normal
./komodod -ac_name=ROGUE -ac_supply=1000000 -pubkey=<yourpubkey> -addnode=<IP_ADDRESS> -ac_cclib=rogue -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60001 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc -daemon
Guide here: https://github.com/KomodoPlatform/komodo/wiki/Get-Started-with-Rogue-Game
Explorer: http://rogue.explorer.dexstats.info/
Player's Handbook: https://github.com/jl777/komodo/blob/jl777/src/cc/rogue/rogue.doc
100 messages
Before 05-Dec-19 12:00 AM
TonyL07-Mar-19 11:25 PM
I think more interesting might be mode like a: who will extract more gold in 20-30 minites win the game or something like this (more dynamic and with countable score result).Lets say auto bailout based on current extract making on block X and gold counting to decide the winner.
But here community opinion is important - it's just my personal one (edited)
1
TonyL07-Mar-19 11:44 PM
Hmm idea is pretty straight forward:
1) Add game length param (in blocks amount) to multiplayer games creation
2) After game_end_length height is reached dont accept more keystrokes from players
3) After it on game_end_length height decide winner from players extracts based on most gold collected and send buyins to winner
It will allow to create blitz games, rapid games, long games and etc so player will be able to decide which game join/create depends of how much free time he have / in which mode he interested in + winner determination and in-game goal is clear and understandable in such case and strategy when you not start game and waiting for everybody die will not work.
@jl777c How do you think is it worth to be implemented?(edited)
Cryptofist08-Mar-19 12:31 AM
@TonyL agreed 100% on the multiplayer opinions.
2
I like the idea of multiple multiplayer formats, but we will need an interface to do that, correct?
TonyL08-Mar-19 12:36 AM
Some modificaitons in CC needed (new param for game creation + keystrokes accepting lock / auto game finishing with gold calculation in extracts)
Displaying GUI/TUI have to handle (check how much blocks left in active game and show countdown X blocks left till finish)(edited)
I already thought about implementation from TUI side: I think I can just open rogue subprocess in new terminal window and print constantly updating information about current game state in TUI terminal (looks like simpliest solution to not defect rogue gameplay)(edited)
Cryptofist08-Mar-19 05:18 AM
I'm going to push for some more people to come test again now. Is there any updates on a windows installer? Do we have anything important to look at right now and can we maybe try the form bounty again?
Or any other incentives for testers?
TonyL08-Mar-19 06:11 AM
There are no any updates regards Windows one yet (it's not saving progress and I'm not sure atm how to troubleshoot it). I think it's better to start such bounty when Windows version will be ready. Will try to research some solution for win from my side today. I think that maybe it's some specifics of windows terminal and will try to play on some Unix terminal ported to Windows or something like that - maybe it'll help.
@ca333 btw fetch-params.bat which included to Windows artefact needs wget64.exe to actually download zcash params
I've used in my bundle binary from here: https://eternallybored.org/misc/wget/ and it seems to work fine(edited)
Today, we’re excited to announce that we are open sourcing Windows Calculator on GitHub under the MIT License. This includes the source code, build system, unit tests, and product roadmap. Our goal is to build an even better user experience in partnership with the community...
They even made news in blog and media posting it everywhere - open sourced CALCULATOR!
2
In 2019
Next one will be open sourced notepad I bet
ronyi08-Mar-19 07:19 AM
Okay. I moved my windows 10 machine, downloading blocks now.
Possible to create "setpubkey.bat" create new address and print new address with private key for new players and set pubkey and write, how to start this game next time?
TonyL08-Mar-19 07:25 AM
TUI setting pubkey automatically if it wasn't set in daemon params, copying ROGUE.conf also and waiting for sync (tested on Windows and it worked)(edited)
Hmm but not sure if it'll be the same each time btw
It using address from getaccountaddress ""
Have to save this pubkey to file also I think and if there pubkey.txt file grab it from there
Write it somewhere it's definetly great idea @ronyi
in any case it doesnt seem any fundamental core feature so I dont feel motivated to do it, not really against it, just not feeling i should do it. maybe someone else can do it
1
TonyL08-Mar-19 07:52 AM
Oh @ronyi there are two dlls in zip - put em to cc/rogue or rogue will not start
1
ronyi08-Mar-19 07:55 AM
Some combination collected gold and killed monsters and highest lvl?(edited)
@CrisF my block number now 48047
TonyL08-Mar-19 07:59 AM
Synced fine on Windows - so daemon should be fine
ronyi08-Mar-19 08:00 AM
Still in sync 28k block
CrisF08-Mar-19 08:03 AM
Thanks @ronyi I'm now at "blocks": 48051
1
TonyL08-Mar-19 08:07 AM
Some combination collected gold and killed monsters and highest lvl? might be too complicated for player to understand how it's calculating but sounds interesting - can be abstracted to some ROGUE score, or rogue-hot level (edited)
Can make rumbles like a 5-10 minutes games and you have to destroy/collect everything to get highest score
ronyi08-Mar-19 08:09 AM
if collect 700gold/50killed monster * lvl7
TonyL08-Mar-19 08:10 AM
Have to make formula with weights argumented by in-game RNG to keep the balance(edited)
ronyi08-Mar-19 08:12 AM
I think is much more correct way than highest lvl or more collected gold or time based solution. But i don't know the right formula.
TonyL08-Mar-19 08:13 AM
Aha, same behaviour now on windows - played 3 levels but progress extracted only for dl1
Maybe Decker's rogue build will help with it
cmder is software package that provides great console experience even on Windows
It's recognized unix escape sequences so maybe it'll behave as unix one in all other stuff
ronyi08-Mar-19 08:24 AM
Another thing: i don't see this message: Which direction?
TonyL08-Mar-19 08:27 AM
It unix application so it behave in windows terminal not as expected - let's wait for native one
ronyi08-Mar-19 08:33 AM
First game: i quit on lvl 3, but extracted only for dl1, same as TonyL.
ronyi08-Mar-19 08:41 AM
CMDER mini: Error opening terminal: cygwin.
48099
48099
Waiting for next block before bailout
jl777c08-Mar-19 08:41 AM
wait for native windows builds from decker
1
CHMEX08-Mar-19 09:00 AM
The explorer is finally back and synched
1
1
1
1
ronyi08-Mar-19 10:16 AM
Possible to find: rogue.xyz.8 to gametxid?
I think think created one game and playes and quit and everythings is looks like good, but warrior is missing and i can't find my gametxid in expoler and my bailout txid.
TonyL08-Mar-19 10:35 AM
@ronyi You may find your gametxid in cclib games 17 past games (or in not finished games if bailout wasn't actually broadcasted)
Then check cclib gameinfo 17 for this game if you need to find a seed(edited)
ronyi08-Mar-19 11:32 AM
I not find my seed in my gameinfo. rogue.573308751621131768.x
No txid for this seed. As if it hadn't happened.(edited)
TonyL08-Mar-19 11:39 AM
It is possible to get seed only from gameinfo - like a no other ways to get it
So it should exist somewhere hmm
I may make games scanner script which will search for specifc seed in games list
But a little bit later
1
ca33308-Mar-19 12:39 PM
thanks @TonyL will add wget exe with next CD update
1
ronyi08-Mar-19 02:53 PM
48486
48486
Waiting for next block before bailout
getrawtransaction: No information available about transaction (code -5)
Let's wait a little bit more
Something went wrong.
sendrawtransaction: 16: bad-txns-vout-negative (code -26)
Press [Enter] to continue...
Gametxid: 6cafb22f37b4839601fb34659bce6ccd9c2dd64bc8fd354476095d1003852fc0
Manual bailout txid: f5b3e56e47a71a5b435174a02662a3ff69fa92241a084dddaa5c70bfe0456e9b(edited)
TonyL08-Mar-19 03:00 PM
It on last keystroke rebroadcasting attempt - maybe just have to handle exception here and allow to bailout in such case
Terminal user interfaces for Komodo CryptoConditions smart-contracts - tonymorony/komodo_cryptoconditions_tui
1
TonyL08-Mar-19 03:23 PM
@ronyi
sendrawtransaction: 16: bad-txns-vout-negative (code -26)
Press [Enter] to continue...
for this one added fix to TUI which should handle such cases
1
ronyi08-Mar-19 03:44 PM
Thank you TonyL. I think something strange in this case. I finded my gametxid with yout scripts and i make the bailout, but txid not in expoler. https://pastebin.com/AH2QjphW


Chocolate cake cupcake topping marzipan. Powder brownie bonbon lemon drops. Cupcake sugar plum faworki jelly beans sugar plum apple pie jelly-o chocolate bar icing.
Donut liquorice cheesecake bonbon cotton candy tart. Oat cake pudding biscuit wafer wypas tiramisu. Carrot cake carrot cake cotton candy sesame snaps jelly-o applicake jelly.
Save to Kippt


People in dysfunctional relationships never seem to see the forest for the trees, and won't meet in the middle, even for mutually beneficial results. This is one of the biggest problems in dysfunctional relationships: people in them are acting entirely selfishly.
People in dysfunctional don't work towards fixing their issues. They fight, learn nothing, and have the same fight again and again, each time coming back to points that have been argued and re-argued on countless occasions.
A dysfunctional relationship is generally made up on two people who are hell bent on self-destruction, so much so that even when things are starting to go well, they'll find some excuse to plunge the relationship straight back into chaos.
People in dysfunctional relationships stay in them because it's somehow simpler to be dependent on drama than it is to take responsibility for their actions where they've caused someone else pain. It's easier to kick and scream than it is to work hard for their own happiness; to truly care for someone in the gentle, tender way that leaves their vulnerable, naked heart in another person's hands.


✔ Order confirmation
Customer details
Name: {{order_struct.name}}
Email: {{order_struct.email}}
Payment: {{order_struct.payment}}
Gender: {{order_struct.gender}}
Burgers: {{order_struct.burgers.join(', ')}}
✘ One of the input fiels were incorrectly filled in.