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_filenames
parameter 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
Column
with 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
ImageDataset
from theImageList
and theColumn
of labels. If theshuffle
parameter is set toTrue
, theImageDataset
will 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
Layer
instances 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
NeuralNetworkClassifier
from anInputConversion
, the list ofLayer
instances:
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]:
['circles', 'circles', 'circles', 'circles', 'circles', 'circles', 'circles', 'squares', 'circles']