Build a Traffic Sign Recognition System with Spring Boot & Deeplearning4j

This tutorial explains how to create a traffic sign recognition application using Spring Boot and Java Deeplearning4j, covering CNN selection, dataset organization, Maven dependencies, data loading, model construction, training, prediction, unit testing, and expected results.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Build a Traffic Sign Recognition System with Spring Boot & Deeplearning4j

Technical Overview

This guide demonstrates how to build a traffic‑sign recognition system using Spring Boot and Java Deeplearning4j. A convolutional neural network (CNN) is employed to classify images of traffic signs.

1. Neural‑Network Choice

A CNN is selected because it extracts local visual features via weight sharing, reduces the number of parameters, and builds hierarchical representations that are well‑suited for image classification.

2. Dataset Format

The dataset should have an images directory containing JPEG/PNG files and a matching labels directory with a plain‑text file per image that stores the class index (e.g., 0 for speed‑limit, 1 for prohibition).

traffic_sign_dataset/
├── images/
│   ├── sign1.jpg
│   ├── sign2.jpg
│   └── ...
├── labels/
│   ├── sign1.txt
│   ├── sign2.txt
│   └── ...

3. Technology Stack

Spring Boot – rapid development and auto‑configuration for Java web applications.

Deeplearning4j – Java deep‑learning library that supports CNNs and other architectures.

Maven Dependencies

<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-core</artifactId>
    <version>1.0.0-beta7</version>
</dependency>
<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-nn</artifactId>
    <version>1.0.0-beta7</version>
</dependency>
<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-ui</artifactId>
    <version>1.0.0-beta7</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Code Examples

1. Data Loading and Pre‑processing

import org.datavec.image.loader.NativeImageLoader;
import org.deeplearning4j.datasets.iterator.impl.ListDataSetIterator;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.DataSet;
import org.nd4j.linalg.dataset.api.preprocessor.DataNormalization;
import org.nd4j.linalg.dataset.api.preprocessor.ImagePreProcessingScaler;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class DataLoader {
    public static ListDataSetIterator<DataSet> loadData(String dataDirectory) {
        // Load images
        File imageDir = new File(dataDirectory + "/images");
        NativeImageLoader loader = new NativeImageLoader(32, 32, 3);
        List<INDArray> images = new ArrayList<>();
        for (File imgFile : imageDir.listFiles()) {
            images.add(loader.asMatrix(imgFile));
        }
        // Load labels (one integer per file)
        File labelDir = new File(dataDirectory + "/labels");
        List<Integer> labels = new ArrayList<>();
        for (File lblFile : labelDir.listFiles()) {
            int label = Integer.parseInt(org.apache.commons.io.FileUtils.readFileToString(lblFile, "UTF-8"));
            labels.add(label);
        }
        // Build DataSet
        DataSet ds = new DataSet(
                images.toArray(new INDArray[0]),
                labels.stream().mapToDouble(i -> i).toArray()
        );
        // Normalize to [0,1]
        DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
        scaler.fit(ds);
        scaler.transform(ds);
        return new ListDataSetIterator<>(ds, 32);
    }
}

2. Model Construction and Training

import org.deeplearning4j.nn.conf.ConvolutionMode;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.lossfunctions.LossFunctions;

public class TrafficSignRecognitionModel {
    public static MultiLayerNetwork buildModel() {
        NeuralNetConfiguration.ListBuilder builder = new NeuralNetConfiguration.Builder()
                .seed(12345)
                .weightInit(WeightInit.XAVIER)
                .l2(0.0005)
                .list();
        // Conv + pool
        builder.layer(0, new ConvolutionLayer.Builder(5,5)
                .nIn(3).stride(1,1).nOut(32)
                .activation(Activation.RELU)
                .convolutionMode(ConvolutionMode.Same)
                .build());
        builder.layer(1, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)
                .kernelSize(2,2).stride(2,2).build());
        // Second conv + pool
        builder.layer(2, new ConvolutionLayer.Builder(5,5)
                .nOut(64)
                .activation(Activation.RELU)
                .convolutionMode(ConvolutionMode.Same)
                .build());
        builder.layer(3, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)
                .kernelSize(2,2).stride(2,2).build());
        // Fully connected
        builder.layer(4, new DenseLayer.Builder().nOut(1024).activation(Activation.RELU).build());
        // Output (assume 10 classes)
        builder.layer(5, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
                .nOut(10)
                .activation(Activation.SOFTMAX)
                .build());
        MultiLayerNetwork net = new MultiLayerNetwork(builder.build());
        return net;
    }

    public static void trainModel(MultiLayerNetwork model, ListDataSetIterator<DataSet> iterator) {
        model.init();
        for (int epoch = 0; epoch < 10; epoch++) {
            model.fit(iterator);
            iterator.reset();
        }
    }
}

3. Prediction

import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.datavec.image.loader.NativeImageLoader;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.api.preprocessor.DataNormalization;
import org.nd4j.linalg.dataset.api.preprocessor.ImagePreProcessingScaler;
import org.nd4j.linalg.factory.Nd4j;
import java.io.File;

public class Prediction {
    public static int predict(MultiLayerNetwork model, File imageFile) throws Exception {
        NativeImageLoader loader = new NativeImageLoader(32, 32, 3);
        INDArray image = loader.asMatrix(imageFile);
        DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
        scaler.transform(image);
        INDArray output = model.output(image);
        return Nd4j.argMax(output, 1).getInt(0);
    }
}

4. Unit Tests

import org.deeplearning4j.datasets.iterator.impl.ListDataSetIterator;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class TrafficSignRecognitionTest {
    private MultiLayerNetwork model;

    @BeforeEach
    public void setup() {
        model = TrafficSignRecognitionModel.buildModel();
    }

    @Test
    public void testLoadData() {
        String dataDir = "path/to/your/dataset";
        ListDataSetIterator<?> iterator = DataLoader.loadData(dataDir);
        assertNotNull(iterator);
    }

    @Test
    public void testTrainModel() {
        String dataDir = "path/to/your/dataset";
        ListDataSetIterator<?> iterator = DataLoader.loadData(dataDir);
        TrafficSignRecognitionModel.trainModel(model, iterator);
        assertNotNull(model);
    }
}

Expected Output

Running the system should return the correct class index for a supplied traffic‑sign image (e.g., the index representing a speed‑limit sign).

References

Deeplearning4j official documentation

Spring Boot official documentation

"Deep Learning" by Ian Goodfellow, Yoshua Bengio, and Aaron Courville

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CNNJavaDeep LearningSpring BootDeeplearning4jTraffic Sign Recognition
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.