Image Classification with Convolutional Neural Networks¶
This tutorial explains how image classification with CNNs can be handled in safeds with the NeuralNetworkClassifier. The data used contains of multiple drawn shapes and can be found on kaggle.
Note
All operations on an NeuralNetworkClassifier return a new NeuralNetworkClassifier. The original NeuralNetworkClassifier will not be changed.
Load data into an ImageDataset¶
- Load images via files in an
ImageList. The data is available underdocs/tutorials/data/shapes. If thereturn_filenamesparameter is set toTrue, a list of all filepaths will be returned as well in the same order as the images in the returnedImageList.
In [1]:
Copied!
from safeds.data.image.containers import ImageList
images, filepaths = ImageList.from_files("data/shapes", return_filenames=True)
from safeds.data.image.containers import ImageList
images, filepaths = ImageList.from_files("data/shapes", return_filenames=True)
- Create a
Columnwith the labels of the images:
In [2]:
Copied!
import re
from safeds.data.tabular.containers import Column
labels = Column(
"label",
[re.search(r"(.*)[\\/](.*)[\\/](.*)\.", filepath).group(2) for filepath in filepaths],
)
import re
from safeds.data.tabular.containers import Column
labels = Column(
"label",
[re.search(r"(.*)[\\/](.*)[\\/](.*)\.", filepath).group(2) for filepath in filepaths],
)
- Create an
ImageDatasetfrom theImageListand theColumnof labels. If theshuffleparameter is set toTrue, theImageDatasetwill be shuffled after each epoch while training a neural network.
In [3]:
Copied!
from safeds.data.labeled.containers import ImageDataset
dataset = ImageDataset[Column](images, labels, shuffle=True)
from safeds.data.labeled.containers import ImageDataset
dataset = ImageDataset[Column](images, labels, shuffle=True)
Create the neural network with a NeuralNetworkClassifier¶
- Create a list of
Layerinstances for your neural network:
In [4]:
Copied!
from safeds.ml.nn.layers import Convolutional2DLayer, FlattenLayer, ForwardLayer, MaxPooling2DLayer
layers = [
Convolutional2DLayer(output_channel=16, kernel_size=3, padding=1),
MaxPooling2DLayer(kernel_size=2, stride=2),
Convolutional2DLayer(output_channel=32, kernel_size=3, padding=1),
MaxPooling2DLayer(kernel_size=2, stride=2),
FlattenLayer(),
ForwardLayer(neuron_count=128),
ForwardLayer(neuron_count=3),
]
from safeds.ml.nn.layers import Convolutional2DLayer, FlattenLayer, ForwardLayer, MaxPooling2DLayer
layers = [
Convolutional2DLayer(output_channel=16, kernel_size=3, padding=1),
MaxPooling2DLayer(kernel_size=2, stride=2),
Convolutional2DLayer(output_channel=32, kernel_size=3, padding=1),
MaxPooling2DLayer(kernel_size=2, stride=2),
FlattenLayer(),
ForwardLayer(neuron_count=128),
ForwardLayer(neuron_count=3),
]
- Create a
NeuralNetworkClassifierfrom anInputConversion, the list ofLayerinstances:
In [5]:
Copied!
from safeds.ml.nn import NeuralNetworkClassifier
from safeds.ml.nn.converters import InputConversionImageToColumn
cnn = NeuralNetworkClassifier[ImageDataset[Column], ImageList](
InputConversionImageToColumn(dataset.input_size),
layers,
)
from safeds.ml.nn import NeuralNetworkClassifier
from safeds.ml.nn.converters import InputConversionImageToColumn
cnn = NeuralNetworkClassifier[ImageDataset[Column], ImageList](
InputConversionImageToColumn(dataset.input_size),
layers,
)
Fit and predict the NeuralNetworkClassifier¶
- Fit the
NeuralNetworkClassifier:
In [6]:
Copied!
cnn_fitted = cnn.fit(dataset, epoch_count=8, batch_size=16)
cnn_fitted = cnn.fit(dataset, epoch_count=8, batch_size=16)
- Predict values from the
NeuralNetworkClassifier:
In [7]:
Copied!
prediction = cnn_fitted.predict(dataset.get_input())
prediction = cnn_fitted.predict(dataset.get_input())
- Shuffle the prediction to get a random order:
In [8]:
Copied!
shuffled_prediction = prediction.shuffle()
shuffled_prediction = prediction.shuffle()
- Display a subset of the input data:
- Display the corresponding predicted labels:
In [10]:
Copied!
shuffled_prediction.get_output().to_list()[0:9]
shuffled_prediction.get_output().to_list()[0:9]
Out[10]:
['triangles', 'triangles', 'triangles', 'triangles', 'triangles', 'triangles', 'triangles', 'triangles', 'triangles']