f# - MathNet 数值内存不足异常

标签 f# math.net mathnet-numerics

我在 F# 项目中使用 MathNet.Numerics,在处理本应在其职责范围内的矩阵时,它会耗尽内存。

编辑:问题绝对不在于 MathNet.Numerics。这是我正在做的事情,尽管我还没有弄清楚那可能是什么。

以下是我构建 MNIST 矩阵的方法。也许我让文件流保持打开状态或其他什么,但我看不出情况会怎样。

let readInt (b : BinaryReader) =
    [1..4] |> List.fold (fun res item -> (res <<< 8) ||| (int)(b.ReadByte())) 0

let readImage (b : BinaryReader, rowArray, colArray) =
    rowArray |> List.collect (fun r -> List.map (fun c -> (b.ReadByte() |> int |> float)/255.0 ) colArray)

let loadMnistImage file =
    use stream = File.Open(file, FileMode.Open)
    use reader = new BinaryReader(stream)
    let magicNumber = readInt(reader)
    let nImages = readInt(reader)
    let nRows = readInt(reader)
    let nCols = readInt(reader)

    let row = [1..nRows]
    let col = [1..nCols]
    let images = [1..nImages] |> List.map (fun _ -> readImage(reader, row, col))
    matrix images;

使用这个,

let mnistTrainingImages = loadMnistImage MnistTrainingImageData
let tr = mnistTrainingImages.Transpose()

爆炸。

是他们还是我?我从 http://yann.lecun.com/exdb/mnist/ 提取文件,以防有人想自己尝试一下。

编辑1:罪魁祸首是对loadMnistImage的调用。根据Gene Belitski的建议,我运行了代码

let rand = System.Random()
let m: double [,] = Array2D.init 60000 784 (fun _ _ -> rand.NextDouble())

行前和行后

let mnistTrainingImages = loadMnistImage MnistTrainingImageData

上线前还好;在该行之后,它因相同的内存不足异常而爆炸。我本以为 use 语句会释放该文件并且我会没事的(而且这不是一个大文件)。但是,我遗漏了一些东西,所以我会继续挖掘,如果有人看到任何东西,请告诉我。

编辑2:当我按如下方式简化文件读取器时,问题就消失了。看来问题出在列表的惰性评估上。

let readImage (b : BinaryReader) =
    (b.ReadByte() |> int |> float)/255.0

let loadMnistImage file =
    use stream = File.Open(file, FileMode.Open)
    use reader = new BinaryReader(stream)
    let magicNumber = readInt(reader)
    let nImages = readInt(reader)
    let nRows = readInt(reader)
    let nCols = readInt(reader)
    Array2D.init nImages (nRows * nCols) (fun _ _ -> readImage reader)

最佳答案

即使使用 32 位 F#3.0 FSI,以下代码片段对我来说也没有问题:

#if INTERACTIVE
#r @"....\packages\MathNet.Numerics.2.6.2\lib\net40\MathNet.Numerics.dll"
#endif

open MathNet.Numerics.LinearAlgebra.Double

let rand = System.Random()
let m: double [,] = Array2D.init 60000 784 (fun _ _ -> rand.NextDouble())
let mx = DenseMatrix.OfArray m
let tmx = mx.Transpose()

必须在您的设置中工作,不是吗?

关于f# - MathNet 数值内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19679123/

相关文章:

performance - 如何重构代码以使其具有功能性风格?

python - 是否有与 Python 的 Counter 集合等效的 F#?

arrays - 如何在 F# 中添加两个数值数组

c# - 我可以将 Math.NET 运行时与 .NET 2.0 或 .NET 3.5 应用程序一起使用吗?

c# - Infix.ParseOrUndefined 序列顺序

f# - 使用 seq 表达式的递归对象警告

c# - 找不到 global.json 指定的 .NET SDK,请检​​查是否安装了指定的版本

.net - 我什么时候应该使用像 Math.NET 这样的线性代数库

c# - 寻找如何进行加权线性回归的示例