io - 使用 F# 读取 MNIST 数据集

标签 io f# mnist

我能做到;我只是不知道为什么会这样。使用我从 http://yann.lecun.com/exdb/mnist/ 下载的 MNIST 数据库, 以及该页面底部的指南,我写了(尚未完成的)方法

// TRAINING SET IMAGE FILE (train-images-idx3-ubyte):
// [offset] [type]          [value]          [description] 
// 0000     32 bit integer  0x00000803(2051) magic number 
// 0004     32 bit integer  60000            number of images 
// 0008     32 bit integer  28               number of rows 
// 0012     32 bit integer  28               number of columns 
// 0016     unsigned byte   ??               pixel 
// 0017     unsigned byte   ??               pixel 
// ........ 
// xxxx     unsigned byte   ??               pixel

// TEST SET IMAGE FILE (t10k-images-idx3-ubyte):
// [offset] [type]          [value]          [description] 
// 0000     32 bit integer  0x00000803(2051) magic number 
// 0004     32 bit integer  10000            number of images 
// 0008     32 bit integer  28               number of rows 
// 0012     32 bit integer  28               number of columns 
// 0016     unsigned byte   ??               pixel 
// 0017     unsigned byte   ??               pixel 
// ........ 
// xxxx     unsigned byte   ??               pixel
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 nColumns = readInt(reader)
    (magicNumber, nImages, nRows, nColumns);;

这是简单的部分。困难的部分是 readInt 函数的形式。我不能只使用 BitConverter.ToInt();我在此页面中找到了答案:https://code.google.com/p/aguaviva-libs/source/browse/c%23/NeuronalNetwork/sets/HandWriting.cs?spec=svn9ffdf444c6317be049572cea59170602c8f28bea&r=9ffdf444c6317be049572cea59170602c8f28bea .

翻译方法

int Read(BinaryReader b, int i)
{
   int res = 0;

   while (i-- > 0)
   {
      res <<= 8;
      res |= b.ReadByte()
   }
   return res;
}

进入 F# 给出

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

(假设 i = 4)。这行得通:在 F# 交互中,行

loadMnistImage @"Data\t10k-images.idx3-ubyte"
loadMnistImage @"Data\train-images.idx3-ubyte"

分别给出(2051, 10000, 28, 28)(2051, 60000, 28, 28)的结果,与评论中的值一致第一个代码片段。

我不明白为什么会这样。按位或运算符上的所有这些移位和折叠是什么?为什么我不能只使用 BitConverter.ToInt() 来代替?

最佳答案

标准库方法IPAddress.NetworkToHostOrder(Int32)从网络顺序转换 int 时考虑执行平台的字节顺序。后者按照标准惯例是大端。由于 MNIST 文件遵循约定并且是 big-endian,因此以下一对标准库方法将作为 readInt 函数的 endian-agnostic 替代品:

let readInt (reader: System.IO.BinaryReader) =
    reader.ReadInt32() |> System.Net.IPAddress.NetworkToHostOrder

涉及 BitConverter 的等效但更详细的变体是

let readInt (reader: System.IO.BinaryReader) =
    (reader.ReadBytes(4),0)
    |> System.BitCoverter.ToInt32
    |> System.Net.IPAddress.NetworkToHostOrder

关于io - 使用 F# 读取 MNIST 数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19370314/

相关文章:

c - 从文件中读取时,我得到特殊字符,这些字符不在我的文本文件中

f# - 更改椭圆的 x/y 坐标

f# - 为什么 FSharp.Data.SqlClient 记录作为对象公开?

python - Python中的线程占用过多的CPU

c# - 递归地将目录名称附加到字符串

python - 如何仅从Keras提供的MNIST数据集中选择特定数字?

ios - 如何使用 MPS (MetalPerformanceShaders) 制作 Flatten 滤镜?

c - 从文件中获取数据并通过管道移动

types - 在学习 F# 时,为什么建议在字段中而不是在赋值时指定类型?