Ich habe kürzlich eine sehr zufriedenstellende Arbeit fertiggestellt. Der gesamte Prozess war nicht nur angenehm und einprägsam, sondern er hat auch wirklich „wissenschaftliche Wirkung und industriellen Output“ erzielt. Ich glaube, dass dieser Artikel das Paradigma des Differential Privacy (DP) Deep Learning verändern wird.
Weil diese Erfahrung so „zufällig“ ist (der Prozess ist voller Zufälle und die Schlussfolgerung ist äußerst clever), möchte ich meine Erfahrungen aus Beobachtung -> Konzeption -> Beweise -> Theorie mit meinen Klassenkameraden teilen -->large Der vollständige Prozess groß angelegter Experimente. Ich werde versuchen, diesen Artikel kurz zu halten und nicht zu viele technische Details einzubeziehen. Adresse des Papiers: arxiv.org/abs/2206.07136 Vollständiger Satz Fügen Sie einen Anhang hinzu. In diesem Artikel möchte ich meine Erfahrungen in chronologischer Reihenfolge aufschreiben (d. h. einen fortlaufenden Bericht), z. B. die Umwege, die ich gemacht habe, und die unerwarteten Situationen während der Recherche, um Studenten, die dies getan haben, als Referenz dienen zu können Ich habe gerade den Weg der wissenschaftlichen Forschung eingeschlagen.
1. Literaturlesung
Der Ursprung der Angelegenheit ist ein Artikel aus Stanford, der jetzt im ICLR erfasst wurde:
Artikel Es ist sehr gut geschrieben und enthält zusammenfassend drei Hauptbeiträge:
1. Bei NLP-Aufgaben ist die Genauigkeit des DP-Modells sehr hoch, was die Anwendung der Privatsphäre in Sprachmodellen fördert. (Im Gegensatz dazu führt DP in CV zu einer sehr großen Genauigkeitsverschlechterung. Beispielsweise hat CIFAR10 ohne vorheriges Training unter der DP-Grenze derzeit nur eine Genauigkeit von 80 %, kann aber ohne Berücksichtigung von DP leicht 95 % erreichen; ImageNets beste DP-Genauigkeit bei Die Zeit betrug weniger als 50 %.
2 Beim Sprachmodell gilt: Je größer das Modell, desto besser. Beispielsweise ist die Leistungsverbesserung von GPT2 von 400 Millionen Parametern auf 800 Millionen Parameter offensichtlich und es wurden auch viele SOTAs erreicht. (Aber in CV- und Empfehlungssystemen ist die Leistung größerer Modelle oft sehr schlecht und kommt sogar einer zufälligen Schätzung nahe. Beispielsweise wurde die beste DP-Genauigkeit von CIFAR10 zuvor durch vierschichtiges CNN und nicht durch ResNet erreicht.)
Bei NLP-Aufgaben gilt: Je größer das DP-Modell, desto besser die Leistung [Xuechen et al. 2021]
3 Die Hyperparameter zum Erhalten von SOTA bei mehreren Aufgaben sind konsistent: Der Clipping-Schwellenwert sollte klein genug eingestellt sein. und die Lernrate muss größer sein. (In allen vorherigen Artikeln ging es darum, einen Beschneidungsschwellenwert für jede Aufgabe anzupassen, was zeit- und arbeitsintensiv war. Es gab noch nie einen Beschneidungsschwellenwert von 0,1 wie diesen, der alle Aufgaben durchläuft, und die Leistung ist so gut.)
Die obige Zusammenfassung ist der Moment, in dem ich den Artikel zu Ende gelesen habe. Soweit ich weiß, stammt der Inhalt in Klammern nicht aus diesem Artikel, sondern aus dem Eindruck, der durch viele frühere Lektüren entstanden ist. Dies beruht auf einer langfristigen Leseakkumulation und einem hohen Grad an Generalisierungsfähigkeit, um schnell Assoziationen und Vergleiche zu ermöglichen.
Tatsächlich ist es für viele Studierende schwierig, mit dem Schreiben von Artikeln zu beginnen, da sie nur den Inhalt eines Artikels sehen können und kein Netzwerk bilden und keinen Zusammenhang mit Wissenspunkten im gesamten Fachgebiet herstellen können. Einerseits lesen Studierende, die gerade erst anfangen, zu wenig und beherrschen noch nicht genügend Wissenspunkte. Dies gilt insbesondere für Studierende, die schon seit langem Projekte von Lehrern übernehmen und diese nicht selbstständig vorschlagen. Andererseits ist der Umfang der Lektüre zwar ausreichend, wird jedoch nicht von Zeit zu Zeit zusammengefasst, was dazu führt, dass die Informationen nicht zu Wissen verdichtet werden oder das Wissen nicht verknüpft wird.
Hier ist das Hintergrundwissen zum DP Deep Learning. Ich werde die Definition von DP vorerst überspringen und es wird keinen Einfluss auf das Lesen haben.
Das sogenannte DP-Deep-Learning bedeutet aus algorithmischer Sicht tatsächlich zwei zusätzliche Schritte: Gradientenbeschneidung pro Probe und Gaußsches Rauschen, mit anderen Worten, solange Sie den Gradienten gemäß diesen beiden Schritten verarbeiten ( Nach der Verarbeitung wird der Gradient als privater Gradient bezeichnet. Anschließend können Sie den Optimierer nach Belieben verwenden, einschließlich SGD/Adam.
Wie privat der endgültige Algorithmus ist, ist eine Frage in einem anderen Teilgebiet, der sogenannten Privacy-Accounting-Theorie. Dieses Gebiet ist relativ ausgereift und erfordert eine starke theoretische Grundlage. Da sich dieser Artikel auf die Optimierung konzentriert, wird er hier nicht erwähnt.
g_i ist der Gradient eines Datenpunkts (Pro-Sample-Gradient), R ist der Clipping-Schwellenwert und Sigma ist der Rauschmultiplikator.
Clip wird wie das normale Beschneiden von Farbverläufen als Beschneidungsfunktion bezeichnet. Wenn der Farbverlauf länger als R ist, wird er auf R beschnitten, und wenn er kürzer als R ist, wird er nicht verschoben.
Zum Beispiel wird die DP-Version von SGD derzeit in allen Arbeiten verwendet, die die Clipping-Funktion in der Pionierarbeit des Privacy Deep Learning (Abadi, Martin, et al. „Deep Learning with Differential Privacy“) verwenden, auch bekannt als Abadis Clipping : Bild.
Aber das ist völlig unnötig. Nach den ersten Prinzipien und ausgehend von der Theorie der Datenschutzbuchhaltung muss die Clipping-Funktion tatsächlich nur erfüllen, dass der Modul von Clip(g_i)*g_i kleiner oder gleich R ist. Mit anderen Worten: Abadis Clipping ist nur eine Funktion, die diese Bedingung erfüllt, aber keineswegs die einzige.
Es gibt viele leuchtende Punkte in einem Artikel, aber nicht alle davon können von mir genutzt werden. Ich muss anhand meiner eigenen Bedürfnisse und Fachkenntnisse beurteilen, was den größten Beitrag leistet.
Die ersten beiden Beiträge dieses Artikels sind tatsächlich sehr empirisch und schwer zu verstehen. Der letzte Beitrag ist sehr interessant. Ich habe mir die Ablationsstudie zu Hyperparametern genau angesehen und einen Punkt gefunden, den der ursprüngliche Autor nicht gefunden hat: Wenn die Beschneidungsschwelle klein genug ist, ist die Beschneidungsschwelle (d. h. die Beschneidungsnorm C) sehr hoch , in der obigen Formel und R ist eine Variable) hat keine Auswirkung.
Longitudinal hat C=0,1, 0,4, 1,6 keinen Unterschied zu DP-Adam [Xuechen et al.
Das hat mein Interesse geweckt und ich habe das Gefühl, dass da irgendein Prinzip dahinterstecken muss. Also habe ich den DP-Adam handgeschrieben, um zu sehen, warum. Tatsächlich ist es ganz einfach:
Wenn R klein genug ist, entspricht das Abschneiden tatsächlich einer Normalisierung! Durch einfaches Einsetzen in den privaten Gradienten (1.1) kann R aus dem Clipping-Teil bzw. dem Rauschteil extrahiert werden:
Und die Form von Adam lässt R gleichzeitig im Gradienten und in der adaptiven Schrittgröße erscheinen. Zähler und Nenner Sobald der Zähler und der Nenner verrechnet sind, ist R verschwunden und die Idee ist da!
Sowohl m als auch v hängen vom Gradienten ab, und das Ersetzen durch private Gradienten führt zu DP-AdamW.
Eine so einfache Substitution beweist meinen ersten Satz: In DP-AdamW sind ausreichend kleine Begrenzungsschwellen einander gleichwertig und es ist keine Parameteranpassung erforderlich.
Das ist zweifellos eine sehr prägnante und interessante Beobachtung, aber sie ergibt nicht genug Sinn, also muss ich darüber nachdenken, welchen Nutzen diese Beobachtung in der Praxis hat.
Tatsächlich bedeutet dies, dass das DP-Training die Parameteranpassungsarbeit um eine Größenordnung reduziert: Unter der Annahme, dass die Lernrate und R auf jeweils 5 Werte angepasst werden (wie in der Abbildung oben gezeigt), dann 25 Kombinationen müssen getestet werden, um die optimalen Hyperparameter zu finden. Jetzt müssen Sie die Lernrate nur noch auf 5 Möglichkeiten anpassen, und die Parameteranpassungseffizienz wurde mehrfach verbessert. Dies ist ein sehr wertvolles Problem für die Branche.
Die Absicht ist hoch genug, die Mathematik ist prägnant genug und eine gute Idee nimmt langsam Gestalt an.
Wenn es nur für Adam/AdamW gilt, sind die Einschränkungen dieser Arbeit immer noch zu groß, also habe ich sie schnell auf AdamW und andere adaptive Optimierer wie AdaGrad ausgeweitet. Tatsächlich kann für alle adaptiven Optimierer nachgewiesen werden, dass der Beschneidungsschwellenwert versetzt wird, sodass keine Parameteranpassung erforderlich ist, was die Fülle des Theorems erheblich erhöht.
Hier gibt es noch ein weiteres interessantes kleines Detail. Wie wir alle wissen, unterscheidet sich Adam mit Gewichtsabnahme von AdamW. Zu diesem Unterschied gibt es auch einen Artikel. Adam hat zwei Möglichkeiten, Gewichtsabnahme hinzuzufügen.
Dieser Unterschied besteht auch beim DP-Optimierer. Das Gleiche gilt für Adam. Wenn ein entkoppelter Gewichtsabfall verwendet wird, hat die Skalierung von R keinen Einfluss auf die Größe des Gewichtsabfalls. Wenn jedoch ein normaler Gewichtsabfall verwendet wird, entspricht eine Vergrößerung von R um das Doppelte einer Verringerung des Gewichtsabfalls um das Doppelte.
Eine andere Sache
Kluge Studenten haben vielleicht herausgefunden, dass ich immer wieder über SGD spreche. Die Antwort ist, dass ich schnell die Theorie des DP-Adaptivoptimierers geschrieben habe Dann habe ich einen Artikel über die Verwendung von DP-SGD im Lebenslauf gepostet und eine Ablationsstudie durchgeführt, aber die Regeln waren völlig anders als die bei Adam, was bei mir einen diagonalen Eindruck hinterlassen hat
Für DP-SGD und wenn R klein genug ist, entspricht eine Erhöhung von lr um das Zehnfache einer Erhöhung von R um das Zehnfache [https://arxiv.org/abs/2201.12328].
Ich war sehr aufgeregt, als ich diesen Artikel sah, denn es war ein weiterer Artikel, der die Wirksamkeit kleiner Clipping-Schwellen bewies.
In der wissenschaftlichen Welt stecken hinter aufeinanderfolgenden Zufällen oft versteckte Regeln.
Ersetzen Sie es einfach und stellen Sie fest, dass SGD einfacher zu analysieren ist als Adam (1.3). Es kann wie folgt angenähert werden:
Offensichtlich kann R erneut vorgeschlagen und mit der Lernrate kombiniert werden, was theoretisch die Beobachtung von Google beweist.
„Insbesondere wenn die Clipping-Norm k-mal verringert wird, sollte die Lernrate k-mal erhöht werden, um eine ähnliche Genauigkeit beizubehalten.“
Es ist schade, dass Google das Phänomen nur gesehen hat und nicht auf die Ebene der Theorie gelangt ist . Hier gibt es auch einen Zufall, das heißt, sie haben im obigen Bild eine Ablationsstudie von zwei Skalen gezeichnet. Nur die linke Skala kann die diagonale Linie erkennen. Allein der Blick auf die rechte Seite lässt keine Schlussfolgerung zu.
Da es keine automatische Anpassung an die Schrittgröße gibt, ignoriert SGD R nicht wie Adam, sondern behandelt R als Teil der Lernrate, sodass keine separate Anpassung erforderlich ist. Die Lernrate wird jedenfalls angepasst zusammen, wenn die Parameter angepasst werden.
Erweitern Sie dann die SGD-Theorie auf Momentum, und alle von Pytorch unterstützten Optimierer wurden analysiert.
Ein innovativer Punkt ist vorhanden, aber streng genommen ist Abadis Ausschnitt nur eine ungefähre Normalisierung und kann nicht ausgeglichen werden, sodass die Konvergenz nicht abschließend analysiert werden kann.
Nach dem Prinzip von Doraemons Iron Man Corps habe ich Normalisierung direkt als neue Gradienten-Clipping-Funktion pro Probe bezeichnet, die das Abadi-Clipping ersetzt, das seit 6 Jahren im gesamten Bereich verwendet wird .
Nach dem Beweis gerade jetzt erfordert das neue Clipping grundsätzlich kein R, daher wird es automatisches Clipping (AUTO-V; V für Vanille) genannt.
Da sich die Form von Abadis Ausschnitt unterscheidet, ist die Genauigkeit unterschiedlich und mein Ausschnitt kann Nachteile haben.
Ich muss also Code schreiben, um meine neue Methode zu testen, und dafür muss nur eine Codezeile geändert werden (es ist schließlich nur ein Bild).
Tatsächlich gibt es neben Abadis Clipping hauptsächlich drei Clipping-Funktionen in Richtung DP-Pro-Sample. Eine davon ist das globale Clipping und die andere ist dieses automatische Clipping. In meiner vorherigen Arbeit wusste ich bereits, wie man Ausschnitte in verschiedenen gängigen Bibliotheken ändert. Die Änderungsmethode habe ich im Anhang am Ende des Artikels aufgeführt.
Nach meinen Tests habe ich festgestellt, dass im Stanford-Artikel während des gesamten Trainingsprozesses von GPT2 alle Iterationen und alle Verläufe pro Stichprobe abgeschnitten wurden. Mit anderen Worten: Zumindest in diesem Experiment entspricht Abadis Clipping vollständig dem automatischen Clipping. Obwohl spätere Experimente gegenüber SOTA verloren haben, hat dies gezeigt, dass meine neue Methode genug Wert hat: eine Clipping-Funktion, die den Clipping-Schwellenwert nicht anpassen muss, und manchmal wird die Genauigkeit nicht geopfert.
Stanfords Artikel befasst sich mit zwei Haupttypen von Sprachmodellexperimenten: Eine ist die generative Aufgabe, bei der GPT2 das Modell ist, und die andere ist die Klassifizierungsaufgabe, bei der RoBERTa das Modell ist. Obwohl das automatische Clipping dem Clipping von Abadi bei Generierungsaufgaben entspricht, ist die Genauigkeit bei Klassifizierungsaufgaben immer um einige Punkte schlechter.
Aufgrund meiner eigenen akademischen Gewohnheiten werde ich den Datensatz zu diesem Zeitpunkt nicht ändern und dann unsere dominanten Experimente zur Veröffentlichung auswählen, geschweige denn Tricks hinzufügen (wie Datenverbesserung und Änderung magischer Modelle). Ich hoffe, dass ich in einem völlig fairen Vergleich nur den Farbverlaufsausschnitt pro Probe vergleichen und den bestmöglichen feuchtigkeitsfreien Effekt erzielen kann.
Tatsächlich haben wir in Gesprächen mit unseren Mitarbeitern festgestellt, dass die reine Normalisierung und das Abadi-Clipping die Informationen zur Verlaufsgröße vollständig verwerfen. Das heißt, beim automatischen Clipping wird der Clipping immer sein, egal wie groß der ursprüngliche Gradient ist R wie folgt: Groß, während Abadi Größeninformationen für Farbverläufe behält, die kleiner als R sind.
Basierend auf dieser Idee haben wir eine kleine, aber äußerst clevere Änderung vorgenommen, genannt AUTO-S-Clipping (S steht für stabil).
Die Verschmelzung von R und Lernrate wird
Ein einfaches Die Zeichnung kann zeigen, dass dieser kleine Wert (normalerweise auf 0,01 eingestellt, tatsächlich kann er auf jede andere positive Zahl eingestellt werden, sehr robust) die Informationen der Gradientengröße behalten kann:
Basierend auf diesem Algorithmus ändern Sie einfach eine Zeile und führen Sie den Stanford-Code erneut aus. Sie erhalten die SOTA von sechs NLP-Datensätzen.
AUTO-S übertrifft alle anderen Clipping-Funktionen bei der E2E-Generierungsaufgabe sowie bei der SST2/MNLI/QNLI/QQP-Klassifizierungsaufgabe.
Eine Einschränkung des Stanford-Artikels besteht darin, dass er sich nur auf NLP konzentriert. Ein Zufall ist, dass Googles Tochtergesellschaft DeepMind zwei Monate nach der Zerstörung von ImageNets DP SOTA einen Artikel veröffentlichte, in dem DP direkt im Lebenslauf erscheint erhöht die ImageNet-Genauigkeit von 48 % auf 84 %!
Papieradresse: https://arxiv.org/abs/2204.13650
In diesem Artikel habe ich mich zunächst mit der Wahl des Optimierers und der Clipping-Schwelle befasst, bis ich mich im Anhang diesem Bild zugewandt habe:
DP-SGDs SOTA auf ImageNet erfordert außerdem, dass der Beschneidungsschwellenwert klein genug ist.
Dennoch funktioniert die kleine Clipping-Schwelle am besten! Mit drei hochwertigen Artikeln, die das automatische Clipping unterstützen, bin ich bereits stark motiviert und bin mir immer sicherer, dass meine Arbeit herausragend sein wird.
Zufälligerweise handelt es sich bei diesem DeepMind-Artikel auch um ein reines Experiment ohne Theorie, was sie auch fast zu der Erkenntnis geführt hat, dass sie R theoretisch nicht brauchen können. Tatsächlich sind sie meiner Idee sehr nahe und haben sogar R entdeckt extrahiert und in die Lernrate integriert werden (interessierte Studierende können sich deren Formeln (2) und (3) ansehen). Aber die Trägheit von Abadis Ausschnitt war zu groß ... Obwohl sie die Regeln herausgefunden hatten, gingen sie nicht weiter.
DeepMind hat auch herausgefunden, dass eine kleine Clipping-Schwelle am besten funktioniert, verstand aber nicht, warum.
Inspiriert von dieser neuen Arbeit begann ich mit CV zu experimentieren, damit mein Algorithmus von allen DP-Forschern verwendet werden kann, anstatt einen Methodensatz für NLP und einen anderen für CV zu verwenden.
Ein guter Algorithmus sollte universell und einfach zu verwenden sein. Fakten haben auch gezeigt, dass automatisches Clipping auch SOTA für CV-Datensätze erreichen kann.
Bei Betrachtung aller oben genannten Papiere wurde SOTA erheblich verbessert und die technischen Auswirkungen sind voll, aber die Theorie ist völlig leer.
Als ich alle Experimente abgeschlossen habe, hat der Beitrag dieser Arbeit die Anforderungen einer Top-Konferenz übertroffen: Ich habe die Parameterauswirkungen von DP-SGD und DP-Adam, die durch kleine Clipping-Schwellen in der Erfahrung verursacht werden, erheblich vereinfacht; wird vorgeschlagen, ohne die Recheneffizienz und den Datenschutz zu beeinträchtigen und ohne dass das kleine γ den Schaden an den Gradientengrößeninformationen repariert, der durch Abadis Clipping- und Normalisierungsexperimente eine ausreichende SOTA-Genauigkeit erreicht.
Ich bin noch nicht zufrieden. Ein Optimierer ohne theoretische Unterstützung ist immer noch nicht in der Lage, einen wesentlichen Beitrag zum Deep Learning zu leisten. Jedes Jahr werden Dutzende neuer Optimierer vorgeschlagen, die im zweiten Jahr alle verworfen werden. Es gibt immer noch nur wenige, die offiziell von Pytorch unterstützt und tatsächlich von der Industrie genutzt werden.
Aus diesem Grund verbrachten meine Mitarbeiter und ich zusätzliche zwei Monate mit der automatischen DP-SGD-Konvergenzanalyse. Der Prozess war schwierig, aber der endgültige Beweis wurde extrem vereinfacht. Die Schlussfolgerung ist ebenfalls sehr einfach: Der Einfluss von Stapelgröße, Lernrate, Modellgröße, Stichprobengröße und anderen Variablen auf die Konvergenz wird quantitativ ausgedrückt und stimmt mit allen bekannten DP-Trainingsverhalten überein.
Insbesondere haben wir bewiesen, dass DP-SGD zwar langsamer konvergiert als Standard-SGD, die Konvergenzgeschwindigkeit jedoch eine Größenordnung beträgt, wenn die Iteration gegen unendlich tendiert. Dies schafft Vertrauen in die Datenschutzberechnung: Das DP-Modell konvergiert, wenn auch spät.
Endlich ist der Artikel, an dem ich seit 7 Monaten schreibe, unerwarteterweise noch nicht vorbei. NeurIPS reichte das Papier im Mai ein und die internen Änderungen wurden am 14. Juni abgeschlossen und an arXiv veröffentlicht. Als Ergebnis sah ich, dass Microsoft Research Asia (MSRA) einen Artikel veröffentlichte, der mit unserem vorgeschlagenen Ausschnitt kollidierte genau das Gleiche wie unser automatisches Ausschneiden:
Genau das gleiche wie unser AUTO-S.
Bei genauem Hinsehen ist sogar der Konvergenzbeweis fast derselbe. Und die beiden Gruppen von uns haben keinen Schnittpunkt. Man kann sagen, dass ein Zufall auf der anderen Seite des Pazifischen Ozeans entstanden ist.
Lassen Sie uns ein wenig über den Unterschied zwischen den beiden Artikeln sprechen: Der andere Artikel ist eher theoretisch und analysiert beispielsweise zusätzlich die Konvergenz von Abadi DP-SGD (ich habe nur das automatische Clipping bewiesen, bei dem es sich um DP-NSGD handelt). ihr Artikel, vielleicht weiß ich nicht, wie man DP-SGD anpasst); die verwendeten Annahmen sind auch etwas anders und unsere Experimente sind mehr und größer (mehr als ein Dutzend Datensätze) und die Äquivalenzbeziehung zwischen Abadis Clipping und Normalisierung ist expliziter etabliert, wie Satz 1 und 2 erklären, warum R ohne Parameteranpassung verwendet werden kann.
Da wir gleichzeitig arbeiten, freue ich mich sehr, dass es Menschen gibt, die einer Meinung sind und sich gegenseitig ergänzen und diesen Algorithmus gemeinsam vorantreiben können, sodass die gesamte Community an dieses Ergebnis glauben und davon profitieren kann so schnell wie möglich. Selbstsüchtig erinnere ich mich natürlich auch daran, dass der nächste Artikel beschleunigt wird!
Wenn ich auf den kreativen Prozess dieses Artikels zurückblicke, müssen von Anfang an Grundkenntnisse die Voraussetzung sein, und eine weitere wichtige Voraussetzung ist, dass ich immer über den Schmerzpunkt der Parameteranpassung nachgedacht habe. Es war eine lange Dürreperiode, daher kann Ihnen die Lektüre des richtigen Artikels dabei helfen, Nektar zu finden. Was den Prozess betrifft, liegt der Kern in der Gewohnheit, Beobachtungen mathematisch zu theoretisieren. In dieser Arbeit ist die Fähigkeit, Code zu implementieren, nicht das Wichtigste. Ich werde eine weitere Kolumne schreiben, die sich auf eine weitere Kern-Codierungsarbeit konzentriert; die abschließende Konvergenzanalyse stützt sich auch auf meine Mitarbeiter und meine eigene Unbezwingbarkeit. Glücklicherweise haben Sie keine Angst davor, zu spät zu einem guten Essen zu kommen, also machen Sie weiter!
Über den Autor
Bu Zhiqi hat einen Bachelor-Abschluss und einen Ph.D. von der University of Pennsylvania. Seine Forschungsrichtung ist Differential Privacy und Deep Learning mit Schwerpunkt auf Optimierungsalgorithmen und Großrechnern.
Das obige ist der detaillierte Inhalt vonWie ich einen Top-Aufsatz von Grund auf geschrieben habe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!