Versionskontrolle für Machine-Learning-Projekte

Originalartikel

Backup

<html> <p>&#160;&#187;&#160;<a href=„https://www.informatik-aktuell.de/betrieb.html“ target=„_self“>Betrieb</a>&#160;&#187;&#160;<a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz.html“ target=„_self“>K&#252;nstliche Intelligenz</a></p>Veit Schiele 11. August 2020<header></header><div class=„ce-textpic ce-left ce-intext“><div class=„ce-gallery ce-row ce-column“ data-ce-columns=„1“ data-ce-images=„1“><figure class=„image“><img class=„image-embed-item“ title=„Mit DVC ko&#776;nnen Sie sprachunabha&#776;ngig ML-Pipelines mit den zugeho&#776;rigen Trainingsdaten, Konfigurationen, Leistungsmetriken usw. definieren. &#169; Adobe: dsdecoret / stock.adobe.com / 211485579“ alt=„Mit DVC ko&#776;nnen Sie sprachunabha&#776;ngig ML-Pipelines mit den zugeho&#776;rigen Trainingsdaten, Konfigurationen, Leistungsmetriken usw. definieren. &#169; Adobe: dsdecoret / stock.adobe.com / 211485579“ src=„https://www.informatik-aktuell.de/fileadmin/_processed_/5/4/csm_720-AdobeStock_211485579_ddd223b4f7.jpg“ width=„350“ height=„196“ referrerpolicy=„no-referrer“ /><figcaption class=„image-caption“>&#169; Adobe: dsdecoret</figcaption></figure></div><div class=„ce-bodytext“><p><strong>In diesem Artikel erfahren Sie, wie die Modellentwicklung f&#252;r maschinelles Lernen (ML) systematisch organisiert werden kann. So kann die Leistung eines Modells verbessert werden, wenn die Parameter feiner abgestimmt oder wenn mehr Trainingsdaten verf&#252;gbar werden. Um die Verbesserung messen zu k&#246;nnen, sollte nachverfolgt werden k&#246;nnen, welche Daten f&#252;r das Training in welcher Modelldefinition und -konfiguration (Parameter etc.) verwendet und welche Modellleistungen damit erzielt wurden. Dabei sollten sowohl die Daten wie auch der zugeh&#246;rige Programmcode in einer Version erfasst werden.</strong></p><p>DVC (<em>Data Version Control</em>) wurde entwickelt, um Sie genau bei dieser Aufgabe zu unterst&#252;tzen <a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#c32318“>[1]</a>. Durch die Implementierung einer DVC-Pipeline werden alle Daten geladen, vorverarbeitet, trainiert und die Leistung bewertet, wobei der Vorgang vollst&#228;ndig reproduzierbar und automatisierbar ist. Trainingsdaten, Modellkonfiguration, das Modell und Leistungsmetriken sind so versioniert, dass Sie bequem zu einer bestimmten Version zur&#252;ckkehren und alle zugeh&#246;rigen Konfigurationen und Daten &#252;berpr&#252;fen k&#246;nnen. Au&#223;erdem bietet DVC einen &#220;berblick &#252;ber Metriken f&#252;r alle Versionen Ihrer Pipeline, mit deren Hilfe Sie die beste Version ermitteln k&#246;nnen. Zudem k&#246;nnen Sie die Trainingsdaten, Modelle, Leistungsmetriken usw. mit anderen teilen und eine effiziente Zusammenarbeit erm&#246;glichen.</p><h2>Warum DVC?</h2><ul><li><strong>Git-annex</strong> speichert wie DVC gro&#223;e Dateien nicht im Git-Repository selbst, sondern in einem lokalen Schl&#252;ssel-Wert-Speicher und verwendet Hardlinks oder Symlinks, anstatt Dateien zu duplizieren <a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#c32318“>[2]</a>.</li><li><strong>Git-LFS</strong> verwendet Reflinks oder Hardlinks, um Kopiervorg&#228;nge zu vermeiden und so gro&#223;e Dateien effizienter verarbeiten zu k&#246;nnen. DVC ist jedoch kompatibel zu deutlich mehr Remote-Speichern (S3, Google Cloud, Azure, SSH usw.) <a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#c32318“>[3]</a>.</li><li>Andere Workflow-Management-Systeme wie <strong>MLflow</strong> sind meist sehr allgemein und nicht speziell f&#252;r die Verwaltung von Daten in ML-Projekten entwickelt worden <a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#c32318“>[4]</a>.</li><li><p><strong>DAGsHub</strong> ist ein DVC-A&#776;quivalent, jedoch nur fu&#776;r Github <a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#c32318“>[5]</a>.</p></li></ul><h2>Ein Beispielprojekt</h2><p>Dieser Artikel f&#252;hrt Sie durch ein Beispielprojekt mit folgenden Phasen:</p><ol><li>Repositories erstellen</li><li>Datenpipelines definieren</li><li>Reproduzieren</li><li>Pipeline visualisieren</li><li>Daten teilen</li></ol></div></div><header><h3>1. Repositories erstellen</h3></header><p>1. Zun&#228;chst wird ein Repository mit einer Versionsverwaltung Ihrer Wahl vorbereitet. In unserem Beispiel ist dies Git, DVC kann jedoch auch mit jeder anderen Versionsverwaltung zusammenarbeiten.</p><pre>$ git init</pre><p>2. In diesem Repository DVC initiieren:</p><pre>$ dvc initYou can now commit the changes to git….</pre><p>3. Initiales Git-Repository einchecken:</p><pre>$ git status neue Datei: .dvc/.gitignore neue Datei: .dvc/config$ git add .dvc $ git commit -m „Initial repo“</pre><p>4. Daten mit DVC verwalten:</p><pre>$ mkdir data$ dvc get https://github.com/iterative/dataset-registry get-started/data.xml \ -o data/data.xml$ dvc add data/data.xml</pre><p>5. Daten&#228;nderungen mit Git synchronisieren:</p><pre>$ git add data/data.xml.dvc data/.gitignore$ git commit -m „Add raw data“</pre><p>6. Entfernten Datenspeicher konfigurieren:</p><p>Sie k&#246;nnen DVC-Daten und -Modelle mit <em>dvc push</em> auch au&#223;erhalb Ihres lokalen Caches an einem entfernten Ort speichern, damit sie sp&#228;ter auch in anderen Umgebungen abgerufen werden k&#246;nnen. &#220;blicherweise sind dies entfernte Cloud-Services (S3, Azure Blob Storage, Google Cloud Storage), aber auch SSH, HDFS, und HTTP sind m&#246;glich. Um das Beispiel m&#246;glichst einfach nachvollziehbar zu halten, w&#228;hlen wir hier einen lokalen Speicherort:</p><pre>$ sudo mkdir -p /var/dvc-storage$ dvc remote add -d local /var/dvc-storageSetting 'local' as a default remote.$ git commit .dvc/config -m „Configure local remote&#8220;[master efaeb84] Configure local remote 1 file changed, 4 insertions(+)</pre><p>7. Speichern und teilen:</p><p>Mit <em>dvc push</em> kopieren Sie Dateien aus Ihrem lokalen DVC-Cache in den zuvor konfigurierten Remote-Storage.</p><pre>$ dvc push</pre><p>8. &#220;berpr&#252;fen:</p><p>Sie k&#246;nnen dies &#252;berpr&#252;fen, z. B. mit:</p><pre>$ ls -R /var/dvc-storagea3 f1/var/dvc-storage/a3:04afb96060aad90176268345e10355/var/dvc-storage/f1:5a7474cd26c014ce0cf7a8a3d50516.dir</pre><p>Beachten Sie, dass beide Versionen der Daten gespeichert sind und &#252;bereinstimmen sollten mit <em>dvc/cache</em>.</p><div class=„ce-image ce-left ce-above ce-gallery ce-row ce-column“><figure class=„image“><a href=„https://www.informatik-aktuell.de/fileadmin/templates/wr/pics/Artikel/03_Betrieb/KI/abb1_Versionskontrolle_schiele.png“ class=„jnlightbox“ data-title=„Abb. 1: Repositories erstellen. &#169; Cusy GmbH, 2020“ rel=„lightbox[lb32386]“ data-lightbox=„lightbox-32386“><img class=„image-embed-item“ title=„Abb. 1: Repositories erstellen. &#169; Cusy GmbH, 2020“ alt=„Abb. 1: Repositories erstellen. &#169; Cusy GmbH, 2020“ src=„https://www.informatik-aktuell.de/fileadmin/_processed_/b/3/csm_abb1_Versionskontrolle_schiele_44c482834d.png“ width=„720“ height=„350“ referrerpolicy=„no-referrer“ /></a><figcaption class=„image-caption“>Abb. 1: Repositories erstellen. &#169; Cusy GmbH, 2020</figcaption></figure></div><header><h3>2. Datenpipelines definieren</h3></header><p>Die Versionierung gro&#223;er Daten f&#252;r Data Science ist ein Schritt in die richtige Richtung, aber noch nicht ausreichend, wenn Daten gefiltert, transformiert oder zum Trainieren von ML-Modellen verwendet werden sollen. Daher erfasst DVC auch die Abfolge der Prozesse bei der Manipulation der Daten. Damit k&#246;nnen die Ergebnisse sp&#228;ter genau so reproduziert werden, wie sie entstanden sind. F&#252;r unser Beispiel soll die Pipeline aus den folgenden f&#252;nf Phasen bestehen:</p><ol><li>Vorbereiten</li><li>Aufteilen von Trainings- und Testdaten</li><li>Merkmalsextraktion</li><li>Trainieren</li><li>Evaluieren</li></ol><p>Das Ergebnis dieser Pipeline sind die Leistungsmetriken des trainierten Modells. Das gesamte Schema sieht so aus:</p><p>Rohdaten &#8594; <em>aufteilen</em> &#8594; Trainings-/Testdaten &#8594; <em>extrahieren</em> &#8594; Features &#8594; <em>trainieren</em> &#8594; Modell &#8594; <em>evaluieren</em> &#8594; Metriken</p><p><strong>2.1. Vorbereiten:</strong> Als Vorbereitung auf die Datenpipeline unseres Beispiels ben&#246;tigen wir zun&#228;chst eine virtuelle Python-Umgebung:</p><pre>$ python3 -m venv venv$ source venv/bin/activate$ pip install -r requirements.txt</pre><p>In unserem Beispiel enth&#228;lt die <em>requirements.txt</em>-Datei die vier Python-Pakete <em>pandas, sklearn, scikit-learn</em> und <em>scipy</em>. Beachten Sie jedoch bitte, dass DVC sprachunabh&#228;ngig und nicht an Python gebunden ist. Niemand kann Sie davon abhalten, die Phasen in Bash, C oder in einer anderen Lieblingssprache oder einem anderen Framework wie Spark, PyTorch usw. zu implementieren.</p><p><strong>2.2. Aufteilen von Trainings- und Testdaten:</strong> Mit <em>dvc run</em> k&#246;nnen Sie einzelne Verarbeitungsphasen erstellen, wobei jede Phase durch eine mit Git verwaltete Quellcode-Datei sowie die Abh&#228;ngigkeiten und Ausgabedaten beschrieben wird. Alle Phasen zusammen bilden dann die DVC-Pipeline. Unsere erste Phase soll die Daten in Trainings- und Testdaten aufteilen:</p><pre>$ dvc run -n split -d src/split.py -d data/data.xml -o data/splitted \python src/split.py data/data.xml</pre><ul><li><em>-n split</em> gibt den Namen mit der Beschreibung der Verarbeitungsphase an.</li><li><em>-d src/split.py</em> und -<em>d data/data.xml</em> geben die Abh&#228;ngigkeiten (<em>dependencies</em>) an. Wenn sich sp&#228;ter eine dieser Daten &#228;ndert, erkennt DVC, dass die Ergebnisse neu berechnet werden m&#252;ssen.</li><li><em>-o data/splitted</em> gibt das Verzeichnis an, in das die Ergebnisse geschrieben werden sollen. In unserem Fall sollte sich der Arbeitsbereich ge&#228;ndert haben in:</li></ul><pre> &#9500;&#9472;&#9472; data &#9474; &#9500;&#9472;&#9472; data.xml &#9474; &#9500;&#9472;&#9472; data.xml.dvc &#9474; &#9492;&#9472;&#9472; splitted+&#9474; &#9500;&#9472;&#9472; test.tsv+&#9474; &#9492;&#9472;&#9472; train.tsv+&#9474;+&#9500;&#9472;&#9472; dvc.lock+&#9500;&#9472;&#9472; dvc.yaml &#9500;&#9472;&#9472; requirements.txt &#9492;&#9472;&#9472; src &#9492;&#9472;&#9472; split.py</pre><ul><li><em>python src/split.py data/data.xml</em> ist der Befehl, der in dieser Verarbeitungsphase ausgef&#252;hrt wird. Die resultierende <em>dvc.yaml</em>-Datei sieht dann so aus:</li></ul><pre> stages: split: cmd: python src/split.py data/data.xml deps: - data/data.xml - src/split.py outs: - data/splitted</pre><p>In <em>dvc.lock</em> werden hingegen die MD5-Hashwerte gespeichert, anhand derer DVC erkennen kann, ob &#196;nderungen an den Dateien vorgenommen wurden:</p><pre> split: cmd: python src/split.py data/data.xml deps: - path: data/data.xml md5: a304afb96060aad90176268345e10355 - path: src/split.py md5: ffa32f4104c363040f27d2bd22db127d outs: - path: data/splitted md5: 1ce9051bf386e57c03fe779d476d93e7.dir</pre><p>Da die Daten im Ausgabeverzeichnis nie mit Git versioniert werden sollten, hat <em>dvc run</em> dies auch bereits in die <em>data/.gitignore</em>-Datei geschrieben:</p><pre> /data.xml+ /splitted</pre><p><strong>2.3. Merkmalsextraktion</strong></p><p>Die n&#228;chste Verarbeitungsphase k&#246;nnen Sie nun erstellen, indem die Ausgabe der vorhergehenden als Abh&#228;ngigkeit definiert wird, in unserem Beispiel mit:</p><pre>dvc run -n featurize -d src/featurization.py -d data/splitted \ -o data/features python src/featurization.py data/splitted data/features</pre><p>Sie k&#246;nnen diese Verarbeitungsphase jedoch auch parametrisieren. Hierf&#252;r erstellen wir in unserem Beispiel die Datei <em>params.yaml</em> mit folgendem Inhalt:</p><pre> max_features: 6000 ngram_range: lo: 1 hi: 2</pre><p>Der Aufruf f&#252;gt dann dem obigen Befehl noch <em>-p &lt;filename&gt;:&lt;params_list&gt;</em> hinzu:</p><pre>$ dvc run -n featurize -d src/featurization.py -d data/splitted \ -p params.yaml:max_features,ngram_range.lo,ngram_range.hi -o data/features \ python src/featurization.py data/splitted data/features</pre><p>Die <em>dvc.yaml</em>-Datei wird dann erg&#228;nzt um:</p><pre> + featurize: + cmd: python src/featurization.py data/splitted data/features + deps: + - data/splitted + - src/featurization.py + params: + - max_features + - ngram_range.lo + - ngram_range.hi + outs: + - data/features</pre><p>Schlie&#223;lich m&#252;ssen noch <em>dvc.lock</em>, <em>dvc.yaml</em> und <em>data/.gitignore</em> im Git-Repository aktualisiert werden:</p><pre>$ git add dvc.lock dvc.yaml data/.gitignore</pre><p>Mit <em>dvc params</em> erhalten Sie weitere Informationen zu den Parametrisierungsoptionen.</p><p><strong>2.4. Trainieren</strong></p><p>Die Trainingsphase wird erstellt mit:</p><pre>$ dvc run -n train -d src/train.py -d data/features -o model.pkl \ python src/train.py data/features model.pkl</pre><p><strong>2.5. Evaluieren</strong></p><pre>$ dvc run -n evaluate -d src/evaluate.py -d model.pkl -d data/features \ -M auc.json python src/evaluate.py model.pkl data/features auc.json</pre><p><em>evaluate.py</em> liest Features aus der <em>features/test.pkl</em>-Datei aus und berechnet den AUC-Wert des Modells. Diese Metrik wird dann in die <em>auc.json</em>-Datei geschrieben. Wir verwenden die <em>-M-Option</em>, um die Datei als Metrik in der <em>dvc.yaml</em>-Datei zu markieren:</p><pre> + evaluate: cmd: python src/evaluate.py model.pkl data/features auc.json + deps: + - data/features + - model.pkl + - src/evaluate.py + metrics: + - auc.json: + cache: false</pre><p>Die Ergebnisse k&#246;nnen Sie sich anzeigen lassen mit <em>dvc metrics</em>:</p><pre> $ dvc metrics show auc.json: 0.514172</pre><p>Um nun unsere erste Version der DVC-Pipeline abzuschlie&#223;en, f&#252;gen wir die Dateien und ein Tag dem Git-Repository hinzu:</p><pre> $ git add dvc.yaml dvc.lock auc.json $ git commit -m 'Add stage &#8249;evaluate&#8250;' $ git tag -a 0.1.0 -m „Initial pipeline version 0.1.0&#8220;</pre><header><h3>3. Reproduzieren</h3></header><p>Wie Sie sehen konnten, macht DVC das Erstellen einer Pipeline sehr einfach. Der wirkliche Vorteil ist jedoch, dass das Reproduzieren der Ergebnisse oder Teilen davon, d. h. das erneute Ausf&#252;hren von Stufen ggf. mit ge&#228;nderten Bedingungen, sehr einfach ist. Hierf&#252;r steht Ihnen <em>dvc repro</em> zur Verf&#252;gung:</p><pre> $ dvc repro Verifying data sources in stage: 'data/data.xml.dvc' Stage 'split' didn't change, skipping Stage 'featurize' didn't change, skipping Stage 'train' didn't change, skipping Stage 'evaluate' didn't change, skipping</pre><p>Sie k&#246;nnen nun z. B. Parameter in der <em>params.yaml</em>-Datei &#228;ndern und anschlie&#223;end die Pipeline erneut durchlaufen:</p><pre>$ dvc reproStage 'data/data.xml.dvc' didn't change, skippingStage 'split' didn't change, skipping Running stage 'featurize' with command: python src/featurization.py data/splitted data/features…Stage 'train' didn't change, skippingStage 'evaluate' didn't change, skippingTo track the changes with git, run: git add dvc.lock</pre><p>In unserem Fall hatte die &#196;nderung der Parameter also keinen Einfluss auf das Ergebnis. Beachten Sie jedoch, dass DVC &#196;nderungen an Abh&#228;ngigkeiten und Ausgaben &#252;ber MD5-Hashwerte erkennt, die in der <em>dvc.lock</em>-Datei gespeichert sind.</p><header><h3>4. Pipeline visualisieren</h3></header><p>Damit sich auch f&#252;r andere schnell die Struktur der Pipeline erschlie&#223;t, kann diese sehr einfach mit <em>dvc dag</em> visualisiert werden:</p><p><em>$ dvc dag</em>&#160;&#160;&#160; +———————+&#160;&#160;&#160; | data/data.xml.dvc |&#160;&#160;&#160; +———————+&#160;&#160;&#160;&#160;&#160; &#160; &#160; &#160;&#160;&#160;&#160;&#160;&#160; *&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160; +——-+&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160; |&#160; split &#160; |&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +——-+&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160; &#160;&#160;&#160;&#160; *&#160;&#160;&#160;&#160;&#160;&#160;&#160; +———–+&#160;&#160;&#160;&#160;&#160;&#160; &#160; | featurize |&#160;&#160;&#160;&#160;&#160;&#160;&#160; +———–+&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +——-+&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; *| train &#160; |&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +——-+&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; *&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; **&#160;&#160; &#160;&#160;&#160; +———-+&#160; &#160; &#160;&#160; | evaluate |&#160; &#160; &#160;&#160; +———-+</p><header><h3>5. Daten teilen</h3></header><p>Sie k&#246;nnen nun Ihren Code und Ihre Trainingsdaten einfach mit anderen Teammitlgiedern teilen. Sofern die Teammitglieder ebenfalls auf unser lokales DVC-Repository in <em>/var/dvc-storage</em> zugreifen k&#246;nnen, k&#246;nnen Sie die Ergebnisse unseres Beispiels reproduzieren mit:</p><pre> $ git clone https://github.com/veit/dvc-example.git $ cd dvc-example $ dvc pull -TR A data/data.xml 1 file added $ ls data/ data.xml data.xml.dvc</pre><header><h2>Fazit</h2></header><p>Mit DVC k&#246;nnen Sie sprachunabh&#228;ngig reproduzierbare ML-Pipelines definieren und zusammen mit den zugeh&#246;rigen Trainingsdaten, Konfigurationen, Leistungsmetriken usw. versioniert speichern. Dabei arbeitet DVC mit allen modernen Versionsverwaltungen zusammen und unterst&#252;tzt viele verschiedene Speicherarten wie S3, Google Cloud, Azure, SSH usw. Damit strukturiert DVC nicht nur die Datenhaltung, sondern durch einzelne, atomare Phasen der DVC-Pipeline bleiben &#196;nderungen in den Daten auch transparent und nachvollziehbar. Insgesamt erleichtert und effektiviert dies die Arbeit an ML-Projekten erheblich.</p><div id=„c32318“ class=„frame quellen frame-type-text frame-layout-0“><header><p>Quellen</p></header><ol><li><a href=„https://dvc.org/“ title=„DVC“ target=„_blank“ rel=„noreferrer“>DVC</a></li><li><a href=„https://git-annex.branchable.com/“ title=„git annex“ target=„_blank“ rel=„noreferrer“>git-annex</a></li><li><a href=„https://git-lfs.github.com/“ title=„LFS“ target=„_blank“ rel=„noreferrer“>Git Large File Storage (LFS)</a>&#160;</li><li><a href=„https://mlflow.org/“ title=„MLflow“ target=„_blank“ rel=„noreferrer“>MLflow</a></li><li><a href=„https://dagshub.com/“ title=„DAGsHub“ target=„_blank“ rel=„noreferrer“>DAGsHub</a></li></ol><p>Github: <a href=„https://github.com/iterative/dvc“ title=„DVC“ target=„_blank“ rel=„noreferrer“>DVC</a>Beispielprojekt: Github: <a href=„https://github.com/veit/dvc-example“ title=„dvc-example“ target=„_blank“ rel=„noreferrer“>dvc-example</a></p><p><a href=„https://www.informatik-aktuell.de/betrieb/kuenstliche-intelligenz/versionskontrolle-fuer-machine-learning-projekte.html#top“><img src=„https://www.informatik-aktuell.de/fileadmin/templates/wr/images/LinkToTop.png“ width=„50“ height=„50“ alt=““ referrerpolicy=„no-referrer“ /></a></p></div><header><p>Autor</p></header><div class=„tx-pwteaser-pi1 main odd“><a href=„https://www.informatik-aktuell.de/autoren-cv/veit-schiele.html“><img src=„https://www.informatik-aktuell.de/fileadmin/_processed_/4/0/csm_200-veit-schiele_f5dbffc384.jpg“ width=„150“ height=„150“ alt=„“ referrerpolicy=„no-referrer“ /></a><h3><a href=„https://www.informatik-aktuell.de/autoren-cv/veit-schiele.html“>Veit Schiele</a></h3>Veit Schiele ist erfahrener Trainer f&#252;r Analysten, Wissenschaftler und Ingenieure bei der Entwicklung von Analyse- und Forschungssoftware sowie Autor des Jupyter-Tutorial und des PyViz-Tutorial.<a href=„https://www.informatik-aktuell.de/autoren-cv/veit-schiele.html“>&gt;&gt;&#160;Weiterlesen</a></div><header><p>Das k&#246;nnte Sie auch interessieren</p></header><p>Kommentare (0)</p> </html>