L'un des schémas de réseau de neurones classiques pour implémenter l'algorithme RL est le suivant:
Où: entrées - entrées du réseau neuronal; Architecture de couche cachée FC - (entièrement connectée) ou architecture de couche cachée CNN - FC - architecture (en fonction de ce qui est appliqué aux entrées); sorties - sorties réseau. Souvent, les sorties du réseau sont une couche softmax qui donne la probabilité d'une des actions de l'ensemble de toutes les actions possibles.
L'inconvénient de cette architecture est qu'il est difficile de mettre en œuvre le choix de plusieurs actions réalisées simultanément.
Pour résoudre ce problème, une architecture avec une couche de masque est proposée. L'architecture proposée est la suivante:
Cette architecture est entièrement cohérente avec l'architecture classique, mais comprend également une couche de masque d'action. Il n'y a qu'un seul moyen de sortir de cette architecture - c'est la valeur de la valeur de l'action (un groupe d'actions exécutées simultanément). La couche de masque d'action peut être implémentée conformément au pseudo-code ci-dessous:
import numpy as np class Layer: def __init__(self, items, item_size, extra_size): assert(items > 0) assert(item_size > 0) assert(extra_size >= 0) self.items = items self.item_size = item_size self.extra_size = extra_size def build(self): self._expand_op = np.zeros((self.items, self.items*self.item_size), \ dtype=np.float32) for i in range(self.items): self._expand_op[i,i*self.item_size:(i+1)*self.item_size] = np.float32(1.0) def call(self, inputs, ops): op_mask_part = inputs[:self.items*self.item_size] if self.extra_size > 0: ext_part = inputs[self.items*self.item_size:] else: ext_part = None
Et l'utilisation de ce code illustre l'extrait de code suivant:
items = 5 item_size = 10 extra_size = 20 l = Layer(items=items, item_size=item_size, extra_size=extra_size) l.build() inputs = np.random.rand(items*item_size+extra_size) ops = np.random.randint(0, 2, (items,), dtype="int") ops = ops.astype(dtype=np.float32) - np.float32(0.5) result = l.call(inputs,ops)
Le code de couche montre que pour chaque action, le réseau neuronal apprend à former une certaine représentation de l'action sous la forme d'une série de poids. Et ces représentations vont au réseau après la couche de masque ou non. Selon l'opération, ces poids peuvent avoir lieu avec la tâche d'une opération sur l'ensemble du groupe de poids d'action (pas seulement la multiplication par [0,1]). Ainsi, la tâche d'actions est formée pour calculer la valeur du groupe d'actions effectuées par le réseau. (Dans le cas classique, la couche softmax a calculé la valeur de toutes les actions; dans l'architecture proposée, le réseau neuronal calcule la valeur d'un groupe d'actions sélectionnées.)
(Pour une définition de la valeur d'une action, voir, par exemple, R.S. Sutton, E.G. Barto Reinforced Learning.)
Exemples d'utilisation de l'architecture proposée
Jeu de Tetris
L'idée d'utiliser cette architecture pour jouer à tetris est la suivante. Aux entrées, nous soumettons l'image du verre du jeu tetris (un pixel, un carré). Nous regroupons les actions individuelles en groupes d'action. L'évaluation d'une action pour un réseau neuronal est un masque de la position finale d'une figure dans un verre. Le chiffre est défini par ses carrés dans le masque d'action dans la couche du masque d'action dans le réseau neuronal. Pour sélectionner un groupe d'actions, nous sélectionnons l'évaluation maximale de l'action (sortie) dans la liste de toutes les positions finales de la figure actuelle.
Dessin. Le champ (cellules bleues) et la forme tombante (cellules gris clair) sont affichés. La position finale de la figurine est toutes les positions possibles à partir desquelles la figurine ne peut pas se déplacer selon les règles du jeu (non représentées).
Agent simulant le mouvement d'une voiture
Dans ce cas, chaque action d'accélération (plusieurs accélérations d'accélération), freinage (plusieurs accélérations possibles lors du freinage), ainsi que plusieurs degrés de rotation ont été modélisés comme des actions élémentaires. Il est entendu qu'en même temps une rotation et l'une des accélérations peuvent être impliquées, ou seulement une action de rotation ou une action d'accélération. Dans ce cas, l'architecture vous permet de spécifier plusieurs actions élémentaires en même temps pour former une action complexe.
Dessin. En plus du champ pour effectuer des actions par le modèle de voiture (sur lequel l'objectif de stationnement est indiqué par des lignes rouges et vertes), les entrées du réseau neuronal (ci-dessous) et les valeurs de l'évaluation des actions pour toutes les actions possibles dans cet état du modèle sont également affichées.
Autres applications possibles de l'architecture
De même, avec l'utilisation de tetris dans un jeu, l'architecture peut être utilisée pour d'autres jeux, où une série de figures et plusieurs actions peuvent être spécifiées sur le terrain en même temps (par exemple, se déplacer sur le terrain de jeu).
En robotique, cette architecture peut servir de méta-réseau coordonnant des éléments structurels individuels en un ensemble commun.
De plus, cette architecture vous permet d'utiliser l'apprentissage par transfert pour pré-former la partie CNN, et vice versa au début pour former la partie RL du réseau neuronal, puis former la partie CNN sur le réseau RL déjà formé sur les données du modèle. Dans l'exemple, lors de la programmation du jeu Tetris, l'apprentissage par transfert a été appliqué avec une formation au début de la partie CNN et de la partie FC à la couche de masque d'action (ce qui est transféré au réseau résultant). Dans le problème du stationnement, je prévois également d'appliquer la formation CNN après avoir appris la partie RL (c'est-à-dire la première cerise).
→ Des exemples de code source du programme peuvent être trouvés
ici