В этом примере показано, как обучить сиамскую сеть идентифицировать похожие изображения рукописных символов.
Сиамская сеть - это тип сети глубокого обучения, которая использует две или более идентичных подсетей, которые имеют одинаковую архитектуру и совместно используют одни и те же параметры и веса. Сиамские сети обычно используются в задачах, которые включают в себя поиск взаимосвязи между двумя сопоставимыми вещами. Некоторые распространенные приложения для сиамских сетей включают распознавание лиц, проверку подписи [1] или идентификацию перефразирования [2]. Сиамские сети хорошо справляются с этими задачами, потому что их общие веса означают, что во время обучения нужно изучать меньше параметров, и они могут дать хорошие результаты с относительно небольшим количеством данных обучения.
Сиамские сети особенно полезны в тех случаях, когда существует большое количество классов с небольшим количеством наблюдений каждого из них. В таких случаях не хватает данных, чтобы обучить глубокую сверточную нейронную сеть классифицировать изображения на эти классы. Вместо этого сиамская сеть может определить, находятся ли два изображения в одном классе.
В этом примере набор данных Omniglot [3] используется для обучения сиамской сети сравнению изображений рукописных символов [4]. Набор данных Omniglot содержит наборы символов для 50 алфавитов, разделенные на 30 используемых для обучения и 20 для тестирования. Каждый алфавит содержит ряд символов от 14 для оджибве (канадские аборигены-суллабики) до 55 для тифинаха. Наконец, каждый персонаж имеет 20 рукописных наблюдений. Этот пример обучает сеть определять, являются ли два рукописных наблюдения различными экземплярами одного и того же символа.
Можно также использовать сиамские сети для идентификации подобных изображений с помощью уменьшения размерности. Пример см. в разделе Подготовка сиамской сети к уменьшению размерности.
Загрузите и извлеките набор учебных данных Omniglot.
url = "https://github.com/brendenlake/omniglot/raw/master/python/images_background.zip"; downloadFolder = tempdir; filename = fullfile(downloadFolder,"images_background.zip"); dataFolderTrain = fullfile(downloadFolder,'images_background'); if ~exist(dataFolderTrain,"dir") disp("Downloading Omniglot training data (4.5 MB)...") websave(filename,url); unzip(filename,downloadFolder); end disp("Training data downloaded.")
Training data downloaded.
Загрузите учебные данные как хранилище данных образа с помощью imageDatastore функция. Укажите метки вручную путем извлечения меток из имен файлов и установки параметра Labels собственность.
imdsTrain = imageDatastore(dataFolderTrain, ... 'IncludeSubfolders',true, ... 'LabelSource','none'); files = imdsTrain.Files; parts = split(files,filesep); labels = join(parts(:,(end-2):(end-1)),'_'); imdsTrain.Labels = categorical(labels);
Обучающий набор данных Omniglot состоит из черно-белых рукописных символов из 30 алфавитов, с 20 наблюдениями каждого символа. Изображения имеют размер 105 на 105 на 1, и ценности каждого пикселя между 0 и 1.
Отображение случайного выбора изображений.
idxs = randperm(numel(imdsTrain.Files),8); for i = 1:numel(idxs) subplot(4,2,i) imshow(readimage(imdsTrain,idxs(i))) title(imdsTrain.Labels(idxs(i)), "Interpreter","none"); end

Чтобы обучить сеть, данные должны быть сгруппированы в пары изображений, которые похожи или отличаются друг от друга. Здесь похожие изображения - это разные рукописные экземпляры одного и того же символа, которые имеют одну и ту же метку, в то время как разнородные изображения разных символов имеют разные метки. Функция getSiameseBatch (определено в разделе «Вспомогательные функции» этого примера) создает рандомизированные пары похожих или разнородных изображений, pairImage1 и pairImage2. Функция также возвращает метку pairLabel, который идентифицирует, является ли пара изображений похожей или непохожей друг на друга. Подобные пары изображений имеют pairLabel = 1, в то время как разные пары имеют pairLabel = 0.
В качестве примера создайте небольшой представительный набор из пяти пар изображений
batchSize = 10; [pairImage1,pairImage2,pairLabel] = getSiameseBatch(imdsTrain,batchSize);
Отображение созданных пар изображений.
for i = 1:batchSize if pairLabel(i) == 1 s = "similar"; else s = "dissimilar"; end subplot(2,5,i) imshow([pairImage1(:,:,:,i) pairImage2(:,:,:,i)]); title(s) end

В этом примере создается новая партия из 180 парных изображений для каждой итерации обучающего цикла. Это гарантирует, что сеть обучена большому количеству случайных пар изображений с приблизительно равными пропорциями сходных и разнородных пар.
Архитектура сиамской сети показана на следующей схеме.

Для сравнения двух изображений каждое изображение проходит через одну из двух одинаковых подсетей, имеющих общий вес. Подсети преобразовывают каждое изображение 105 на 105 на 1 в 4096-мерный вектор особенности. Изображения того же класса имеют сходные 4096-мерные представления. Векторы выходных признаков из каждой подсети объединяются посредством вычитания, и результат передается через fullyconnect работа с одним выходом. A sigmoid операция преобразует это значение в вероятность между 0 и 1, указывая предсказание сети о том, являются ли изображения похожими или разнородными. Двоичная потеря перекрестной энтропии между предсказанием сети и истинной меткой используется для обновления сети во время обучения.
В этом примере две идентичные подсети определены как dlnetwork объект. Финал fullyconnect и sigmoid операции выполняются как функциональные операции на выходах подсети.
Создайте подсеть как серию слоев, которая принимает изображения 105 на 105 на 1 и производит вектор особенности размера 4096.
Для convolution2dLayer используйте узкое нормальное распределение для инициализации весов и смещения.
Для maxPooling2dLayer объекты, задайте для шага значение 2.
За финал fullyConnectedLayer укажите размер выходного сигнала 4096 и используйте узкое нормальное распределение для инициализации весов и смещения.
layers = [
imageInputLayer([105 105 1],'Name','input1','Normalization','none')
convolution2dLayer(10,64,'Name','conv1','WeightsInitializer','narrow-normal','BiasInitializer','narrow-normal')
reluLayer('Name','relu1')
maxPooling2dLayer(2,'Stride',2,'Name','maxpool1')
convolution2dLayer(7,128,'Name','conv2','WeightsInitializer','narrow-normal','BiasInitializer','narrow-normal')
reluLayer('Name','relu2')
maxPooling2dLayer(2,'Stride',2,'Name','maxpool2')
convolution2dLayer(4,128,'Name','conv3','WeightsInitializer','narrow-normal','BiasInitializer','narrow-normal')
reluLayer('Name','relu3')
maxPooling2dLayer(2,'Stride',2,'Name','maxpool3')
convolution2dLayer(5,256,'Name','conv4','WeightsInitializer','narrow-normal','BiasInitializer','narrow-normal')
reluLayer('Name','relu4')
fullyConnectedLayer(4096,'Name','fc1','WeightsInitializer','narrow-normal','BiasInitializer','narrow-normal')];
lgraph = layerGraph(layers);Чтобы обучить сеть с помощью пользовательского цикла обучения и включить автоматическое дифференцирование, преобразуйте график слоев в dlnetwork объект.
dlnet = dlnetwork(lgraph);
Создание весов для финала fullyconnect операция. Инициализируйте веса путем выборки случайного выбора из узкого нормального распределения со стандартным отклонением 0,01.
fcWeights = dlarray(0.01*randn(1,4096)); fcBias = dlarray(0.01*randn(1,1)); fcParams = struct(... "FcWeights",fcWeights,... "FcBias",fcBias);
Для использования сети создайте функцию forwardSiamese (определяется в разделе «Вспомогательные функции» этого примера), который определяет, как две подсети и вычитание, fullyconnect, и sigmoid операции совмещены. Функция forwardSiamese принимает сеть, структура, содержащая параметры для fullyconnect операция и два обучающих образа. forwardSiamese функция выводит прогноз о сходстве двух изображений.
Создание функции modelGradients (определено в разделе «Вспомогательные функции» данного примера). modelGradients функция принимает сиамскую подсеть dlnet, структура параметров для fullyconnect операция и мини-пакет входных данных X1 и X2 с их этикетками pairLabels. Функция возвращает значения потерь и градиенты потерь относительно обучаемых параметров сети.
Цель сиамской сети состоит в различении этих двух входов X1 и X2. Выход сети - это вероятность между 0 и 1, где значение ближе к 0 указывает на то, что изображения отличаются друг от друга, а значение ближе к 1 что изображения похожи. Потеря определяется двоичной перекрестной энтропией между прогнозируемой оценкой и истинным значением метки:
(1-y),
где истинная метка может быть 0 или 1, а является предсказанной меткой.
Укажите параметры для использования во время обучения. Обучение для 10000 итераций.
numIterations = 10000; miniBatchSize = 180;
Укажите параметры оптимизации ADAM:
Установка коэффициента обучения на 0.00006.
Инициализируйте среднюю градиентную скорость и среднюю градиентно-квадратную скорость затухания с помощью [] для обоих dlnet и fcParams.
Задать коэффициент градиентного затухания равным 0.9 и квадрат градиентного коэффициента распада до 0.99.
learningRate = 6e-5; trailingAvgSubnet = []; trailingAvgSqSubnet = []; trailingAvgParams = []; trailingAvgSqParams = []; gradDecay = 0.9; gradDecaySq = 0.99;
Обучение на GPU, если он доступен. Для использования графического процессора требуется Toolbox™ параллельных вычислений и поддерживаемое устройство графического процессора. Сведения о поддерживаемых устройствах см. в разделе Поддержка графического процессора по выпуску (Parallel Computing Toolbox). Для автоматического определения наличия графического процессора и размещения соответствующих данных на графическом процессоре установите значение executionEnvironment кому "auto". Если у вас нет графического процессора или вы не хотите использовать его для обучения, установите значение executionEnvironment кому "cpu". Для обеспечения использования графического процессора для обучения установите значение executionEnvironment кому "gpu".
executionEnvironment = "auto";Для контроля хода обучения можно построить график потерь обучения после каждой итерации. Создание переменной plots который содержит "training-progress". Если вы не хотите отображать ход обучения, установите для этого значения значение "none".
plots = "training-progress";Инициализируйте параметры графика для графика хода выполнения учебных потерь.
plotRatio = 16/9; if plots == "training-progress" trainingPlot = figure; trainingPlot.Position(3) = plotRatio*trainingPlot.Position(4); trainingPlot.Visible = 'on'; trainingPlotAxes = gca; lineLossTrain = animatedline(trainingPlotAxes); xlabel(trainingPlotAxes,"Iteration") ylabel(trainingPlotAxes,"Loss") title(trainingPlotAxes,"Loss During Training") end
Обучение модели с помощью пользовательского цикла обучения. Закольцовывать обучающие данные и обновлять сетевые параметры на каждой итерации.
Для каждой итерации:
Извлеките пакет пар изображений и меток с помощью getSiameseBatch функция, определенная в разделе Создание пакетов пар изображений.
Преобразовать данные в dlarray объекты с базовым типом single и укажите метки размеров 'SSCB' (пространственные, пространственные, канальные, пакетные) для данных изображения и 'CB' (канал, партия) для этикеток.
Для обучения GPU преобразуйте данные в gpuArray объекты.
Оценка градиентов модели с помощью dlfeval и modelGradients функция.
Обновление параметров сети с помощью adamupdate функция.
% Loop over mini-batches. for iteration = 1:numIterations % Extract mini-batch of image pairs and pair labels [X1,X2,pairLabels] = getSiameseBatch(imdsTrain,miniBatchSize); % Convert mini-batch of data to dlarray. Specify the dimension labels % 'SSCB' (spatial, spatial, channel, batch) for image data dlX1 = dlarray(single(X1),'SSCB'); dlX2 = dlarray(single(X2),'SSCB'); % If training on a GPU, then convert data to gpuArray. if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu" dlX1 = gpuArray(dlX1); dlX2 = gpuArray(dlX2); end % Evaluate the model gradients and the generator state using % dlfeval and the modelGradients function listed at the end of the % example. [gradientsSubnet, gradientsParams,loss] = dlfeval(@modelGradients,dlnet,fcParams,dlX1,dlX2,pairLabels); lossValue = double(gather(extractdata(loss))); % Update the Siamese subnetwork parameters. [dlnet,trailingAvgSubnet,trailingAvgSqSubnet] = ... adamupdate(dlnet,gradientsSubnet, ... trailingAvgSubnet,trailingAvgSqSubnet,iteration,learningRate,gradDecay,gradDecaySq); % Update the fullyconnect parameters. [fcParams,trailingAvgParams,trailingAvgSqParams] = ... adamupdate(fcParams,gradientsParams, ... trailingAvgParams,trailingAvgSqParams,iteration,learningRate,gradDecay,gradDecaySq); % Update the training loss progress plot. if plots == "training-progress" addpoints(lineLossTrain,iteration,lossValue); end drawnow; end

Загрузите и извлеките набор тестовых данных Omniglot.
url = 'https://github.com/brendenlake/omniglot/raw/master/python/images_evaluation.zip'; downloadFolder = tempdir; filename = fullfile(downloadFolder,'images_evaluation.zip'); dataFolderTest = fullfile(downloadFolder,'images_evaluation'); if ~exist(dataFolderTest,'dir') disp('Downloading Omniglot test data (3.2 MB)...') websave(filename,url); unzip(filename,downloadFolder); end disp("Test data downloaded.")
Test data downloaded.
Загрузите тестовые данные как хранилище данных образа с помощью imageDatastore функция. Укажите метки вручную путем извлечения меток из имен файлов и установки параметра Labels собственность.
imdsTest = imageDatastore(dataFolderTest, ... 'IncludeSubfolders',true, ... 'LabelSource','none'); files = imdsTest.Files; parts = split(files,filesep); labels = join(parts(:,(end-2):(end-1)),'_'); imdsTest.Labels = categorical(labels);
Набор тестовых данных содержит 20 алфавитов, которые отличаются от тех, на которых обучалась сеть. Всего в наборе тестовых данных 659 различных классов.
numClasses = numel(unique(imdsTest.Labels))
numClasses = 659
Для вычисления точности сети создайте набор из пяти случайных мини-пакетов тестовых пар. Используйте predictSiamese функция (определенная в разделе «Вспомогательные функции» этого примера) для оценки сетевых прогнозов и вычисления средней точности по мини-пакетам.
accuracy = zeros(1,5); accuracyBatchSize = 150; for i = 1:5 % Extract mini-batch of image pairs and pair labels [XAcc1,XAcc2,pairLabelsAcc] = getSiameseBatch(imdsTest,accuracyBatchSize); % Convert mini-batch of data to dlarray. Specify the dimension labels % 'SSCB' (spatial, spatial, channel, batch) for image data. dlXAcc1 = dlarray(single(XAcc1),'SSCB'); dlXAcc2 = dlarray(single(XAcc2),'SSCB'); % If using a GPU, then convert data to gpuArray. if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu" dlXAcc1 = gpuArray(dlXAcc1); dlXAcc2 = gpuArray(dlXAcc2); end % Evaluate predictions using trained network dlY = predictSiamese(dlnet,fcParams,dlXAcc1,dlXAcc2); % Convert predictions to binary 0 or 1 Y = gather(extractdata(dlY)); Y = round(Y); % Compute average accuracy for the minibatch accuracy(i) = sum(Y == pairLabelsAcc)/accuracyBatchSize; end % Compute accuracy over all minibatches averageAccuracy = mean(accuracy)*100
averageAccuracy = 88.6667
Чтобы визуально проверить, правильно ли сеть идентифицирует сходные и разнородные пары, создайте небольшой пакет пар изображений для тестирования. Используйте функцию predictSiamese, чтобы получить прогноз для каждой тестовой пары. Отображение пары изображений с предсказанием, оценкой вероятности и меткой, указывающей, было ли предсказание правильным или неправильным.
testBatchSize = 10;
[XTest1,XTest2,pairLabelsTest] = getSiameseBatch(imdsTest,testBatchSize);
% Convert test batch of data to dlarray. Specify the dimension labels
% 'SSCB' (spatial, spatial, channel, batch) for image data and 'CB'
% (channel, batch) for labels
dlXTest1 = dlarray(single(XTest1),'SSCB');
dlXTest2 = dlarray(single(XTest2),'SSCB');
% If using a GPU, then convert data to gpuArray
if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
dlXTest1 = gpuArray(dlXTest1);
dlXTest2 = gpuArray(dlXTest2);
end
% Calculate the predicted probability
dlYScore = predictSiamese(dlnet,fcParams,dlXTest1,dlXTest2);
YScore = gather(extractdata(dlYScore));
% Convert predictions to binary 0 or 1
YPred = round(YScore);
% Extract data to plot
XTest1 = extractdata(dlXTest1);
XTest2 = extractdata(dlXTest2);
% Plot images with predicted label and predicted score
testingPlot = figure;
testingPlot.Position(3) = plotRatio*testingPlot.Position(4);
testingPlot.Visible = 'on';
for i = 1:numel(pairLabelsTest)
if YPred(i) == 1
predLabel = "similar";
else
predLabel = "dissimilar" ;
end
if pairLabelsTest(i) == YPred(i)
testStr = "\bf\color{darkgreen}Correct\rm\newline";
else
testStr = "\bf\color{red}Incorrect\rm\newline";
end
subplot(2,5,i)
imshow([XTest1(:,:,:,i) XTest2(:,:,:,i)]);
title(testStr + "\color{black}Predicted: " + predLabel + "\newlineScore: " + YScore(i));
end
Сеть способна сравнивать тестовые изображения, чтобы определить их сходство, даже если ни одно из этих изображений не было в обучающем наборе данных.
Функция forwardSiamese используется во время обучения сети. Функция определяет, каким образом подсети и fullyconnect и sigmoid операции объединяются для формирования полной сиамской сети. forwardSiamese принимает структуру сети и два обучающих изображения и выводит прогноз о сходстве двух изображений. В этом примере функция forwardSiamese представлен в разделе Определение сетевой архитектуры.
function Y = forwardSiamese(dlnet,fcParams,dlX1,dlX2) % forwardSiamese accepts the network and pair of training images, and returns a % prediction of the probability of the pair being similar (closer to 1) or % dissimilar (closer to 0). Use forwardSiamese during training. % Pass the first image through the twin subnetwork F1 = forward(dlnet,dlX1); F1 = sigmoid(F1); % Pass the second image through the twin subnetwork F2 = forward(dlnet,dlX2); F2 = sigmoid(F2); % Subtract the feature vectors Y = abs(F1 - F2); % Pass the result through a fullyconnect operation Y = fullyconnect(Y,fcParams.FcWeights,fcParams.FcBias); % Convert to probability between 0 and 1. Y = sigmoid(Y); end
Функция predictSiamese использует обученную сеть для прогнозирования сходства двух изображений. Функция аналогична функции forwardSiamese, определено ранее. Однако predictSiamese использует predict вместо функции с сетью forward функция, потому что некоторые глубокие уровни обучения ведут себя по-разному во время обучения и прогнозирования. В этом примере функция predictSiamese представлен в разделе Оценка точности сети.
function Y = predictSiamese(dlnet,fcParams,dlX1,dlX2) % predictSiamese accepts the network and pair of images, and returns a % prediction of the probability of the pair being similar (closer to 1) % or dissimilar (closer to 0). Use predictSiamese during prediction. % Pass the first image through the twin subnetwork F1 = predict(dlnet,dlX1); F1 = sigmoid(F1); % Pass the second image through the twin subnetwork F2 = predict(dlnet,dlX2); F2 = sigmoid(F2); % Subtract the feature vectors Y = abs(F1 - F2); % Pass result through a fullyconnect operation Y = fullyconnect(Y,fcParams.FcWeights,fcParams.FcBias); % Convert to probability between 0 and 1. Y = sigmoid(Y); end
Функция modelGradients принимает сиамцев dlnetwork объект net, пара входных данных мини-партии X1 и X2и метка, указывающая, являются ли они похожими или разнородными. Функция возвращает градиенты потерь относительно обучаемых параметров в сети и двоичных потерь перекрестной энтропии между предсказанием и истинностью основания. В этом примере функция modelGradients вводится в разделе Определение функции градиентов модели.
function [gradientsSubnet,gradientsParams,loss] = modelGradients(dlnet,fcParams,dlX1,dlX2,pairLabels) % The modelGradients function calculates the binary cross-entropy loss between the % paired images and returns the loss and the gradients of the loss with respect to % the network learnable parameters % Pass the image pair through the network Y = forwardSiamese(dlnet,fcParams,dlX1,dlX2); % Calculate binary cross-entropy loss loss = binarycrossentropy(Y,pairLabels); % Calculate gradients of the loss with respect to the network learnable % parameters [gradientsSubnet,gradientsParams] = dlgradient(loss,dlnet.Learnables,fcParams); end function loss = binarycrossentropy(Y,pairLabels) % binarycrossentropy accepts the network's prediction Y, the true % label, and pairLabels, and returns the binary cross-entropy loss value. % Get precision of prediction to prevent errors due to floating % point precision precision = underlyingType(Y); % Convert values less than floating point precision to eps. Y(Y < eps(precision)) = eps(precision); %convert values between 1-eps and 1 to 1-eps. Y(Y > 1 - eps(precision)) = 1 - eps(precision); % Calculate binary cross-entropy loss for each pair loss = -pairLabels.*log(Y) - (1 - pairLabels).*log(1 - Y); % Sum over all pairs in minibatch and normalize. loss = sum(loss)/numel(pairLabels); end
Следующие функции создают рандомизированные пары изображений, которые похожи или отличаются друг от друга, на основе их меток. В этом примере функция getSiameseBatch представлен в разделе Создание пар похожих и разнородных изображений.
function [X1,X2,pairLabels] = getSiameseBatch(imds,miniBatchSize) % getSiameseBatch returns a randomly selected batch or paired images. On % average, this function produces a balanced set of similar and dissimilar % pairs. pairLabels = zeros(1,miniBatchSize); imgSize = size(readimage(imds,1)); X1 = zeros([imgSize 1 miniBatchSize]); X2 = zeros([imgSize 1 miniBatchSize]); for i = 1:miniBatchSize choice = rand(1); if choice < 0.5 [pairIdx1,pairIdx2,pairLabels(i)] = getSimilarPair(imds.Labels); else [pairIdx1,pairIdx2,pairLabels(i)] = getDissimilarPair(imds.Labels); end X1(:,:,:,i) = imds.readimage(pairIdx1); X2(:,:,:,i) = imds.readimage(pairIdx2); end end function [pairIdx1,pairIdx2,pairLabel] = getSimilarPair(classLabel) % getSimilarSiamesePair returns a random pair of indices for images % that are in the same class and the similar pair label = 1. % Find all unique classes. classes = unique(classLabel); % Choose a class randomly which will be used to get a similar pair. classChoice = randi(numel(classes)); % Find the indices of all the observations from the chosen class. idxs = find(classLabel==classes(classChoice)); % Randomly choose two different images from the chosen class. pairIdxChoice = randperm(numel(idxs),2); pairIdx1 = idxs(pairIdxChoice(1)); pairIdx2 = idxs(pairIdxChoice(2)); pairLabel = 1; end function [pairIdx1,pairIdx2,label] = getDissimilarPair(classLabel) % getDissimilarSiamesePair returns a random pair of indices for images % that are in different classes and the dissimilar pair label = 0. % Find all unique classes. classes = unique(classLabel); % Choose two different classes randomly which will be used to get a dissimilar pair. classesChoice = randperm(numel(classes),2); % Find the indices of all the observations from the first and second classes. idxs1 = find(classLabel==classes(classesChoice(1))); idxs2 = find(classLabel==classes(classesChoice(2))); % Randomly choose one image from each class. pairIdx1Choice = randi(numel(idxs1)); pairIdx2Choice = randi(numel(idxs2)); pairIdx1 = idxs1(pairIdx1Choice); pairIdx2 = idxs2(pairIdx2Choice); label = 0; end
[1] Бромли, Дж., И. Гайон, Я. ЛеКанн, Э. Зекингер и Р. Шах. «Проверка подписи с использованием» сиамской «нейронной сети задержки времени». В трудах 6-й Международной конференции по нейронным системам обработки информации (NIPS 1993), 1994, pp737-744. Доступна при проверке подписи с использованием нейронной сети задержки времени «Siamese» на веб-сайте NIPS Proceedings.
[2] Венпег, Ю. и Х. Шютце. «Сверточная нейронная сеть для идентификации парафраза». В трудах 2015 года Конференция Североамериканского отделения ACL, 2015, pp901-911. Доступна в сверточной нейронной сети для идентификации парафраза на сайте антологии ACL
[3] Лейк, Б. М., Салахутдинов, Р. и Тененбаум, Дж. Б. «Обучение концепции на уровне человека посредством вероятностной программной индукции». Наука, 350 (6266), (2015) pp1332-1338.
[4] Кох, Г., Земель, Р., и Салахутдинов, Р. (2015). «Сиамские нейронные сети для однокадрового распознавания изображений». В трудах 32-й Международной конференции по машинному обучению, 37 (2015). Доступен в Siamese Neural Networks для однокадрового распознавания изображений на веб-сайте ICML '15 .
adamupdate | dlarray | dlfeval | dlgradient | dlnetwork