Compnet
Supplementary Materials for the 2021 IEEE SPL paper "CompNet: Competitive Neural Network for Palmprint Recognition Using Learnable Gabor Kernels"
Install / Use
/learn @xuliangcs/CompnetREADME
CompNet
CompNet: Competitive Neural Network for Palmprint Recognition Using Learnable Gabor Kernels
[ paper | supp | cite | license ]
<img src="./res/compnet.png" alt="Framework of the CompNet" style="zoom:80%;" />1. Related Materials
-
Paper: online
-
Supplementary Material: pdf
-
Publicly Available Datasets: Tongji, IITD, REST, NTU, XJTU-UP
2. Visualizations

Fig. 2.1 CB17x17_Gabor feature maps obtained at different epochs

Fig. 2.2 CB17x17_SCC feature maps obtained at different epochs

Fig. 2.3 CB7x7_Conv1 feature maps obtained at different epochs
<img src="./res/08_cb2_conv2.gif" style="zoom:200%;" />Fig. 2.4 CB17x17_Conv2 feature maps obtained at different epochs
Each row represents feature maps obtained from one ROI image, and each column corresponds to a single feature channel.
3. Requirements
Recommanded hardware requirement for training:
- GPU Mem $\gt$ 6G
- CPU Mem $\geq$ 16G (32G is recommended for highspeed data augmentation)
Software development environment:
- cuda&cudnn&gpu-driver
Anaconda: download & installPyTorch: installation command lines are as followsconda create -n compnet python=3.8 conda activate compnet conda install pytorch==1.7.0 torchvision==0.8.0 torchaudio==0.7.0 cudatoolkit=11.0 -c pytorch pip install -r requirements.txt
tips:
requirements.txtcould be found at the root folder of this project- for PyTorch 1.7 with other CUDA versions, please refer to the official pytorch installation commands
- the speed of different network servers and conda sources varies a lot when install the above packages
- for more details of the software environment, pls refer to the
pip listrst - version selection strategy: pytorch->cuda->cudnn
Other tested versions:
- cuda: 10.2 / 11.0
- cudnn: 7.6.5.32 / 9.1.0.70
- pytorch: 1.2 / 1.7
- torchvision: 0.4 / 0.8
- python: 3.7.4 / 3.8.19
- opencv: 3.2.7 / 4.8.1.78
- numpy: 1.16.4 / 1.24.3
- scikit-learn: 0.21.3 / 1.0.2
- scipy: 1.3.1 / 1.10.1
Tips: If a particular version is no longer available for download, you can try replacing it with a newer version. However, running the code may encounter compatibility issues, such as deprecated functions or changes in default parameters. Please search for solutions based on the error messages and the actual intent of the code.
4. PyTorch Implementation
Configurations
-
modify
path1andpath2ingenText.pypath1: path of the training set (e.g., Tongji session1)path2: path of the testing set (e.g., Tongji session2)
-
modify
num_classesintrain.py,test.py, andinference.py- Tongji: 600, IITD: 460, REST: 358, XJTU-UP: 200, KTU: 145
Commands
cd path/to/CompNet/
#in the CompNet folder:
#prepare data
cp ./data/for_reference/genText_xxx.py ./data/genText.py
#where xxx is the dataset name, e.g., tongji =>genText_tongji.py
Modify the DB path variable in ./data/genText.py
#the sample naming format should be consistent with the script's requirements
#more details can be found in the following Dataset preparation section
#generate the training and testing data sets
python ./data/genText.py
mv ./train.txt ./data/
mv ./test.txt ./data/
#train the network
python train.py
#test the model
python test.py
#inference
python inference.py
#Metrics
#obtain the genuine-impostor matching score distribution curve
python getGI.py ./rst/veriEER/scores_xxx.txt scores_xxx
#obtain the EER and the ROC curve
python getEER.py ./rst/veriEER/scores_xxx.txt scores_xxx
The .pth file will be generated at the current folder, and all the other results will be generated in the ./rst folder.
🗞️tips: GPU -> CPU (more details):
# training on GPU, test on CPU
torch.load('net_params.pth', map_location='cpu')
Dataset preparation
- The
genText.pyscript is responsible for traversing images in the dataset folder and parsing class labels (starting from 0) based on each filename's format.- For each sample, the full path (including the filename) and its corresponding class label (separated by a space) are saved as a single line in either the
train.txtortest.txtfile. - In our experiments, each individual palm represents a unique class.
- For each sample, the full path (including the filename) and its corresponding class label (separated by a space) are saved as a single line in either the
- The method used to extract
userIDandsampleIDfrom image filenames is implemented within the script, handling two main scenarios:- For the original Tongji dataset, image filenames range sequentially from
00001.bmpto06000.bmp. Every consecutive group of 10 samples originates from the same palm. Therefore, ingenText.py, theuserID(class label) is derived by integer division of the numeric filename by 10 (i.e., filename // 10). - or other datasets with complex directory structures, preprocessing can be applied to simplify organization, such as renaming files and placing them into a single folder. In such cases, the
userIDparsing logic ingenText.pymust align with the new filename and directory conventions. - The recommended renaming format is:
xxxx_yyyy.zzzxxxxdenotes theuserID, representing a unique palm.yyyydenotes thesampleID, representing an individual capture of that palm.IDswith fewer than four digits are zero-padded on the left.zzzis the image file extension (e.g., bmp, jpg, tiff,etc.).- Example:
0010_0003.bmprepresents the 3rd sample of palm #10.
- For the original Tongji dataset, image filenames range sequentially from
Sample output of genText.py:
test.txt:
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00001.bmp 0
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00002.bmp 0
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00003.bmp 0
...
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00008.bmp 0
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00009.bmp 0
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00010.bmp 0
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00011.bmp 1
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00012.bmp 1
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00013.bmp 1
...
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00018.bmp 1
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00019.bmp 1
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00020.bmp 1
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00021.bmp 2
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00022.bmp 2
/home/sunny/datasets/Tongji/palmprint/ROI/session2/00023.bmp 2
...
/home/sunny/datasets/Tongji/palmprint/ROI/session2/05991.bmp 599
/home/sunny/datasets/Tongji/palmprint/ROI/session2/05992.bmp 599
/home/sunny/datasets/Tongji/palmprint/ROI/session2/05993.bmp 599
...
/home/sunny/datasets/Tongji/palmprint/ROI/session2/05998.bmp 599
/home/sunny/datasets/Tongji/palmprint/ROI/session2/05999.bmp 599
/home/sunny/datasets/Tongji/palmprint/ROI/session2/06000.bmp 599
test.txt (IITD):
/home/sunny/datasets/IITD/roi/0001_0001.bmp 0
/home/sunny/datasets/IITD/roi/0001_0002.bmp 0
/home/sunny/datasets/IITD/roi/0001_0003.bmp 0
/home/sunny/datasets/IITD/roi/0002_0001.bmp 1
/home/sunny/datasets/IITD/roi/0002_0002.bmp 1
/home/sunny/datasets/IITD/roi/0002_0003.bmp 1
/home/sunny/datasets/IITD/roi/0003_0001.bmp 2
/home/sunny/datasets/IITD/roi/0003_0002.bmp 2
/home/sunny/datasets/IITD/roi/0003_0003.bmp 2
/home/sunny/datasets/IITD/roi/0004_0001.bmp 3
/home/sunny/datasets/IITD/roi/0004_0002.bmp 3
/home/sunny/datasets/IITD/roi/0004_0003.bmp 3
...
5. Framework
compnet(
(cb1): CompetitiveBlock(
(gabor_conv2d): GaborConv2d()
(argmax): Softmax(dim=1)
(conv1): Conv2d(9, 32, kernel_size=(5, 5), stride=(1, 1))
(maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 12, kernel_size=(1, 1), stride=(1, 1))
)
(cb2): CompetitiveBlock(
(gabor_conv2d): GaborConv2d()
(argmax): Softmax(dim=1)
(conv1): Conv2d(9, 32, kernel_size=(5, 5), stride=(1, 1))
(maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 12, kernel_size=(1, 1), stride=(1, 1))
)
(cb3): CompetitiveBlock(
(gabor_conv2d): GaborConv2d()
(argmax): Softmax(dim=1)
(conv1): Conv2d(9, 32, kernel_size=(5, 5), stride=(1, 1))
(maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 12, kernel_size=(1, 1), stride=(1, 1))
)
(fc): Linear(in_features=9708, out_features=512, bias=True)
(drop): Dropout(p=0.25, inplace=False)
(arclayer): ArcMarginProduct()
)
6. Citation
🌻If it helps you, we would like you to cite the following paper:🌱
Related Skills
node-connect
353.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
353.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
353.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
