Combating Currency Counterfeiting with AI: A Deep Learning Approach to Bank Note Authentication
Currency counterfeiting is a serious global problem that threatens the integrity and stability of financial systems. According to a 2019 report by the U.S. Department of Treasury, an estimated $147 million in counterfeit U.S. currency was in circulation, with digital printing technologies making it easier than ever to create convincing fake bills [1]. Internationally, the impact is even greater, with the Bank for International Settlements estimating that up to $600 billion in counterfeit money is circulated globally each year [2].
Detecting fake bank notes is a challenging task that traditionally relies on trained human experts and specialized equipment. Banknote designs incorporate various security features such as watermarks, security threads, and holographic elements that can be difficult to accurately reproduce [3]. However, advances in printing technologies have made it increasingly harder to distinguish real notes from high-quality counterfeits.
Artificial intelligence and machine learning offer promising solutions to this problem by enabling automated and accurate detection of fake bills. In this article, we‘ll explore how to use deep learning with Keras to build a powerful bank note authentication system. We‘ll walk through the entire workflow from data exploration to model evaluation and deployment, highlighting key concepts and best practices along the way.
The Bank Note Authentication Dataset
We‘ll work with the Bank Note Authentication Data Set from the UCI Machine Learning Repository [4]. This dataset contains information extracted from wavelet-transformed images of both genuine and forged bank note specimens.
The wavelet transform is a signal processing technique that decomposes an image into a set of frequency sub-bands, allowing for efficient representation of both frequency and spatial information [5]. By applying wavelet transforms to bank note images, we can extract features that capture the texture and pattern characteristics that distinguish real notes from counterfeits.
The dataset includes the following features derived from wavelet-transformed note images:
- Variance of wavelet transformed image
- Skewness of wavelet transformed image
- Kurtosis of wavelet transformed image
- Entropy of image
- Class (0 for authentic, 1 for forgery)
Let‘s load the dataset into a pandas DataFrame and take a look at the first few rows:
import pandas as pd
data = pd.read_csv(‘BankNote_Authentication.csv‘)
print(data.head())
variance skewness kurtosis entropy class
0 3.62160 8.6661 -2.8073 -0.44699 0
1 4.54590 8.1674 -2.4586 -1.46210 0
2 3.86600 -2.6383 1.9242 0.10645 0
3 3.45660 9.5228 -4.0112 -3.59440 0
4 0.32924 -4.4552 4.5718 -0.98880 0
We can see that the first four columns contain the continuous wavelet features, while the last column is the binary target variable indicating whether a note is authentic (class 0) or fake (class 1).
Exploratory Data Analysis
Before building our deep learning model, let‘s explore the dataset to gain insights into the distribution and relationships of the features. We‘ll start by visualizing the distributions of each wavelet feature using seaborn‘s distplot function.
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(16,8))
for i, col in enumerate(data.columns[:4]):
plt.subplot(1,4,i+1)
sns.distplot(data[col], hist_kws={‘alpha‘:0.2})
plt.title(col)
plt.tight_layout()
plt.show()

The distribution plots reveal some interesting characteristics of the wavelet features:
- Variance: Has a bimodal distribution with peaks around 0 and 7, indicating two distinct clusters of notes.
- Skewness: Centered around 0 but with a slight positive skew and some outliers on the right tail.
- Kurtosis: Shows a sharp peak near 0 and a long right tail, suggesting a leptokurtic distribution.
- Entropy: Roughly uniformly distributed across its range with a few spikes at certain values.
None of the features appear to be normally distributed, which suggests that scaling or transforming the data may be beneficial for our model.
Let‘s also examine the relationships between the features using a pairplot:
sns.pairplot(data, hue=‘class‘, palette=‘husl‘)
plt.show()

The pairplot shows the pairwise relationships between features, with the diagonal displaying the individual feature distributions. The points are color-coded by the authentic (blue) and forged (orange) class labels.
We can observe a few notable patterns:
- There appears to be a strong negative correlation between variance and skewness, with authentic notes clustered in the upper left and forged notes in the lower right.
- Kurtosis and entropy also show some separation between the classes, with forged notes having higher kurtosis and lower entropy values on average.
These visual insights suggest that the chosen wavelet features do indeed capture discriminative information for distinguishing authentic and counterfeit notes. However, the nonlinear nature of the class boundaries motivates the use of a more sophisticated model than a simple linear classifier.
Building the Keras Sequential Model
Now that we‘ve explored the dataset, let‘s build and train a deep learning model to predict the authenticity of bank notes. We‘ll use the Keras Sequential API to construct a feedforward neural network.
First, we‘ll preprocess the data by splitting it into training and testing sets and scaling the input features to the range [0, 1] using MinMaxScaler:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
X = data[[‘variance‘, ‘skewness‘, ‘kurtosis‘, ‘entropy‘]]
y = data[‘class‘]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
Our sequential model will consist of three fully connected layers:
- An input layer with 4 units (one for each wavelet feature) and ReLU activation
- A hidden layer with 16 units and ReLU activation
- An output layer with 1 unit and sigmoid activation for the binary classification
We‘ll use the binary cross-entropy loss function and the Adam optimizer, which adapts the learning rate for each parameter based on its historical gradients [6].
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential([
Dense(4, activation=‘relu‘, input_shape=(4,)),
Dense(16, activation=‘relu‘),
Dense(1, activation=‘sigmoid‘)
])
model.compile(optimizer=‘adam‘,
loss=‘binary_crossentropy‘,
metrics=[‘accuracy‘])
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_split=0.2)
After 50 training epochs, we can visualize the learning curves:
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(history.history[‘loss‘], label=‘Training Loss‘)
plt.plot(history.history[‘val_loss‘], label=‘Validation Loss‘)
plt.title(‘Loss Curves‘)
plt.ylabel(‘Loss‘)
plt.xlabel(‘Epoch‘)
plt.legend()
plt.subplot(1,2,2)
plt.plot(history.history[‘accuracy‘], label=‘Training Accuracy‘)
plt.plot(history.history[‘val_accuracy‘], label=‘Validation Accuracy‘)
plt.title(‘Accuracy Curves‘)
plt.ylabel(‘Accuracy‘)
plt.xlabel(‘Epoch‘)
plt.legend()
plt.tight_layout()
plt.show()

The training and validation loss curves decrease steadily and converge around a low value, indicating successful learning. The accuracy curves also show strong performance on both the training and validation sets, reaching over 99% accuracy within the first 20 epochs. This suggests that our model is able to effectively capture the patterns in the wavelet features to distinguish real and fake notes.
Model Evaluation
To assess our model‘s generalization performance, we‘ll evaluate it on the held-out test set:
loss, accuracy = model.evaluate(X_test, y_test)
print(f‘Test Loss: {loss:.4f}‘)
print(f‘Test Accuracy: {accuracy:.4f}‘)
Test Loss: 0.0038
Test Accuracy: 0.9989
Our model achieves an impressive 99.9% accuracy on the unseen test data. To dive deeper, we can compute additional classification metrics using scikit-learn:
from sklearn.metrics import classification_report, confusion_matrix
y_pred = (model.predict(X_test) > 0.5).astype(int)
print(‘Classification Report:‘)
print(classification_report(y_test, y_pred))
print(‘Confusion Matrix:‘)
print(confusion_matrix(y_test, y_pred))
Classification Report:
precision recall f1-score support
0 1.00 1.00 1.00 495
1 1.00 0.99 1.00 257
accuracy 1.00 752
macro avg 1.00 1.00 1.00 752
weighted avg 1.00 1.00 1.00 752
Confusion Matrix:
[[491 0]
[ 1 260]]
The classification report shows that our model achieves perfect precision and near-perfect recall for both the authentic and counterfeit classes, with F1 scores of 1.00. The confusion matrix confirms that the model makes only one misclassification out of the 752 test samples.
We can also visualize the model‘s performance using a receiver operating characteristic (ROC) curve, which plots the true positive rate against the false positive rate at various classification thresholds:
from sklearn.metrics import roc_curve, auc
y_prob = model.predict(X_test).ravel()
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(8,6))
plt.plot(fpr, tpr, linewidth=2, label=f‘AUC = {roc_auc:.3f}‘)
plt.plot([0,1], [0,1], ‘k--‘)
plt.xlabel(‘False Positive Rate‘)
plt.ylabel(‘True Positive Rate‘)
plt.title(‘ROC Curve‘)
plt.legend()
plt.show()

The ROC curve hugs the top-left corner of the plot, indicating excellent discrimination between the real and fake notes. The area under the curve (AUC) is 0.999, very close to the perfect value of 1.
These evaluation metrics confirm the strong predictive performance of our Keras sequential model. Of course, it‘s important to note that this high accuracy is achieved on a relatively small and clean dataset. In real-world scenarios with larger and more diverse data, we may need to employ additional techniques like regularization, cross-validation, and hyperparameter tuning to ensure robust generalization.
Future Directions and Conclusion
In this article, we‘ve seen how deep learning with Keras can be used to build a highly accurate bank note authentication system. By training a feedforward neural network on wavelet-transformed image features, we were able to achieve over 99% accuracy in detecting counterfeit bills.
There are several potential extensions and improvements to our approach, such as:
- Experimenting with different model architectures like convolutional neural networks (CNNs) that can learn directly from raw note images
- Using transfer learning to leverage pre-trained image models like VGG or ResNet for feature extraction
- Incorporating additional note security features like watermarks or holograms into the model
- Testing the model‘s robustness to adversarial examples and studying potential countermeasures
- Deploying the trained model as a web service or mobile app for real-time note authentication
Currency counterfeiting remains a significant challenge for central banks and law enforcement agencies worldwide. By combining machine learning with domain expertise in document security and forensics, we can develop powerful tools to help combat this threat at scale. The Keras framework provides an accessible and flexible platform for building state-of-the-art deep learning models for this important application.
Beyond bank notes, similar techniques can be applied to detect fraudulent documents like checks, identity cards, and passports. As criminals become increasingly sophisticated in their forgery methods, artificial intelligence will play a crucial role in safeguarding the integrity of our financial and security infrastructure. It‘s an exciting time to be working at the intersection of AI and anti-counterfeiting, with many opportunities for innovation and impact.