tripletlib 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 templateprotection
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.4
2
+ Name: tripletlib
3
+ Version: 0.1.0
4
+ Summary: A lightweight library for training and evaluating embedding models with triplet loss
5
+ Author: Ted Kane
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: torch
11
+ Requires-Dist: numpy
12
+ Requires-Dist: scikit-learn
13
+ Requires-Dist: scipy
14
+ Provides-Extra: examples
15
+ Requires-Dist: matplotlib; extra == "examples"
16
+ Requires-Dist: pandas; extra == "examples"
17
+ Dynamic: license-file
18
+
19
+ # TripletLib
20
+
21
+ TripletLib is a lightweight Python library for training and evaluating embedding models using **triplet loss**. It is designed to help you build models that learn meaningful embeddings for images, time series, or any vector data, enabling tasks like verification, retrieval, or classification based on similarity.
22
+
23
+ ## What is Triplet Loss?
24
+
25
+ A "triplet" is a set of 3 samples of data `(anchor, positive, negative)`. The `anchor` is a data sample from a specific class, the `positive` is another sample from the *same* class, and the `negative` is a sample from an entirely different class.
26
+ Triplet loss is a type of metric learning objective that trains an embedding model to map inputs into a vector space such that:
27
+
28
+ - Samples from the **same class** (e.g., anchor and positive) are close together.
29
+ - Samples from **different classes** (e.g., anchor and negative) are far apart.
30
+
31
+ This is particularly useful for tasks like biometric identification (e.g., face recognition), where traditional classification cannot generalize to unseen classes (new faces).
32
+
33
+ ## Features
34
+
35
+ - Base `EmbeddingModel` class with a built-in training loop.
36
+ - `TripletDataset` wrapper to automatically generate triplets from any dataset.
37
+ - Utilities for evaluating embeddings with **EER** and **AUC** metrics.
38
+ - Compatible with PyTorch and supports GPU acceleration.
39
+
40
+ ## Installation
41
+
42
+ You can install TripletLib via pip:
43
+
44
+ ```bash
45
+ pip install tripletlib
46
+ ```
47
+ ## Usage
48
+ ```python
49
+ import torch
50
+ from tripletlib.triplet_utils import EmbeddingModel, TripletDataset
51
+ from torch.utils.data import DataLoader
52
+
53
+ # Example: using a simple linear embedding model
54
+ class LinearEmbeddingModel(EmbeddingModel):
55
+ def __init__(self, input_size, embedding_dim=64, lr=1e-3, margin=1.0, device="cpu"):
56
+ super().__init__(embedding_dim, margin=margin, device=device)
57
+ self.fc = torch.nn.Sequential(
58
+ torch.nn.Linear(input_size, 128),
59
+ torch.nn.ReLU(),
60
+ torch.nn.Linear(128, embedding_dim)
61
+ )
62
+ self.optimizer = torch.optim.Adam(self.parameters(), lr=lr)
63
+
64
+ def forward(self, x):
65
+ x = self.fc(x)
66
+ return torch.nn.functional.normalize(x, p=2, dim=1)
67
+
68
+ # Prepare your dataset as a list of (feature, label) tuples
69
+ train_dataset = [(torch.randn(10), label) for label in range(5) for _ in range(20)]
70
+ triplet_train = TripletDataset(train_dataset)
71
+ dataloader_train = DataLoader(triplet_train, batch_size=16, shuffle=True)
72
+
73
+ # Instantiate and train the model
74
+ model = LinearEmbeddingModel(input_size=10, embedding_dim=64, lr=1e-3)
75
+ history = model.fit(dataloader_train, epochs=5)
76
+ ```
77
+
78
+ ## Examples
79
+ You can find examples of real usages in `/examples`, including:
80
+ - Keystroke Dynamics: Comparing typing patterns to determine if they are from the same individual.
81
+ - More to come...
82
+
@@ -0,0 +1,64 @@
1
+ # TripletLib
2
+
3
+ TripletLib is a lightweight Python library for training and evaluating embedding models using **triplet loss**. It is designed to help you build models that learn meaningful embeddings for images, time series, or any vector data, enabling tasks like verification, retrieval, or classification based on similarity.
4
+
5
+ ## What is Triplet Loss?
6
+
7
+ A "triplet" is a set of 3 samples of data `(anchor, positive, negative)`. The `anchor` is a data sample from a specific class, the `positive` is another sample from the *same* class, and the `negative` is a sample from an entirely different class.
8
+ Triplet loss is a type of metric learning objective that trains an embedding model to map inputs into a vector space such that:
9
+
10
+ - Samples from the **same class** (e.g., anchor and positive) are close together.
11
+ - Samples from **different classes** (e.g., anchor and negative) are far apart.
12
+
13
+ This is particularly useful for tasks like biometric identification (e.g., face recognition), where traditional classification cannot generalize to unseen classes (new faces).
14
+
15
+ ## Features
16
+
17
+ - Base `EmbeddingModel` class with a built-in training loop.
18
+ - `TripletDataset` wrapper to automatically generate triplets from any dataset.
19
+ - Utilities for evaluating embeddings with **EER** and **AUC** metrics.
20
+ - Compatible with PyTorch and supports GPU acceleration.
21
+
22
+ ## Installation
23
+
24
+ You can install TripletLib via pip:
25
+
26
+ ```bash
27
+ pip install tripletlib
28
+ ```
29
+ ## Usage
30
+ ```python
31
+ import torch
32
+ from tripletlib.triplet_utils import EmbeddingModel, TripletDataset
33
+ from torch.utils.data import DataLoader
34
+
35
+ # Example: using a simple linear embedding model
36
+ class LinearEmbeddingModel(EmbeddingModel):
37
+ def __init__(self, input_size, embedding_dim=64, lr=1e-3, margin=1.0, device="cpu"):
38
+ super().__init__(embedding_dim, margin=margin, device=device)
39
+ self.fc = torch.nn.Sequential(
40
+ torch.nn.Linear(input_size, 128),
41
+ torch.nn.ReLU(),
42
+ torch.nn.Linear(128, embedding_dim)
43
+ )
44
+ self.optimizer = torch.optim.Adam(self.parameters(), lr=lr)
45
+
46
+ def forward(self, x):
47
+ x = self.fc(x)
48
+ return torch.nn.functional.normalize(x, p=2, dim=1)
49
+
50
+ # Prepare your dataset as a list of (feature, label) tuples
51
+ train_dataset = [(torch.randn(10), label) for label in range(5) for _ in range(20)]
52
+ triplet_train = TripletDataset(train_dataset)
53
+ dataloader_train = DataLoader(triplet_train, batch_size=16, shuffle=True)
54
+
55
+ # Instantiate and train the model
56
+ model = LinearEmbeddingModel(input_size=10, embedding_dim=64, lr=1e-3)
57
+ history = model.fit(dataloader_train, epochs=5)
58
+ ```
59
+
60
+ ## Examples
61
+ You can find examples of real usages in `/examples`, including:
62
+ - Keystroke Dynamics: Comparing typing patterns to determine if they are from the same individual.
63
+ - More to come...
64
+
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tripletlib"
7
+ version = "0.1.0"
8
+ description = "A lightweight library for training and evaluating embedding models with triplet loss"
9
+ authors = [
10
+ { name = "Ted Kane" }
11
+ ]
12
+ readme = "README.md"
13
+ license = { text = "MIT" }
14
+ requires-python = ">=3.8"
15
+
16
+ dependencies = [
17
+ "torch",
18
+ "numpy",
19
+ "scikit-learn",
20
+ "scipy",
21
+ ]
22
+
23
+ [project.optional-dependencies]
24
+ examples = ["matplotlib", "pandas"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ from .triplet_utils import *
2
+ from .evaluation_utils import *
@@ -0,0 +1,77 @@
1
+ import numpy as np
2
+ import torch
3
+ from scipy.interpolate import interp1d
4
+ from scipy.optimize import brentq
5
+ from sklearn.metrics import roc_auc_score, roc_curve
6
+
7
+
8
+ def compute_eer_from_scores(y_true, y_scores):
9
+ """
10
+ Compute Equal Error Rate (EER) from true labels and predicted scores.
11
+
12
+ Args:
13
+ y_true (array-like): True binary labels (0 or 1).
14
+ y_scores (array-like): Predicted scores or probabilities.
15
+
16
+ Returns:
17
+ eer (float): Equal Error Rate.
18
+ eer_threshold (float): Score threshold corresponding to EER.
19
+ """
20
+ # Compute FPR, TPR, thresholds
21
+ fpr, tpr, thresholds = roc_curve(y_true, y_scores, pos_label=1)
22
+
23
+ eer = brentq(lambda x: 1. - x - interp1d(fpr, tpr)(x), 0., 1.)
24
+ eer_threshold = interp1d(fpr, thresholds)(eer)
25
+ return 1-eer, eer_threshold
26
+
27
+
28
+ def compute_eer_from_triplets(anchor_emb, positive_emb, negative_emb):
29
+ """
30
+ Compute EER from a batch of triplet embeddings.
31
+
32
+ Args:
33
+ anchor_emb (torch.Tensor): [batch_size, embedding_dim]
34
+ positive_emb (torch.Tensor): [batch_size, embedding_dim]
35
+ negative_emb (torch.Tensor): [batch_size, embedding_dim]
36
+
37
+ Returns:
38
+ eer (float): Equal Error Rate.
39
+ eer_threshold (float): Distance threshold corresponding to EER.
40
+ """
41
+ y_true, y_scores = compute_dists_from_triplets(anchor_emb, positive_emb, negative_emb)
42
+ eer, eer_threshold = compute_eer_from_scores(y_true, y_scores)
43
+ return eer, eer_threshold
44
+
45
+
46
+ def compute_auc_from_triplets(anchor_emb, positive_emb, negative_emb):
47
+ """
48
+ Compute ROC AUC from a batch of triplet embeddings.
49
+
50
+ Args:
51
+ anchor_emb (torch.Tensor): [batch_size, embedding_dim]
52
+ positive_emb (torch.Tensor): [batch_size, embedding_dim]
53
+ negative_emb (torch.Tensor): [batch_size, embedding_dim]
54
+
55
+ Returns:
56
+ auc (float): Area Under the ROC Curve.
57
+ """
58
+ y_true, y_scores = compute_dists_from_triplets(anchor_emb, positive_emb, negative_emb)
59
+
60
+ # Compute ROC AUC
61
+ auc = roc_auc_score(y_true, y_scores)
62
+ return auc
63
+
64
+
65
+ def compute_dists_from_triplets(anchor_emb, positive_emb, negative_emb):
66
+ anchor_emb = anchor_emb.view(anchor_emb.size(0), -1)
67
+ positive_emb = positive_emb.view(positive_emb.size(0), -1)
68
+ negative_emb = negative_emb.view(negative_emb.size(0), -1)
69
+
70
+ # Compute Euclidean distances
71
+ pos_distances = torch.norm(anchor_emb - positive_emb, p=2, dim=1).cpu().detach().numpy()
72
+ neg_distances = torch.norm(anchor_emb - negative_emb, p=2, dim=1).cpu().detach().numpy()
73
+
74
+ # Labels: 1 for positive (same class), 0 for negative (different class)
75
+ y_alike = np.concatenate([np.ones_like(pos_distances), np.zeros_like(neg_distances)])
76
+ total_dists = np.concatenate([pos_distances, neg_distances])
77
+ return y_alike, total_dists
@@ -0,0 +1,193 @@
1
+ from abc import ABC, abstractmethod
2
+ import random
3
+
4
+ import numpy as np
5
+ import torch
6
+ from torch.utils.data import Dataset
7
+ from tqdm import tqdm
8
+
9
+ from .evaluation_utils import compute_eer_from_triplets, compute_auc_from_triplets, compute_dists_from_triplets
10
+
11
+
12
+ class EmbeddingModel(torch.nn.Module, ABC):
13
+ """
14
+ Base class for models trained with triplet loss.
15
+ Subclasses must implement forward() to compute embeddings.
16
+ """
17
+
18
+ def __init__(self, embedding_dim, margin=1.0, device="cpu"):
19
+ super().__init__()
20
+ self.embedding_dim = embedding_dim
21
+ self.device = device
22
+
23
+ # Triplet loss (standard margin-based)
24
+ self.criterion = torch.nn.TripletMarginLoss(margin=margin, p=2)
25
+
26
+ @abstractmethod
27
+ def forward(self, x):
28
+ """
29
+ Compute embeddings for input batch x.
30
+ Must be implemented by subclasses.
31
+ """
32
+ pass
33
+
34
+ def fit(self, dataloader_train, dataloader_val=None, epochs=10, model_out_path='model_out.pth') -> dict[
35
+ str, list[float]]:
36
+ """
37
+ Train the model using triplet loss.
38
+
39
+ Args:
40
+ dataloader_train: iterable yielding (anchor, positive, negative) batches
41
+ dataloader_val: iterable yielding (anchor, positive, negative) batches
42
+ epochs: number of training epochs
43
+ model_out_path: output path for the model
44
+
45
+ Returns:
46
+ history: a dictionary containing historical performance metrics of the model across all epochs
47
+ """
48
+
49
+ history = dict()
50
+ history['aucs_train'] = []
51
+ history['aucs_val'] = []
52
+ history['losses_train'] = []
53
+ history['losses_val'] = []
54
+ history['eers_train'] = []
55
+ history['eers_val'] = []
56
+
57
+ self.to(self.device)
58
+ self.train()
59
+
60
+ for epoch in range(epochs):
61
+ epoch_loss_train = 0.0
62
+ epoch_auc_train = 0.0
63
+ epoch_eer_train = 0.0
64
+ for (anchor, positive, negative) in tqdm(dataloader_train, total=len(dataloader_train),
65
+ desc='Training Loop'):
66
+ anchor, positive, negative = (
67
+ anchor.to(self.device),
68
+ positive.to(self.device),
69
+ negative.to(self.device),
70
+ )
71
+
72
+ # Forward pass: compute embeddings
73
+ anchor_emb = self.forward(anchor)
74
+ pos_emb = self.forward(positive)
75
+ neg_emb = self.forward(negative)
76
+
77
+ # Compute loss
78
+ loss = self.criterion(anchor_emb, pos_emb, neg_emb)
79
+
80
+ # Backprop
81
+ self.optimizer.zero_grad()
82
+ loss.backward()
83
+ self.optimizer.step()
84
+
85
+ epoch_loss_train += loss.item()
86
+ epoch_auc_train += compute_auc_from_triplets(anchor_emb, pos_emb, neg_emb)
87
+ epoch_eer_train += compute_eer_from_triplets(anchor_emb, pos_emb, neg_emb)[0]
88
+
89
+ mean_loss_train = epoch_loss_train / len(dataloader_train)
90
+ mean_auc_train = epoch_auc_train / len(dataloader_train)
91
+ mean_eer_train = epoch_eer_train / len(dataloader_train)
92
+ history['eers_train'].append(mean_eer_train)
93
+ history['aucs_train'].append(mean_auc_train)
94
+ history['losses_train'].append(mean_loss_train)
95
+ print(f"Epoch {epoch + 1}: Train Loss: {mean_loss_train:.4f}")
96
+
97
+ if dataloader_val is not None:
98
+ self.eval()
99
+ epoch_loss_val = 0.0
100
+ epoch_auc_val = 0.0
101
+ epoch_eer_val = 0.0
102
+ with torch.no_grad():
103
+ for (anchor, positive, negative) in tqdm(dataloader_val, total=len(dataloader_val),
104
+ desc='Validation Loop'):
105
+ anchor, positive, negative = (
106
+ anchor.to(self.device),
107
+ positive.to(self.device),
108
+ negative.to(self.device),
109
+ )
110
+
111
+ # Forward pass: compute embeddings
112
+ anchor_emb = self.forward(anchor)
113
+ pos_emb = self.forward(positive)
114
+ neg_emb = self.forward(negative)
115
+
116
+ # Compute loss
117
+ loss = self.criterion(anchor_emb, pos_emb, neg_emb)
118
+
119
+ epoch_loss_val += loss.item()
120
+ epoch_auc_val += compute_auc_from_triplets(anchor_emb, pos_emb, neg_emb)
121
+ epoch_eer_val += compute_eer_from_triplets(anchor_emb, pos_emb, neg_emb)[0]
122
+
123
+ mean_loss_val = epoch_loss_val / len(dataloader_val)
124
+ mean_auc_val = epoch_auc_val / len(dataloader_val)
125
+ mean_eer_val = epoch_eer_val / len(dataloader_val)
126
+ history['eers_val'].append(mean_eer_val)
127
+ history['aucs_val'].append(mean_auc_val)
128
+ history['losses_val'].append(mean_loss_val)
129
+ print(f"Epoch {epoch + 1}: Validation Loss: {mean_loss_val:.4f}")
130
+
131
+ torch.save(self.state_dict(), model_out_path)
132
+ return history
133
+
134
+ def predict_triplet_distances(self, dataloader):
135
+ total_alike = []
136
+ total_dists = []
137
+ with torch.no_grad():
138
+ for (anchor, positive, negative) in tqdm(dataloader, total=len(dataloader),
139
+ desc='Evaluation Loop'):
140
+ anchor, positive, negative = (
141
+ anchor.to(self.device),
142
+ positive.to(self.device),
143
+ negative.to(self.device),
144
+ )
145
+
146
+ # Forward pass: compute embeddings
147
+ anchor_emb = self.forward(anchor)
148
+ pos_emb = self.forward(positive)
149
+ neg_emb = self.forward(negative)
150
+ y_alike, dists = compute_dists_from_triplets(anchor_emb, pos_emb, neg_emb)
151
+ total_alike.extend(y_alike)
152
+ total_dists.extend(dists)
153
+
154
+ return np.array(total_alike), np.array(total_dists)
155
+
156
+
157
+ class TripletDataset(Dataset):
158
+ def __init__(self, base_dataset):
159
+ """
160
+ Wraps a basic dataset to generate triplets.
161
+
162
+ Args:
163
+ base_dataset: base dataset to be wrapped
164
+ """
165
+ self.base_dataset = base_dataset
166
+
167
+ # Build index lists for each class
168
+ self.class_to_indices = {}
169
+ for idx, (_, label) in enumerate(self.base_dataset):
170
+ if label not in self.class_to_indices:
171
+ self.class_to_indices[label] = []
172
+ self.class_to_indices[label].append(idx)
173
+
174
+ self.labels = [label for _, label in self.base_dataset]
175
+
176
+ def __getitem__(self, index):
177
+ anchor_sample, anchor_label = self.base_dataset[index]
178
+
179
+ # Positive: random sample with the same label (different index)
180
+ positive_index = index
181
+ while positive_index == index: # TODO: This can get stuck forever, make sure it's possible.
182
+ positive_index = random.choice(self.class_to_indices[anchor_label])
183
+ positive_sample, _ = self.base_dataset[positive_index]
184
+
185
+ # Negative: random sample from a different label
186
+ negative_label = random.choice([label for label in self.class_to_indices.keys() if label != anchor_label])
187
+ negative_index = random.choice(self.class_to_indices[negative_label])
188
+ negative_sample, _ = self.base_dataset[negative_index]
189
+
190
+ return anchor_sample, positive_sample, negative_sample
191
+
192
+ def __len__(self):
193
+ return len(self.base_dataset)
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.4
2
+ Name: tripletlib
3
+ Version: 0.1.0
4
+ Summary: A lightweight library for training and evaluating embedding models with triplet loss
5
+ Author: Ted Kane
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: torch
11
+ Requires-Dist: numpy
12
+ Requires-Dist: scikit-learn
13
+ Requires-Dist: scipy
14
+ Provides-Extra: examples
15
+ Requires-Dist: matplotlib; extra == "examples"
16
+ Requires-Dist: pandas; extra == "examples"
17
+ Dynamic: license-file
18
+
19
+ # TripletLib
20
+
21
+ TripletLib is a lightweight Python library for training and evaluating embedding models using **triplet loss**. It is designed to help you build models that learn meaningful embeddings for images, time series, or any vector data, enabling tasks like verification, retrieval, or classification based on similarity.
22
+
23
+ ## What is Triplet Loss?
24
+
25
+ A "triplet" is a set of 3 samples of data `(anchor, positive, negative)`. The `anchor` is a data sample from a specific class, the `positive` is another sample from the *same* class, and the `negative` is a sample from an entirely different class.
26
+ Triplet loss is a type of metric learning objective that trains an embedding model to map inputs into a vector space such that:
27
+
28
+ - Samples from the **same class** (e.g., anchor and positive) are close together.
29
+ - Samples from **different classes** (e.g., anchor and negative) are far apart.
30
+
31
+ This is particularly useful for tasks like biometric identification (e.g., face recognition), where traditional classification cannot generalize to unseen classes (new faces).
32
+
33
+ ## Features
34
+
35
+ - Base `EmbeddingModel` class with a built-in training loop.
36
+ - `TripletDataset` wrapper to automatically generate triplets from any dataset.
37
+ - Utilities for evaluating embeddings with **EER** and **AUC** metrics.
38
+ - Compatible with PyTorch and supports GPU acceleration.
39
+
40
+ ## Installation
41
+
42
+ You can install TripletLib via pip:
43
+
44
+ ```bash
45
+ pip install tripletlib
46
+ ```
47
+ ## Usage
48
+ ```python
49
+ import torch
50
+ from tripletlib.triplet_utils import EmbeddingModel, TripletDataset
51
+ from torch.utils.data import DataLoader
52
+
53
+ # Example: using a simple linear embedding model
54
+ class LinearEmbeddingModel(EmbeddingModel):
55
+ def __init__(self, input_size, embedding_dim=64, lr=1e-3, margin=1.0, device="cpu"):
56
+ super().__init__(embedding_dim, margin=margin, device=device)
57
+ self.fc = torch.nn.Sequential(
58
+ torch.nn.Linear(input_size, 128),
59
+ torch.nn.ReLU(),
60
+ torch.nn.Linear(128, embedding_dim)
61
+ )
62
+ self.optimizer = torch.optim.Adam(self.parameters(), lr=lr)
63
+
64
+ def forward(self, x):
65
+ x = self.fc(x)
66
+ return torch.nn.functional.normalize(x, p=2, dim=1)
67
+
68
+ # Prepare your dataset as a list of (feature, label) tuples
69
+ train_dataset = [(torch.randn(10), label) for label in range(5) for _ in range(20)]
70
+ triplet_train = TripletDataset(train_dataset)
71
+ dataloader_train = DataLoader(triplet_train, batch_size=16, shuffle=True)
72
+
73
+ # Instantiate and train the model
74
+ model = LinearEmbeddingModel(input_size=10, embedding_dim=64, lr=1e-3)
75
+ history = model.fit(dataloader_train, epochs=5)
76
+ ```
77
+
78
+ ## Examples
79
+ You can find examples of real usages in `/examples`, including:
80
+ - Keystroke Dynamics: Comparing typing patterns to determine if they are from the same individual.
81
+ - More to come...
82
+
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ tripletlib/__init__.py
5
+ tripletlib/evaluation_utils.py
6
+ tripletlib/triplet_utils.py
7
+ tripletlib.egg-info/PKG-INFO
8
+ tripletlib.egg-info/SOURCES.txt
9
+ tripletlib.egg-info/dependency_links.txt
10
+ tripletlib.egg-info/requires.txt
11
+ tripletlib.egg-info/top_level.txt
@@ -0,0 +1,8 @@
1
+ torch
2
+ numpy
3
+ scikit-learn
4
+ scipy
5
+
6
+ [examples]
7
+ matplotlib
8
+ pandas
@@ -0,0 +1 @@
1
+ tripletlib