[PYTHON] Vorsichtsmaßnahmen beim Erben der DatasetMixin-Klasse

Über diesen Artikel

Ich habe mich für die Verwendung von Trainer mit Chainer entschieden. Als ich DatasetMixin geerbt habe, eine Klasse zum Übergeben von Daten an lIterator, und mein eigenes Dataset erstellt habe, habe ich einen kleinen Fehler gemacht, aber einen kleinen Fehler gemacht, sodass ich ihn als Aufzeichnung aufbewahren werde.

(Ergänzung) Die in diesem Artikel angenommene Version von Chainer ist 1.20. Die Situation kann sich mit der neuen Version ändern.

Fehlermeldung aufgetreten

Die Ausgabefehlermeldung war schwierig (schwer zu verstehen), um die Ursache zu beheben.

  File "cupy/cuda/device.pyx", line 66, in cupy.cuda.device.Device.__enter__ (cupy/cuda/device.cpp:1621)
  File "cupy/cuda/device.pyx", line 81, in cupy.cuda.device.Device.use (cupy/cuda/device.cpp:1862)
  File "cupy/cuda/runtime.pyx", line 178, in cupy.cuda.runtime.setDevice (cupy/cuda/runtime.cpp:2702)
  File "cupy/cuda/runtime.pyx", line 130, in cupy.cuda.runtime.check_status (cupy/cuda/runtime.cpp:2028)
cupy.cuda.runtime.CUDARuntimeError: cudaErrorInvalidDevice: invalid device ordinal

Als ich diese Nachricht sah, dachte ich: "Habe ich beim Schreiben der GPU-Verarbeitung des Modells oder der Daten einen Fehler gemacht?" Also habe ich verzweifelt versucht, mit cuda.cupy herumzuspielen, aber ich konnte keine Lösung finden.

Sie haben es vielleicht bemerkt, wenn Sie die Dokumentation sorgfältig gelesen haben, aber am Ende habe ich mir die Chainer-Quelle angesehen, um die Ursache zu verstehen.

Ein Teil des Codes, den ich erstellt habe

class MyDataset(chainer.dataset.DatasetMixin):
    def __init__(self, path):
        label_list = {}
        def get_label(l):
            num = label_list.get(l, -1)
            if num < 0:
                label_list[l] = len(label_list)
                return label_list[l]
            return num
        flist = []
        llist = []
        for root, dirs, files in os.walk(path):
            label = os.path.basename(root) #Verwenden Sie den Verzeichnisnamen als Bezeichnung
            label_num = get_label(label)
            for file in files:
                flist.append(os.path.join(root, file))
                llist.append(label_num)
        self.flist = flist
        self.llist = llist

    def __len__(self):
        return len(self.flist)

    def get_example(self, i):
        fname = self.flist[i]
        label = self.llist[i]
        img = Image.open(fname)
        img = np.asarray(img, dtype=np.float32).transpose(2, 0, 1)
        return img, label

Wenn Sie diese Klasse verwenden, um mit Iterator und Trainer mit einer GPU-fähigen Kette zu trainieren, tritt der obige Fehler unabhängig davon auf, ob eine GPU verwendet wird oder nicht.

Der folgende Fehler ist bei der CPU-Version von Chainer aufgetreten.

    check_cuda_available()
  File "/path/to/lib/python3.4/site-packages/chainer/cuda.py", line 83, in check_cuda_available
    raise RuntimeError(msg)
RuntimeError: CUDA environment is not correctly set up
(see https://github.com/pfnet/chainer#installation).CuPy is not correctly installed. Please check your environment, uninstall Chainer and reinstall it with `pip install chainer --no-cache-dir -vvvv`.

Ursache

Die einfache Geschichte ist, dass der von get_example zurückgegebene Label-Wert kein Numpy-Objekt ist. Wenn Sie Code ohne Verwendung von Trainer schreiben, ist es leicht zu bemerken, dass TypeError ("numpy.ndarray oder cuda.ndarray werden erwartet.") Wird angezeigt, wenn es sich zum Zeitpunkt des Umschließens des Werts in Variable nicht um ein numpy-Objekt handelt. Als ich es jedoch Iterator / Trainer überließ, wurde ein anderer Fehler angezeigt, sodass ich die Ursache nicht finden konnte (sollte ich eine Typprüfung anfordern?).

Gegenmaßnahmen

In diesem Fall besteht die Lösung darin, die Array-Liste mit den Beschriftungswerten in ein Numpy-Objekt zu verwandeln.

@@ -16,7 +16,7 @@
                 flist.append(os.path.join(root, file))
                 llist.append(label_num)
         self.flist = flist
-        self.llist = llist
+        self.llist = np.asarray(llist, dtype=np.int32)
 
     def __len__(self):
         return len(self.flist)

Schließlich

Wenn Sie Trainer verwenden, können Sie eine ausgefallene Fortschrittsausgabe (ProgressBar ()) erhalten, die cool ist. Verwenden wir also Trainer.

Recommended Posts

Vorsichtsmaßnahmen beim Erben der DatasetMixin-Klasse
Vorsichtsmaßnahmen bei Verwendung der Funktion urllib.parse.quote
Python-Variablenargument Ein Memorandum beim Erben einer definierten Klasse
Vorsichtsmaßnahmen bei der Installation von Paketen in der Conda-Umgebung
Vorsichtsmaßnahmen beim Umgang mit Luigi
Vorsichtsmaßnahmen bei der Installation von fbprophet
Vorsichtsmaßnahmen bei der Verwendung von Chainer
Vorsichtsmaßnahmen für das TensorFlow-Upgrade (auf 1.3)
Vorsichtsmaßnahmen beim Erstellen eines zweidimensionalen Arrays mit denselben Werten
Vorsichtsmaßnahmen bei Verwendung einer Liste oder eines Wörterbuchs als Standardargument