-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
index.html
303 lines (278 loc) · 10.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<!--
@license
Copyright 2019 Google LLC. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=============================================================================
-->
<html>
<head>
<link rel="stylesheet" href="../shared/tfjs-examples.css" />
<style>
#train {
margin-top: 10px;
}
label {
display: inline-block;
width: 250px;
padding: 6px 0 6px 0;
}
.canvases {
display: inline-block;
}
.status {
border: none;
font-size: 20px;
text-align: center;
resize: none;
}
.query {
font-size: 20px;
text-align: left;
resize: none;
}
.textarea {
font-size: 20px;
text-align: center;
resize: none;
}
.textoutput {
font-size: 20px;
text-align: left;
resize: none;
}
.container {
width: 80%;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.divTable {
display: table;
width: 100%;
}
.divTableRow {
display: table-row;
}
.divTableHeading {
background-color: #EEE;
display: table-header-group;
}
.divTableCell,
.divTableHead {
border: 1px solid #999999;
display: table-cell;
padding: 3px 10px;
}
.divTableCellKey {
border: 1px solid #999999;
display: table-cell;
padding: 3px 10px;
font-weight: bold;
}
.divTableHeading {
background-color: #EEE;
display: table-header-group;
font-weight: bold;
}
.divTableFoot {
background-color: #EEE;
display: table-footer-group;
font-weight: bold;
}
.divTableBody {
display: table-row-group;
}
</style>
</head>
<body>
<div class="container">
<section class='title-area'>
<h3>TensorFlow.js: tfjs-data</h3>
Building a tf.data.Dataset from a generator function.
</section>
</div>
<p class='section-head'>How to use this demo.</p>
This demo is meant to illustrate how to train a model using a tf.data.Dataset
constructed from a generator using <pre>tf.data.generator()</pre>.
In this case, we will predict the likelihood of
winning a game. The game itself is described below, and implemented in game.
js.The game exports a function we will use as a "generator" function to
create a dataset. We will then fit a model to this dataset using
<pre>model.fitDataset()</pre>, with the goal of predicting
the "win" state from features calculated from Player 1's hand. The output
logit value will be larger for hands which the model considers more likely
to win.
<p class='section-head'>How to use this app.</p>
<ol>
<li> Familiarize yourself with the rules of the game below.</li>
<li> Simulate the game by pressing the <i>simulate-game</i> button.</li>
<li> Select how many cards each player gets using the drop-down menu.</li>
<li> See how games are generated, wins are calculated, and notice that the
simulation count increases.</li>
<li> Familiarize yourself with the tensor-valued features calculated from
player 1's hand.</li>
<li> See what batches of data looks like by clicking dataset-to-array.</li>
<li> Before training a model, select a batchSize, the number of
batchesPerEpoch, and how many epochs to train on.</li>
<li> When you are ready, train a model on the generated features by
clicking <i>'train-model-using-fit-dataset'</i>.</li>
<li> Once the model is trained, make predictions by entering values
for the user's hand, and clicking predict.</li>
</ol>
<div class="divTable">
<div class="divTableRow">
<!-- Left hand pane -->
<div class="divTableCell" style='width:50%'>
<p></p>
<p class='section-head'>Game Simulation</p>
Click "Simulate Game" to run one play of the game. Three numbers will be
randomly selected for each player. The "win" status will indicate
whether player one's 'win' status according to the following rules..
<p></p>
Rules:
<ul>
<li>The player with the largest group of same-valued cards wins. E.g.,
if player 1 has three-of-a-kind, and player 2 only has a pair,
player 1 wins.</li>
<li>If both players have the same sized maximal group, then the player
with the group with the largest face
value wins. E.g., A pair of 5s beats a pair of 4s.</li>
<li>If neither player even has a pair, the player with the highest
single card wins.</li>
<li>Ties are settled randomly, 50/50.</li>
</ul>
Number of cards per hand
<select id='select-cards-per-hand'>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<p></p>
<button id='simulate-game'>simulate-game</button>
<h3>Simulation Results (Simulations so far =
<div style=display:inline id=num-simulations-so-far>0</div>)
</h3>
<p></p>
<div class='divTable'>
<div class='divTableRow' id='sim-features-row'>
<div id='player1Cell' , class='divTableCell' style='width:40%'>
<b>player 1</b>
<div class='divTable'>
<div class='divTableRow' id='player1-row'>
</div>
</div>
</div>
<div id='player2Cell' , class='divTableCell' style='width:40%'>
<b>opponent</b>
<div class='divTable'>
<div class='divTableRow' id='player2-row'>
</div>
</div>
</div>
<div class='divTableCell' style='width:10%'><b>win?</b>
<div class='divTable'>
<div class='divTableRow' id='result-row'>
</div>
</div>
</div>
</div>
</div>
<p></p>
<div class='divTable'>
<div class='divTableRow'>
<div class='divTableCell' style='width:100%'>
<b>Game to features and label.</b> Note that the features fed into
the model only include values visible to player
1, since we want to predict whether player 1 will win.
<p></p>
</div>
</div>
</div>
<div class='divTable'>
<div class='divTableRow'>
<div class='divTableCell' style='width:20%'><b>Features:</b> </div>
<div class='divTableCell' style='width:80%' id='sim-features'>
Click "sample" to run
</div>
</div>
<div class='divTableRow'>
<div class='divTableCell' style='width:20%'><b>Label:</b> </div>
<div class='divTableCell' style='width:80%' id='sim-label'></div>
</div>
</div>
<div id="generated-sample-data-message"></div>
<p class='section-head'>Data Pipeline</p>
<h4>tf.dataFromGenerator(simulation↑)</h4>
<h4>.map(gameToFeaturesAndLabel)</h4>
<h4>.batch(
<input type="number" id="generator-batch" value="100">)</h4>
<h4>.take(
<input type="number" id="generator-take" value="5">)</h4>
<h4>.toArray()
<button id="dataset-to-array">dataset-to-array</button>
</h4>
<p></p>
<div class="container" id="to-array-container">
</div>
</div>
<!-- Right hand pane -->
<div class="divTableCell" style='width:50%'>
<p class='section-head'>Train & Evaluate Model</p>
<div id="train-model-message"></div>
<h4>batchesPerEpoch
<input type="number" id="batches-per-epoch" value="50">
<h4>Epochs to train
<input type="number" id="epochs-to-train" value="50">
</h4>
Expected simulations = batchSize * batchesPerEpoch * epochs =
<div id='expected-simulations' style='display:inline'></div>
<button id="train-model-using-fit-dataset">
train-model-using-fit-dataset
</button>
<button id="stop-training" disabled="true">stop-training</button>
<section>
<p class='section-head'>Training Progress</p>
<p id="training-status"></p>
<p id="training-message"></p>
<div id="training-stats">
<div class="canvases">
<label id="training-loss-label"></label>
<div id="training-loss-canvas"></div>
</div>
<div class="canvases">
<label id="training-accuracy-label"></label>
<div id="training-accuracy-canvas"></div>
</div>
</div>
Note that since each player has an equal chance of winning, we
expect that a completely naive estimator will have an accuracy of
0.5. An estimator with perfect accuracy is not possible, since the
estimator does not have access to the opponent player's hand.
</section>
<section>
<p class='section-head'>Use Trained Model</p>
<div id='prediction-input'></div>
<button id="predict" disabled="true">predict</button>
Output of model:
<div class="container" id="prediction" style='display:inline'> </div>
<p></p>
Note that this prediction is larger for hands that the model
considers more likely to win, but are not calibrated probabilities.
</section>
</div>
</div>
</div>
<script type="module" src="./index.js"></script>
</body>
</html>