Februar 2016

Band 31, Nummer 2

Dieser Artikel wurde maschinell übersetzt.

Microsoft Azure – Azure Service Fabric, Q-Learning und Tic-Tac-Toe

Durch Jesus Aguilar

Innovationen in Cloud-computing die Hindernisse für verteilte Datenverarbeitung Eintrag reduzieren und Clientanwendungen Nische Technologien erfordern spezielle und teure Infrastruktur zu einer einfachen Ware Angebot für alle Software-Entwickler oder Lösung Architect für maschinelles lernen. In diesem Artikel beschreibe ich die Implementierung einer vertiefenden lernen Verfahren, das die verteilte Computing- und Speicherressourcen Funktionen von Azure Service Fabric die nächste Iteration des Azure Platform-as-a-Service-Angebot nutzt. Um das Potenzial dieses Ansatzes zu demonstrieren, werde ich zeigen, wie Sie Service Fabric verwenden vornehmen und der Reliable Actors-Programmiermodell eine intelligente Back-End zu erstellen, die die nächste vorhersagen können in ein Spiel Tic verschieben. Spiele War, alle Benutzer?

Geben Sie Q-Learning

Heute innovative datengesteuerte Lösungen wie z. B. Recommendations, Erkennung und Meldung von Betrug Erkennung überall konfrontiert. Software Engineering Teams verwenden überwachtes und unüberwachtes lernen Techniken zum Implementieren dieser Lösungen. Trotz der umfangreichen Funktionen dieser Ansätze gibt es Fälle, in denen sie nur schwer anwendbar sind.

Vertiefenden Lernen ist eine Methode, die Szenarien behandelt, die Sie als Sequenz von Zuständen und Übergängen darstellen können. Im Gegensatz zu anderen maschinelles Ansätze versuchen nicht vertiefenden lernen, um Muster zu verallgemeinern, durch das Trainieren eines Modells aus bezeichneten Informationen (das beaufsichtigte lernen) oder nicht bezeichneten Daten (unbeaufsichtigtes lernen). Stattdessen konzentriert sich diese auf Probleme, die Sie als eine Folge von Zuständen und Übergängen modellieren können.

Angenommen Sie, Sie ein Szenario, das Sie als eine Folge von Zuständen, die zu der endgültige Status darstellen können (bezeichnet als absorbing Status) führen. Stellen Sie sich ein Roboter Entscheidungen Hindernisse oder künstliche Intelligenz (AI) in einem Spiel soll einen Gegner beat zu vermeiden. In vielen Fällen ist die Sequenz von Zuständen, die zu einer bestimmten Situation bewährte nächsten Schritt für das-Agent/Roboter/AI-Zeichen bestimmt.

Q-Learning ist eine Bekräftigung learning-Technik, die einen iterative Belohnung Mechanismus verwendet, um optimale transitional Pfade in einem statuscomputermodell zu suchen. Es funktioniert bemerkenswert auch wenn die Anzahl von Zuständen und ihre Übergänge begrenzte ist. In diesem Artikel stelle ich, wie Service Fabric So erstellen eine End-to-End-Q-Learning-Lösung und zeigen, wie Sie eine intelligente Back-End erstellen können, die "Gewusst wie: Wiedergeben von Tic erfährt" verwendet. (Beachten Sie, dass State Machine-Szenarien auch als Markov-Entscheidungsprozesse [MDPs] bezeichnet werden).

Erstens, einige grundlegende Theorie Q-lernen. Betrachten Sie die Zustände und Übergänge in den Abbildung 1. Bei jedem Zustand finden möchten, welcher Status ein Agent muss auf Weiter, um den gold Zustand ankommen Übergang sagen – und gleichzeitig die Anzahl der Übergänge. Eine Möglichkeit, dieses Problem zu lösen ist, jeden Status einen Belohnung Wert zuzuweisen. Die Belohnung schlägt vor, den Wert der Übergang in einen Zustand auf Ihr Ziel: das Gold abrufen.

Eine Sequenz von Zuständen, die zu den Gold-Status
Abbildung 1: Sequenz von Zuständen, die zu den Gold-Status

Ganz einfach, oder? Die Herausforderung wird den Nutzen für die einzelnen Zustände zu identifizieren. Der F-Learning-Algorithmus identifiziert Boni rekursiv durchlaufen und Zustände, die in den absorbing (Gold) Zustand führen Boni zuweisen. Der Algorithmus berechnet einen Zustand belohnen, indem Sie ohne Berücksichtigung der Bonuspunkte aus den nachfolgenden Status. Wenn zwei Boni in einem Zustand befindet – das ist möglich, wenn ein Zustand in mehr als einem Pfad vorhanden ist, hat den höchsten Vorrang. Der Preisnachlass hat eine wichtige Auswirkung auf das System. Von ohne Berücksichtigung den nutzen, der Algorithmus verringert den Wert der Belohnung für Zustände, die nicht das Gold sind und die Zustände, die das Gold am nächsten mehr Gewicht zugewiesen.

Ein Beispiel dafür, wie der Algorithmus die Belohnung berechnet, betrachten Sie das Statusdiagramm in Abbildung 1. Wie Sie sehen, gibt es drei Wege zum Gold:

1-5 > -> 4 G ->

1-5 > -> 3-4 >-G >

1-5 > -> 3-2 > -> 4 G ->

Nach dem Ausführen des Algorithmus Brute force Übergang (Iteration durch alle möglichen Pfade im Diagramm), die der Algorithmus berechnet und weist die Boni für die gültige Pfade. Rewards werden mit dem Faktor Rabatt von 0,9 berechnet.

1(R=72)-5(R=81) > 4(R=90) -> -> G (R = 100)

1(R=64)-5(R=72) > 3(R=81) -> -> 4(R=90) -> G(R=100)

1(R=58)-5(R=64) > 3(R=72) -> -> 2(R=81) -> 4(R=90) -> G(R=100)

Da in einigen Staaten mehr als eine Belohnung haben, wird der höchste Wert Vorrang. Abbildung 2 zeigt die Zuordnung endgültige belohnen.

Letzte Boni
Abbildung 2 letzte Boni

Mit diesen Informationen kann ein Agent den optimalen Weg für jeden Status Gold identifizieren, durch den Übergang in den Status mit der höchsten nutzen. Z. B. wenn der Agent im Zustand 5 ist, muss es die Auswahl für den Übergang zum Status 3 oder 4, und 4 wird die Wahl, da die Belohnung höher ist.

Azure Service Fabric

Service Fabric wird die nächste Iteration des Azure Platform-as-a-Service-Angebot ermöglicht Entwicklern das Erstellen verteilter Anwendungen mit zwei verschiedenen übergeordneten Programmiermodelle: Reliable Actors und Reliable Services. Diese Programmiermodelle ermöglichen Ihnen die Infrastruktur einer verteilten Plattform nutzen. Die Plattform verarbeitet die schwierigsten Aufgaben im Zusammenhang mit Wartung und Ausführung einer verteilten Anwendung – Wiederherstellung nach Fehlern, Verteilung der Dienste, um sicherzustellen, dass effiziente Ressourcenverwendung, parallelen Updates und Seite-an-Seite-Versionskontrolle, um nur einige zu nennen.

Service Fabric bietet ein Cluster bietet Ihnen eine höhere Abstraktionsebene verwenden, anstatt die zugrunde liegende Infrastruktur kümmern. Der Code ausgeführt wird, auf den Knoten des Service Fabric-Cluster, und Sie können mit mehreren Knoten-Cluster auf einem einzelnen Computer zu Entwicklungszwecken oder auf mehreren Servern (virtuelle oder physische Computer) für Produktionsarbeitslasten hosten. Die Plattform verwaltet den Lebenszyklus der die Akteure und-Dienste sowie die Wiederherstellung bei Fehlern der Infrastruktur.

Service Fabric führt Reliable Actors und Services mit statusbehafteter Semantik. Diese Funktion übersetzt in eine vollständig integrierte Entwicklungsprozess, in dem Sie Clientanwendungen, die verteilte und daher hoch verfügbaren Daten beizubehalten entwickeln können, ohne einen externen Speicher (z. B. eine von einem externen Speicher oder caching-Ebene) auch, in Ihrer Architektur.

Durch Implementieren des F-Learning-Algorithmus als Dienst im Service Fabric können profitieren Sie von mit verteilten computing und niedriger Latenz Zustand Speicherfunktionen aktivieren, führen Sie den Algorithmus, die Ergebnisse beibehalten und alles als zuverlässige Endpunkte für die Clients den Zugriff auf verfügbar machen. Alle diese Funktionen sind zusammen in einer einzigen Lösung mit eine einheitliche Programmierung und Verwaltung. Besteht keine Notwendigkeit zum Hinzufügen weiterer Komponenten für Ihre Architektur, z. B. einen externen Speicher, Cache oder messaging-System. Kurz gesagt, müssen Sie eine Lösung, in der Ihre Compute, Daten und Dienste innerhalb der gleichen integrierten Plattform befinden. Das ist eine elegante Lösung in meinem Buch!

Q-Learning und zuverlässige Akteure

Das Actor-Modell vereinfacht den Entwurf von hochgradig parallele Anwendungen. Im Actor-Modell sind Akteure die grundlegende Einheit für die Berechnung. Ein Akteur ist eine Grenze für Funktion und Zustand. Sie können ein Akteur als objektentität in einem verteilten System Leben vorstellen. Service Fabric verwaltet den Lebenszyklus des Actors. Beim Ausfall instanziiert erneut Service Fabric den Actor in einem fehlerfreien Knoten automatisch. Wenn ein statusbehafteter Actor für aus irgendeinem Grund oder den Knoten (denken VM abstürzt), es tritt ein Fehler ausgeführt wird, ist der Akteur z. B. auf einem anderen Computer mit all seinen Status (Daten) intakt automatisch neu erstellt.

Service Fabric verwaltet außerdem, wie eine Instanz eines Akteurs zugegriffen wird. Die Plattform garantiert, dass es sich bei an einem gegebenen Zeitpunkt nur eine Methode auf einem bestimmten Akteur gleichzeitig ausgeführt wird. Wenn zwei gleichzeitige Aufrufe an den gleichen Actor vorhanden sind, wird Service Fabric eine Warteschlange, andere fahren Sie fort. Das hat zur Folge ist, dass in einem Akteur Code nicht Racebedingungen, Sperren oder Synchronisierung Gedanken.

Wie zuvor beschrieben, durchläuft der F-Learning-Algorithmus Zustände mit dem Ziel auslasten Zustände und Zustände mit. Nachdem der Algorithmus einen absorbing Status mit einer Belohnung identifiziert wird, berechnet es Boni für alle Zustände, die in den absorbing-Zustand führen.

Das Actor-Modell kann ich diese Funktionalität als Akteur modellieren, die einen Zustand im Kontext des Q-Learning-Algorithmus (Stellen Sie sich der Stufen im gesamten Diagramm) darstellt. In meiner Implementierung ist die Actor-Typ, der diese Zustände darstellt QState. Ein Übergang zu einem QState Akteur, enthält eine Belohnung wird, wird der QState-Actor einen anderen Actor-Instanz einen anderen Typ (QTrainedState) für jede der QState Akteure in den Pfad erstellen. QTrainedState Actors beibehalten der maximale Bonuspunkte und eine Liste der nachfolgenden Zustände, die die Prämie ergeben. Die Liste enthält die Status-Token (der einen Status, in dem Diagramm eindeutig identifiziert wird), der nachfolgenden Status.

In Abbildung 3, ich die Logik des Algorithmus mit Actors, für ein sehr einfaches Szenario, in dem Status Status Token 3 absorbing ist, enthält eine Belohnung 100 und ist nur eines von vielen Lernmitteln mit zwei vorherigen Status (Status Token 1 und 2) dargestellt. Jeder Kreis stellt eine Instanz eines Akteurs QStates in Blau und QTrainedStates in orange dargestellt. Sobald der Übergangsphase der QState mit Status 3 erreicht hat, wird der QState-Actor zwei QTrainedStates, eine für jede der vorherigen QStates erstellt. Für den QTrainedState-Actor, der Zustand Token 2 darstellt, der vorgeschlagene Übergang (für eine Belohnung 90) token 3 Status, und für den QTrainedState-Actor, der Status-Token 1 darstellt, ist des vorgeschlagenen Übergangs (für eine Belohnung 81) token 2 angeben.

Bestimmen und Boni beibehalten
Abbildung 3 ermitteln und Beibehalten von belohnt.

Es ist möglich, dass mehrere Zustände der gleichen Belohnung erzielt werden, damit der QTrainedState Akteur eine Auflistung von Status-Token als untergeordnete Elemente Status weiterhin auftritt.

Der folgende Code zeigt die Implementierung der Schnittstellen für die Akteure QState und QTrainedState, IQState und IQTrainedState aufgerufen. QStates haben zwei Verhaltensweisen: Wechsel zu anderen QStates, und starten den Übergang zu verarbeiten, wenn keine vorherigen Übergangs vorhanden ist:

public interface IQState : IActor
{
  Task StartTrainingAsync(int initialTransitionValue);
  Task TransitionAsync(int? previousStateToken, int transitionValue);
}
public interface IQTrainedState:IActor
{
 .Task AddChildQTrainedStateAsync(int stateToken, double reward);
 .Task<List<int>> GetChildrenQTrainedStatesAsync();
}

Beachten Sie, dass die Implementierung der IQTrainedState die Methode GetChildrenQTrainedStatesAsync Flächen. Diese Methode ist wie der QTrainedState-Actor trainierten Daten, enthält die Zustände mit dem höchsten Wert der Belohnung für jeden Zustand im System verfügbar gemacht wird. (Beachten Sie, dass alle Akteure in der Service Fabric eine von IActor abgeleitete Schnittstelle implementieren müssen.)

QState-Actor

Nach dem Definieren der Schnittstellen, kann ich auf die Implementierung der Akteure verschieben. Ich beginne mit der Actor QState und die TransitionAsync-Methode, dies ist der Grundstein des Algorithmus und die meiste Arbeit sich befindet. TransitionAsync vereinfacht den Übergang in einen anderen durch Erstellen einer neuen Instanz von einem Akteur QState und dieselbe Methode erneut aufrufen.

Sie Fragen sich möglicherweise, wenn durch Aufrufen der Methode rekursives den Aufwand für das Aufrufen der Methode durch einen anderen Actor-Instanz vermeiden möchten. Einen rekursiven Methodenaufruf handelt es sich um einen rechenintensiven Vorgang in einem einzelnen Knoten. Im Gegensatz dazu durch Instanziieren einen anderen Actor, umgeleitet Sie Advantange Funktionen von Service Fabric werden, wenn die Plattform die Verarbeitung auf horizontale Computerressourcen verteilt.

Um die Zuweisung der Belohnung zu verwalten, werde ich eine Erinnerung registrieren. Erinnerungen werden neue Konstrukte im Actor-Programmiermodell eingeführt, mit denen Sie asynchrone Arbeit zu planen, ohne die Ausführung einer Methode blockiert.

Erinnerungen sind nur für statusbehaftete Actors verfügbar. Für statusfreie und statusbehaftete Actors bietet die Plattform Zeitgeber, die ähnliche Muster zu aktivieren. Ein wichtiger Aspekt ist, dass bei der Actor Garbage Collection-Vorgangs verzögert wird. die Plattform sollten nicht dennoch Zeitgeberrückrufe Nutzung. Wenn der Garbage Collector zum Einsatz kommt, werden der Zeitgeber beendet. Akteure werden nicht Garbage Collection während der Ausführung einer Methode übergeben. Verwenden Sie Erinnerungen, um wiederholte Ausführung zu gewährleisten. Weitere Informationen finden Sie unter bit.ly/1RmzKfr.

Das Ziel ist in Bezug auf den Algorithmus die Belohnung Zuordnung ausführen, ohne Blockierung der Übergangsprozess. Planen eine Arbeitsaufgabe im Threadpool durch einen Rückruf wird in der Regel ausreichend. jedoch ist im Actor-Programmiermodell dieser Ansatz nicht empfehlenswert, wie Sie die parallelitätsvorteile der Plattform verloren geht.

Die Plattform wird sichergestellt, dass nur eine Methode zu einem beliebigen Zeitpunkt ausgeführt wird. Diese Funktion ermöglicht es Ihnen, Code zu schreiben, ohne Berücksichtigung der Parallelität; d. h. es müssen keine Threadsicherheit kümmern. Wie erwartet, ist es ein Kompromiss: Sie müssen vermeiden, Erstellen von Aufgaben oder Threads, um Vorgänge in den Actor-Methoden zu umschließen. Die Erinnerungen ermöglichen es Ihnen, Hintergrund Verarbeitungsszenarien mit der parallelitätsgarantien der Plattform implementieren Siehe Abbildung 4.

Abbildung 4 TransitionAsync in der QState-Klasse

public abstract class QState : StatefulActor, IQState, IRemindable
{
  // ...
  public Task TransitionAsync(int? previousStateToken, int transitionValue)
  {
    var rwd = GetReward(previousStateToken, transitionValue);
    var stateToken = transitionValue;
    if (previousStateToken != null)
        stateToken = int.Parse(previousStateToken.Value + stateToken.ToString());
    var ts = new List<Task>();
    if (rwd == null || !rwd.IsAbsorbent)
      ts.AddRange(GetTransitions(stateToken).Select(p =>
        ActorProxy.Create<IQState>(ActorId.NewId(),
        "fabric:/QLearningServiceFab").TransitionAsync(stateToken, p)));
    if (rwd != null)
      ts.Add(RegisterReminderAsync("SetReward",
        Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(rwd))
        , TimeSpan.FromMilliseconds(0)
        , TimeSpan.FromMilliseconds(-1), ActorReminderAttributes.Readonly));
      return Task.WhenAll(ts);
  }
  // ...
}

(Beachten Sie, dass DueTime von TimeSpan.FromMilliseconds(0)) eine unmittelbare Ausführung bedeutet).

Um die Implementierung der IQState abzuschließen, implementiert der folgende Code die StartTransitionAsync-Methode, wo ich eine Erinnerung verwenden, um einen blockierenden Aufruf für lang andauernde zu vermeiden:

public Task StartTrainingAsync(int initialTransitionValue)
  {
    return RegisterReminderAsync("StartTransition",
      Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { TransitionValue =
      initialTransitionValue })), TimeSpan.FromMilliseconds(0),
      TimeSpan.FromMilliseconds(-1),
      ActorReminderAttributes.Readonly);
  }

Um die Implementierung der Klasse QState abzuschließen, beschreibe ich die Implementierung der SetRewardAsync und den ReceiveReminderAsync Methoden aus Abbildung 5. Die SetReward-Methode erstellt oder aktualisiert einen statusbehafteten Actor (die Implementierung von IQTrainedState). Um nachfolgende Aufrufe den Actor zu suchen, ich das Status-Token verwenden, als Akteur-Id – Actors adressierbar sind.

Abbildung 5 die SetRewardAsync und die ReceiveReminderAsync-Methoden

public Task SetRewardAsync(int stateToken, double stateReward, double discount)
  {
    var t = new List<Task>();
    var reward = stateReward;
    foreach (var pastState in GetRewardingQStates(stateToken))
    {
      t.Add(ActorProxy
        .Create<IQTrainedState>(new ActorId(pastState.StateToken),
          "fabric:/QLearningServiceFab")
        .AddChildQTrainedStateAsync(pastState.NextStateToken, reward));
      reward = reward * discount;
    }
    return Task.WhenAll(t);
  }
public async Task ReceiveReminderAsync(string reminderName,
  byte[] context, TimeSpan dueTime, TimeSpan period)
  {
    await UnregisterReminderAsync(GetReminder(reminderName));
    var state = JsonConvert.DeserializeObject<JObject>(
      Encoding.UTF8.GetString(context));
    if (reminderName == "SetReward")
    {
      await SetRewardAsync(state["StateToken"].ToObject<int>(),
        state["Value"].ToObject<double>(),
        state["Discount"].ToObject<double>());
    }
    if (reminderName == "StartTransition")
    {
      await TransitionAsync(null, state["TransitionValue"].ToObject<int>());
    }
  }

QTrainedState-Actor

Der zweite Actor in der Projektmappe ist QTrainedState. Die Daten in QTrainedState-Actor müssen dauerhaften, daher dieser Actor als ein statusbehafteter Actor implementiert.

In Service Fabric Sie implementieren einen statusbehafteten Actor durch Ableiten einer Klasse von StatefulActor oder die StatefulActor < T >-Basisklassen und Implementieren einer Schnittstelle IActor abgeleitet. T ist der Typ der Zustandsinstanz, die serialisierbar sein muss und ein Verweistyp. Beim Aufrufen einer Methode einer Klasse StatefulActor < T > abgeleitet, lädt die Plattform des Status vom Status-Anbieter und nach Abschluss des Aufrufs die Plattform, speichert er automatisch. Im Fall der QTrainedState modelliert ich den Status (dauerhafte Daten), verwenden die folgende Klasse:

[DataContract]
public class QTrainedStateState
{
  [DataMember]
  public double MaximumReward { get; set; }
  [DataMember]
  public HashSet<int> ChildrenQTrainedStates { get; set; }
}

Abbildung 6 zeigt die vollständige Implementierung der QTrainedState-Klasse, die die beiden Methoden der IQTrainedState-Schnittstelle implementiert.

Abbildung 6: die QTrainedState-Klasse

public class QTrainedState : StatefulActor<QTrainedStateState>, IQTrainedState
{
  protected async override Task OnActivateAsync()
  {
    this.State =
      await ActorService.StateProvider.LoadStateAsync<QTrainedStateState>(
      Id, "qts") ??
      new QTrainedStateState() { ChildrenQTrainedStates = new HashSet<int>() };
    await base.OnActivateAsync();
  }
  protected async override Task OnDeactivateAsync()
  {
    await ActorService.StateProvider.SaveStateAsync(Id, "qts", State);
    await base.OnDeactivateAsync();
  }
  [Readonly]
  public  Task AddChildQTrainedStateAsync(int stateToken, double reward)
  {
    if (reward < State.MaximumReward)
    {
      return Task.FromResult(true);
    }
    if (Math.Abs(reward - State.MaximumReward) < 0.10)
    {
      State.ChildrenQTrainedStates.Add(stateToken);
      return Task.FromResult(true);
    }
      State.MaximumReward = reward;
      State.ChildrenQTrainedStates.Clear();
      State.ChildrenQTrainedStates.Add(stateToken);
      return Task.FromResult(true);
  }
  [Readonly]
  public Task<List<int>> GetChildrenQTrainedStatesAsync()
  {
    return Task.FromResult(State.ChildrenQTrainedStates.ToList());
  }
}

Stellt die Akteure

Zu diesem Zeitpunkt weist die Lösung alles, was Sie zum Starten des Trainings und persistent gespeichert werden. Aber noch nicht diskutiert wurde wie Clients diese Actors interagieren. Auf einer hohen Ebene besteht aus dieser Aktivität der Schulung beginnen und die beibehaltenen Daten abzufragen. Jede dieser Interaktionen korreliert gut mit einer API-Vorgang und eine RESTful-Implementierung erleichtert die Integration mit Clients.

Ergänzung der beiden Programmiermodelle ist Service Fabric eine umfassende Orchestrierung und die Prozess-Management-Plattform. Der Fehler Recovery und Ressourcen-Management, das für die Akteure und Services vorhanden ist auch für andere Prozesse verfügbar. Sie können z. B. Node.js oder ASP.NET 5-Prozesse, die von Service Fabric und profitieren Sie von diesen Funktionen ohne weiteren Aufwand verwaltet ausführen. Ich kann also nur eine standardmäßige ASP.NET 5-Web-API-Anwendung verwenden, und erstellen einen API-Controller, die den entsprechenden Actor-Funktionen verfügbar macht, siehe Abbildung 7.

Abbildung 7 API-Controllers

[Route("api/[controller]")]
public class QTrainerController : Controller
{
  [HttpGet()]
  [Route("[action]/{startTrans:int}")]
  public  async Task<IActionResult>  Start(int startTrans)
  {
    var actor = ActorProxy.Create<IQState>(ActorId.NewId(),
      "fabric:/QLearningServiceFab/");
    await actor.StartTrainingAsync(startTrans);
    return Ok(startTrans); 
  }
  [HttpGet()]
  [Route("[action]/{stateToken}")]
  public async Task<int> NextValue(int stateToken)
  {
    var actor = ActorProxy.Create<IQTrainedState>(new ActorId(stateToken),
      "fabric:/QLearningServiceFab");
    var qs = await actor.GetChildrenQTrainedStatesAsync();
    return qs.Count == 0 ? 0 : qs[new Random().Next(0, qs.Count)];
  }
}

Und Tic?

Was bleibt jetzt besteht darin, die Lösung mit einem konkreten Szenario verwenden. Hierzu verwende ich ein einfaches Spiel: Tic.

Ziel ist es, einen Satz von QTrainedStates zu trainieren, das Sie Abfragen können, um das nächste verschieben in ein Spiel Tic vorherzusagen. Eine Möglichkeit zu kümmern ist, dass der Computer als beide Player fungiert und Lernen aus den Ergebnissen.

Beachten Sie für die Implementierung zurückgehen, dass QState eine abstrakte Klasse. Die Idee ist die grundlegenden Aspekte des Algorithmus zu kapseln, und platzieren Sie die Logik im jeweiligen Szenario in einer abgeleiteten Klasse. Ein Szenario definiert drei Teile des Algorithmus: wie der Übergang zwischen Zuständen (Richtlinie) auftritt. welche Zustände sind absorbing und haben eine anfängliche Belohnung; und die Zustände der Algorithmus eine Belohnung mit einem Rabatt zugewiesen. Für jeden dieser Teile besitzt die QState-Klasse eine Methode, bei denen Sie diese Semantik für ein bestimmtes Szenario lösen implementiert. Diese Methoden sind GetTransitions, GetReward und GetRewardingQStates.

Die Frage: Wie können Sie ein Spiel Tic als Sequenz von Zuständen und Übergängen modellieren?

Betrachten Sie das Spiel in den Abbildung 8, in dem jede Zelle eine Nummer zugewiesen wurde. Sie können jede Reihe als einen Übergang von einem Zustand in einen anderen vorstellen in denen der Übergang der Zelle Wert, in dem der Spieler wiedergeben stammt. Jeder Status-Token ist eine Kombination aus der vorherigen deaktiviert (Zellen) und den Übergang-Wert. Im Beispiel Abbildung 8, ein Übergang von 1 bis 14, und klicken Sie dann 142 usw., modelliert die Schritte des Spiels, in dem der Spieler, der die erste wiedergegeben Wins aktivieren. Und in diesem Fall alle Zustände, die zu 14273 (die gewinnende und auslasten Status) zugeordnet sein eine Belohnung: 1 und 142.

Tic-Szenario
Abbildung 8: die Tic-Szenario

Zurückgehen, Q-Learning, was muss ich bereitstellen, sind alle (absorbing) Endzustände, jeweils mit einer anfänglichen belohnen. Drei Typen der Zustände ergibt für Tic, eine Belohnung: ein Gewinn, eine Verbindung oder eines Blocks (Verweis auf einen Punkt, wenn Ihr Gegner gerade gewonnen haben, damit Sie gezwungen sind, an der Reihe zu verwenden, um ihn zu blockieren). Ein Gewinn und einem gleichwertigen Objekt sind absorbing, d. h. das Spiel beendet. ein Block ist jedoch nicht, und das Spiel wird fortgesetzt. Abbildung 9 zeigt die Implementierung der GetReward-Methode für das Spiel Tic.

Abbildung 9: die GetReward-Methode

internal override IReward GetReward(int? previousStateToken, int transitionValue)
{
  var game = new TicTacToeGame(previousStateToken,transitionValue);
  IReward rwd = null;
  if (game.IsBlock)
  {
    rwd = new TicTacToeReward() { Discount = .5, Value = 95, IsAbsorbent = false,
      StateToken = game.StateToken};
  }
  if (game.IsWin)
  {
    rwd = new TicTacToeReward() { Discount = .9, Value = 100, IsAbsorbent = true,
      StateToken = game.StateToken };
  }
  if (game.IsTie)
  {
    rwd = new TicTacToeReward() { Discount = .9, Value = 50, IsAbsorbent = true,
      StateToken = game.StateToken };
  }
  return rwd;
}

Als Nächstes muss ich nach ein Zustand mit einem Belohnung identifiziert wird, den Algorithmus mit den Zuständen bereitstellen, die mit einer anfänglichen Belohnung in den Zustand geführt hat, damit eine reduzierte Belohnung zugewiesen werden kann. Win oder Block Szenarien sind dies alle vorherigen Status der Spieler gewinnen oder blockierenden (Wiedergabe). Auf Verbindungen müssen alle Zustände (Wiedergabe) der beiden Spieler eine Belohnung zugewiesen werden:

internal override IEnumerable<IPastState> GetRewardingQStates(int stateToken)
{
  var game = new TicTacToeGame(stateToken);
  if (game.IsTie)           
    return game.GetAllStateSequence();           
  return game.GetLastPlayersStateSequence();
}

Schließlich muss eine übergangsrichtlinie zu implementieren, die bestimmt, wie der Algorithmus die Zustände durchlaufen. Für das Spiel werde ich eine übergangsrichtlinie implementieren, in denen alle mögliche Kombinationen genauer untersucht werden:

internal override IEnumerable<int> GetTransitions(int stateToken)
{
  var game = new TicTacToeGame(stateToken);
  return game.GetPossiblePlays();
}

Wiedergabe für den Computer

An diesem Punkt kann ich veröffentlichen Sie die Projektmappe und starten die Schulung durch Aufrufen von REST-API und die anfängliche Übergänge bereitstellen: 1 bis 9.

Einmal die Schulung abgeschlossen ist, die API können Sie eine Anwendung erstellen, die einfach eine Status-Token zu übergeben und den vorgeschlagenen Wert empfangen kann. Der Quellcode für diesen Artikel enthält eine universelle Windows-Plattform-app, die Back-End verwendet. Abbildung 10 zeigt das Spiel.

Ein Tic-Spiel
Abbildung 10: Spiel Tic

Nachbereitung

Mithilfe von Q-Learning und Service Fabric konnte ich eine End-to-End-Framework zu erstellen, die eine Plattform für verteilte berechnen und Beibehalten von Daten nutzt. Um dies zu veranschaulichen, habe ich das Spiel Tic ein Back-End erstellen, lernt im Spiel, und wird in einem akzeptablen Umfang nur, der angibt, tritt ein Gewinn, einem gleichwertigen Objekt oder einen Block aus, und lassen Sie den Computer des Spiels erfahren Sie.


Jesus Aguilarist leitender cloudarchitekt bei Microsoft im Technical Evangelism and Development Team, wo er arbeitet mit fantastische Unternehmen, die in der Cloud geboren sind und die, Bereitstellung überzeugender Erfahrungen zu skalieren. Er ist Software Engineering und Lösungsentwurf Herzen und fängt Sie seine Aufmerksamkeit mit Begriffen wie "Vorhersageanalysen" "Skalierbarkeit", "Parallelität", "Design Patterns" und "< Wählen einer der Buchstaben > aaS." Sie können ihm auf Twitter folgen: @giventocode und überprüfen Sie seinen Blog unter giventocode.com.

Dank den folgenden technischen Experten von Microsoft für die Überprüfung dieses Artikels: Rob Bagby, Mike Lanzetta und Matthew Snider
Er ist ein leitender Cloud Architect für Microsoft. In dieser Rolle funktioniert Rob mit einflussreichen ISVs, sodass ihre Software in Azure zu implementieren. Vor dieser Position gearbeitet Rob als Berater erstellen lose gekoppelt, verwaltbare und skalierbare Systeme.

Mike Lanzetta ist Entwickler im Partner Catalyst-Team bei Microsoft mit Schwerpunkt auf Machine Learning, Big Data und Systeme programmieren. Er verfügt über eine von MS in CSE von der University of Washington und ist seit über 20 Jahren in Unternehmen von Startups bis hin zu Amazon und Microsoft in der Branche.

Matt Snider wechselte in 2008 an einen kleinen Teil des .NET arbeiten. Nach der Auslieferung von .NET 4 er verknüpft das Service Fabric-Team als die ersten technischen PM, zu allen anderen Bereichen arbeiten und dann mit dem Team seit. Heutzutage funktioniert er in erster Linie auf der Cluster-Ressourcen-Manager (Orchestrator), der zuverlässigen Auflistungen und die Failover-Replikation Teile des Stapels. Wenn Sie nicht in verteilten Systemen arbeiten, genießt er Bier, wandern und Musik.