【发布时间】:2020-10-07 01:14:54
【问题描述】:
我一直在研究 Yann LeCun 和他的同事在 1994 年引入的用于识别签名的 Siamese 神经网络架构("Signature verification using a Siamese time delay neural network".pdf,NIPS 1994)。
我在理解这个 Siamese 神经网络模型的一般架构时遇到了一些问题,并与 Cross Validated 的朋友讨论了它。我想我终于明白了,所以现在我要进行下一步:实现它。
我们最后说全局算法应该是这样的:
- 为第一个签名创建卷积神经网络 convNetA。
- 为第二个签名创建卷积神经网络 convNetB。
- 将 convNetA 权重与 convNetB 权重绑定。
- 设置余弦相似度函数来计算损失。
- 运行训练(向前和向后)。
我是 Torch 的新手,所以我真的不知道如何实现这个算法。这是我的第一个版本:
-- training
function gradientUpdate(perceptron, dataset, target, learningRate, max_iterations)
for i = 1, max_iterations do
predictionValue = perceptron:forward(dataset)
-- is this the cosine similarity?
-- [output] forward(input):
-- Takes an input object, and computes the corresponding output of the module. In general input and output are Tensors.
io.write(" pre-predictionValue= "..predictionValue .."\n");
-- the minus is because we're goin' backwards
gradientWrtOutput = torch.Tensor({-target})
perceptron:zeroGradParameters() -- zeroGradParameters(): If the module has parameters, this will zero the accumulation of the gradients with respect to these parameters, accumulated through accGradParameters(input, gradOutput,scale) calls. Otherwise, it does nothing.
-- initialization
perceptron:backward(dataset, gradientWrtOutput) -- Performs a backpropagation step through the module, with respect to the given input.
perceptron:updateParameters(learningRate)
end
end
require "os"
require "nn"
input_number=5
output_number=2
-- imagine we have one network we are interested in, it is called "perceptronAAA"
perceptronAAA= nn.Sequential();
perceptronAAA:add(nn.Linear(input_number, output_number))
-- But we want to push examples towards or away from each other
-- so we make another copy of it called perceptronBBB
-- this *shares* the same weights via the set command, but has its own set of temporary gradient storage
-- that's why we create it again (so that the gradients of the pair don't wipe each other)
perceptronBBB= perceptronAAA:clone('weight', 'bias')
-- we make a parallel table that takes a pair of examples as input. they both go through the same (cloned) perceptron
-- ParallelTable is a container module that, in its forward() method, applies the i-th member module to the i-th input, and outputs a table of the set of outputs.
parallel_table = nn.ParallelTable()
parallel_table:add(perceptronAAA)
parallel_table:add(perceptronBBB)
-- now we define our top level network that takes this parallel table and computes the cosine distance betweem
-- the pair of outputs
perceptron= nn.Sequential()
perceptron:add(parallel_table)
perceptron:add(nn.CosineDistance())
-- lets make two example vectors
x_vector = torch.rand(input_number)
y_vector = torch.rand(input_number)
dataset = {x_vector, y_vector}
function dataset:size() return #dataset end
-- matrix having 5 rows * 2 columns
max_iterations = 100
learnRate = 0.1
target = 1 -- the target for cosine similarity is +1 on forwards, that becomes -1 on backwards
-- TRAINING:
-- push the pair x_vector and y_vector together, the distance should get larger..
gradientUpdate(perceptron, dataset, target, learnRate, max_iterations)
您认为这是对具有余弦相似度函数以最小化的连体神经网络的正确实现吗?或者您能看到其中的任何错误/错误内容吗?
2020 年 10 月编辑:感谢大家在过去 5 年里帮助我理解这个模型!我最近出版了一本书章节,解释了我对孪生神经网络的理解,并报告了我在科学文献中发现的这个模型的所有可能应用。你可以在这里找到它:“Siamese neural networks: an overview”。 我希望你能发现它有用:如果这本书的章节现在存在,那也是因为你们当时提供的极好的帮助。再次感谢!
【问题讨论】:
-
这太酷了,你的灵感是什么?
-
对设计的小评论:当您进行信号验证时,航空电子工程使用 3 个系统,这些系统必须在不同的数据集上进行训练:主系统接受输入并产生输出信号。然后使用二级和三级系统检查初级系统信号。如果二级和三级系统不一致,则认为系统 1 有故障并丢弃信号。这是双重冗余验证,对于关键任务黑盒系统非常有用。这种方法应该会稍微简化您的架构。
-
我看到您在我回答后加入了 Code Review,我对您的反馈很感兴趣。请对我的回答发表评论,或在the 2nd Monitor 中给我发消息。如果您认为值得,也可以采纳答案。
-
@syb0rg 您的回答看起来很有趣,但它没有回答我的问题。我在问:“你认为这是一个具有余弦相似度函数最小化的连体神经网络的正确实现吗?”你认为是还是不是?谢谢
-
@DavideChicco.it 是的,但您确实明白代码审查的目的是改进代码,对吗?你应该自己验证它是一个正确的实现。
标签: performance algorithm lua machine-learning neural-network