A Neural Network experiment using Keras python library

in #steemstem8 years ago (edited)

out.gif
A screenshot gif which shows the training and validation process etc using the ANN python code.

I did a neural network experiment recently. I used a python code written by Adrian at Pyimagesearch library called Keras with tensorflow backend to classify 2 kinds of images. The code(from here) was meant to be used for classifying cat and dog images. Instead cat-dog data, I used a synthetic image dataset containing horizontal and vertical white lines in a black background.

Please note that this is not an article meant to understand the math behind the neural networks. I will keep the math for a future article. Today, I want to share the excitement from this experiment I did on my Linux machine. :)

Neural Networks are very fascinating. Especially in the present era where we have a lot of data and computational power at hand, many algorithms which were dead literally has gained life in applications. Applications like Image classification, objection detection, face recognition from videos and product recommendations powered by Deep learning is so common these days. Giant companies like google, facebook deploy a lot of Deep learning algorithms very efficiently. How many of you are aware that there are steemit bots powered by Artificial intelligence? @effofex mentions about such a bot called @trufflepig in this article. @trufflepig is supposed to find underpaid quality content in steemit. What makes it unique is that it even predicts the value of post in SBDs! Let us hope that @trufflepig will be a successful project.

Artificial Neural Network: A minimal intro

Artificial neural networks(ANNs for short) are feedforward circuits for computational purposes. Common tasks include classification problems, prediction problems and many more. The below image is an example of a neural network with one hidden layer. The other layers are obviously input and output ones.

A sample neural network.[Figure from wikimedia commons, Author: Glosser.ca, License: CC BY-SA 3.0]

Why is it called neural network?: Each computational unit element is an abstraction inspired from the biological neuron, although artificial neuron is nowhere near to a real one. The whole concept of using neuron as a computational element is that these units are supposed to learn from the data which is supplied to the neural network. So mathematically we can represent an artificial neuron as below:

Artificial neuron unit.[Figure from wikimedia commons, Author: Chrislb, License: CC BY-SA 3.0]

An artificial neuron gets a vector{x values} as input which is respectively multiplied by weights{w values}. The resulting value may be added with a bias value. The neuron fires(gets activated) when this value is above a threshold(which is decided by the activation function).

Training ANN

Initially, you have a dumb network with random weights. Say if you want to classify cats and dogs from images. The first requirement is to have a labeled database of cat-dog images. So you convert image matrices to vectors and pass it through ANNs having multiple layers. Now you know which image is which and pass a cat image(say cat is labeled 0) and the output will be garbage most probably. Here is where the algorithm called backpropagation comes into the picture. Since we expected cat output we can calculate mean squared error(or other metrics). Now backpropagation is an algorithm which can be used to propagate the errors back so that the weights in the ANN can be corrected so that it outputs cat image as 0. For a better understanding, see the youtube video by 3blue1brown below:

The most important thing in ANN is backpropagation. This is done multiple times so as to get the correct weights on ANN, so that it gives a cat image label 0 and dog image label 1. Once it is trained you can validate and test the model. Testing is done on new data.

EXPERIMENT

Preparing data

My experiment begins with generating data. So I generated 5000 images each of white horizontal and vertical lines in the black background. This is meant to be a binary classification problem, which means the code will classify your input image into either horizontal or vertical category. The Matlab code I wrote to generate data:


clear,clc,close all

% initial conditions
m = zeros(32,32,2500);

%horizontal lines
for i=1:5000
    r= randi([1 32],[1 1]);
    c= sort(randi([1 32],[1 2]));
    m(r,c(1):c(2),i) = 1;
    imwrite(m(:,:,i),strcat('/home/devanandt/Documents/ML_HOBBY/hor_ver/data/','h.',num2str(i-1),'.jpg'),'jpeg');
end
m = zeros(32,32,2500);
%vertical
for i=1:5000
    c= randi([1 32],[1 1]);
    r= sort(randi([1 32],[1 2]));
    m(r(1):r(2),c,i) = 1;
    imwrite(m(:,:,i),strcat('/home/devanandt/Documents/ML_HOBBY/hor_ver/data/','v.',num2str(i-1),'.jpg'),'jpeg');
end

Each image is 32 x 32 in size. So my data is in the location /home/devanandt/Documents/ML_HOBBY/hor_ver/data/ of my machine. The naming of the files is made to match the labeling. If it is a horizontal line image we name format as h.<number of image>.jpg and for vertical line images we have format l.<number of image>.jpg. So we have a total of 10000 images.

Python Code

This code is adapted from Adrian's Pyimagesearch's article. His code is MIT licensed. So I can adapt it for my purposes.

# USAGE
# python hor_ver_ANN_train.py --dataset /home/devanandt/Documents/ML_HOBBY/hor_ver/data/ --epochs #number

# import the necessary packages (scikit-learn, numpy, opencv, keras..)
from sklearn.preprocessing import LabelEncoder
from sklearn.cross_validation import train_test_split
from keras.models import Sequential
from keras.layers import Activation
from keras.optimizers import SGD
from keras.layers import Dense
from keras.utils import np_utils
from imutils import paths
import numpy as np
import argparse
import cv2
import os

def image_to_feature_vector(image, size=(32, 32)):
    # resize the image to a fixed size, then flatten the image into
    # a list of raw pixel intensities
    return cv2.resize(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), size).flatten()

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
    help="path to input dataset")
ap.add_argument("-e", "--epochs", required=True,
        help="epochs")

args = vars(ap.parse_args())

# grab the list of images that we'll be describing
print("[INFO] describing images...")
imagePaths = list(paths.list_images(args["dataset"]))

# initialize the data matrix and labels list
data = []
labels = []

# loop over the input images
for (i, imagePath) in enumerate(imagePaths):
    # load the image and extract the class label (assuming that our
    # path as the format: /path/to/dataset/{class}.{image_num}.jpg
    image = cv2.imread(imagePath)
    label = imagePath.split(os.path.sep)[-1].split(".")[0]

    # construct a feature vector raw pixel intensities, then update
    # the data matrix and labels list
    features = image_to_feature_vector(image)
    data.append(features)
    labels.append(label)

    # show an update every 100 images
    if i > 0 and i % 100 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))

# encode the labels, converting them from strings to integers
le = LabelEncoder()
labels = le.fit_transform(labels)

# scale the input image pixels to the range [0, 1], then transform
# the labels into vectors in the range [0, num_classes] -- this
# generates a vector for each label where the index of the label
# is set to `1` and all other entries to `0`
data = np.array(data) / 255.0
labels = np_utils.to_categorical(labels, 2)

# partition the data into training and testing splits, using 75%
# of the data for training and the remaining 25% for testing
print("[INFO] constructing training/testing split...")
(trainData, testData, trainLabels, testLabels) = train_test_split(
    data, labels, test_size=0.25, random_state=42)

# define the architecture of the network
model = Sequential()
model.add(Dense(768, input_dim=32*32*1, init="uniform",
    activation="relu"))
model.add(Dense(384, init="uniform", activation="relu"))
model.add(Dense(2))
model.add(Activation("softmax"))

# train the model using SGD
print("[INFO] compiling model...")
sgd = SGD(lr=0.001)
model.compile(loss="binary_crossentropy", optimizer=sgd,
    metrics=["accuracy"])
model.fit(trainData, trainLabels, epochs=int(args["epochs"]), batch_size=128,
    verbose=1)

# show the accuracy on the testing set
print("[INFO] evaluating on testing set...")
(loss, accuracy) = model.evaluate(testData, testLabels,
    batch_size=128, verbose=1)
print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,
    accuracy * 100))

model.save('hor_ver_32_32.h5') 

Please read Adrian's article for the working of code and understanding Keras etc.

$python hor_ver_ANN_train.py --dataset /home/devanandt/Documents/ML_HOBBY/hor_ver/data/ --epochs 1000

This code produces a trained ANN in a model which is saved in this file hor_ver_32_32.h5(Keras model file). The accuracy was measured to be like 95%.

Now we can use this h5 file to classify external outputs(which are supposed to be horizontal and vertical white lines in black background).

Deploying trained ANN

So you can load Keras model file using the python script below.

# USAGE
# python hor_ver_ANN_classifier.py /path/to/image_file
from keras.models import load_model
import cv2
import numpy as np
import sys

def image_to_feature_vector(image, size=(32, 32)):
    # resize the image to a fixed size, then flatten the image into
    # a list of raw pixel intensities
    return cv2.resize(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), size).flatten()

#loads a pre-trained model for cat-dog classification
model = load_model('hor_ver_32_32.h5')

image_test = cv2.imread(sys.argv[1])
image_test = image_to_feature_vector(image_test)
pr = model.predict_classes(np.array([image_test]))

if pr==[1]:
    print "Vertical line"
else:
    print "Horizontal line"

FUN part

Let us show new images to the trained ANN model now. My testing folder is files as below:

$ python hor_ver_ANN_classifier.py /home/devanandt/Documents/ML_HOBBY/hor_ver/testing/image_file.jpg

Except for 17.jpg(colored image) and 16.jpg(noisy image?), all images gave correct output. Even slightly curved images are properly approximated by our model.

The most amazing part for me is the approximations made up by the ANN. By approximation I mean the capability of ANN to classify an image like below as vertical:

15.jpg

You can access my files on GitHub too. Link here: https://github.com/dexterdev/STEEMIT/tree/master/ANN/HOR_VER

References for further reading


Join #steemSTEM

#steemSTEM is a community project with the goal to promote and support Science, Technology, Engineering and Mathematics related content and activities on the STEEM blockchain. If you wish to support the #steemSTEM project you can: Contribute STEM content using the #steemstem tag | Support steemstem authors | Join our curation trail | Join our Discord community | Delegate SP to steemstem

Convenient Delegation Links:

50 SP | 100SP | 500SP | 1000SP | 5000SP | 10000SP | 50000SP

Image courtesy: @elvisxx71


All images without mentioning image sources are my creations or snapshots from computer :)

Follow me @dexterdev


 ____ _______  ______ _________ ____ ______    
/  _ /  __\  \//__ __/  __/  __/  _ /  __/ \ |\
| | \|  \  \  /  / \ |  \ |  \/| | \|  \ | | //
| |_/|  /_ /  \  | | |  /_|    | |_/|  /_| \// 
\____\____/__/\\ \_/ \____\_/\_\____\____\__/

Sort:  

Seems like anyone who reads this can try this out. So, through some slightly different set of programs you can even rectify the problem of 'not categorising coloured images' I guess. Isn't it?

Honestly, this is one of your few posts that I gave some attention to read. All other posts are technically too hard to understand man. :)

You can train ANN for any objective. By the way I omitted lot of math. Back propagation is challenging to understand in my opinion. 😃

Pretty cool! I've tried tensorflow few months ago using "TensorFlow for poets", it's an amazing tool for beginners! I trained it with Starwars characters as well as cathedrals to test the limits. A fun thing to do is to test a picture that has nothing to do with the dataset (an apple for example) and see how it reacts.

I look forward to your next article :)

I keep meaning to play with this stuff more. I've done the tensorflow tutorials and need to find a signifiant, but low pressure, project.

There's a lot of great stuff out there that would help me professionally - particularly removal of background noise, feature identification, and segmentation.

I'm also personally curious in text summarization, adversarial networks, and have a special place in my heart for watching videos of reinforcement learning networks figuring out how to play video games.

Cool. I am also interested in neural network powered molecular dynamics which is another area which is getting more attention these days.

I'm also personally curious in text summarization

Will it help you curate steemit better?

I'm just starting to get into molecular dynamics. Well, sorta. I've been following some nice work simulating microbial interactions which uses LAMMPS as a base.

For some reason, text summarization never occurred to me in relation to steemit. But now that I'm thinking about it, document classification could be useful.

That sounds great.

Nice article. FYI, @trufflepig uses a random forest instead of an ANN or some Deep Learning Architecture, less tweaking and no need for heavy lifting CPUs or even GPUs :-D

Oh. Is it? That's cool. So random forest is a computationally inexpensive ML algorithm. I am yet to learn that. Thank you.

By the way, those who want to install these libraries in python I recommend installing Anaconda package. Let me know if any of you have doubts regarding this. These deep learning libraries have capability to run on CPUs and GPUs. I have used CPU version. For larger data sets and deep networks GPUs will accelerate the pace of training.

Loading...