3

我有以下要移植到 F#的稀疏过滤 MATLAB 代码。我知道 MATLAB 的 F# Type Provider 但不能在这里使用它,因为它会创建对 MATLAB 的依赖(我可以用它来测试)

function [optW] = SparseFiltering(N, X);
   % N = # features to learn, X = input data (examples in column)
   % You should pre-process X by removing the DC component per example,
   % before calling this function.
   % e.g., X = bsxfun(@minus, X, mean(X));
   addpath minFunc/ % Add path to minFunc optimization package
   optW = randn(N, size(X, 1));
   optW = minFunc(@SparseFilteringObj, optW(:), struct('MaxIter', 100), X, N);
   optW = reshape(optW, [N, size(X, 1)]);
end

function [Obj, DeltaW] = SparseFilteringObj (W, X, N)
   % Reshape W into matrix form
   W = reshape(W, [N, size(X,1)]);
   % Feed Forward
   F = W*X; % Linear Activation
   Fs = sqrt(F.ˆ2 + 1e-8); % Soft-Absolute Activation
   [NFs, L2Fs] = l2row(Fs); % Normalize by Rows
   [Fhat, L2Fn] = l2row(NFs'); % Normalize by Columns
   % Compute Objective Function
   Obj = sum(sum(Fhat, 2), 1);
   % Backprop through each feedforward step
   DeltaW = l2grad(NFs', Fhat, L2Fn, ones(size(Fhat)));
   DeltaW = l2grad(Fs, NFs, L2Fs, DeltaW');
   DeltaW = (DeltaW .* (F ./ Fs)) * X';
   DeltaW = DeltaW(:);
end

function [Y,N] = l2row(X) % L2 Normalize X by rows
   % We also use this to normalize by column with l2row(X')
   N = sqrt(sum(X.ˆ2,2) + 1e-8);
   Y = bsxfun(@rdivide,X,N);
end

function [G] = l2grad(X,Y,N,D) % Backpropagate through Normalization
   G = bsxfun(@rdivide, D, N) - bsxfun(@times, Y, sum(D.*X, 2) ./ (N.ˆ2));
end

我了解大部分 MATLAB 代码,但我不确定minFunc.Net 中 MATLAB 的等价物是什么。我相信我想要其中之一Microsoft.SolverFoundation.Solvers根据 MA​​TLAB 的网站

... minFunc 的默认参数调用准牛顿策略,其中使用 Shanno-Phua 缩放的有限内存 BFGS 更新来计算步长方向,并使用包围线搜索满足强 Wolfe 条件的点计算步长方向。在线搜索中,(受保护的)三次插值用于生成试验值,并且该方法在目标函数进入参数不产生实值输出的区域的迭代中切换到 Armijo 回溯线搜索

鉴于上述信息,任何人都可以确认Microsoft.SolverFoundation.Solvers.CompactQuasiNewtonModel是正确的方法吗?

此外,将上述代码移植到 F# 时是否还有其他明显的“陷阱”?(此类端口的新手)

4

1 回答 1

4

我认为CompactQuasiNewtonSolver是你最好的选择。如果您查看SolverFoundation 的示例,这里有CQN演示如何实现和求解 Rosenbrock 函数的示例。它的结果与我在minFunc 的 Rosenbrock 示例中看到的一致。上面的示例是用 C# 编写的;但它应该很容易翻译成 F#。

此外,将上述代码移植到 F# 时是否还有其他明显的“陷阱”?(这种类型的端口的新手)?

您可能需要一个好的线性代数包来接近 MATLAB 代码。Math.Net似乎是一个理想的选择,因为它具有良好的 F# 支持。

或者,您可以使用Accord.NET框架重新实现代码。该框架具有用于机器学习优化的L-BFGS 算法的实现,因此它更接近您的目的。

于 2013-09-11T07:55:28.447 回答