Die Mathe-Redaktion - 13.12.2019 22:27 - Registrieren/Login
Auswahl
ListenpunktHome
ListenpunktAktuell und Interessant ai
ListenpunktArtikelübersicht/-suche
ListenpunktAlle Links / Mathe-Links
ListenpunktFach- & Sachbücher
ListenpunktMitglieder / Karte / Top 15
ListenpunktRegistrieren/Login
ListenpunktArbeitsgruppen
Listenpunkt? im neuen Schwätz
ListenpunktWerde Mathe-Millionär!
ListenpunktFormeleditor fedgeo
Schwarzes Brett
Aktion im Forum
Suche
Stichwortsuche in Artikeln und Links von Matheplanet
Suchen im Forum
Suchtipps

Bücher
Englische Bücher
Software
Suchbegriffe:
Mathematik bei amazon
Naturwissenschaft & Technik
In Partnerschaft mit Amazon.de
Kontakt
Mail an Matroid
[Keine Übungsaufgaben!]
Impressum

Bitte beachten Sie unsere Nutzungsbedingungen, die Distanzierung, unsere Datenschutzerklärung und
die Forumregeln.

Sie können Mitglied werden. Mitglieder können den Matheplanet-Newsletter bestellen, der etwa alle 2 Monate erscheint.

Der Newsletter Okt. 2017

Für Mitglieder
Mathematisch für Anfänger
Wer ist Online
Aktuell sind 321 Gäste und 19 Mitglieder online.

Sie können Mitglied werden:
Klick hier.

Über Matheplanet
 
Zum letzten Themenfilter: Themenfilter:
Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmieren » Einlesen von Bildern aus der MNIST Dataset
Druckversion
Druckversion
Antworten
Antworten
Autor
Universität/Hochschule Einlesen von Bildern aus der MNIST Dataset
Lucky_7
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 21.01.2018
Mitteilungen: 164
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Themenstart: 2019-11-18 10:43


In einem Tutorial zum Einlesen von Daten aus der MNIST-Dataset, habe ich folgende Funktion gefunden:
Python
import gzip
import numpy as np
 
def OpenImage(myFile):
    with gzip.open(myFile, "rb") as f:
        data = f.read()
        return np.frombuffer(data, dtype=np.uint8, offset=16).reshape(-1,28,28).astype(np.float32)
Hierzu habe ich ein paar Fragen:
Die Bilder der MNIST-Dataset sind im Byte-Format gespeichert (Datentyp Unsigned Byte, jeder Pixel-Wert wird also durch 8 Bits repräsentiert). Wenn ich nun die 60000 Bilder des Datasets lade, enthält dieses File erst einmal einen Header von 16 Bytes Länge. Wenn ich also die Bilder einzeln einlesen möchte, muss ich diesen Header ignorieren (deshalb der offset von 16 in np.frombuffer() ).
Zu meiner Frage: Wieso wird hier np.frombuffer() verwendet? Ich meine, ich lese doch eigentlich von einer Datei, nicht von einem Buffer! Offenbar bewirkt f.read(), dass meine Datei in einen Buffer geladen wird. Ist das immer der Fall? Steht das irgendwie im Zusammenhang damit, dass meine Bilder im Byte-Format gespeichert sind?
Und warum wird eigentlich in np.frombuffer() der dtype als np.uint8 angegeben? Laut Magic Number der MNIST-Dataset, werden die Pixel als Unsigned Byte gespeichert. Das ist vermutlich dasselbe, kann das sein?
Und zu guter letzt: Das reshape(-1,28,28) bewirkt was? Meine Bilder müssten doch bereits 28x28 Pixel haben. Und als np.float32 will ich die wieso haben?
Sorry, Fragen über Fragen. Vrmtl. ist np.float32 für irgendeine matplotlib Funktion wichtig. Aber ich würde es gerne verstehen.



  Profil  Quote  Link auf diesen Beitrag Link
Yggdrasil
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 01.07.2004
Mitteilungen: 854
Aus: Berlin
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.1, eingetragen 2019-11-18 20:55


Hallo Lucky_7
2019-11-18 10:43 - Lucky_7 im Themenstart schreibt:
Zu meiner Frage: Wieso wird hier np.frombuffer() verwendet? Ich meine, ich lese doch eigentlich von einer Datei, nicht von einem Buffer! Offenbar bewirkt f.read(), dass meine Datei in einen Buffer geladen wird. Ist das immer der Fall? Steht das irgendwie im Zusammenhang damit, dass meine Bilder im Byte-Format gespeichert sind?

Es handelt sich um ein Buffer, weil die Datei nicht direkt gelesen wird, sondern von gzip während des Lesens entpackt wird.
Das das Bild nicht erst komplett entpackt wird erschließt sich in diesem Fall vielleicht nicht, aber bei sehr großen Dateien möchte man sie oft nicht im ganzen entpacken, sondern stückweise. (Wären alle Bilder in einer Datei will man sie vermutlich auch nicht komplett entpacken sondern nur einen Teil.)

2019-11-18 10:43 - Lucky_7 im Themenstart schreibt:
Und warum wird eigentlich in np.frombuffer() der dtype als np.uint8 angegeben? Laut Magic Number der MNIST-Dataset, werden die Pixel als Unsigned Byte gespeichert. Das ist vermutlich dasselbe, kann das sein?

uint8 steht für 'unsigned integer with 8 bit' und ist eine gängige Namenskonvention. Die Eingabedaten werden also wie von dir gewünscht interpretiert.


2019-11-18 10:43 - Lucky_7 im Themenstart schreibt:
Und zu guter letzt: Das reshape(-1,28,28) bewirkt was? Meine Bilder müssten doch bereits 28x28 Pixel haben.

Da der Header ignoriert wird, sind die Dimensionen des Bildes unbekannt. Ohne Reshape wird der Inhalt daher erst einmal als eindimensionaler Vektor 1x(N*M) interpretiert.
Mit reshape(...) wird dann die Breite und Höhe der Matrix angepasst. Das Produkt der beiden Werte muss zur Länge des Vektors passen. Was die '-1' ganz vorne zu bedeuten hat, kann ich dir aber nicht sagen.

2019-11-18 10:43 - Lucky_7 im Themenstart schreibt:
 Und als np.float32 will ich die wieso haben?
Sorry, Fragen über Fragen. Vrmtl. ist np.float32 für irgendeine matplotlib Funktion wichtig. Aber ich würde es gerne verstehen.

Oftmals geht man bei den Werten der Farben von Fließkommazahlen im Interval [0,1] aus. Die Eingabe besteht aber aus Ganzzahlen im Bereich [0,255] und muss daher noch normiert werden.


Gruß Yggdrasil



  Profil  Quote  Link auf diesen Beitrag Link
Lucky_7
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 21.01.2018
Mitteilungen: 164
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.2, vom Themenstarter, eingetragen 2019-11-18 21:04


wow, vielen Dank Yggdrasil! Das hat mir echt geholfen



  Profil  Quote  Link auf diesen Beitrag Link
Lucky_7
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 21.01.2018
Mitteilungen: 164
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.3, vom Themenstarter, eingetragen 2019-11-18 22:03


Hast du zufällig eine Referenz dafür, dass gzip Dateien nicht vollständig entpackt, sondern stückweise in einen Buffer läd. Das habe ich so doch richtig verstanden, oder? Ich konnte das bisher nirgends finden.
Und data.read() liest dann aus diesem Buffer?



  Profil  Quote  Link auf diesen Beitrag Link
Yggdrasil
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 01.07.2004
Mitteilungen: 854
Aus: Berlin
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.4, eingetragen 2019-11-19 19:29


2019-11-18 22:03 - Lucky_7 in Beitrag No. 3 schreibt:
Hast du zufällig eine Referenz dafür, dass gzip Dateien nicht vollständig entpackt, sondern stückweise in einen Buffer läd. Das habe ich so doch richtig verstanden, oder? Ich konnte das bisher nirgends finden.
Und data.read() liest dann aus diesem Buffer?

Hallo, da habe ich mich leider geirrt!
Es handelt sich zwar um einen Buffer, da gzip.GzipFile auf io.BufferedIOBase basiert, aber
data = f.read()
liest die gesamte Datei ein. Für np.frombuffer ist data dann eine trivialer bytes-String.



  Profil  Quote  Link auf diesen Beitrag Link
Lucky_7
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 21.01.2018
Mitteilungen: 164
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.5, vom Themenstarter, eingetragen 2019-11-19 22:17


Also, passiert folgendes:

1. Gzip entpackt meine Datei.
2. data = file.read() öffnet die entpackte Datei und speichert sie als Byte-String in die Variable data
3. np.frombuffer()... tja. Diese Funktion modifiziert nun meine Variable data. Aber wieso ist sie dazu in der Lage? np.frombuffer liest doch aus einem Buffer. data befindet sich jetzt im Buffer, weil alle Variablen irgendwo im Memory, also im Buffer, gespeichert sind?

Tut mir leid, ich stehe ich voll auf dem Schlauch



  Profil  Quote  Link auf diesen Beitrag Link
Yggdrasil
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 01.07.2004
Mitteilungen: 854
Aus: Berlin
Zum letzten BeitragZum nächsten BeitragZum vorigen BeitragZum erstem Beitrag  Beitrag No.6, eingetragen 2019-11-20 11:03

  return np.frombuffer(data, dtype=np.uint8, offset=16).reshape(-1,28,28).astype(np.float32)

np.frombuffer(...) modifiziert die Variable data nicht, sondern
gibt ein neues Objekt zurück. Anderenfalls wäre die Kette, X().Y().Z(), an Funktions- bzw. Methodenaufrufen auch nicht sehr sinnvoll.

Es passiert also folgendes.
3a) np.frombuffer(...) erzeugt array-Objekt aus dem Inhalt von data
3b) .reshape(...) erzeugt neues Array in den Dimensionen 28x28. Diese Methode wird auf die Rückgabe von frombuffer angewendet.
3c) .astype(...) erzeugt erneut ein neues Array aus dem Objekt der vorherigen Rückgabe.

Obige Zeile ist im Prinzip also nur um eine Kurzschreibweise von
  arr1 = np.frombuffer(data, dtype=np.uint8, offset=16)
  arr2 = arr1.reshape(-1,28,28)
  arr3 = astype(np.float32)
  return arr3

Wenn du bei dieser Sache aber voll auf dem Schlauch stehst würde ich unbedingt dazu raten, die Grundlagen von Python anzuschauen. Danach sollte insbesondere klar sein, wie man solche Fragen zügig(!) eigenständig beantworten kann.
Letztlich habe ich auch nur eine Python-Shell geöffnet und angeschaut was passiert, wenn ich die fraglichen Codezeilen ausführe.



  Profil  Quote  Link auf diesen Beitrag Link
Lucky_7 hat die Antworten auf ihre/seine Frage gesehen.
Lucky_7 hatte hier bereits selbst das Ok-Häkchen gesetzt.
Neues Thema [Neues Thema] Antworten [Antworten]    Druckversion [Druckversion]

 


Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2019 by Matroids Matheplanet
This web site was made with PHP-Nuke, a web portal system written in PHP. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]