[PYTHON] L'histoire de la création du Mel Icon Generator version 2

introduction

L'icône dessinée par Melville, appelée "Mel Icon", gagne en popularité auprès de nombreuses personnes en raison de son style unique. Ci-dessus se trouve l'icône de Melville . En particulier, il est connu que de nombreuses personnes demandent à cette personne de créer une icône et de l'utiliser comme icône Twitter. Exemple d'icône mel typique

(De gauche à droite, Yukatayu , Shun Shun , kaage (à partir du 5 août 2020))

Je veux aussi une icône mel comme celle-ci! !! !! !! !! !! C'est pourquoi j'ai implémenté un générateur d'icônes mel par machine learning! !! !! !! !! ....... est un aperçu des travaux antérieurs . Cette fois, nous avons fait un gros examen de l'algorithme pour améliorer de nombreux points et avons grandement évolué le générateur Mel Icon. Dans cet article, je présenterai la méthode utilisée pour cela.

Qu'est-ce que le GAN

Une méthode appelée GAN (Generative adversarial networks) est utilisée pour générer des images.

is20tech001zu004-1.jpg Citation du chiffre Original

Cette technique combine deux choses: un réseau neuronal (Generator) qui génère des images et un réseau neuronal (Discriminator) qui identifie si les données d'entrée sont ou non une icône mel. Generator essaie de générer une image qui ressemble autant que possible à une icône mel afin de tromper le discriminateur. Le discriminateur apprend à identifier les images avec plus de précision pour ne pas être dupe. Au fur et à mesure que les deux réseaux de neurones s'entraînent, le générateur sera capable de générer des images proches de l'icône Mel. En bref, c'est Generator VS Discriminator.

Progressive GAN Il existe différents types de méthodes, même si elles s'appellent GAN. Cette fois, j'utilise l'un d'entre eux, ** Progressive GAN **. Par exemple, d'abord, le nombre de fois où l'apprentissage est effectué, qui est une couche convolutive correspondant à une faible résolution de 4x4, puis la couche convolutive correspondant à 8x8 est ajoutée pour l'apprentissage, puis 16x16 est ajouté. C'est une manière de procéder à l'apprentissage tout en augmentant progressivement la résolution.

Au début de l'apprentissage, le générateur est prêt à produire des images de résolution 4x4 comme indiqué. Discriminator prend également une image de résolution 4x4 comme entrée et génère une valeur qui indique à quel point elle ressemble à une icône mel.

Le générateur génère une image et le discriminateur est entré avec deux types: l'image générée et l'image réelle (icône mel des données d'entraînement).

Après avoir appris à une résolution 4x4 dans une certaine mesure, nous ajouterons une couche de convolution correspondant à 8x8 et continuerons à apprendre.

Lorsque 8x8 est terminé, ajoutez 16x16 et ainsi de suite, et ainsi de suite, et enfin la structure sera comme ça. L'objectif était cette fois de produire une image 256x256.

Le GAN a la faiblesse que l'apprentissage a tendance à être instable lorsque l'on essaie d'apprendre des images avec une résolution relativement élevée. Cependant, le GAN progressif peut surmonter cela en examinant d'abord les caractéristiques générales de l'image, puis en se concentrant progressivement sur les parties petites et complexes.

Préparation du jeu de données

Pour que le générateur puisse générer des images semblables à des icônes de mel, et pour que le discriminateur puisse identifier si l'image d'entrée est une icône de mel, apportez autant d'icônes de mel réel que possible. Vous devez créer un ensemble de données qui sera les données de l'enseignant et l'utiliser pour la formation. Cette fois, M. Melville a fourni toutes les icônes Mel créées jusqu'à présent. Ce nombre est 751. (Accablant ..... Merci .... !!!!!!) De là, je rechercherai une icône de mel qui peut être utilisée pour l'apprentissage. Cette fois, j'ai exclu Mel Icon, qui est trop irrégulière, de l'apprentissage. En particulier

C'est comme ça. De plus, certaines icônes étaient presque les mêmes mais légèrement différentes en termes de longueur de cheveux. Compte tenu de leur impact sur l'apprentissage global, nous avons ajouté jusqu'à 4 icônes mel similaires à l'ensemble de données et les avons exclues s'il y en avait 5 ou plus.

Le nombre d'ensembles de données pouvant être utilisés de cette manière est d'environ 640. Considérant que la dernière fois était d'au plus 100 feuilles, la quantité qui peut être utilisée a augmenté de plus de 6 fois. Ceux-ci sont utilisés comme données d'entraînement.

Créer un générateur

Le rôle du générateur est de prendre une séquence de nombres aléatoires (que nous appellerons bruit) en entrée et de générer une image en forme d'icône de mel basée sur elle. Lorsque vous entrez l'icône de mel générée dans Discriminator, vous apprendrez à la tromper comme une véritable icône de mel. En tant qu'opération de base, le générateur génère une image en convoluant à plusieurs reprises le bruit d'entrée.

Dans l'état initial, les réseaux neuronaux qui composent le générateur sont comme indiqué dans la figure ci-dessous.

Il s'agit d'une image de saisie des données de la couche supérieure, de leur traitement, de leur transmission à la couche inférieure en séquence et de l'obtention des données de la couche inférieure.

La couche de convolution supérieure reçoit l'entrée de bruit vers le générateur (l'amplitude du bruit est de 512 canaux et une résolution de 4 x 4), traite la convolution et produit des données avec 256 canaux et une résolution de 4 x 4. Faire. Les données sont transmises à la couche de convolution suivante, et ainsi de suite, et la dernière couche produit une image avec 3 canaux et une résolution de 4x4. Le nombre de canaux de sortie 3 dans la dernière couche correspond à chacun des (R, V, B), et 4x4 est la résolution de l'image sortie par le générateur.

Tout en apprenant ces couches, nous allons "introduire" petit à petit les couches correspondant à la prochaine résolution "8x8". ("Introduction petit à petit" sera décrit plus tard.) Nous visons les états suivants en "introduisant petit à petit".

Ici, une couche appelée Upsample est prise en sandwich entre la couche 4x4 et la couche 8x8. Lorsque des données avec une résolution de 4x4 sont entrées, cette couche les convertit en une résolution de 8x8 et les génère en sortie. Ceci est réalisé en complétant bien les valeurs intermédiaires de chaque pixel. Cela vous permet de relier les données entre les couches 4x4 et 8x8.

"Introduit petit à petit"

On sait que si vous commencez soudainement à introduire une nouvelle couche, cela aura un effet négatif sur l'apprentissage. Par conséquent, Progressive GAN "introduira" des couches petit à petit.

Par exemple, lors de l'ajout d'une couche 8x8 après une couche 4x4, la sortie de la couche 4x4 multipliée par (1-α) et la sortie de la couche 8x8 Obtenez le produit de α. Ensuite, ajoutez ces deux pour créer une image de sortie. Définissez la valeur de α sur 0 au début et approchez-la de 1 lorsque le nombre d'apprentissage augmente.

Lorsque α vaut 0, le réseau neuronal du générateur est le même que ci-dessous.

Lorsque α vaut 1, le réseau neuronal du générateur est le même que ci-dessous.

En approchant progressivement l'état où α est 0 à l'état 1, il devient possible d'apprendre en mélangeant progressivement des couches haute résolution au lieu de commencer soudainement l'apprentissage haute résolution.

Nous allons l'utiliser pour la transition de 8x8 à 16x16, la transition de 16x16 à 32x32, etc. Enfin, nous étudierons dans le but de créer un réseau capable de générer les icônes mel à 3 canaux suivantes avec une résolution de 256 x 256 et (R, V, B).

Créer un discriminateur

Le rôle de Discriminator est de prendre des données d'image comme entrée et d'identifier s'il s'agit d'une véritable icône mel. Vous apprendrez à améliorer la précision afin de ne pas être dupé par le générateur.

Dans l'état initial, les réseaux neuronaux qui composent le discriminateur sont comme indiqué dans la figure ci-dessous. (La partie rouge de la figure, MiniBatchStd, sera décrite plus tard.)

La couche de convolution supérieure reçoit l'image (correspondant à 3 canaux (correspondant à (R, V, B), résolution 4x4), résolution 4x4) entrée vers Discriminator, et traite la convolution à 256 canaux, résolution 4 Sortez les données x4 et passez-les à la couche suivante. La couche suivante traite les données, les transmet à la couche suivante, et ainsi de suite, et la dernière couche génère des données avec 1 canal et 1 x 1 résolution. Ces données de sortie 1x1x1, en bref, une valeur, est une valeur qui montre à quel point l'image d'entrée ressemble à une icône mel.

Comme avec le Generator, tout en apprenant ces couches, nous allons "introduire" petit à petit les couches correspondant à la prochaine résolution "8x8", en visant les états suivants.

Dans Generator, afin de relier les données entre les couches correspondant à chaque résolution, un processus appelé Upsample a été appliqué pour augmenter la résolution, puis passer les données à la couche suivante. Discriminator insère un processus appelé Downsample, qui fonctionne exactement de la manière opposée. Cela permet, par exemple, de convertir des données de résolution 8x8 en 4x4 et de relier les données de la couche 8x8 à la couche 4x4. (Dans pytorch, une fonction appelée AdaptiveAvgPool2d est utile pour ce faire.)

Comme avec le générateur, augmentez progressivement la valeur de α de 0 à 1 de cette manière et mélangez doucement de nouvelles couches.

En fin de compte, nous prendrons l'icône mel à 3 canaux suivante avec une résolution de 256 x 256 et (R, V, B) comme entrée, et apprendrons à viser un réseau capable de juger s'il est authentique ou faux.

Réduire le mode VS

Le "Mini Batch Std", qui n'est contenu que dans la couche 4x4, empêche un phénomène appelé "mode collapse".

Qu'est-ce que la réduction de mode?

Je veux que Generator génère autant de types d'icônes de mel que possible. Cependant, même si le GAN entre différents nombres aléatoires, il peut se retrouver dans un état où il ne produit que des images pour lesquelles vous pouvez difficilement faire la différence. Un tel phénomène est appelé effondrement de mode.

C'est le résultat du travail précédent, mais je vais l'expliquer en utilisant ceci car c'est le meilleur exemple.

La ligne supérieure montre 5 types de données utilisées pour l'entraînement et la ligne inférieure montre 5 types d'images produites par GAN. Vous pouvez voir que les résultats de sortie sont presque les mêmes même si vous avez entré des nombres aléatoires différents 5 fois.

Ce phénomène est dû à la "dégustation" du générateur. Supposons qu'une image générée réussisse à tromper Discriminator. Si vous générez une autre image qui est presque la même que cette image, il est fort probable que vous puissiez à nouveau tromper Discriminator. En répétant cela, seule presque la même image peut être générée.

Écart type du mini lot

Progressive GAN a une fonction qui empêche le générateur de faire cela. C'est la couche appelée "Mini Batch Std". Cela trouve une statistique appelée l'écart type du mini-lot et empêche la réduction du mode.

Le discriminateur reçoit plusieurs images à la fois lors de l'identification des images et prend un écart type pour chaque pixel de l'image. Par exemple, si vous recevez 8 images, vous devrez identifier si les 8 images sont sorties du générateur ou d'une véritable icône mel, mais pour chaque pixel de l'image pour ces 8 images. Prend l'écart type à.

De plus, si l'écart type est pris pour chaque pixel, la moyenne est prise pour tous les canaux et pixels.

En conséquence, les mêmes données que celles de l'image d'origine avec 1 canal et la même résolution sortiront finalement du calque MiniBatch Std. Passez-le au calque 4x4 suivant en tant qu'ensemble avec l'image d'origine.

Cette valeur est une quantité qui indique la diversité des images d'entrée qui ont été entrées plusieurs fois. (C'est une image comme la dispersion.) Si cela semble trop petit, Discriminator peut déterminer que le générateur a commencé à tricher et peut détecter que l'image d'entrée est l'image générée. Si le générateur génère uniquement des images similaires, il sera détecté par Discriminator comme une image générée. Par conséquent, il est obligé de générer différents types d'images.

La couche Mini Batch Std, qui peut faire cela, est associée à la couche 4x4 près de la fin du Discriminator pour éliminer la possibilité d'effondrement du mode.

Méthode d'apprentissage / fonction d'erreur

Le générateur et le discriminateur utilisent ** WGAN-GP ** comme fonction de perte. La définition est la suivante.

-E[d_{fake}]
E[d_{fake}] - E[d_{real}] + \lambda E_{\substack{\hat{x}\in P_{\hat{x}}}}[(||\nabla_{\hat{x}}D(\hat{x})||_{2}-1)^{2}]

Je vais les expliquer dans l'ordre.

Entrez le bruit $ z $ dans Generator et obtenez autant d'images qu'il y a de mini-lots. (Ci-après, le nombre de mini-lots est $ M $. Cette fois, $ M = 8 $.) Entrez-le dans Discriminator et sortez $ M $ pour chaque image pour montrer à quel point elle ressemble à une icône mel. Laisse moi. Appelons cela $ d_ {fake} $. De plus, saisissez l'icône Mel réelle dans le Discriminateur pour $ M $, et laissez la sortie de $ M $ à ce moment-là être $ d_ {real} $.

WGAN-GP utilise ces $ d_ {real} $ et $ d_ {fake} $ pour calculer la perte.

Générateur d'apprentissage

Le générateur essaie de générer autant que possible une image semblable à une icône de mel afin de tromper le discriminateur lorsqu'une séquence de nombres composée de nombres aléatoires est entrée.

Fonction de perte

Dans WGAN-GP, la fonction de perte de Generator est définie comme suit.

-E[d_{fake}]

Le fait est que l'image générée par $ M $ à partir du générateur est jugée par le discriminateur, la moyenne de la sortie est prise et un moins est ajouté. Il semble que WGAN-GP soit connu pour fonctionner de manière empirique s'il est défini comme ceci. Adam a été utilisé comme méthode d'optimisation pour la propagation des erreurs, et le taux d'apprentissage a été fixé à 0,0005, et les moments primaire et secondaire d'Adam ont été fixés à 0,0 et 0,99, respectivement.

De plus, uniquement lors de l'apprentissage de la couche 256 x 256, si l'apprentissage est répété un certain nombre de fois, le taux d'apprentissage est réduit à 0,0001. (Désolé, je pense que la génération de l'icône mel fonctionne relativement bien ... (peut-être à cause de mon esprit.)

Discriminateur d'apprentissage

Après la propagation d'erreur de Generator, vient ensuite la propagation d'erreur de Discriminator.

Fonction de perte

Dans WGAN-GP, la fonction de perte du discriminateur est définie comme suit.

E[d_{fake}] - E[d_{real}] + \lambda E_{\substack{\hat{x}\in P_{\hat{x}}}}[(||\nabla_{\hat{x}}D(\hat{x})||_{2}-1)^{2}]

gradient penalty La définition de la pénalité de gradient est la suivante.

\lambda E_{\substack{\hat{x}\in P_{\hat{x}}}}[(||\nabla_{\hat{x}}D(\hat{x})||_{2}-1)^{2}]

Cependant, la distribution de l'image générée et la distribution de l'image réelle sont respectivement définies sur $ P_ {fake} $ et $ P_ {real} $.

\epsilon\in U[0,1],x_{fake}\in P_{fake},x_{real}\in P_{real}
\hat{x}=(1-\epsilon)x_{fake}+\epsilon x_{real}

J'ai décidé.

Laissez-moi vous expliquer l'image à ce sujet. (C'est juste une image. C'est aussi assez à propos.)

Il y a beaucoup d'images $ \ hat {x} $ qui sont un mélange d'images générées et d'images réelles à des ratios aléatoires. Considérez l'espace créé par la sortie lorsque celui-ci est placé dans le Discriminator. Dans le Discriminator optimisé, on sait que le gradient est de 1 à presque chaque point de cet espace. Peut-être est-il pratique d'être autour de 1 pour que le gradient ne disparaisse pas ou ne diverge pas pendant la propagation de l'erreur. Par conséquent, même avec le discriminateur Mel Icon Generator, nous procéderons à l'apprentissage pour que cette valeur devienne 1. Le terme pour cela est pénalité de gradient, c'est-à-dire

\lambda E_{\substack{\hat{x}\in P_{\hat{x}}}}[(||\nabla_{\hat{x}}D(\hat{x})||_{2}-1)^{2}]

est.

De plus, cette fois, la constante $ \ lambda $ est définie sur 10,0. (Puisque le matériel de référence a été décidé à 10,0, je l'ai suivi.)

Ce qui précède est la fonction de perte de Discriminator dans WGAN-GP. Ici, prenez le carré de $ d_ {real} $ et ajoutez $ E [{d_ {real}} ^ 2] $ qui est la moyenne d'entre eux. .. Cette section réduit l'impact négatif d'une inclinaison extrême sur l'apprentissage.

E[d_{fake}] - E[d_{real}] + \lambda E_{\substack{\hat{x}\in P_{\hat{x}}}}[(||\nabla_{\hat{x}}D(\hat{x})||_{2}-1)^{2}] + \beta E[{d_{real}}^2]

La constante $ \ beta $ est de 0,001. (Ceci est également dû au fait que le matériau de référence a été décidé à 0,001.)

Ce qui précède est la fonction de perte de Discriminator utilisée cette fois. Adam a été utilisé comme méthode d'optimisation pour la propagation des erreurs, et le taux d'apprentissage a été fixé à 0,0005, et le moment primaire et le moment secondaire d'Adam (taux d'atténuation exponentielle utilisé pour l'estimation du moment) ont été fixés à 0,0 et 0,99, respectivement. De plus, uniquement lors de l'apprentissage de la couche 256 x 256, si l'apprentissage est répété un certain nombre de fois, le taux d'apprentissage est réduit à 0,0001. (À l'exception de la fonction de perte, c'est exactement la même chose que Generator.)

Vue d'ensemble

L'image présentée ci-dessus est réimprimée, mais le générateur et le discriminateur créés précédemment sont combinés pour former un GAN progressif. Avec l'état suivant comme objectif final, nous apprendrons de la basse résolution pour chaque couche.

produire

Cette fois, nous avons décidé de passer à la résolution suivante tous les 8 mini-lots et 7500 apprentissages. Apprenez à utiliser l'icône de mel que vous avez reçue et laissez le générateur générer l'icône de mel.

** D'accord! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! ** **

J'ai réussi à générer une image différente à chaque fois. La résolution a également été améliorée. Progressive GAN Sérieusement génial! !! !! !! !! !! !! !!

Le résultat lors de l'apprentissage est le suivant.

Vous pouvez voir que l'apprentissage progresse pour chaque résolution.

À part: augmentation des données

Dans l'apprentissage automatique, une technique appelée «augmentation des données» est souvent utilisée comme l'une des méthodes pour augmenter les types d'images dans un ensemble de données. Pour chaque apprentissage, vous pouvez gonfler l'ensemble de données en convertissant de manière aléatoire le contraste et la teinte de l'image, en basculant vers la gauche et vers la droite, en modifiant l'angle et en déformant l'image entière.

Cependant, cela pose des problèmes avec le générateur d'icônes Mel. Tout d'abord, la particularité de Mel Icon est que la tête est dessinée de manière à pousser à partir du bas à gauche.

(Icône: Minagi (à partir du 5 août 2020))

Pour cette raison, il y a une forte possibilité que la distorsion de l'image, la rotation, l'inversion gauche-droite, etc. soient apprises involontairement, il est donc préférable de l'arrêter. De plus, je n'utilise pas la conversion de teinte car une icône de couleur étrange apparaît. Cependant, comme il y avait peu d'effets négatifs sur la conversion de contraste, j'ai également appris à utiliser l'augmentation des données.

La gauche est l'image d'origine et la droite est l'image convertie avec le contraste doublé. De cette façon, j'ai pensé qu'il serait possible d'augmenter massivement le nombre d'ensembles de données par rapport à la fois précédente, et j'ai doublé avidement le nombre d'apprentissages avant d'exécuter et de sortir l'apprentissage. Le résultat est ci-dessous.

Je ne pense pas que ce soit beaucoup mieux que lorsque je ne l'ai pas utilisé, mais cette méthode semble également être bonne.

Résumé

Le générateur d'icônes Mel surmonte non seulement l'effondrement du mode avec le GAN progressif, mais réussit également à augmenter la résolution. Le GAN progressif semble être une technique qui peut même générer des images haute résolution en Full HD, selon la méthode et l'ensemble de données. (Je pense que 256x256 est suffisant si vous l'utilisez comme icône Twitter.) Même dans le monde réel, les exemples d'application dans le domaine médical semblent actifs et il semble que cette méthode continuera à attirer davantage l'attention à l'avenir.

Générons une image palpitante avec Progressive GAN.

Code source

Le code que j'ai écrit se trouve dans ce référentiel. https://github.com/zassou65535/image_generator_2

prime

Lorsque la moyenne (torche.moyenne) a été prise pour chaque pixel des 640 images environ utilisées dans l'ensemble de données cette fois, les images suivantes sont apparues.

Je l'ai essayé avec diverses statistiques de la même manière. Voici l'écart type (torch.std), la valeur médiane (torch.median) et la valeur la plus fréquente (torch.mode) dans l'ordre à partir de la gauche.

J'ai également essayé la valeur minimale (torch.min) et la valeur maximale (torch.max), mais seules des images en noir et blanc sont apparues, respectivement.

À propos, lorsque j'ai calculé l'écart type (torch.std) pour 5 images extraites au hasard, j'ai obtenu ceci. Cela pourrait être un peu à la mode.

De plus, si la valeur minimale (torch.min) est calculée pour tous les ensembles de données de près de 640 feuilles, seules les images proches du noir seront sorties, mais si le nombre est supprimé à environ 7, cela ressemblera à ceci. L'icône apparaîtra. Voici la valeur minimale pour 7 images sélectionnées au hasard.

Précédent travail

L'histoire de la création d'un générateur d'icônes mel

référence

GAN pratique ~ Apprentissage en profondeur avec un réseau de génération hostile Apprendre tout en faisant-Développement avec PyTorch Deep learning > Implémenter PGGAN avec Pytorch PGGAN "Apprentissage du curriculum rempli de gentillesse" [Lecture ronde DL] Formation améliorée des GAN de Wasserstein GAN (4) WGAN

Recommended Posts

L'histoire de la création du Mel Icon Generator version 2
L'histoire de la création d'un générateur d'icônes mel
L'histoire de la fabrication d'un moule immuable
L'histoire de sys.path.append ()
L'histoire de la création d'un réseau neuronal de génération musicale
Aligner la version de chromedriver_binary
L'histoire de la construction de Zabbix 4.4
L'histoire de la création d'un bot de boîte à questions avec discord.py
L'histoire de la rétrogradation de la version de tensorflow dans la démo de Mask R-CNN.
Tester la version du module argparse
L'histoire de Python et l'histoire de NaN
Élever la version de pyenv elle-même
L'histoire de la participation à AtCoder
pyenv-changer la version python de virtualenv
L'histoire du "trou" dans le fichier
L'histoire du remontage du serveur d'application
L'histoire de l'exportation d'un programme
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
L'histoire de la création d'un pilote standard pour db avec python.
[Pythonista] L'histoire de la réalisation d'une action pour copier le texte sélectionné
L'histoire de la création d'un module qui ignore le courrier avec python
L'histoire d'essayer de reconnecter le client
L'histoire de la création d'un robot LINE pour le petit-déjeuner d'une université de 100 yens avec Python
Comment vérifier la version de Django
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
À propos de l'environnement virtuel de Python version 3.7
[Python] Essayez pydash de la version Python de lodash
L'histoire de l'étudiant qui a développé le nouveau site de contre-mesures contre le virus corona (version Ishikawa)
L'histoire de la manipulation des variables globales Python
Version Migemo de la commande: find ,: mfind
L'histoire d'essayer deep3d et de perdre
L'histoire de la création d'une caméra sonore avec Touch Designer et ReSpeaker
Décodage du modèle LSTM de Keras.
L'histoire de l'exécution de l'application asp.net core 3.1 sur la version arm64 Amazon Linux 2
L'histoire de la création d'un package qui accélère le fonctionnement de Juman (Juman ++) & KNP
L'histoire du traitement A du blackjack (python)
L'histoire du changement de pep8 en pycodestyle
L'histoire de la fabrication d'une boîte qui interconnecte la mémoire AL de Pepper et MQTT
L'histoire de la création d'une application Web qui enregistre des lectures approfondies avec Django
L'histoire de la création d'un Line Bot qui nous raconte le calendrier de la programmation du concours
L'histoire de la fabrication de soracom_exporter (j'ai essayé de surveiller SORACOM Air avec Prometheus)
L'histoire de l'apprentissage profond avec TPU
Essai du parseur d'emacs-org orgparse pour python
Utilisez la dernière version de PyCharm sur Ubuntu
Écrire une note sur la version python de python virtualenv
Traitement d'image? L'histoire du démarrage de Python pour
Essayez Progate Free Edition [Python I]
L'histoire de la recherche du n optimal dans N poing
L'histoire de la mauvaise lecture de la ligne d'échange de la commande supérieure
L'histoire de la lecture des données HSPICE en Python
L'histoire d'essayer Sourcetrail × macOS × VS Code
L'histoire de l'affichage des fichiers multimédias dans Django
[Petite histoire] Téléchargez l'image de Ghibli immédiatement
Histoire de passer de Pipenv à la poésie
L'histoire du lancement d'un serveur Minecraft depuis Discord
Une histoire qui réduit l'effort de fonctionnement / maintenance