Skip to content

Commit 810e604

Browse files
committed
add image classification tutorial
1 parent 78e6d6d commit 810e604

File tree

5 files changed

+188
-1
lines changed

5 files changed

+188
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
1919
- ### [Machine Learning](https://www.thepythoncode.com/topic/machine-learning)
2020
- ### [Natural Language Processing](https://www.thepythoncode.com/topic/nlp)
2121
- [How to Build a Spam Classifier using Keras in Python](https://www.thepythoncode.com/article/build-spam-classifier-keras-python). ([code](machine-learning/nlp/spam-classifier))
22-
- [How to Detect Human Faces in Python using OpenCV](https://www.thepythoncode.com/article/detect-faces-opencv-python). ([code](machine-learning/face_detection))
2322

23+
- [How to Detect Human Faces in Python using OpenCV](https://www.thepythoncode.com/article/detect-faces-opencv-python). ([code](machine-learning/face_detection))
2424
- [Building a Speech Emotion Recognizer using Scikit-learn](https://www.thepythoncode.com/article/building-a-speech-emotion-recognizer-using-sklearn). ([code](machine-learning/speech-emotion-recognition))
25+
- [How to Make an Image Classifier in Python using Keras](https://www.thepythoncode.com/article/image-classification-keras-python). ([code](machine-learning/image-classifier))
2526
- [Top 8 Python Libraries For Data Scientists and Machine Learning Engineers](https://www.thepythoncode.com/article/top-python-libraries-for-data-scientists).
2627

2728
- ### [General Python Topics](https://www.thepythoncode.com/topic/general-python-topics)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# [How to Make an Image Classifier in Python using Keras](https://www.thepythoncode.com/article/image-classification-keras-python)
2+
To run this:
3+
- `pip3 install -r requirements.txt`
4+
- First, you need to train the model using `python train.py`
5+
- Edit the code in `test.py` for you optimal model weights in `results` folder ( currently empty because you need to train first ) and run:
6+
```
7+
python test.py
8+
```
9+
**Output:**
10+
```
11+
10000/10000 [==============================] - 3s 331us/step
12+
Test accuracy: 81.17999999999999 %
13+
frog
14+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
keras
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from train import load_data
2+
from keras.models import load_model
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
6+
# CIFAR-10 classes
7+
categories = {
8+
0: "airplane",
9+
1: "automobile",
10+
2: "bird",
11+
3: "cat",
12+
4: "deer",
13+
5: "dog",
14+
6: "frog",
15+
7: "horse",
16+
8: "ship",
17+
9: "truck"
18+
}
19+
20+
# load the testing set
21+
(_, _), (X_test, y_test) = load_data()
22+
# load the model with optimal weights
23+
model = load_model("results/cifar10-loss-0.58-acc-0.81.h5")
24+
# evaluation
25+
loss, accuracy = model.evaluate(X_test, y_test)
26+
print("Test accuracy:", accuracy*100, "%")
27+
28+
# get prediction for this image
29+
sample_image = X_test[7500]
30+
prediction = np.argmax(model.predict(sample_image.reshape(-1, *sample_image.shape))[0])
31+
print(categories[prediction])
32+
33+
# show the first image
34+
plt.axis('off')
35+
plt.imshow(sample_image)
36+
plt.savefig("frog.png")
37+
plt.show()
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
from keras.datasets import cifar10 # importing the dataset from keras
2+
from keras.models import Sequential
3+
from keras.layers import Dense, Dropout, Activation, Flatten
4+
from keras.layers import Conv2D, MaxPooling2D
5+
from keras.callbacks import ModelCheckpoint, TensorBoard
6+
from keras.utils import to_categorical
7+
import os
8+
9+
# hyper-parameters
10+
batch_size = 64
11+
# 10 categories of images (CIFAR-10)
12+
num_classes = 10
13+
# number of training epochs
14+
epochs = 30
15+
16+
def create_model(input_shape):
17+
"""
18+
Constructs the model:
19+
- 32 Convolutional (3x3)
20+
- Relu
21+
- 32 Convolutional (3x3)
22+
- Relu
23+
- Max pooling (2x2)
24+
- Dropout
25+
26+
- 64 Convolutional (3x3)
27+
- Relu
28+
- 64 Convolutional (3x3)
29+
- Relu
30+
- Max pooling (2x2)
31+
- Dropout
32+
33+
- 128 Convolutional (3x3)
34+
- Relu
35+
- 128 Convolutional (3x3)
36+
- Relu
37+
- Max pooling (2x2)
38+
- Dropout
39+
40+
- Flatten (To make a 1D vector out of convolutional layers)
41+
- 1024 Fully connected units
42+
- Relu
43+
- Dropout
44+
- 10 Fully connected units (each corresponds to a label category (cat, dog, etc.))
45+
"""
46+
47+
# building the model
48+
model = Sequential()
49+
50+
model.add(Conv2D(filters=32, kernel_size=(3, 3), padding="same", input_shape=input_shape))
51+
model.add(Activation("relu"))
52+
model.add(Conv2D(filters=32, kernel_size=(3, 3), padding="same"))
53+
model.add(Activation("relu"))
54+
model.add(MaxPooling2D(pool_size=(2, 2)))
55+
model.add(Dropout(0.25))
56+
57+
model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same"))
58+
model.add(Activation("relu"))
59+
model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same"))
60+
model.add(Activation("relu"))
61+
model.add(MaxPooling2D(pool_size=(2, 2)))
62+
model.add(Dropout(0.25))
63+
64+
model.add(Conv2D(filters=128, kernel_size=(3, 3), padding="same"))
65+
model.add(Activation("relu"))
66+
model.add(Conv2D(filters=128, kernel_size=(3, 3), padding="same"))
67+
model.add(Activation("relu"))
68+
model.add(MaxPooling2D(pool_size=(2, 2)))
69+
model.add(Dropout(0.25))
70+
71+
# flattening the convolutions
72+
model.add(Flatten())
73+
# fully-connected layers
74+
model.add(Dense(1024))
75+
model.add(Activation("relu"))
76+
model.add(Dropout(0.5))
77+
model.add(Dense(num_classes, activation="softmax"))
78+
79+
# print the summary of the model architecture
80+
model.summary()
81+
82+
# training the model using rmsprop optimizer
83+
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
84+
return model
85+
86+
87+
def load_data():
88+
"""
89+
This function loads CIFAR-10 dataset, normalized, and labels one-hot encoded
90+
"""
91+
# loading the CIFAR-10 dataset, splitted between train and test sets
92+
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
93+
print("Training samples:", X_train.shape[0])
94+
print("Testing samples:", X_test.shape[0])
95+
print(f"Images shape: {X_train.shape[1:]}")
96+
97+
# converting image labels to binary class matrices
98+
y_train = to_categorical(y_train, num_classes)
99+
y_test = to_categorical(y_test, num_classes)
100+
101+
# convert to floats instead of int, so we can divide by 255
102+
X_train = X_train.astype("float32")
103+
X_test = X_test.astype("float32")
104+
X_train /= 255
105+
X_test /= 255
106+
107+
return (X_train, y_train), (X_test, y_test)
108+
109+
110+
if __name__ == "__main__":
111+
112+
# load the data
113+
(X_train, y_train), (X_test, y_test) = load_data()
114+
115+
# constructs the model
116+
model = create_model(input_shape=X_train.shape[1:])
117+
118+
# some nice callbacks
119+
tensorboard = TensorBoard(log_dir="logs/cifar10-model-v1")
120+
checkpoint = ModelCheckpoint("results/cifar10-loss-{val_loss:.2f}-acc-{val_acc:.2f}.h5",
121+
save_best_only=True,
122+
verbose=1)
123+
124+
# make sure results folder exist
125+
if not os.path.isdir("results"):
126+
os.mkdir("results")
127+
128+
# train
129+
model.fit(X_train, y_train,
130+
batch_size=batch_size,
131+
epochs=epochs,
132+
validation_data=(X_test, y_test),
133+
callbacks=[tensorboard, checkpoint],
134+
shuffle=True)

0 commit comments

Comments
 (0)