Dies ist eine Fortsetzung des vorherigen Artikels (https://qiita.com/kuroitu/items/221e8c477ffdd0774b6b). In diesem Artikel bereiten wir uns auf die Codierung vor. Wenn Sie es selbst implementieren möchten, aber es ist ziemlich ... bitte werfen Sie einen Blick darauf. (Grundsätzlich kann ich keine komplizierten Techniken anwenden, also mach dir keine Sorgen) ** Die Codierungsumgebung ist ein Jupyter-Notebook. ** ** ** Wenn Sie es auf Modulebene an anderer Stelle verwalten möchten, kommentieren Sie den Befehl wie "Importieren" aus. Wenn es nicht funktioniert, lass es mich in den Kommentaren wissen ... Der nächste Artikel ist hier
__repr__
und __str__
](Implementierung der Methoden #repr und str)__len__
](Implementierung der Methode #len)__setitem__
](Implementierung der Methode #setitem)Machen Sie zuerst einen Basisbehälter.
baselayer.py
import numpy as np
class BaseLayer():
"""
Alle zugrunde liegenden Ebenenklassen
Beschreiben Sie die Verarbeitung, die der Zwischenschicht und der Ausgabeschicht gemeinsam ist.
"""
def __init__(self):
pass
def forward(self):
"""
Implementierung der Vorwärtsausbreitung
"""
pass
def backward(self):
"""
Implementierung der Backpropagation
"""
pass
def update(self):
"""
Implementierung des Parameterlernens
"""
pass
middlelayer.py
import numpy as np
#import .baselayer import BaseLayer
class MiddleLayer(BaseLayer):
"""
Mittelklasse
Die Eingangsschicht wird auch hinsichtlich der Montage als eine der Zwischenschichten behandelt.
"""
pass
outputlayer.py
import numpy as np
#from .baselayer import BaseLayer
class OutputLayer(BaseLayer):
"""
Ausgabeebenenklasse
"""
pass
Hier bereiten wir einen Manager für die Handhabung von Layer-Modulen vor. ** Zum Schluss setzen Sie den Code zusammen. Bitte beachten Sie, dass Sie möglicherweise vergessen haben, den Code in der Mitte zu ändern. ** ** ** Grundsätzlich werden wir es mit dem Typ "List" und "Dictionary" von Python machen.
layermanager.py
import numpy as np
#from .layer import *
class _TypeManager():
"""
Manager-Klasse für Ebenentypen
"""
N_TYPE = 2 #Anzahl der Ebenentypen
MIDDLE = 0 #Nummerierung der mittleren Schicht
OUTPUT = 1 #Nummerierung der Ausgabeebene
class LayerManager(_TypeManager):
"""
Manager-Klasse zum Verwalten von Ebenen
"""
def __init__(self):
pass
Die Klasse "LayerManager" kennt den Typ "Wörterbuch" und ermöglicht es Ihnen, eine Liste von Ebenen zu führen und diese hinzuzufügen / zu entfernen.
Lassen Sie uns auch _TypeManager
erben.
Das "Layer" -Modul ist übrigens ein Modul zum Importieren aller "Layer" -bezogenen Module.
layer.py
from .middlelayer import *
from .outputlayer import *
from ._layererror import *
Das _layererror
-Modul wird später beschrieben, aber wir planen, es zu einem Modul zu machen, das die in der Ebene auftretenden Fehler zusammenfasst.
Implementieren Sie zunächst eine spezielle Methode der Klasse "LayerManager". Eine Liste der speziellen Methoden finden Sie unter Offizielle Dokumentation.
Implementieren Sie nun die Methode __init__
der Klasse LayerManager
.
Erstens ist die Methode init eine der speziellen Methoden von Python und eine der Methoden, die beim Erstellen einer Instanz einer Klasse aufgerufen werden.
Mit anderen Worten, beschreiben Sie die Aktion, die Sie ausführen möchten, wenn die LayerManager-Klasse generiert wird.
Hier
--Halten Sie eine Liste von Ebenen --Halten Sie eine Liste der Ebenennamen
Ich möchte, dass Sie es tun, also implementieren Sie es so.
layermanager.py
def __init__(self):
self.__layer_list = [] #Liste der Ebenen
self.__name_list = [] #Namensliste für jede Schicht
self.__ntype = np.zeros(self.N_TYPE) #Anzahl der Ebenen nach Typ
__repr__
und __str__
Die Methode "repr" ist eine "offizielle" Zeichenfolgendarstellung, die von der Funktion "repr", einer der in Python integrierten Funktionen, aufgerufen wird. Es heißt "offiziell", aber der Punkt ist, dass es detaillierte Informationen sind. Die "str" -Methode ist eine "inoffizielle" Zeichenfolgendarstellung, die von einer der in Python integrierten Funktionen, der "str" -Funktion und den integrierten Funktionen "format" und "print" aufgerufen wird. Die Bedeutung von "informell" ist, dass es leicht zu lesen ist.
layermanager.py
def __repr__(self):
layerRepr= "layer_list: " + repr(self.__layer_list)
nameRepr = "name_list: " + repr(self.__name_list)
ntypeRepr = "ntype: " + repr(self.__ntype)
return (layerRepr + "\n"
+ nameRepr + "\n"
+ ntypeRepr)
def __str__(self):
layerStr = "layer_list: " + str(self.__layer_list)
nameStr = "name_list: " + str(self.__name_list)
ntypeStr = "ntype: " + str(self.__ntype)
return (layerStr + "\n"
+ nameStr + "\n"
+ ntypeStr)
__len__
MethodeDie Methode __len__
beschreibt das Verhalten beim Aufruf von der Funktion len
, einer der in Python integrierten Funktionen.
Geben wir die Anzahl der Ebenen zurück, über die die Klasse "LayerManager" verfügt.
layermanager.py
def __len__(self):
"""
In Python integrierte Funktionen`len`Beschreibt den Vorgang beim Aufruf von.
Gibt die Summe der Anzahl der Ebenen nach Typ zurück.
"""
return np.sum(self.__ntype)
Die Methode __getitem__
ist eine Methode, die beim Abrufen eines Elements durch Angabe eines Index usw. in einer Python-Liste oder einem Numpy-Array aufgerufen wird.
layermanager.py
def __getitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
x = lm[3].~~
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Scheibe und str,Zugriff nur über int zulassen.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, beziehen Sie sich auf die Liste der Ebenen mit Slice.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Gibt die Elemente der Liste der anwendbaren Ebenen zurück.
if key in self.__name_list:
index = self.__name_list.index(key)
return self.__layer_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, wird das entsprechende Element in der Liste der Ebenen zurückgegeben.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
else:
raise KeyError("{}: Not defined such key type.".format(key))
__setitem__
ist eine Methode, die häufig im Typ Dictionary
usw. verwendet wird und aufgerufen wird, wenn key
und value
wie lm [key] = value
gesetzt werden.
Erlaube nur das Überschreiben von Elementen und gib andernfalls einen Fehler aus.
Der Grund ist, dass wir nicht möchten, dass Benutzer ihren eigenen "Schlüssel" registrieren, da wir die Namensregeln später verwenden werden.
layermanager.py
def __setitem__(self, key, value):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
lm[1] = x
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Es ist nur das Überschreiben von Elementen zulässig, und das Hinzufügen neuer Elemente ist verboten.
"""
value_type = ""
if isinstance(value, list):
#Auf der rechten Seite angegeben'value'Aber'list'Wenn
#Alle Elemente'BaseLayer'Fehler, wenn die Klasse sie erbt oder nicht.
if not np.all(
np.where(isinstance(value, BaseLayer), True, False)):
self.AssignError()
value_type = "list"
elif isinstance(value, BaseLayer):
#Auf der rechten Seite angegeben'value'Aber'BaseLayer'Ist es eine Klasse?
#Fehler, wenn es nicht vererbt wird.
self.AssignError(type(value))
if value_type == "":
value_type = "BaseLayer"
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, überschreiben Sie das Element in der Liste der Ebenen.
#jedoch'value_type'Aber'list'Sonst ein Fehler.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "list":
self.AssignError(value_type)
self.__layer_list[key] = value
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Überschreiben Sie die Elemente in der Liste der zutreffenden Ebenen.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
if key in self.__name_list:
index = self.__name_list.index(key)
self.__layer_list[index] = value
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, überschreiben Sie das entsprechende Element in der Ebenenliste.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
#Auch ein abnormaler Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
self.__layer_list[key] = value
else:
raise KeyError(key, ": Undefined such key type.")
__delitem__
ist eine Methode, die vondel lm [key]
usw. aufgerufen wird. Dadurch wird nur das angegebene Element gelöscht.
Die Verarbeitung nach dem Löschen ist jedoch etwas mühsam.
layermanager.py
def __delitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
del lm[2]
Weil es aufgerufen wird, wenn auf das Element der Liste oder des Arrays von der del-Anweisung wie zugegriffen wird
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Wenn das angegebene Element vorhanden ist, wird es gelöscht und umbenannt.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, löschen Sie das angegebene Element unverändert
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[slice]
del self.__name_list[slice]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Löschen Sie das entsprechende Element.
if key in self.__name_list:
del self.__layer_list[index]
del self.__name_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn der Schlüssel eine Ganzzahl ist, löschen Sie das entsprechende Element in der Ebenenliste.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[key]
else:
raise KeyError(key, ": Undefined such key type.")
#Umbenennen
self._rename()
Übrigens bedeutet "_" (einfacher Unterstrich) das "private" Attribut, das schwächer ist als "__" (doppelter Unterstrich). Auf diese kann von außen als "Klassenname._Renamezugegriffen werden. Auf doppelte Unterstriche kann jedoch nur zugegriffen werden, wenn beispielsweise" Klassenname ._ Modulname __ Methodenname "verwendet wird. .. Außerdem können Modulfunktionen, die nicht zu einer Klasse gehören, nicht von
from module name import * importiert werden, wenn
private durch
_angegeben ist. Sie müssen es
from module name import _ method name` richtig aufrufen.
Von hier aus implementieren wir benutzerdefinierte (dh wir definieren) Funktionen. Hier werde ich im Grunde die berühmten Punkte des Typs "List" und des Typs "Dictionary" implementieren.
Implementieren Sie vorerst die in der vorherigen Implementierung verwendete Methode "_rename". Wann ist das notwendig?
Es gibt zwei Möglichkeiten. Wenn Sie Ihr Bestes geben und über die Logik nachdenken, können Sie anscheinend die Anzahl der Änderungen reduzieren, aber es ist problematisch, daher werde ich von Anfang an darauf zurückkommen. Weil es einfach zu implementieren ist. ** Wartbarkeit ist wichtig. ** ** **
layermanager.py
def _rename(self):
"""
Wenn die Benennung der Namensliste aufgrund der Listenoperation gegen die Regeln verstößt
Benennen Sie die Namensliste und jede Ebene um, um die Regeln erneut zu erfüllen.
Die Namensregel lautet[Ebenentyp][Welche Nummer]Wird besorgt.
Wenn der Ebenentyp Mittlere Ebene ist, Mittlere Ebene
Ausgabe für Ausgabeschicht
Es wird als abgekürzt.
Die Nummer wird nach Typ gezählt.
Auch hier wieder__Zählt nTypen.
"""
#Initialisieren Sie die Anzahl der Ebenen nach Typ
self.__ntype = np.zeros(self.N_TYPE)
#Zählen Sie jede Ebene neu und benennen Sie sie um
for i in range(len(self)):
if "Middle" in self.__name_list[i]:
self.__ntype[self.MIDDLE] += 1
self.__name_list[i] = "Middle{}".format(
self.__ntype[self.MIDDLE])
self.__layer_list[i].name = "Middle{}".format(
self.__ntype[self.MIDDLE])
elif "Output" in self.__name_list[i]:
self.__ntype[self.OUTPUT] += 1
self.__name_list[i] = "Output{}".format(
self.__ntype[self.OUTPUT])
self.__layer_list[i].name = "Output{}".format(
self.__ntype[self.OUTPUT])
else:
raise UndefinedLayerType(self.__name_list[i])
Implementieren Sie die bekannte Methode "Anhängen" in die Methode zum Hinzufügen von Elementen zur Liste. Da es am Ende hinzugefügt wird, gibt es keine komplizierte Verarbeitung.
layermanager.py
def append(self, *, name="Middle", **kwds):
"""
Implementierung der bekannten Append-Methode, bei der Elemente zu einer Liste hinzugefügt werden.
"""
if "prev" in kwds:
# 'prev'Ist im Schlüsselwort enthalten
#Dies bedeutet, dass die Anzahl der Elemente in der vorherigen Ebene angegeben wird.
#Grundsätzlich soll es also an der Zeit sein, die erste Schicht einzufügen
#Davon abgesehen wird es grundsätzlich automatisch ermittelt und nicht angegeben.
if len(self) != 0:
if kwds["prev"] != self.__layer_list[-1].n:
#Fehler, wenn er nicht mit der Anzahl der Einheiten am Ende übereinstimmt.
raise UnmatchUnitError(self.__layer_list[-1].n,
kwds["prev"])
else:
if len(self) == 0:
#Die erste Ebene muss immer die Anzahl der Eingabeeinheiten angeben.
raise UnmatchUnitError("Input units", "Unspecified")
else:
#Die Anzahl der Einheiten in der letzten Ebene'kwds'Hinzufügen
kwds["prev"] = self.__layer_list[-1].n
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Fügen Sie eine Ebene hinzu.
if name == "Middle":
#Erhöhen Sie die Ebene nach Typ
self.__ntype[self.MIDDLE] += 1
#Zum Namen hinzufügen
name += str(self.__ntype[self.MIDDLE])
#Zur Namensliste hinzufügen
self.__name_list.append(name)
#Erstellen Sie abschließend eine Ebene und fügen Sie sie der Liste hinzu.
self.__layer_list.append(
MiddleLayer(name=name, **kwds))
elif name == "Output":
#Dies ist auch das gleiche.
self.__ntype[self.OUTPUT] += 1
name += str(self.__ntype[self.OUTPUT])
self.__name_list.append(name)
self.__layer_list.append(
OutputLayer(name=name, **kwds))
#Wenn Sie hier keine else-Anweisung zeichnen, ändern Sie den Namen gemäß der Namensregel
#Schon abnormal auf der Bühne'name'Wurde weggelassen.
Das ist vielleicht nicht sehr vertraut? Implementieren Sie die Methode "Erweitern" von "Liste".
example.py
x = [1, 2, 3]
y = [4, 5, 6]
x.append(y)
print(x)
Dann
[1, 2, 3, [4, 5, 6]]
Ich denke es wird so sein. Mit der Methode "verlängern"
example.py
x = [1, 2, 3]
y = [4, 5, 6]
x.extend(y)
print(x)
Das Ergebnis von
[1, 2, 3, 4, 5, 6]
Es wird sein.
layermanager.py
def extend(self, lm):
"""
Ein weiterer Layer-Manager, der bereits in der Extend-Methode vorhanden ist'lm'Elemente von
Füge alle Hinzu.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
if len(self) != 0:
if self.__layer_list[-1].n != lm[0].prev:
#Mit der Anzahl der Einheiten in Ihrer letzten Ebene
# 'lm'Fehler, wenn die Anzahl der Eingaben in der ersten Schicht von nicht gleich ist.
raise UnmatchUnitError(self.__layer_list[-1].n,
lm[0].prev)
#Beziehungsweise'extend'Nach Methode hinzufügen
self.__layer_list.extend(lm.layer_list)
self.__name_list.extend(lm.name_list)
#Umbenennen
self._rename()
Dies ist möglicherweise auch nicht sehr vertraut. Eine Methode, die ein Element an einer bestimmten Position hinzufügt.
layermanager.py
def insert(self, prev_name, name="Middle", **kwds):
"""
Geben Sie in der Einfügemethode den Namen der vorherigen Ebene an und kombinieren Sie ihn mit dieser Ebene.
Fügen Sie ein Element hinzu.
"""
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
# 'prev'Ist im Schlüsselwort enthalten
# 'prev_name'Fehler, wenn er nicht mit der Anzahl der Einheiten in der in angegebenen Ebene übereinstimmt.
if "prev" in kwds:
if kwds["prev"] \
!= self.__layer_list[self.index(prev_name)].n:
raise UnmatchUnitError(
kwds["prev"],
self.__layer_list[self.index(prev_name)].n)
# 'n'Ist im Schlüsselwort enthalten
if "n" in kwds:
# 'prev_name'Wenn ist nicht der letzte
if prev_name != self.__name_list[-1]:
#Fehler, wenn er nicht mit der Anzahl der Einheiten in der nächsten Ebene übereinstimmt.
if kwds["n"] != self.__layer_list[
self.index(prev_name)+1].prev:
raise UnmatchUnitError(
kwds["n"],
self.__layer_list[self.index(prev_name)].prev)
#Wenn es noch keine Elemente gibt'append'Geben Sie einen Fehler bei der Verwendung der Methode ein.
if len(self) == 0:
raise RuntimeError(
"You have to use 'append' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Element einfügen
#In diesem Moment,'name'Befolgen Sie noch nicht die Namensregeln,
#Ich werde es später umbenennen, also mach dir keine Sorgen.
if "Middle" in name:
self.__layer_list.insert(index,
MiddleLayer(name=name, **kwds))
self.__name_list.insert(index, name)
elif "Output" in name:
self.__layer_list.insert(index,
OutputLayer(name=name, **kwds))
self.__name_list.insert(index, name)
#Umbenennen
self._rename()
Dies ist das Original. Es verhält sich wie eine Kombination der Methoden "Erweitern" und "Einfügen".
layermanager.py
def extend_insert(self, prev_name, lm):
"""
Dies ist die ursprüngliche Funktion.
Es verhält sich wie eine Kombination aus der Extend-Methode und der Insert-Methode.
Einfach ausgedrückt ist es wie das Einfügen eines weiteren Ebenenmanagers.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
#Die Anzahl der Einheiten der Schichten vor und nach dem angegebenen Ort sowie der ersten und letzten Schicht von lm
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
if len(self) != 0:
if self.__layer_list[self.index(prev_name)].n \
!= lm.layer_list[0].prev:
#Mit der Anzahl der Einheiten an Ihrem angegebenen Standort'lm'Die erste Anzahl von Einheiten in
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
raise UnmatchUnitError(
self.__layer_list[self.index(prev_name)].n,
lm.layer_list[0].prev)
if prev_name != self.__name_list[-1]:
# 'prev_name'Ist nicht meine letzte Schicht
if lm.layer_list[-1].n \
!= self.__layer_list[self.index(prev_name)+1].prev:
# 'lm'Die Anzahl der Einheiten am Ende und die nächste Ebene Ihres festgelegten Standorts
# 'prev'Fehler, wenn er nicht mit der Anzahl der Einheiten übereinstimmt.
raise UnmatchUnitError(
lm.layer_list[-1].n,
self.__layer_list[self.index(prev_name)+1].prev)
else:
#Wenn Sie keine Elemente haben'extend'Ich erhalte eine Fehlermeldung bei der Verwendung der Methode.
raise RuntimeError(
"You have to use 'extend' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Elemente nach der Einfügeposition'buf'Entfernen Sie es nach dem Evakuieren einmal
#Fügen Sie ein Element mit der Extend-Methode hinzu
layer_buf = self.__layer_list[index:]
name_buf = self.__name_list[index:]
del self.__layer_list[index:]
del self.__name_list[index:]
self.extend(lm)
#Fügen Sie das evakuierte Element hinzu
self.__layer_list.extend(layer_buf)
self.__name_list.extend(name_buf)
#Umbenennen
self._rename()
Die Methode "remove" entfernt das angegebene Element, nicht wahr? Dies wurde bereits mit [Implementierung der del-Anweisung](Implementierung der Methode #delitem) durchgeführt. Rufen Sie es einfach auf.
layermanager.py
def remove(self, key):
"""
Die Methode remove entfernt das Element mit dem angegebenen Namen.
Es darf auch durch Index angegeben werden.
"""
#Bereits implementiert'del'Der Satz ist in Ordnung.
del self[key]
Anders als oben ist es eine Methodenliste, die nützlich ist.
layermanager.py
def index(self, target):
return self.__name_list.index(target)
def name(self, indices):
return self.__name_list[indices]
Wir werden die Eigenschaften hier implementieren. Grundsätzlich wird nur "Getter" benötigt, also dekorieren Sie es mit "@ property" und implementieren Sie es. Wenn Sie einen "Setter" hinzufügen möchten, können Sie den Dekorator "@ property name.setter" verwenden.
layermanager.py
@property
def layer_list(self):
return self.__layer_list
@property
def name_list(self):
return self.__name_list
@property
def ntype(self):
return self.__ntype
Der Code des vorherigen Ebenenmanagers wird integriert und als Volltext veröffentlicht. Natürlich werden wir in zukünftigen Artikeln Methoden usw. hinzufügen.
layermanager.py
import numpy as np
#from .layer import *
class _TypeManager():
"""
Manager-Klasse für Ebenentypen
"""
N_TYPE = 2 #Anzahl der Ebenentypen
MIDDLE = 0 #Nummerierung der mittleren Schicht
OUTPUT = 1 #Nummerierung der Ausgabeebene
class LayerManager(_TypeManager):
"""
Manager-Klasse zum Verwalten von Ebenen
"""
def __init__(self):
self.__layer_list = [] #Liste der Ebenen
self.__name_list = [] #Namensliste für jede Schicht
self.__ntype = np.zeros(self.N_TYPE) #Anzahl der Ebenen nach Typ
def __repr__(self):
layerRepr= "layer_list: " + repr(self.__layer_list)
nameRepr = "name_list: " + repr(self.__name_list)
ntypeRepr = "ntype: " + repr(self.__ntype)
return (layerRepr + "\n"
+ nameRepr + "\n"
+ ntypeRepr)
def __str__(self):
layerStr = "layer_list: " + str(self.__layer_list)
nameStr = "name_list: " + str(self.__name_list)
ntypeStr = "ntype: " + str(self.__ntype)
return (layerStr + "\n"
+ nameStr + "\n"
+ ntypeStr)
def __len__(self):
"""
In Python integrierte Funktionen`len`Beschreibt den Vorgang beim Aufruf von.
Gibt die Summe der Anzahl der Ebenen nach Typ zurück.
"""
return np.sum(self.__ntype)
def __getitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
x = lm[3].~~
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Scheibe und str,Zugriff nur über int zulassen.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, beziehen Sie sich auf die Liste der Ebenen mit Slice.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Gibt die Elemente der Liste der anwendbaren Ebenen zurück.
if key in self.__name_list:
index = self.__name_list.index(key)
return self.__layer_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, wird das entsprechende Element in der Liste der Ebenen zurückgegeben.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
else:
raise KeyError(key, ": Undefined such key type.")
def __setitem__(self, key, value):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
lm[1] = x
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Es ist nur das Überschreiben von Elementen zulässig, und das Hinzufügen neuer Elemente ist verboten.
"""
value_type = ""
if isinstance(value, list):
#Auf der rechten Seite angegeben'value'Aber'list'Wenn
#Alle Elemente'BaseLayer'Fehler, wenn die Klasse sie erbt oder nicht.
if not np.all(
np.where(isinstance(value, BaseLayer), True, False)):
self.AssignError()
value_type = "list"
elif isinstance(value, BaseLayer):
#Auf der rechten Seite angegeben'value'Aber'BaseLayer'Ist es eine Klasse?
#Fehler, wenn es nicht vererbt wird.
self.AssignError(type(value))
if value_type == "":
value_type = "BaseLayer"
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, überschreiben Sie das Element in der Liste der Ebenen.
#jedoch'value_type'Aber'list'Sonst ein Fehler.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "list":
self.AssignError(value_type)
self.__layer_list[key] = value
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Überschreiben Sie die Elemente in der Liste der zutreffenden Ebenen.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
if key in self.__name_list:
index = self.__name_list.index(key)
self.__layer_list[index] = value
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, überschreiben Sie das entsprechende Element in der Ebenenliste.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
#Auch ein abnormaler Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
self.__layer_list[key] = value
else:
raise KeyError(key, ": Undefined such key type.")
def __delitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
del lm[2]
Weil es aufgerufen wird, wenn auf das Element der Liste oder des Arrays von der del-Anweisung wie zugegriffen wird
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Wenn das angegebene Element vorhanden ist, wird es gelöscht und umbenannt.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, löschen Sie das angegebene Element unverändert
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[slice]
del self.__name_list[slice]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Löschen Sie das entsprechende Element.
if key in self.__name_list:
del self.__layer_list[index]
del self.__name_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn der Schlüssel eine Ganzzahl ist, löschen Sie das entsprechende Element in der Ebenenliste.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[key]
else:
raise KeyError(key, ": Undefined such key type.")
#Umbenennen
self._rename()
def _rename(self):
"""
Wenn die Benennung der Namensliste aufgrund der Listenoperation gegen die Regeln verstößt
Benennen Sie die Namensliste und jede Ebene um, um die Regeln erneut zu erfüllen.
Die Namensregel lautet[Ebenentyp][Welche Nummer]Wird besorgt.
Wenn der Ebenentyp Mittlere Ebene ist, Mittlere Ebene
Ausgabe für Ausgabeschicht
Es wird als abgekürzt.
Die Nummer wird nach Typ gezählt.
Auch hier wieder__Zählt nTypen.
"""
#Initialisieren Sie die Anzahl der Ebenen nach Typ
self.__ntype = np.zeros(self.N_TYPE)
#Zählen Sie jede Ebene neu und benennen Sie sie um
for i in range(len(self)):
if "Middle" in self.__name_list[i]:
self.__ntype[self.MIDDLE] += 1
self.__name_list[i] = "Middle{}".format(
self.__ntype[self.MIDDLE])
self.__layer_list[i].name = "Middle{}".format(
self.__ntype[self.MIDDLE])
elif "Output" in self.__name_list[i]:
self.__ntype[self.OUTPUT] += 1
self.__name_list[i] = "Output{}".format(
self.__ntype[self.OUTPUT])
self.__layer_list[i].name = "Output{}".format(
self.__ntype[self.OUTPUT])
else:
raise UndefinedLayerType(self.__name_list[i])
def append(self, *, name="Middle", **kwds):
"""
Implementierung der bekannten Append-Methode, bei der Elemente zu einer Liste hinzugefügt werden.
"""
if "prev" in kwds:
# 'prev'Ist im Schlüsselwort enthalten
#Dies bedeutet, dass die Anzahl der Elemente in der vorherigen Ebene angegeben wird.
#Grundsätzlich soll es also an der Zeit sein, die erste Schicht einzufügen
#Davon abgesehen wird es grundsätzlich automatisch ermittelt und nicht angegeben.
if len(self) != 0:
if kwds["prev"] != self.__layer_list[-1].n:
#Fehler, wenn er nicht mit der Anzahl der Einheiten am Ende übereinstimmt.
raise UnmatchUnitError(self.__layer_list[-1].n,
kwds["prev"])
else:
if len(self) == 0:
#Die erste Ebene muss immer die Anzahl der Eingabeeinheiten angeben.
raise UnmatchUnitError("Input units", "Unspecified")
else:
#Die Anzahl der Einheiten in der letzten Ebene'kwds'Hinzufügen
kwds["prev"] = self.__layer_list[-1].n
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Fügen Sie eine Ebene hinzu.
if name == "Middle":
#Erhöhen Sie die Ebene nach Typ
self.__ntype[self.MIDDLE] += 1
#Zum Namen hinzufügen
name += str(self.__ntype[self.MIDDLE])
#Zur Namensliste hinzufügen
self.__name_list.append(name)
#Erstellen Sie abschließend eine Ebene und fügen Sie sie der Liste hinzu.
self.__layer_list.append(
MiddleLayer(name=name, **kwds))
elif name == "Output":
#Dies ist auch das gleiche.
self.__ntype[self.OUTPUT] += 1
name += str(self.__ntype[self.OUTPUT])
self.__name_list.append(name)
self.__layer_list.append(
OutputLayer(name=name, **kwds))
#Wenn Sie hier keine else-Anweisung zeichnen, ändern Sie den Namen gemäß der Namensregel
#Schon abnormal auf der Bühne'name'Wurde weggelassen.
def extend(self, lm):
"""
Ein weiterer Layer-Manager, der bereits in der Extend-Methode vorhanden ist'lm'Elemente von
Füge alle Hinzu.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
if len(self) != 0:
if self.__layer_list[-1].n != lm[0].prev:
#Mit der Anzahl der Einheiten in Ihrer letzten Ebene
# 'lm'Fehler, wenn die Anzahl der Eingaben in der ersten Schicht von nicht gleich ist.
raise UnmatchUnitError(self.__layer_list[-1].n,
lm[0].prev)
#Beziehungsweise'extend'Nach Methode hinzufügen
self.__layer_list.extend(lm.layer_list)
self.__name_list.extend(lm.name_list)
#Umbenennen
self._rename()
def insert(self, prev_name, name="Middle", **kwds):
"""
Geben Sie in der Einfügemethode den Namen der vorherigen Ebene an und kombinieren Sie ihn mit dieser Ebene.
Fügen Sie ein Element hinzu.
"""
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
# 'prev'Ist im Schlüsselwort enthalten
# 'prev_name'Fehler, wenn er nicht mit der Anzahl der Einheiten in der in angegebenen Ebene übereinstimmt.
if "prev" in kwds:
if kwds["prev"] \
!= self.__layer_list[self.index(prev_name)].n:
raise UnmatchUnitError(
kwds["prev"],
self.__layer_list[self.index(prev_name)].n)
# 'n'Ist im Schlüsselwort enthalten
if "n" in kwds:
# 'prev_name'Wenn ist nicht der letzte
if prev_name != self.__name_list[-1]:
#Fehler, wenn er nicht mit der Anzahl der Einheiten in der nächsten Ebene übereinstimmt.
if kwds["n"] != self.__layer_list[
self.index(prev_name)+1].prev:
raise UnmatchUnitError(
kwds["n"],
self.__layer_list[self.index(prev_name)].prev)
#Wenn es noch keine Elemente gibt'append'Geben Sie einen Fehler bei der Verwendung der Methode ein.
if len(self) == 0:
raise RuntimeError(
"You have to use 'append' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Element einfügen
#In diesem Moment,'name'Befolgen Sie noch nicht die Namensregeln,
#Ich werde es später umbenennen, also mach dir keine Sorgen.
if "Middle" in name:
self.__layer_list.insert(index,
MiddleLayer(name=name, **kwds))
self.__name_list.insert(index, name)
elif "Output" in name:
self.__layer_list.insert(index,
OutputLayer(name=name, **kwds))
self.__name_list.insert(index, name)
#Umbenennen
self._rename()
def extend_insert(self, prev_name, lm):
"""
Dies ist die ursprüngliche Funktion.
Es verhält sich wie eine Kombination aus der Extend-Methode und der Insert-Methode.
Einfach ausgedrückt ist es wie das Einfügen eines weiteren Ebenenmanagers.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
#Die Anzahl der Einheiten der Schichten vor und nach dem angegebenen Ort sowie der ersten und letzten Schicht von lm
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
if len(self) != 0:
if self.__layer_list[self.index(prev_name)].n \
!= lm.layer_list[0].prev:
#Mit der Anzahl der Einheiten an Ihrem angegebenen Standort'lm'Die erste Anzahl von Einheiten in
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
raise UnmatchUnitError(
self.__layer_list[self.index(prev_name)].n,
lm.layer_list[0].prev)
if prev_name != self.__name_list[-1]:
# 'prev_name'Ist nicht meine letzte Schicht
if lm.layer_list[-1].n \
!= self.__layer_list[self.index(prev_name)+1].prev:
# 'lm'Die Anzahl der Einheiten am Ende und die nächste Ebene Ihres festgelegten Standorts
# 'prev'Fehler, wenn er nicht mit der Anzahl der Einheiten übereinstimmt.
raise UnmatchUnitError(
lm.layer_list[-1].n,
self.__layer_list[self.index(prev_name)+1].prev)
else:
#Wenn Sie keine Elemente haben'extend'Ich erhalte eine Fehlermeldung bei der Verwendung der Methode.
raise RuntimeError(
"You have to use 'extend' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Elemente nach der Einfügeposition'buf'Entfernen Sie es nach dem Evakuieren einmal
#Fügen Sie ein Element mit der Extend-Methode hinzu
layer_buf = self.__layer_list[index:]
name_buf = self.__name_list[index:]
del self.__layer_list[index:]
del self.__name_list[index:]
self.extend(lm)
#Fügen Sie das evakuierte Element hinzu
self.__layer_list.extend(layer_buf)
self.__name_list.extend(name_buf)
#Umbenennen
self._rename()
def remove(self, key):
"""
Die Methode remove entfernt das Element mit dem angegebenen Namen.
Es darf auch durch Index angegeben werden.
"""
#Bereits implementiert'del'Der Satz ist in Ordnung.
del self[key]
def index(self, target):
return self.__name_list.index(target)
def name(self, indices):
return self.__name_list[indices]
@property
def layer_list(self):
return self.__layer_list
@property
def name_list(self):
return self.__name_list
@property
def ntype(self):
return self.__ntype
Einführung in das Modul "_layererror". Derzeit werden nur die Fehler implementiert, die bisher in der Implementierung aufgetreten sind. Dies kann ebenfalls hinzugefügt werden.
_layererror.py
class LayerManagerError(Exception):
"""Basisklasse für benutzerdefinierte Fehler in Layer-Modulen"""
pass
class AssignError(LayerManagerError):
def __init__(self, value=None):
if not value is None:
self.value = value
self.message = (str(value)
+ ": Assigning that value is prohibited.")
else:
self.value = None
self.message = "Assigning that value is prohibited."
def __str__(self):
return self.message
class UnmatchUnitError(LayerManagerError):
def __init__(self, prev, n):
self.prev = prev
self.n = n
self.message = "Unmatch units: {} and {}.".format(prev, n)
def __str__(self):
return self.message
class UndefinedLayerError(LayerManagerError):
def __init__(self, type_name):
self.type = type_name
self.message = str(type_name) + ": Undefined layer type."
def __str__(self):
return self.message
Der Erste
_layererror.py
class LayerManagerError(Exception):
"""Basisklasse für benutzerdefinierte Fehler in Layer-Modulen"""
pass
Ausnahmen über Ebenen abfangen
example.py
try:
raise AssignError()
except LayerManagerError:
print("catch LayerManagerError")
Auf diese Weise können Sie alle Fehler abfangen, die davon erben. Natürlich können Sie Fehler auch einzeln abfangen. Außerdem kann die Fehleranweisung erst ausgegeben werden, nachdem die Methode str definiert wurde.
Also habe ich hier eine Vorlage für Ebenenobjekte, einen Manager für deren Behandlung und ein Modul für die Fehlerkontrolle erstellt. Wir werden den Inhalt der Implementierung im nächsten und den folgenden Artikeln weiter hinzufügen.
baselayer.py
import numpy as np
class BaseLayer():
"""
Alle zugrunde liegenden Ebenenklassen
Beschreiben Sie die Verarbeitung, die der Zwischenschicht und der Ausgabeschicht gemeinsam ist.
"""
def __init__(self):
pass
def forward(self):
"""
Implementierung der Vorwärtsausbreitung
"""
pass
def backward(self):
"""
Implementierung der Backpropagation
"""
pass
def update(self):
"""
Implementierung des Parameterlernens
"""
pass
middlelayer.py
import numpy as np
#import .baselayer import BaseLayer
class MiddleLayer(BaseLayer):
"""
Mittelklasse
Die Eingangsschicht wird auch hinsichtlich der Montage als eine der Zwischenschichten behandelt.
"""
pass
outputlayer.py
import numpy as np
#from .baselayer import BaseLayer
class OutputLayer(BaseLayer):
"""
Ausgabeebenenklasse
"""
pass
layermanager.py
import numpy as np
#from .layer import *
class _TypeManager():
"""
Manager-Klasse für Ebenentypen
"""
N_TYPE = 2 #Anzahl der Ebenentypen
MIDDLE = 0 #Nummerierung der mittleren Schicht
OUTPUT = 1 #Nummerierung der Ausgabeebene
class LayerManager(_TypeManager):
"""
Manager-Klasse zum Verwalten von Ebenen
"""
def __init__(self):
self.__layer_list = [] #Liste der Ebenen
self.__name_list = [] #Namensliste für jede Schicht
self.__ntype = np.zeros(self.N_TYPE) #Anzahl der Ebenen nach Typ
def __repr__(self):
layerRepr= "layer_list: " + repr(self.__layer_list)
nameRepr = "name_list: " + repr(self.__name_list)
ntypeRepr = "ntype: " + repr(self.__ntype)
return (layerRepr + "\n"
+ nameRepr + "\n"
+ ntypeRepr)
def __str__(self):
layerStr = "layer_list: " + str(self.__layer_list)
nameStr = "name_list: " + str(self.__name_list)
ntypeStr = "ntype: " + str(self.__ntype)
return (layerStr + "\n"
+ nameStr + "\n"
+ ntypeStr)
def __len__(self):
"""
In Python integrierte Funktionen`len`Beschreibt den Vorgang beim Aufruf von.
Gibt die Summe der Anzahl der Ebenen nach Typ zurück.
"""
return np.sum(self.__ntype)
def __getitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
x = lm[3].~~
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Scheibe und str,Zugriff nur über int zulassen.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, beziehen Sie sich auf die Liste der Ebenen mit Slice.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Gibt die Elemente der Liste der anwendbaren Ebenen zurück.
if key in self.__name_list:
index = self.__name_list.index(key)
return self.__layer_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, wird das entsprechende Element in der Liste der Ebenen zurückgegeben.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
return self.__layer_list[key]
else:
raise KeyError(key, ": Undefined such key type.")
def __setitem__(self, key, value):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
lm[1] = x
Wird aufgerufen, wenn auf ein Element einer Liste oder eines Arrays zugegriffen wird, z
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Es ist nur das Überschreiben von Elementen zulässig, und das Hinzufügen neuer Elemente ist verboten.
"""
value_type = ""
if isinstance(value, list):
#Auf der rechten Seite angegeben'value'Aber'list'Wenn
#Alle Elemente'BaseLayer'Fehler, wenn die Klasse sie erbt oder nicht.
if not np.all(
np.where(isinstance(value, BaseLayer), True, False)):
self.AssignError()
value_type = "list"
elif isinstance(value, BaseLayer):
#Auf der rechten Seite angegeben'value'Aber'BaseLayer'Ist es eine Klasse?
#Fehler, wenn es nicht vererbt wird.
self.AssignError(type(value))
if value_type == "":
value_type = "BaseLayer"
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, überschreiben Sie das Element in der Liste der Ebenen.
#jedoch'value_type'Aber'list'Sonst ein Fehler.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "list":
self.AssignError(value_type)
self.__layer_list[key] = value
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Überschreiben Sie die Elemente in der Liste der zutreffenden Ebenen.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
if key in self.__name_list:
index = self.__name_list.index(key)
self.__layer_list[index] = value
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn key eine Ganzzahl ist, überschreiben Sie das entsprechende Element in der Ebenenliste.
#jedoch'value_type'Aber'BaseLayer'Sonst ein Fehler.
#Auch ein abnormaler Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
if value_type != "BaseLayer":
raise AssignError(value_type)
self.__layer_list[key] = value
else:
raise KeyError(key, ": Undefined such key type.")
def __delitem__(self, key):
"""
Zum Beispiel
lm = LayerManager()
+----------------+
| (Element zu lm hinzufügen) |
+----------------+
del lm[2]
Weil es aufgerufen wird, wenn auf das Element der Liste oder des Arrays von der del-Anweisung wie zugegriffen wird
Beschreiben Sie den Vorgang zu diesem Zeitpunkt.
Wenn das angegebene Element vorhanden ist, wird es gelöscht und umbenannt.
"""
if isinstance(key, slice):
#Wenn der Schlüssel ein Slice ist, löschen Sie das angegebene Element unverändert
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[slice]
del self.__name_list[slice]
elif isinstance(key, str):
#Wenn der Schlüssel eine Zeichenfolge ist, rufen Sie den Index aus der Namensliste jeder Ebene und ab
#Löschen Sie das entsprechende Element.
if key in self.__name_list:
del self.__layer_list[index]
del self.__name_list[index]
else:
#Wenn der Schlüssel nicht vorhanden ist, wird ein KeyError ausgegeben.
raise KeyError("{}: No such item".format(key))
elif isinstance(key, int):
#Wenn der Schlüssel eine Ganzzahl ist, löschen Sie das entsprechende Element in der Ebenenliste.
#Ungewöhnlicher Wert(Index außerhalb des Bereichs usw.)Wann wird eingegeben
#Python gibt mir einen Fehler.
del self.__layer_list[key]
else:
raise KeyError(key, ": Undefined such key type.")
#Umbenennen
self._rename()
def _rename(self):
"""
Wenn die Benennung der Namensliste aufgrund der Listenoperation gegen die Regeln verstößt
Benennen Sie die Namensliste und jede Ebene um, um die Regeln erneut zu erfüllen.
Die Namensregel lautet[Ebenentyp][Welche Nummer]Wird besorgt.
Wenn der Ebenentyp Mittlere Ebene ist, Mittlere Ebene
Ausgabe für Ausgabeschicht
Es wird als abgekürzt.
Die Nummer wird nach Typ gezählt.
Auch hier wieder__Zählt nTypen.
"""
#Initialisieren Sie die Anzahl der Ebenen nach Typ
self.__ntype = np.zeros(self.N_TYPE)
#Zählen Sie jede Ebene neu und benennen Sie sie um
for i in range(len(self)):
if "Middle" in self.__name_list[i]:
self.__ntype[self.MIDDLE] += 1
self.__name_list[i] = "Middle{}".format(
self.__ntype[self.MIDDLE])
self.__layer_list[i].name = "Middle{}".format(
self.__ntype[self.MIDDLE])
elif "Output" in self.__name_list[i]:
self.__ntype[self.OUTPUT] += 1
self.__name_list[i] = "Output{}".format(
self.__ntype[self.OUTPUT])
self.__layer_list[i].name = "Output{}".format(
self.__ntype[self.OUTPUT])
else:
raise UndefinedLayerType(self.__name_list[i])
def append(self, *, name="Middle", **kwds):
"""
Implementierung der bekannten Append-Methode, bei der Elemente zu einer Liste hinzugefügt werden.
"""
if "prev" in kwds:
# 'prev'Ist im Schlüsselwort enthalten
#Dies bedeutet, dass die Anzahl der Elemente in der vorherigen Ebene angegeben wird.
#Grundsätzlich soll es also an der Zeit sein, die erste Schicht einzufügen
#Davon abgesehen wird es grundsätzlich automatisch ermittelt und nicht angegeben.
if len(self) != 0:
if kwds["prev"] != self.__layer_list[-1].n:
#Fehler, wenn er nicht mit der Anzahl der Einheiten am Ende übereinstimmt.
raise UnmatchUnitError(self.__layer_list[-1].n,
kwds["prev"])
else:
if len(self) == 0:
#Die erste Ebene muss immer die Anzahl der Eingabeeinheiten angeben.
raise UnmatchUnitError("Input units", "Unspecified")
else:
#Die Anzahl der Einheiten in der letzten Ebene'kwds'Hinzufügen
kwds["prev"] = self.__layer_list[-1].n
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Fügen Sie eine Ebene hinzu.
if name == "Middle":
#Erhöhen Sie die Ebene nach Typ
self.__ntype[self.MIDDLE] += 1
#Zum Namen hinzufügen
name += str(self.__ntype[self.MIDDLE])
#Zur Namensliste hinzufügen
self.__name_list.append(name)
#Erstellen Sie abschließend eine Ebene und fügen Sie sie der Liste hinzu.
self.__layer_list.append(
MiddleLayer(name=name, **kwds))
elif name == "Output":
#Dies ist auch das gleiche.
self.__ntype[self.OUTPUT] += 1
name += str(self.__ntype[self.OUTPUT])
self.__name_list.append(name)
self.__layer_list.append(
OutputLayer(name=name, **kwds))
#Wenn Sie hier keine else-Anweisung zeichnen, ändern Sie den Namen gemäß der Namensregel
#Schon abnormal auf der Bühne'name'Wurde weggelassen.
def extend(self, lm):
"""
Ein weiterer Layer-Manager, der bereits in der Extend-Methode vorhanden ist'lm'Elemente von
Füge alle Hinzu.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
if len(self) != 0:
if self.__layer_list[-1].n != lm[0].prev:
#Mit der Anzahl der Einheiten in Ihrer letzten Ebene
# 'lm'Fehler, wenn die Anzahl der Eingaben in der ersten Schicht von nicht gleich ist.
raise UnmatchUnitError(self.__layer_list[-1].n,
lm[0].prev)
#Beziehungsweise'extend'Nach Methode hinzufügen
self.__layer_list.extend(lm.layer_list)
self.__name_list.extend(lm.name_list)
#Umbenennen
self._rename()
def insert(self, prev_name, name="Middle", **kwds):
"""
Geben Sie in der Einfügemethode den Namen der vorherigen Ebene an und kombinieren Sie ihn mit dieser Ebene.
Fügen Sie ein Element hinzu.
"""
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
# 'prev'Ist im Schlüsselwort enthalten
# 'prev_name'Fehler, wenn er nicht mit der Anzahl der Einheiten in der in angegebenen Ebene übereinstimmt.
if "prev" in kwds:
if kwds["prev"] \
!= self.__layer_list[self.index(prev_name)].n:
raise UnmatchUnitError(
kwds["prev"],
self.__layer_list[self.index(prev_name)].n)
# 'n'Ist im Schlüsselwort enthalten
if "n" in kwds:
# 'prev_name'Wenn ist nicht der letzte
if prev_name != self.__name_list[-1]:
#Fehler, wenn er nicht mit der Anzahl der Einheiten in der nächsten Ebene übereinstimmt.
if kwds["n"] != self.__layer_list[
self.index(prev_name)+1].prev:
raise UnmatchUnitError(
kwds["n"],
self.__layer_list[self.index(prev_name)].prev)
#Wenn es noch keine Elemente gibt'append'Geben Sie einen Fehler bei der Verwendung der Methode ein.
if len(self) == 0:
raise RuntimeError(
"You have to use 'append' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Lesen Sie den Layertyp und ändern Sie den Namen gemäß der Namensregel
if name == "mid" or "m":
name = "Middle"
elif name == "out" or "o":
name = "Output"
else:
raise UndefinedLayerError(name)
#Element einfügen
#In diesem Moment,'name'Befolgen Sie noch nicht die Namensregeln,
#Ich werde es später umbenennen, also mach dir keine Sorgen.
if "Middle" in name:
self.__layer_list.insert(index,
MiddleLayer(name=name, **kwds))
self.__name_list.insert(index, name)
elif "Output" in name:
self.__layer_list.insert(index,
OutputLayer(name=name, **kwds))
self.__name_list.insert(index, name)
#Umbenennen
self._rename()
def extend_insert(self, prev_name, lm):
"""
Dies ist die ursprüngliche Funktion.
Es verhält sich wie eine Kombination aus der Extend-Methode und der Insert-Methode.
Einfach ausgedrückt ist es wie das Einfügen eines weiteren Ebenenmanagers.
"""
if not isinstance(lm, LayerManager):
# 'lm'Fehler, wenn die Instanz von nicht LayerManager ist.
raise TypeError(type(lm), ": Unexpected type.")
# 'prev_name'Fehler, wenn nicht vorhanden.
if not prev_name in self.__name_list:
raise KeyError(prev_name, ": No such key.")
#Die Anzahl der Einheiten der Schichten vor und nach dem angegebenen Ort sowie der ersten und letzten Schicht von lm
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
if len(self) != 0:
if self.__layer_list[self.index(prev_name)].n \
!= lm.layer_list[0].prev:
#Mit der Anzahl der Einheiten an Ihrem angegebenen Standort'lm'Die erste Anzahl von Einheiten in
#Wenn sie nicht übereinstimmen, tritt ein Fehler auf.
raise UnmatchUnitError(
self.__layer_list[self.index(prev_name)].n,
lm.layer_list[0].prev)
if prev_name != self.__name_list[-1]:
# 'prev_name'Ist nicht meine letzte Schicht
if lm.layer_list[-1].n \
!= self.__layer_list[self.index(prev_name)+1].prev:
# 'lm'Die Anzahl der Einheiten am Ende und die nächste Ebene Ihres festgelegten Standorts
# 'prev'Fehler, wenn er nicht mit der Anzahl der Einheiten übereinstimmt.
raise UnmatchUnitError(
lm.layer_list[-1].n,
self.__layer_list[self.index(prev_name)+1].prev)
else:
#Wenn Sie keine Elemente haben'extend'Ich erhalte eine Fehlermeldung bei der Verwendung der Methode.
raise RuntimeError(
"You have to use 'extend' method instead.")
#Index der Einfügeposition abrufen
index = self.index(prev_name) + 1
#Elemente nach der Einfügeposition'buf'Entfernen Sie es nach dem Evakuieren einmal
#Fügen Sie ein Element mit der Extend-Methode hinzu
layer_buf = self.__layer_list[index:]
name_buf = self.__name_list[index:]
del self.__layer_list[index:]
del self.__name_list[index:]
self.extend(lm)
#Fügen Sie das evakuierte Element hinzu
self.__layer_list.extend(layer_buf)
self.__name_list.extend(name_buf)
#Umbenennen
self._rename()
def remove(self, key):
"""
Die Methode remove entfernt das Element mit dem angegebenen Namen.
Es darf auch durch Index angegeben werden.
"""
#Bereits implementiert'del'Der Satz ist in Ordnung.
del self[key]
def index(self, target):
return self.__name_list.index(target)
def name(self, indices):
return self.__name_list[indices]
@property
def layer_list(self):
return self.__layer_list
@property
def name_list(self):
return self.__name_list
@property
def ntype(self):
return self.__ntype
_layererror.py
class LayerManagerError(Exception):
"""Basisklasse für benutzerdefinierte Fehler in Layer-Modulen"""
pass
class AssignError(LayerManagerError):
def __init__(self, value=None):
if not value is None:
self.value = value
self.message = (str(value)
+ ": Assigning that value is prohibited.")
else:
self.value = None
self.message = "Assigning that value is prohibited."
def __str__(self):
return self.message
class UnmatchUnitError(LayerManagerError):
def __init__(self, prev, n):
self.prev = prev
self.n = n
self.message = "Unmatch units: {} and {}.".format(prev, n)
def __str__(self):
return self.message
class UndefinedLayerError(LayerManagerError):
def __init__(self, type_name):
self.type = type_name
self.message = str(type_name) + ": Undefined layer type."
def __str__(self):
return self.message
Recommended Posts