3

私がすることができます; なぜそれが機能するのかわかりません。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(); 私はこのページで答えを見つけまし:

メソッドの翻訳

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)

私が理解していないのは、なぜそれが機能するのかということです。ビットごとの or 演算子でのこのビットシフトとフォールディングは何ですか? BitConverter.ToInt()代わりに使用できないのはなぜですか?

4

2 に答える 2