In this tutorial, you will see that the overall model is structured by putting together all the building blocks (functions implemented in the previous tutorials) together in the right order.
Before structuring the model, we will write one more function, which we'll use to define our model weights and bias:
def initialize_with_zeros(dim): w = np.zeros((dim,1)) b = 0 return w, b So we will implement the final model, but as before, first, let's see what are the inputs and outputs to it:
Arguments:
X_train - training set represented by a NumPy array of shape (ROWS * COLS * CHANNELS, m_train);
Y_train - training labels represented by a NumPy array (vector) of shape (1, m_train);
X_test - test set represented by a NumPy array of shape (ROWS * COLS * CHANNELS, m_test);
Y_test - test labels represented by a NumPy array (vector) of shape (1, m_test);
num_iterations - hyperparameter representing the number of iterations to optimize the parameters;
learning_rate - hyperparameter representing the learning rate used in the update rule of optimize();
print_cost - Set to true to print the cost every 100 iterations.
Return:
dict - a dictionary containing information about the model.
Here is the final model code:
def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False): # initialize parameters with zeros w, b = initialize_with_zeros(X_train.shape[0]) # Gradient descent parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost) # Retrieve parameters w and b from dictionary "parameters" w = parameters["w"] b = parameters["b"] # Predict test/train set examples Y_prediction_test = predict(w,b,X_test) Y_prediction_train = predict(w,b,X_train) # Print train/test Errors print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100)) print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100)) dict = {"costs": costs, "Y_prediction_test": Y_prediction_test, "Y_prediction_train": Y_prediction_train, "w": w, "b": b, "learning_rate": learning_rate, "num_iterations:": num_iterations} return dict So finally we have defined our final logistic regression model, so let's train it on our dataset for 3000 iterations with a learning rate of 0.003:
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 3000, learning_rate = 0.003, print_cost = True) As for now, we have trained our model. Let's test it out with one test image:
test_image = "cat.jpg" my_image = read_image(test_image).reshape((1, ROWS*COLS*CHANNELS)).T my_predicted_image = predict(d["w"], d["b"], my_image) print(np.squeeze(my_predicted_image)) Bellow is our training results, as we did 3000 training steps, and as a result, we received test accuracy of 58.6% and train accuracy of 68.24%. This is not that accurate, but evaluating that we are using simple logistic regression, it's not that bad, even it predicted our image as a CAT!
Cost after iteration 100: 0.671626 Cost after iteration 200: 0.663768 Cost after iteration 300: 0.658534 Cost after iteration 400: 0.654486 Cost after iteration 500: 0.651100 Cost after iteration 600: 0.648129 Cost after iteration 700: 0.645438 Cost after iteration 800: 0.642949 Cost after iteration 900: 0.640613 Cost after iteration 1000: 0.638401 Cost after iteration 1100: 0.636290 Cost after iteration 1200: 0.634267 Cost after iteration 1300: 0.632320 Cost after iteration 1400: 0.630441 Cost after iteration 1500: 0.628624 Cost after iteration 1600: 0.626863 Cost after iteration 1700: 0.625154 Cost after iteration 1800: 0.623493 Cost after iteration 1900: 0.621878 Cost after iteration 2000: 0.620305 Cost after iteration 2100: 0.618771 Cost after iteration 2200: 0.617275 Cost after iteration 2300: 0.615814 Cost after iteration 2400: 0.614387 Cost after iteration 2500: 0.612991 Cost after iteration 2600: 0.611626 Cost after iteration 2700: 0.610289 Cost after iteration 2800: 0.608979 Cost after iteration 2900: 0.607695 train accuracy: 68.24391869376875 % test accuracy: 58.6 % 0.0 Full tutorial code:
import os import cv2 import numpy as np import matplotlib.pyplot as plt import scipy ROWS = 64 COLS = 64 CHANNELS = 3 TRAIN_DIR = 'Train_data/' TEST_DIR = 'Test_data/' train_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] test_images = [TEST_DIR+i for i in os.listdir(TEST_DIR)] def read_image(file_path): img = cv2.imread(file_path, cv2.IMREAD_COLOR) return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC) def prepare_data(images): m = len(images) X = np.zeros((m, ROWS, COLS, CHANNELS), dtype=np.uint8) y = np.zeros((1, m)) for i, image_file in enumerate(images): X[i,:] = read_image(image_file) if 'dog' in image_file.lower(): y[0, i] = 1 elif 'cat' in image_file.lower(): y[0, i] = 0 return X, y def sigmoid(z): s = 1/(1+np.exp(-z)) return s def propagate(w, b, X, Y): m = X.shape[1] # FORWARD PROPAGATION (FROM X TO COST) z = np.dot(w.T, X)+b # tag 1 A = sigmoid(z) # tag 2 cost = (-np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))/m # tag 5 # BACKWARD PROPAGATION (TO FIND GRAD) dw = (np.dot(X,(A-Y).T))/m # tag 6 db = np.average(A-Y) # tag 7 cost = np.squeeze(cost) grads = {"dw": dw, "db": db} return grads, cost def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False): costs = [] for i in range(num_iterations): # Cost and gradient calculation grads, cost = propagate(w, b, X, Y) # Retrieve derivatives from grads dw = grads["dw"] db = grads["db"] # update w and b w = w - learning_rate*dw b = b - learning_rate*db # Record the costs if i % 100 == 0: costs.append(cost) # Print the cost every 100 training iterations if print_cost and i % 100 == 0: print ("Cost after iteration %i: %f" %(i, cost)) # update w and b to dictionary params = {"w": w, "b": b} # update derivatives to dictionary grads = {"dw": dw, "db": db} return params, grads, costs def predict(w, b, X): m = X.shape[1] Y_prediction = np.zeros((1, m)) w = w.reshape(X.shape[0], 1) z = np.dot(w.T, X) + b A = sigmoid(z) for i in range(A.shape[1]): # Convert probabilities A[0,i] to actual predictions p[0,i] if A[0,i] > 0.5: Y_prediction[[0],[i]] = 1 else: Y_prediction[[0],[i]] = 0 return Y_prediction def initialize_with_zeros(dim): w = np.zeros((dim, 1)) b = 0 return w, b def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False): # initialize parameters with zeros w, b = initialize_with_zeros(X_train.shape[0]) # Gradient descent parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost) # Retrieve parameters w and b from dictionary "parameters" w = parameters["w"] b = parameters["b"] # Predict test/train set examples Y_prediction_test = predict(w,b,X_test) Y_prediction_train = predict(w,b,X_train) # Print train/test Errors print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100)) print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100)) dict = {"costs": costs, "Y_prediction_test": Y_prediction_test, "Y_prediction_train": Y_prediction_train, "w": w, "b": b, "learning_rate": learning_rate, "num_iterations:": num_iterations} return dict train_set_x, train_set_y = prepare_data(train_images) test_set_x, test_set_y = prepare_data(test_images) train_set_x_flatten = train_set_x.reshape(train_set_x.shape[0], ROWS*COLS*CHANNELS).T test_set_x_flatten = test_set_x.reshape(test_set_x.shape[0], -1).T train_set_x = train_set_x_flatten/255 test_set_x = test_set_x_flatten/255 d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 3000, learning_rate = 0.003, print_cost = True) test_image = "cat.jpg" my_image = read_image(test_image).reshape(1, ROWS*COLS*CHANNELS).T my_predicted_image = predict(d["w"], d["b"], my_image) print(np.squeeze(my_predicted_image)) Conclusion:
So congratulations on building our first image classification model. In the next tutorial, we'll analyze it further and examine possible choices for the learning rate a.