Vous apprendre à utiliser TensorFlow et Keras pour créer l'APP "Hot Dog Recognition" dans la série télévisée américaine "Silicon Valley"

Source : Poulet mécanique

Auteur : Yaoyao

La longueur de cet article est 10000 mots , lecture recommandée 20 min+

Cet article vous apprend à développer votre propre application~

L'émission à succès de HBO "Silicon Valley" a récemment lancé une application d'intelligence artificielle qui peut faire la distinction entre "hot dog" et "pas un hot dog" (comme Jian Yang dans la quatrième saison de l'émission, épisode 4), l'application Il est actuellement disponible sur Android et iOS, mais uniquement pour les utilisateurs aux États-Unis et au Canada.

Lorsque vous prenez une photo de la nourriture (ou que vous pouvez utiliser la photo sur votre téléphone), il vous dira que l'objet est "Hotdog or Not Hotdog", c'est tout ce qu'il fait, toute l'application est très simple.

Pour identifier avec précision les hot-dogs, les auteurs ont développé une architecture de réseau neuronal qui s'exécute directement sur les téléphones mobiles et l'a formée avec les GPU TensorFlow, Keras et Nvidia.

Bien que la fonctionnalité soit ridicule, l'application est un exemple concret d'exploitation de l'apprentissage en profondeur et de l'informatique de pointe. Tous les programmes d'intelligence artificielle s'exécutent à 100 % sur l'appareil de l'utilisateur et les photos prises peuvent être traitées sans quitter le téléphone.

Cela permet aux utilisateurs de profiter d'une meilleure expérience (pas besoin d'aller vers et depuis le cloud), de capacités d'utilisation hors ligne et d'une meilleure protection de la vie privée. Cela nous permet également d'exécuter des applications sans frais généraux avec des millions d'utilisateurs, ce qui nous permet d'économiser beaucoup d'argent par rapport à l'IA traditionnelle basée sur le cloud.

L'équipement utilisé par l'auteur pour développer l'application (l'eGPU sur la photo sert à entraîner l'IA qui n'est "pas un hot-dog")

L'application a été développée par un développeur utilisant un ordinateur portable et un GPU pour modifier manuellement les données. Cet exemple nous dit qu'avec la technologie actuelle, nous n'avons pas besoin du soutien des entreprises technologiques, Les développeurs individuels et les amateurs peuvent également développer des applications intéressantes avec des ressources limitées. Sans plus tarder, apprenons à développer votre propre application.

Table des matières

1. Application

2. Du prototype au produit

1. Prototype

2. TensorFlow, structure initiale et apprentissage par transfert

3. Keras et SqueezeNet

3. Architecture DeepDog

1. Formation

2. Exécution du réseau de neurones sur votre téléphone

3. Utilisation des réseaux de neurones pour modifier le comportement de l'application

4. Expérience utilisateur, expérience développeur et l'Uncanny Valley of AI

1. Application

L'application vous permet d'abord de prendre une photo, puis vous indique si vous prenez un hot-dog. Cette fonctionnalité est simple et un clin d'il aux applications d'IA récentes comme ImageNet. Alors que nous investissons plus de ressources d'ingénierie dans les hot-dogs que quiconque, l'application a ses moments idiots.

Il parait que tant qu'il y a du ketchup, c'est un hot-dog

Au contraire, parfois, il peut aussi montrer son côté spirituel dans des situations compliquées. Comme l'a rapporté Engadget : "Incroyable ! Mon expérience avec cette application en 20 minutes est meilleure que mon expérience avec Shazam (une application qui peut deviner les titres des chansons) en deux ans."

Il ne semble pas pouvoir tromper 'ce n'est pas un hot-dog'.

2. Du prototype au produit

Je ne sais pas si vous avez déjà vécu cette expérience : lorsque vous lisez Hacker News (un site d'actualités sociales sur les pirates informatiques et les startups), vous pensez : "Ils ont fait ça pour 10 millions de dollars en financement de série A ? J'en suis un. Pouvez-vous le faire ce week-end ? »

Eh bien, cette application vous donnera le même sentiment, et elle a vraiment été prototypée en un seul week-end à l'aide de l'API Vision de Google Cloud Platform et de React Native.

Mais la version finale de l'App Market est ce que nous avons passé quelques mois (à temps partiel) à peaufiner. Nous avons fait quelques optimisations que les profanes ne peuvent pas comprendre. Nous avons passé des semaines à maximiser la précision des applications, le temps de formation de l'IA, le temps de test et à itérer notre configuration et nos outils, ce qui a rendu notre développement itératif plus efficace.

De plus, nous avons passé tout un week-end à optimiser l'expérience utilisateur sur iOS et Android

).

Habituellement, la plupart des articles de blog techniques et des articles académiques ignorent cette partie et montrent directement leur solution finale. Mais afin de vous donner une leçon du passé, nous avons ici abrégé les solutions irréalisables que nous avons essayées. Après cela, nous présenterons la solution finale réussie.

1. Prototype

Exemple d'image et sortie d'API correspondante de la documentation Google Cloud Vision

Nous avons choisi d'utiliser React Native pour le prototypage car, d'une part, c'était un bon terrain d'essai, et d'autre part, cela nous a permis de supporter très rapidement de nombreux appareils. Les faits ont prouvé que notre choix était correct.

Nous avons gardé React Native pour le reste du projet : même si cela ne simplifiait pas toujours notre charge de travail, et que nous avons délibérément limité le design de l'application, React Native a finalement fait le travail.

L'API Vision dans Google Cloud, que nous utilisions lors du prototypage, a été rapidement abandonnée par nous. Il y a trois raisons :

  • Sa précision dans l'identification des hot-dogs est médiocre. Bien qu'il soit bon pour reconnaître beaucoup d'objets, vous avez du mal à le faire reconnaître une seule chose. Il y a eu beaucoup d'échecs lorsque nous l'avons essayé en 2016.

  • Comme il s'agit d'un service cloud, il sera beaucoup plus lent que sur un appareil (Internet ! Trop ! Lent !) Et il ne prend pas en charge la fonctionnalité hors ligne. Et une fois que la photo quitte l'appareil, elle déclenche des considérations juridiques et de confidentialité.

  • Enfin, une fois qu'une application est en ligne, l'utilisation de Google Cloud Services peut s'avérer coûteuse.

Avec ces facteurs à l'esprit, nous avons entrepris d'expérimenter ce qui est désormais populaire "l'informatique de pointe", ce qui signifie dans ce cas former le réseau de neurones sur nos propres ordinateurs portables avant de le transférer et de l'intégrer directement dans nos appareils mobiles. De cette façon, le réseau de neurones peut effectuer des inférences et s'exécuter directement sur le téléphone de l'utilisateur.

2. TensorFlow, structure initiale et apprentissage par transfert

Après une conversation fortuite avec Pete Warden de l'équipe TensorFlow, nous avons réalisé la capacité de TensorFlow à fonctionner directement sur un appareil iOS, nous avons donc commencé à explorer dans cette direction. Après React Native, TensorFlow est devenu notre deuxième outil de développement finalisé.

Il ne nous a fallu qu'une journée pour intégrer l'exemple de caméra Objective C++ de TensorFlow dans notre bibliothèque React Native, et il a fallu un peu plus de temps pour utiliser leur script d'apprentissage par transfert.

Le script d'apprentissage par transfert peut vous aider à recycler la structure Inception pour gérer des problèmes d'image plus spécifiques. Inception est le nom d'un ensemble de structures neuronales que Google utilise pour résoudre les problèmes de reconnaissance d'images. Certaines Inceptions sont formées et pondérées. Dans la grande majorité des cas, les réseaux de reconnaissance d'images sont entraînés sur ImageNet.

ImageNet organise un concours annuel pour exploiter la structure du réseau neuronal qui peut le mieux reconnaître plus de 20000 articles différents, y compris les hot-dogs. Mais tout comme l'API Vision dans Google Cloud, bien que cette concurrence soit filtrée horizontalement et verticalement, face à la reconnaissance de 20000 articles, l'algorithme fait encore défaut. Dans ce cas, l'apprentissage par transfert consiste à prendre un réseau de neurones entièrement formé et à le recycler en un outil capable de mieux effectuer une seule tâche spécifique.

Cela implique un certain degré "d'oubli", soit en coupant directement toute la couche de la pile, soit en effaçant lentement la capacité du réseau de neurones à distinguer d'autres objets (tels que des chaises) et en se concentrant plutôt sur l'identification de ce dont vous avez besoin (dans ce cas, un Hot-dog).

Le réseau de neurones (Inception) mentionné ci-dessus a été formé avec 14 millions d'images dans ImageNet. Nous n'avons utilisé que quelques milliers d'images de hot-dogs, ce qui a grandement amélioré sa capacité à reconnaître les hot-dogs.

Le plus grand avantage de l'apprentissage par transfert est que vous pouvez obtenir de meilleurs résultats plus rapidement que de partir de zéro sans utiliser beaucoup de données. Un ensemble de formation complet nécessite non seulement plusieurs GPU et des millions d'images, mais prend également des mois. L'apprentissage par transfert peut généralement se faire en quelques heures avec un ordinateur portable et deux ou trois mille images.

L'un des grands défis que nous avons est de déterminer lesquels sont des hot-dogs et lesquels ne le sont pas.

Définir "qu'est-ce qu'un hot-dog" est étonnamment difficile (est-ce que la saucisse en tranches compte ? Si oui, quel type de saucisses compte ?), et cela implique également différentes compréhensions culturelles et géographiques des hot-dogs.

De même, l'environnement ouvert d'une application signifie que nous devons gérer une quantité presque infinie d'entrées d'utilisateurs. Bien que certains problèmes d'identification informatique soient relativement limités (comme la vérification des boulons pour les défauts de qualité avec les rayons X), nous aurons affaire à des selfies, des photos de paysage et de nombreuses photos de nourriture.

On peut dire que cette méthode de développement est bonne et qu'elle apporte des résultats d'optimisation. Cependant, nous avons déconseillé cette approche pour deux raisons :

Premièrement, nos données d'entraînement doivent être gravement déséquilibrées, car il y a beaucoup plus d'exemples "pas un hot-dog" que "est un hot-dog".

Cela signifie que si vous entraînez votre algorithme avec 3 images de hot-dogs et 97 images de non-hot-dogs, même s'il reconnaît 0% de hot-dogs et 100% de non-hot-dogs, il sera précis par défaut Toujours jusqu'à 97 % ! Ce n'est pas simple à résoudre même avec TensorFlow pour l'apprentissage par transfert. En d'autres termes, cela nous indique essentiellement que nous devons utiliser le modèle d'apprentissage en profondeur pour contrôler la formation et importer des poids à partir de zéro.

À ce moment-là, nous avons décidé de mordre la balle et de recommencer avec Keras (une bibliothèque logicielle d'apprentissage en profondeur qui fournit des abstractions plus belles et plus pratiques basées sur TensorFlow).

Keras est livré avec des outils d'entraînement très puissants, ainsi qu'une option de catégorie de poids, qui correspond parfaitement à la situation où nos données d'entraînement sont sérieusement déséquilibrées. Nous en avons profité pour essayer d'autres architectures neuronales populaires telles que VGG, mais un problème restait non résolu : aucune de ces architectures ne fonctionnait bien avec l'iPhone.

Ils occupent trop de mémoire et font planter d'autres applications. Un autre point est qu'ils prennent parfois plus de 10 secondes pour calculer et traiter, ce qui est très mauvais du point de vue de l'expérience utilisateur. Nous avons essayé de nombreuses façons d'essayer d'atténuer ce problème, mais au final, ces structures neuronales sont trop grandes pour le téléphone.

3. Keras et SqueezeNet

Figure : SqueezeNet SqueezeNet et AlexNet (le créateur de l'architecture de vision par ordinateur)

Pour vous donner une idée du temps, c'est probablement vers le milieu de notre projet. À ce stade, l'interface utilisateur est terminée à 90 % et, fondamentalement, aucune modification ne sera apportée. Mais avec le recul, le réseau de neurones à l'époque n'en faisait au mieux que 20 %.

Nous avons une certaine compréhension de la difficulté et un bon ensemble de données, mais le code d'architecture neuronale final n'est même pas une seule ligne de code. À l'époque, notre code neuronal n'était pas suffisamment stable pour fonctionner sur les téléphones, et notre précision ne s'améliorerait même pas de manière significative au cours des prochaines semaines.

Le problème le plus immédiat auquel nous sommes confrontés est simple, si Inception et VGG sont trop gros, existe-t-il un réseau de neurones plus simple et formé que nous pouvons utiliser pour l'apprentissage par transfert ?

Nous avons exploré Xception, Enet et SqueezeNet. Nous avons rapidement décidé d'utiliser SqueezeNet.

SqueezeNet dispose d'une fonction de localisation explicite, qui peut être utilisée comme solution d'apprentissage en profondeur intégrée. En outre, il existe des modèles Keras formés disponibles sur GitHub (yay ! Site open source !)

Alors, quelle différence cela peut-il faire? Une structure comme VGG doit utiliser près de 138 millions de paramètres (les nombres nécessaires pour simuler les valeurs entre neurones et neurones). Inception a été grandement amélioré, avec seulement 23 millions de paramètres. SqueezeNet n'a besoin que de 1,25 million de paramètres en comparaison.

Cela apporte deux avantages :

  • Pendant la formation, il est beaucoup plus rapide d'utiliser un petit réseau. Ne pas avoir autant de paramètres en mémoire à mapper signifie que vous pouvez vous entraîner simultanément (augmentant la taille du lot) et le réseau de neurones convergera (estimer les calculs) plus rapidement.

  • Au cours du développement, ce modèle était plus petit et plus rapide. SqueezeNet n'a besoin que de moins de 10 Mo de RAM, tandis que quelque chose comme Inception aura besoin de plus de 100 Mo de RAM. Cet écart est énorme, et il est particulièrement important car certains appareils mobiles ne disposent pas de 100 Mo de RAM. Les petits réseaux de neurones fonctionnent également plus rapidement que les plus grands.

Bien sûr, puisqu'il y a des gains et des pertes :

  • La « mémoire » d'un petit système nerveux ne fonctionnera pas : il ne peut pas gérer des tâches complexes (comme reconnaître 20 000 objets différents), ni même des dépendances complexes (comme faire la distinction entre un hot-dog à la new-yorkaise et un hot-dog à la Chicago- style hot-dog).

  • En corollaire, les petits réseaux de neurones seront généralement moins précis que les grands réseaux de neurones. En essayant d'identifier les 20000 objets différents d'ImageNet, SqueezeNet n'était précis qu'à 58 %, contre 72 % pour VGG.

  • Il est également un peu plus difficile d'utiliser l'apprentissage par transfert sur de petits réseaux de neurones. En théorie, nous pouvons traiter SqueezeNet de la même manière que nous traitons Inception et VGG : laissez-le d'abord oublier certaines informations, puis recyclez-le pour qu'il reconnaisse les hot-dogs et les non-hot-dogs.

    Mais dans le processus de candidature proprement dit, nous avons constaté que cette méthode rend difficile pour nous d'ajuster les progrès d'apprentissage, et les résultats obtenus ne sont toujours pas aussi bons que la formation SqueezeNet à partir de zéro. Ce problème peut également provenir de l'ouverture de notre projet (les utilisateurs prennent des photos et téléchargent eux-mêmes des photos).

  • En général, les petits réseaux de neurones sur-adaptent rarement, mais nous avons rencontré ce problème lors de l'utilisation de plusieurs "petites" structures. Le surajustement signifie que votre réseau de neurones est trop spécifique et ne peut reconnaître que les photos de hot-dogs sur lesquelles vous l'avez formé et ne peut pas le généraliser.

  • Utiliser l'exemple humain comme analogie, c'est comme une personne qui vient de mémoriser l'image du hot-dog que vous lui avez montrée sans abstraire le concept pour se rendre compte qu'un hot-dog est une saucisse dans un petit pain, parfois du matériel assaisonné et ainsi de suite. Si vous lui montrez une toute nouvelle photo d'un hot-dog (différente de l'originale), il dira que ce n'est pas un hot-dog.

  • Puisqu'un petit réseau de neurones a généralement une "mémoire" moins bonne, il n'est pas difficile de voir pourquoi il serait plus difficile pour eux de se spécialiser dans un élément. Mais il y a eu des moments où notre petit réseau de neurones a atteint une précision de 99 %, puis n'a soudainement pas pu reconnaître les images qui n'étaient pas là lors de la formation précédente.

  • Ce problème disparaît une fois que nous avons ajouté suffisamment de jeux de données. L'ensemble de données ici signifie que nous apportons des modifications aléatoires appropriées (étirement ou déformation) aux images importées, donc au lieu de s'entraîner cent fois pour chacune des milliers d'images, nous utilisons la fonction Apporter des modifications significatives au graphique afin que le réseau de neurones ne fonctionne pas. t se contente de mémoriser l'image, mais mémorise la composition du hot-dog (pain, saucisse, assaisonnement, etc.), tout en restant flexible (au lieu de mémoriser des pixels spéciaux dans une certaine image).

Exemple de données du blog Keras

Pendant ce temps, nous avons commencé à essayer d'affiner la structure du réseau neuronal. En particulier, nous avons commencé à utiliser la nomenclature par lots et expérimenté différentes fonctions d'activation.

  • La normalisation par lots peut aider votre réseau de neurones à apprendre plus rapidement en "lissant" les valeurs de la pile. La raison exacte pour laquelle la normalisation par lots a cette fonctionnalité n'est pas entièrement comprise, mais elle permet à votre réseau de neurones d'atteindre une plus grande précision avec moins de formation, ou d'obtenir une plus grande précision en même temps avec la même quantité de formation.

  • Une fonction d'activation est une fonction interne qui détecte si votre "neurone" est activé. ReLU (Rectified Linear Unit) est encore utilisé dans de nombreux articles académiques, mais nous avons obtenu les meilleurs résultats avec ELU.

Après avoir ajouté la normalisation par lots et l'ELU à SqueezeNet, nous avons formé un réseau de neurones avec une précision de plus de 90 % à partir de zéro. Cependant, notre réseau de neurones est encore relativement fragile, ce qui signifie que le même réseau sera parfois surajusté et sous-ajusté lorsqu'il sera testé dans la pratique. Même ajouter plus d'exemples à l'ensemble de données et augmenter les données de formation n'a pas répondu à nos attentes.

Ainsi, bien que cette étape ait bien fonctionné et créé une application entièrement compatible avec l'iPhone, nous sommes passés à notre quatrième et dernière structure en un instant.

3. Structure DeepDog

depuis keras.applications.imagenet_utils importer _obtain_input_shape

de keras importer le backend en tant que K

de keras.layers importer Input, Convolution2D, SeparableConvolution2D, \

GlobalAveragePooling2d \

Dense, Activation, Normalisation par lots

à partir de keras.models importer le modèle

depuis keras.engine.topology importer get_source_inputs

depuis keras.utils importer get_file

depuis keras.utils importer layer_utils

def DeepDog(input_tensor=Aucun, input_shape=Aucun, alpha=1, classes=1000):

input_shape = _obtain_input_shape(input_shape,

default_size=224,

taille_min=48,

data_format=K.image_data_format(),

include_top=Vrai)

si input_tensor vaut None :

img_input = Entrée(forme=input_shape)

autre:

sinon K.is_keras_tensor(input_tensor):

img_input = Input(tenseur=input_tensor, shape=input_shape)

autre:

img_input = input_tenseur

x = Convolution2D(int(32*alpha), (3, 3), foulées=(2, 2), padding='same')(img_input)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(32*alpha), (3, 3), strides=(1, 1), padding='same')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(64 * alpha), (3, 3), foulées=(2, 2), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(128 * alpha), (3, 3), foulées=(1, 1), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(128 * alpha), (3, 3), foulées=(2, 2), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(256 * alpha), (3, 3), foulées=(1, 1), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(256 * alpha), (3, 3), foulées=(2, 2), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

pour _ dans la plage (5):

x = SeparableConvolution2D(int(512 * alpha), (3, 3), strides=(1, 1), padding='same')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(512 * alpha), (3, 3), foulées=(2, 2), padding='même')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = SeparableConvolution2D(int(1024 * alpha), (3, 3), strides=(1, 1), padding='same')(x)

x = Normalisation par lots()(x)

x = Activation('elu')(x)

x = GlobalAveragePooling2D()(x)

out = Dense(1, activation='sigmoïde')(x)

si input_tensor n'est pas None :

entrées = get_source_inputs(input_tensor)

autre:

entrées = img_input

model = Model(inputs, out, name='deepdog')

modèle de retour

1. Conception

Notre structure finale a été largement inspirée par l'article de Google du 17 avril dans MobileNets. L'article affirme que Google introduira une nouvelle architecture neuronale qui peut atteindre une précision comparable à Inception sur un projet simple comme le nôtre avec seulement environ 4 millions de paramètres.

Cela signifie qu'il s'agit du compromis parfait entre SqueezeNet (une structure trop simplifiée pour nos besoins) et Inception/VGG. L'article mentionnait également la possibilité d'ajuster la taille et la difficulté du réseau neuronal, qui était capable de faire un compromis entre mémoire et précision, ce qui a résolu notre maladie cardiaque à l'époque.

Moins d'un mois avant la mise en ligne de l'application, nous étions impatients de reconstituer les résultats dans l'article. Cependant, le plus dramatique est que le jour de la publication de l'article, un étudiant de l'Université de technologie d'Istanbul, Refik Can Malli, a pris l'initiative de fournir publiquement le code Keras sur GitHub.

Notre structure finale est sensiblement différente de celle des MobileNets, ou plutôt des structures traditionnelles, notamment :

  • Nous n'avons pas utilisé la normalisation par lots dans notre traitement, car l'article Xception (qui traite en particulier des convolutions sur les réseaux profonds) semble souligner que la normalisation par lots rend en fait notre structure moins précise. Ne pas utiliser la normalisation par lots réduit également la taille de notre réseau de neurones.

  • Nous avons remplacé ReLU par ELU. Comme nos précédentes expériences SqueezeNet, ELU offre une vitesse et une précision de fusion supérieures à ReLU. Nous n'utilisons pas PELU. Parce que bien qu'agréable à utiliser, cette fonction d'activation semble rester bloquée dans un état binaire à chaque fois que nous l'utilisons. Ainsi, la précision de notre réseau oscille entre 0 % et 100 % au fur et à mesure que nous passons d'un lot à l'autre, plutôt que d'augmenter progressivement. Nous ne connaissons pas la raison de ce problème, il peut s'agir d'une erreur d'implémentation ou d'une erreur de l'utilisateur. Nous avons essayé de fusionner l'axe largeur/hauteur dans l'image, mais cela n'a pas fonctionné.

  • Nous n'avons pas utilisé SELU. Après avoir fait quelques recherches sur les versions iOS et Android, les résultats sont très similaires à ceux de PELU. Nous soupçonnons que SELU ne peut pas être utilisé seul comme raccourci vers une fonction d'activation. En fait, comme le titre de l'article le montre, SELU fait partie de la structure étroite du SNN.

  • Nous continuons à utiliser la normalisation par lots lors de l'utilisation d'ELU. Bien qu'il existe de nombreuses indications que cette étape n'est pas nécessaire, chaque fois que nous exécutons une expérience, nous ne pouvons pas converger sans normalisation par lots. C'est peut-être parce que notre structure est trop petite.

  • Nous utilisons la normalisation par lots avant l'activation. Bien que cela ait été un sujet brûlant récemment, aucune de nos expériences de normalisation par lots après activation sur de petits réseaux de neurones n'a bien convergé.

  • Pour optimiser le réseau de neurones, nous avons utilisé les taux d'apprentissage cycliques (CLR) et le modèle Keras de (partenaire) Brad Kenstler). Le CLR peut solidement trouver le taux d'apprentissage optimal pendant la formation. Plus important encore, en ajustant la progression de l'apprentissage de haut en bas, cela nous aide à atteindre une précision finale supérieure à celle des optimiseurs traditionnels. Pour les deux raisons ci-dessus, nous avons décidé d'utiliser le CLR pour former le réseau de neurones à l'avenir.

  • Nous estimons qu'il n'est pas nécessaire d'ajuster la valeur de ou dans la structure MobileNets. Parce que notre modèle est suffisamment petit pour atteindre l'objectif lorsque = 1. = 1 notre opération est aussi assez rapide. Cependant, des ajustements peuvent être nécessaires en cas d'exécution sur des appareils mobiles plus anciens ou des plates-formes intégrées.

Alors, comment fonctionne cette pile ? L'apprentissage en profondeur donne souvent à chacun un sentiment de "boîte noire". Mais alors que de nombreuses parties sont en effet mystérieuses, le réseau de neurones que nous utilisons nous transmet souvent des informations pour révéler son fonctionnement. Nous pouvons voir les couches dans la pile et comment ces couches activent des images d'entrée spécifiques. Cela nous indique la capacité de chaque couche à identifier séparément les saucisses, le pain et d'autres caractéristiques du hot-dog.

2. Formation

La qualité des données est critique. Quelle est la qualité des données de formation fournies, meilleure sera la structure du réseau neuronal. Relever la barre des données de formation est l'une des trois choses sur lesquelles nous passons le plus de temps sur ce projet.

Les principales améliorations que nous avons apportées sont les suivantes :

  • Obtenez plus d'images et des images plus diverses (longueur et largeur, arrière-plan, éclairage, différences culturelles, perspective, composition, etc.).

  • Faites correspondre le type d'image à la valeur d'entrée de produit attendue (image utilisateur). Notre hypothèse est que la plupart du temps, les gens prennent des photos de hot-dogs ou d'autres aliments, ou parfois les gens essaient de tester l'application avec des objets aléatoires, donc notre ensemble de données a été construit avec ces facteurs à l'esprit.

  • Alimentez votre réseau de neurones avec des images similaires qui pourraient sembler fausses. Les hot-dogs sont plus facilement confondus avec d'autres aliments (comme les hamburgers, ou simplement les saucisses, ou les mini-carottes et les mini-tomates rôties). Cela se reflète dans notre ensemble de données.

  • Distorsion d'image attendue : dans le cas des téléphones portables, la plupart des images seront de qualité inférieure à la "moyenne" avec un reflex numérique. L'éclairage de l'appareil photo du téléphone n'est pas non plus satisfaisant. Les photos provenant d'appareils mobiles sont généralement plus sombres ou inclinées. Les ensembles de données à grande échelle sont la clé pour résoudre le problème.

Nous supposons également que si les utilisateurs n'ont pas de hot-dog sous la main, ils rechercheront des photos du hot-dog sur Google, puis utiliseront leur téléphone pour prendre une capture d'écran de l'ordinateur, ce qui entraînera une autre distorsion (si la photo est prise sous un angle, l'image sera faussée, et si vous utilisez le Il y aura également des taches lumineuses et des ondulations de moiré évidentes sur l'écran LCD prises par l'appareil photo du téléphone portable).

Ces distorsions particulières peuvent facilement confondre nos réseaux de neurones, comme certains des articles universitaires récents sur l'incapacité des réseaux convolutifs à résister au bruit. La plupart des problèmes peuvent être résolus en utilisant la fonction de décalage de canal de Keras.

Image : Wikimedia Exemple de distorsion : moiré et points de lumière.

Certains coins et recoins du problème sont difficiles à détecter. En particulier, les photos avec flou artistique ou bokeh peuvent parfois confondre notre réseau de neurones. Ce problème est difficile à résoudre.

Tout d'abord, il y a très peu de photos de hot-dogs prises avec un flou artistique (on a faim rien qu'à y penser).

Deuxièmement, cela fait plus de mal que de bien si nous passons beaucoup de capacité de réseau neuronal à former la capacité à reconnaître le flou artistique, car la grande majorité des photos prises avec des appareils mobiles n'ont pas cette fonctionnalité. Nous avons choisi de ne pas considérer cette question du tout.

Notre ensemble de données final était de 150000 images, dont seulement 3000 photos de hot-dogs : tant pour les hot-dogs, mais tellement de choses qui n'étaient pas des hot-dogs. Ici, le déséquilibre 49: 1 que nous rattrapons avec les paramètres de poids de la classe Keras. La plupart des 147000 images restantes sont de la nourriture, et il y en a environ 3000 qui ne sont pas de la nourriture, ce qui aide notre réseau à mieux s'intégrer et à ne pas être confondu par une vraie chose portant un manteau de hot-dog.

Les conditions de notre extension de données sont les suivantes :

  • La rotation que nous avons ajoutée était comprise entre ±135 degrés - beaucoup plus grande que la moyenne, puisque nous avons tapé du code sans tenir compte de l'orientation du téléphone.

  • Déplacer la hauteur et la largeur de 20 %

  • Plage de coupe 30 %

  • Plage de zoom 10 %

  • Changement de canal 20 %

  • Retournements horizontaux aléatoires pour aider les réseaux de neurones à améliorer la généralisation

Ces chiffres sont nos intuitions basées sur l'expérimentation et notre compréhension du fonctionnement réel de l'application, et non des expériences rigoureuses.

La dernière clé de notre préparation de données a été l'utilisation du générateur de données d'image multiprocessus Keras de Patrick Rodriguez.

Bien que Keras ait sa propre implémentation de multi-lignes et multi-traitements, nous avons constaté que la base de données de Patrick s'exécute plus rapidement (les raisons spécifiques que nous n'avons pas encore eu le temps d'étudier). Cette bibliothèque nous a permis de réduire notre temps de formation des deux tiers.

Le réseau de neurones a été formé sur un MacBook Pro 2015 avec un GPU externe. Notre eGPU à l'époque était une Nvidia GTX 980 Ti, mais nous aurions acheté une 1080 Ti si nous avions commencé à le faire maintenant.

Nous avons pu entraîner le réseau par lots de 128 images à l'époque. Notre réseau neuronal a été formé sur un total de 240 époques, ce qui signifie qu'il nous a fallu 240 époques pour exécuter 150000 graphiques. Cela a pris 80 heures.

Nous formons le réseau de neurones dans les trois étapes suivantes :

La première étape comprend 112 sessions de formation (7 cycles CLR complets avec 8 sessions de formation en une étape).

Notre taux d'apprentissage est compris entre 0,005 et 0,03, basé sur la méthode triangulaire 2 (ce qui signifie que le taux d'apprentissage maximal est divisé par deux toutes les 16 fois).

La deuxième étape comporte 64 formations supplémentaires (4 cycles CLR sont complétés avec 8 formations dans la première étape), et le taux d'apprentissage est compris entre 0,0004 et 0,0045, toujours basé sur la méthode triangulaire 2.

La deuxième étape comporte 64 formations supplémentaires (4 cycles CLR avec 8 formations dans la première étape), le taux d'apprentissage est compris entre 0,000015 et 0,0002, toujours basé sur la méthode triangulaire 2.

Mise à jour : la version précédente du graphique contenait des informations incorrectes

Bien que les taux d'apprentissage aient été obtenus en exécutant les expériences linéaires recommandées par l'article du CLR, ces chiffres sont en fait assez faciles à comprendre. La valeur maximale de chaque commande est d'environ la moitié de la valeur minimale de l'étape précédente, ce qui est conforme à la norme recommandée dans l'industrie (si vous rencontrez un plateau de précision pendant la formation, réduisez de moitié votre taux d'apprentissage).

Pour gagner du temps, une partie de notre formation a été réalisée sur un Ubuntu exécutant une instance Paperspace P5000. Au cours de cette partie de la formation, nous avons pu doubler la taille du lot. Nous avons constaté que dans ce cas, le taux d'apprentissage optimal pour chaque époque était également presque doublé.

3. Exécution du réseau de neurones sur votre téléphone

Bien que nous ayons construit une structure neuronale relativement compacte et l'avons formée pour être mobile, nous avons encore beaucoup de travail à faire pour qu'elle fonctionne bien. Essayer d'exécuter directement une structure de réseau neuronal aussi avancée peut rapidement consommer des centaines de Mo de RAM, et la plupart des téléphones de nos jours n'ont pas beaucoup de mémoire supplémentaire. En dehors de l'optimisation de votre réseau de neurones, la façon dont vous manipulez les images, ou même le chargement de TensorFlow lui-même, peut avoir un impact sur la vitesse d'exécution de votre réseau de neurones, la quantité de RAM que vous utilisez et l'expérience utilisateur sur le point de planter.

C'est probablement la partie la plus mystérieuse du projet. Nous pouvons difficilement trouver des informations à ce sujet, peut-être parce qu'il y a si peu d'exemples d'applications d'apprentissage en profondeur fonctionnant sur des appareils mobiles aujourd'hui. Cependant, nous sommes ici pour remercier l'équipe TensorFlow, en particulier Pete Warden, Andrew Harp et Chad Whipkey pour leur patience.

  • En arrondissant les poids de notre réseau de neurones, nous avons réduit la taille du réseau aux trois quarts de la taille d'origine.

En fin de compte, au lieu d'utiliser des valeurs stockées arbitraires de notre formation, notre optimisation sélectionne les N valeurs les plus fréquentes et définit tous les paramètres de votre réseau de neurones sur ces valeurs. Cela peut réduire la taille du réseau de neurones après compression.

Cependant, cela n'a aucun effet sur la taille de l'application non compressée ou sur l'utilisation de la mémoire. Nous n'avons pas mis cette optimisation dans le produit final, car d'une part notre réseau de neurones était assez petit, et d'autre part, nous n'avons pas eu le temps de quantifier l'impact de cet arrondi sur la précision de l'application.

  • La bibliothèque logicielle TensorFlow est optimisée en la compilant sur iOS.

  • Supprimez les algorithmes inutiles de la bibliothèque logicielle TensorFlow : TensorFlow est une machine virtuelle dans le sens où elle comprend un nombre ou n'importe quel algorithme TensorFlow : addition, multiplication, concaténation de chaînes, etc.

Vous pouvez économiser beaucoup de mémoire en supprimant les algorithmes inutiles de la bibliothèque logicielle TensorFlow lors de la compilation vers iOS.

  • D'autres améliorations sont également possibles. Par exemple, un autre travail indépendant de l'auteur a une augmentation de 1 Mo de la taille binaire d'Android. On peut donc supposer qu'il existe également un endroit pour améliorer l'optimisation dans le code iOS de TensorFlow.

En plus de la possibilité d'utiliser TensorFlow sur iOS, nous avons également examiné les propres bibliothèques de logiciels d'apprentissage en profondeur d'Apple (BNNS, MPSCNN et plus tard CoreML). Nous aurions pu concevoir le réseau de neurones sur Keras, l'entraîner sur TensorFlow, puis exporter toutes les valeurs, réimplémenter avec BNNS ou MPSCNN (ou importer directement de CoreML) et charger les paramètres dans la nouvelle implémentation.

Cependant, le plus gros obstacle avec ces nouvelles bibliothèques de logiciels Apple est qu'elles ne fonctionnent que sur iOS 10+, et nous voulions également que l'application fonctionne sur les versions antérieures d'iOS. Avec iOS 10+ adopté par le public et le framework mis à jour, nous n'aurons peut-être pas besoin d'utiliser TensorFlow dans un avenir proche.

#importer < CodePush/CodePush.h >

NSString* FilePathForResourceName (nom NSString*, extension NSString*) {

// NSString* file_path = ;

NSString* chemin_fichier = ;

si (chemin_fichier == NULL) {

JOURNAL (FATAL) < < "Impossible de trouver '" < < < < "."

< < < < "' en liasse.";

}

renvoie file_path ;

}

AIManager.mm hébergé avec par GitHub

importer React, {Composant} de 'réagir' ;

import { AppRegistry } de 'react-native' ;

importer CodePush depuis "react-native-code-push" ;

importer l'application depuis './App' ;

la classe nothotdog étend le composant {

rendre() {

revenir (

< Application / >

)

}

}

exiger('./deepdog.pdf')

const codePushOptions = { checkFrequency : CodePush.CheckFrequency.ON_APP_RESUME } ;

AppRegistry.registerComponent('nothotdog', () = > CodePush(codePushOptions)(nothotdog));

index.ios.js hébergé avec par GitHub

En quoi notre projet est-il différent ?

En fait, il y a beaucoup de choses que nous n'avons pas eu le temps de faire ou que nous avons essayées et échouées. Voici les idées que nous explorerons à l'avenir :

  • Ajustez plus soigneusement nos paramètres de croissance des données.

  • de bout en bout, c'est-à-dire une abstraction que l'application finalise, comme si notre application a 2 catégories de hot-dogs ou plus quel est le seuil de reconnaissance (on finit par faire dire à l'application "hot-dog" si la reconnaissance est supérieure à 0,90 et le par défaut 0,5), le double du poids, etc.

  • Ajoutez un mécanisme de rétroaction à l'application - permettant aux utilisateurs de se plaindre en cas de problème ou permettant à l'application d'optimiser activement le réseau neuronal.

  • Utilisez une résolution de reconnaissance d'image supérieure à 224 x 224 pixels. En fin de compte, nous voulons utiliser une valeur MobileNets supérieure à 1,0.

4. Expérience utilisateur, expérience développeur et l'étrange vallée de l'IA

Enfin, nous voulons parler de l'énorme impact de l'expérience utilisateur, de l'expérience des développeurs et des biais intégrés sur le développement d'une application d'IA. Je pourrais écrire un autre article de blog (ou même un livre) pour chaque point, mais ici nous allons parler très solidement de l'impact de ces trois choses dans notre propre expérience.

L'expérience utilisateur est plus critique à chaque étape du développement d'applications d'IA que les applications traditionnelles. Il n'existe actuellement aucun algorithme d'apprentissage en profondeur qui vous donnera des résultats parfaits, mais il existe de nombreuses situations où la bonne combinaison d'apprentissage en profondeur et d'expérience utilisateur vous donnera des résultats presque parfaits.

Rien ne remplace les attentes d'une expérience utilisateur appropriée et, en particulier, peut conduire les développeurs sur la bonne voie lors de la conception de réseaux de neurones, définir des attentes appropriées pour les utilisateurs du logiciel et aider à résoudre les bogues inévitables de l'IA. Construire une application d'IA sans penser à l'expérience utilisateur, c'est comme former un réseau de neurones sans Stochastic Gradient Descent : vous vous retrouverez au fond de l'Uncanny Valley sur votre chemin pour construire l'IA parfaite.

Photo : nouveau scientifique

L'expérience des développeurs est également essentielle, car la formation à l'apprentissage en profondeur prend beaucoup de temps et vous n'avez pas à attendre que le programme soit formé pour s'exécuter. Nous vous recommandons de vous concentrer d'abord sur l'expérience du développeur, car vous pourrez alors toujours optimiser le temps d'exécution (parallélisme GPU manuel, injection de données multivariées, pipelines TensorFlow et même réimplémenter votre caffe2/pyTorch) si vous avez quelque chose d'utile et bien entretenu. Même si vous utilisez une API et une documentation relativement basiques comme TensorFlow, votre expérience de développeur sera grandement améliorée.

De la même manière, vous ne pouvez pas vous permettre d'avoir la flexibilité de développer par vous-même dans un environnement GPU natif à bas prix. Pouvoir afficher/modifier des images localement et modifier le code avec vos outils préférés peut grandement améliorer la qualité et la rapidité du développement de projets d'IA.

En ce qui concerne le biais inhérent aux applications d'IA, la grande majorité des autres applications d'IA rencontreront probablement des problèmes plus difficiles que nous. Mais même notre simple application souffre de préjugés culturels. Par exemple, notre application ne reconnaît pas les hot-dogs français, les hot-dogs asiatiques ou d'autres types auxquels nous n'avons pas accès.

Ce que nous devons réaliser, c'est que l'IA ne peut pas prendre de meilleures décisions que les humains, qu'elles sont conçues par des humains imparfaits et qu'il est compréhensible qu'elles soient contaminées par des préjugés humains.

Merci à tous les partenaires qui ont utilisé et partagé cette application ! Nous regardons des photos de hot-dogs tous les jours depuis quelques mois, ouvrant la porte et regardant par la fenêtre et le monde est plein de hot-dogs...

Regarder la Coupe d'Asie 51 jeux, en laissant les Orangistes ne équipes pas vraiment faibles
Précédent
Portefeuille échelle de risque merveilleux! Beaucoup sont d'origine VC projet « HAITOU » par « Mongolie » dans
Prochain
publique de la police Heze voulait 20 fugitifs! Venez maison Conseil Nouvel An droit
Explosion des modèles pour créer un produit de victoire rapide, prendre pied aux données | dialogue Laboratoire de données Additionne Est
Huppé a volé à East Lake pour l'hiver
Singularity University Fondateur: AI dépassera l'intelligence humaine devenir plus avancée intelligente
Chengdu Xingcheng appel rideau dans le runner-up de la couronne
carnaval « Double 11 » en fait été de 10 ans, plus de 11 personnes sécher son premier single
Exclusive | trajectoire de menteur discrimination avec la souris
Jamais! Seulement approché avec la Chine, le pays « se battre »
7 minutes des objectifs de planification de raid + 1V3 vague tourné dans le monde, 22 ans, Zhang Yuning 2 Conquérir la sécurité nationale de l'aide étrangère!
Exclusive | technologie de reconnaissance faciale peut être utilisée pour identifier les baleines? Kaggle concours d'identification des baleines enseigner NO.1 vous atteindre!
Exclusive | demande et la perspective de la technologie de l'intelligence artificielle dans le domaine médical (ci-joint PPT)
Lire la couverture de la semaine XIX | Ce deux à onze est de ne pas acheter l'Est ou la Vénus de Milo?