deepLearn addLayer

Complex: Signature Verification with a Weight-Sharing Siamese Network

Scénario de test & Cas d'usage

Business Context

A financial institution needs to verify customer signatures by comparing a new signature image with a reference image on file. This requires a Siamese Network, which uses two identical, parallel CNN branches that share the same weights to process the two images and produce comparable feature vectors.
About the Set : deepLearn

Creation and training of deep neural networks.

Discover all actions of deepLearn
Data Preparation

This scenario focuses on building the complex model architecture. We will create an empty model table named 'siamese_signature_model'.

Copied!
1/* Model architecture test. No
2data step needed. */

Étapes de réalisation

1
Initialize the model and add two separate INPUT layers, one for the 'reference_signature' and one for the 'new_signature'.
Copied!
1PROC CAS;
2DEEPLEARN.addLayer / modelTable={name='siamese_signature_model', replace=true} name='input_ref' layer={type='input', nchannels=1, width=150, height=50};
3DEEPLEARN.addLayer / modelTable={name='siamese_signature_model'} name='input_new' layer={type='input', nchannels=1, width=150, height=50};
4RUN;
2
Build the first branch of the network. Add a Convolutional layer ('conv1_ref') and a Pooling layer ('pool1_ref') connected to the 'input_ref' layer.
Copied!
1PROC CAS;
2DEEPLEARN.addLayer / modelTable={name='siamese_signature_model'} name='conv1_ref' layer={type='convolution', nFilters=8, width=5, act='relu'} srcLayers={'input_ref'};
3DEEPLEARN.addLayer / modelTable={name='siamese_signature_model'} name='pool1_ref' layer={type='pooling', width=2, pool='max'} srcLayers={'conv1_ref'};
4RUN;
3
Build the second branch. Add a Convolutional layer ('conv1_new') connected to 'input_new'. Critically, use the 'sharingWeights' parameter to share weights from 'conv1_ref'.
Copied!
1PROC CAS;
2DEEPLEARN.addLayer /
3 modelTable={name='siamese_signature_model'}
4 name='conv1_new'
5 layer={type='convolution', nFilters=8, width=5, act='relu'}
6 srcLayers={'input_new'}
7 sharingWeights='conv1_ref';
8RUN;
4
Add the corresponding Pooling layer for the second branch, also sharing weights from its counterpart in the first branch (though pooling layers have no weights, this tests syntax).
Copied!
1PROC CAS;
2DEEPLEARN.addLayer /
3 modelTable={name='siamese_signature_model'}
4 name='pool1_new'
5 layer={type='pooling', width=2, pool='max'}
6 srcLayers={'conv1_new'}
7 sharingWeights='pool1_ref';
8RUN;
5
Add a CONCAT layer to merge the outputs from the two parallel branches ('pool1_ref' and 'pool1_new') before feeding them to the final decision layers.
Copied!
1PROC CAS;
2DEEPLEARN.addLayer /
3 modelTable={name='siamese_signature_model'}
4 name='concat_features'
5 layer={type='concat'}
6 srcLayers={'pool1_ref', 'pool1_new'};
7RUN;

Expected Result


A Siamese network architecture is created in the 'siamese_signature_model' table. The model summary should show two input layers and two parallel branches ('conv1_ref'/'pool1_ref' and 'conv1_new'/'pool1_new') whose outputs are merged by the 'concat_features' layer. The model definition should confirm that 'conv1_new' shares weights with 'conv1_ref'.