Siamese Networks 介绍
你并不总是需要很大的数据来训练你的模型,学习如何在每类中使用很少的图像数量构建一个模型
当涉及到图像分类时,深度神经网络是最常用的算法。这部分是因为它们可以有任意数量的可训练参数。然而,这是以需要大量数据为代价的,而这些数据有时是不可用的。我将在PyTorch中讨论旨在缓解此类问题的一次性学习,以及如何实现能够使用它的神经网络。
在现代化的深度学习时代的神经网络在每一个任务中几乎都起到了很好的作用,但是这些神经网络依赖于更多的数据来执行。 对于某些问题,如面部识别和验证签名的,我们不能总是依赖于获得更多的数据,来解决这种任务,我们有一个新的类型的神经网络结构称为Siamese Networks。
它只使用几张数字图像,以就能获得更好的预测。 能从很少的数据中学到特征使 Siamese Networks 最近几年很受欢迎。 在本文中,我们将探索它是什么,以及如何开发一个签名认证系统与Pytorch使用 Siamese Networks。
什么是 Siamese Networks
暹罗神经网络是一类神经网络架构 包含两个或两个以上的 相同的(identicala) 子网 。 identicala 这意味着,它们有相同的配置相同的参数和权值。 参数更新跨两个子网镜像。 它是用来发现输入通过比较其特征向量的相似性,所以在许多应用程序中使用这些网络.
传统上,一个神经网络学习如何预测的多个类别。 这带来了一个问题时,我们需要添加或删除新的类别的数据。 在这种情况下,我们必须更新的神经网络和重新训练在全数据集。 此外,深神经网络需要大量数据的训练。 SNNs,另一方面,学习相似的功能。 因此,我们可以训练它,看看如果两个图像都是相同的(这是我们将在这里做的). 这使我们能够进行分类的新类别的数据,而无需训练网络。
Siamese 网络的优缺点:
Siamese Networks的主要优点是,
- 对类别不平衡更健壮:借助一次性学习,每类给定几张图像就足以让 Siamese Networks 在未来识别这些图像
- 对具有最佳分类器的集成很好:鉴于其学习机制与分类器有些不同,使用分类器对其进行简单平均可以比平均 2 个相关监督模型(例如 GBM 和 RF 分类器)做得更好
- 从语义相似性中学习: Siamese 专注于学习嵌入(在更深的层),将相同的类/概念放在一起。因此,可以学习语义相似度。
Siamese 网络的缺点可能是,
- 比普通网络需要更多的训练时间:由于 Siamese 网络涉及二次学习(查看所有可用信息),它比普通分类类型的学习(逐点学习)慢
- 不输出概率:由于训练涉及成对学习,它不会输出预测的概率,而是与每个类的距离
Siamese Networks 中使用的损失函数:
由于Siamese网络的训练通常涉及成对学习,在这种情况下不能使用交叉熵损失,主要有两个损失函数主要用于训练这些Siamese网络,它们是
Triplet loss 是一种损失函数,其中将基线(锚点(anchor))输入与正(真)输入和负(假)输入进行比较。从基线(锚点)输入到正(真)输入的距离被最小化,从基线(锚点)输入到负(假)输入的距离被最大化。
在上面的等式中,alpha 是一个边际项,用于“拉伸”三元组中相似和不同对之间的距离差异,fa、fa、fn 是锚点、正负图像的特征嵌入。
在训练过程中,将图像三元组(锚图像、负图像、正图像)(锚图像、负图像、正图像)作为单个样本输入模型。这背后的想法是锚和正图像之间的距离应该小于锚和负图像之间的距离。
对比损失: 是现在使用率很高的一种流行的损失函数,它是一个 基于距离的损失 与更传统的相反 错误预测损失 该损失用于学习嵌入,其中两个相似点的欧几里德距离较小,而两个不同的点具有较大的欧几里德距离。
我们定义 Dw
使欧氏距离.Dw 被定义为姐妹 siamese 网络输出之间的欧几里德距离。数学上的欧几里得距离是:
Gw
是我们网络对于一张图片的输出. X1 和 X2 输入数据对.
使用 Siamese Networks 进行签名认证
Siamese 网络大多是用于核查系统,例如面部识别签名认证,等等,让我们实现一个签名认证系统使用 Siamese 神经网络在Pytorch
数据集和进行预处理的数据集:
我们将要使用的 ICDAR2011年数据集,其中包括对签名的荷兰语的用户的真正和欺诈行为,并的数据集本身是分开作为训练和文件夹,里面的每个文件夹,其中包括用户的文件夹分开作为真正的和伪造,还有标签的数据集,可作为CSV文件,可以下载的数据集 在这里
现在来送这个的原始数据进入我们的神经网络,我们必须把所有的图像进张量和添加标签的CSV文件的图像,要做到这一点,我们可以使用的定义的数据集类从Pytorch,这里是我们的充分代码看起来像
#preprocessing and loading the dataset
class SiameseDataset():
def __init__(self,training_csv=None,training_dir=None,transform=None):
# used to prepare the labels and images path
self.train_df=pd.read_csv(training_csv)
self.train_df.columns =["image1","image2","label"]
self.train_dir = training_dir
self.transform = transform
def __getitem__(self,index):
# getting the image path
image1_path=os.path.join(self.train_dir,self.train_df.iat[index,0])
image2_path=os.path.join(self.train_dir,self.train_df.iat[index,1])
# Loading the image
img0 = Image.open(image1_path)
img1 = Image.open(image2_path)
img0 = img0.convert("L")
img1 = img1.convert("L")
# Apply image transformations
if self<