Что я неправильно читаю в наборе данных MNIST?

Я пытаюсь использовать набор рукописных цифр MNIST для проекта, и я пытаюсь прочитать каждое изображение в виде двумерного массива 28 на 28 целых чисел от 1 до 255, что соответствует цвету каждого пикселя в оттенках серого. Я скачал тренировочный файл (train-images-idx3-ubyte.gz) с их веб-сайта (http://yann.lecun.com/exdb/mnist/), и у меня возникли проблемы с обработкой этого файла. Он описывает формат файла как 16 байт информации заголовка, за которыми следуют биты без знака, каждый из которых содержит один пиксель, организованный построчно. Подробнее см. на веб-сайте.

В своем коде я пытаюсь прочитать файл в массив байтов (который, когда я его запускаю, имеет тот же размер, что и указанный файл: 9 912 422 байта). Затем я начинаю с семнадцатого байта, чтобы пропустить заголовок и компенсировать тот факт, что java пытается сделать байт целым числом со знаком, добавляя 128 к абсолютному значению всех отрицательных отрицательных чисел (их первый бит был единицей). Чтобы проверить, работает ли это, я попытался распечатать его, используя класс панели рисования, который, как я знаю, работает, и я вижу только статику, в пикселях вообще нет шаблона. Что я делаю неправильно при обработке файла? Спасибо!

 File file=new File("train-images-idx3-ubyte.gz");
 long size = file.length(); 
 System.out.println(size);        
 byte[] contents=new byte[(int)size];
 FileInputStream in = new FileInputStream(file);
 in.read(contents);
 in.close();
 DrawingPanel panel = new DrawingPanel(400, 400);
 Graphics g = panel.getGraphics(); 
 int xloc = 0;
 int yloc = 0;                         
 for(int jj = 0; jj < 28; jj++)
 {
    for(int ii = 0; ii < 28; ii++)
    {
       int x = (int) contents[17+jj*28+ii];
       if(x < 0)
       {
          x = (x * (0-1)) + 128;
       }
       System.out.print(x + " ");
       int color = (255 - x);
       g.setColor(new Color(x,x,x));
       g.fillRect(xloc,yloc,10,10);
           xloc += 10;
    }
    System.out.println();
    yloc+= 10;
    xloc = 0;
 }

person Justin Sanders    schedule 27.07.2017    source источник
comment
Вам может понадобиться специальная библиотека для правильного чтения файла GZIP, например. здесь для начала.   -  person Tim Biegeleisen    schedule 27.07.2017
comment
Я думаю, вы должны сначала разархивировать файл, а затем прочитать несжатый файл.   -  person Greg Kopff    schedule 27.07.2017


Ответы (2)


Для тех, кто столкнется с этим вопросом в будущем, комментарии были правильными, вам нужно сначала разархивировать файл gz, однако я изучил это, и это выглядело очень сложно.

Пока я изучал это, я обнаружил, что csv данных легко доступен в Интернете через быстрый поиск в Google, поэтому, если вы не любите извлекать файлы самостоятельно, я бы порекомендовал использовать это!

person Justin Sanders    schedule 27.07.2017
comment
Чтобы разархивировать их в Windows, вы можете использовать стороннее программное обеспечение, например 7-Zip. (В противном случае tar -xvzf [file-path] в командной строке/терминале должно работать.) - person h4nek; 19.07.2019

После того, как вы разархивируете данные, ваш код будет хорошо работать на моем сайте, но только после этих изменений.

  • если(х‹0) х+=128; // исправить подписанный int

  • если(х>255) х=255; //закрыть любое высокое значение

  • инт цвет = (255 - х);

  • g.setColor (новый цвет (цвет, цвет, цвет)); // вместо х,х,х

person George    schedule 12.08.2020