How do I import an "idx3-ubyte" file?


#1

I am wondering how to import the files found on this website into Processing: http://yann.lecun.com/exdb/mnist/

They’re supposed to contain thousands of 28x28 byte arrangements, each with its own “grayscale” value. In essence, they’re images. But the files don’t have a .dat extension, an extension I’ve learned to use thanks to the saveBytes() and loadBytes() reference tutorials on the Processing website.

I don’t know what an .idx3-ubyte extension is and how to import it into an arbitrary Processing array correctly, and the Java guides I found online didn’t help either, as the usual Processing code that I’m familiar with looks nothing like those chunks of code.

I also don’t know how the bytes are structured inside the file, although I would assume the first 784 (28*28) bytes would correspond to the first supposed image, going left to right, downwards, and the next 784 would correspond to the second image, and so on.

Even figuring out how to convert this into a .dat file would help, as I am able to import those into and out of Processing easily.

(Question copied from: https://forum.processing.org/two/discussion/comment/124774)


#2

Hi @Tsskyx, I am honestly not routined in this field, but have you seen https://github.com/jeffheaton/aifh/blob/master/vol3/vol3-dl4j-examples/src/main/java/com/heatonresearch/aifh/util/MNIST.java ? If not, it seems like it might be able to help you.


#3

Okay. Turns out the answer was very simple, Processing is already perfectly capable of reading that file, I didn’t even know that! I just saw that everyone was having issues with it and didn’t understand the file extension myself. :smiley:

Here’s the code I quickly put together:

byte[] trainSet, labelSet;
int cellSize = 15;
int count = 0;

void settings() {
  size(28*cellSize, 28*cellSize);
}

void setup() {
  trainSet = loadBytes("train-images.idx3-ubyte");
  labelSet = loadBytes("train-labels.idx1-ubyte");
  noStroke();
  textAlign(CENTER, CENTER);
  textSize(30);
}

void draw() {
  for (int i = 0; i < 28; i++) {
    for (int j = 0; j < 28; j++) {
      fill(int(trainSet[784*count+28*i+j+16])); //the first 16 bits are meta data
      rect(cellSize*j, cellSize*i, cellSize, cellSize);
    }
  }
  fill(255, 0, 0);
  text(int(labelSet[count+8]), 30, 30); //the first 8 bits are meta data
}

void mousePressed() {
  count++;
}

Side note, these files are training and testing examples for a simple digit-recognizing neural network, and I’m so glad that the standard importing method still works for these files, else I would probably have to generate those testing examples myself, which would get unwieldy very quickly. :confused: