* Train a `tf.Model` to recognize Iris flower type. * * @param trainDataset A tf.Dataset object yielding features and targets. The * features must be of shape [numTrainExamples, 4], while the targets must be * [numTrainExamples, 3]. The four feature dimensions include the * petal_length,
(trainDataset, validationDataset)
| 38 | * @returns The trained `tf.Model` instance. |
| 39 | */ |
| 40 | async function trainModel(trainDataset, validationDataset) { |
| 41 | ui.status('Training model... Please wait.'); |
| 42 | |
| 43 | const params = ui.loadTrainParametersFromUI(); |
| 44 | |
| 45 | // Define the topology of the model: two dense layers. |
| 46 | const model = tf.sequential(); |
| 47 | model.add(tf.layers.dense({ |
| 48 | units: 10, |
| 49 | activation: 'sigmoid', |
| 50 | inputShape: [data.IRIS_NUM_FEATURES] |
| 51 | })); |
| 52 | model.add(tf.layers.dense({units: 3, activation: 'softmax'})); |
| 53 | model.summary(); |
| 54 | |
| 55 | const optimizer = tf.train.adam(params.learningRate); |
| 56 | model.compile({ |
| 57 | optimizer: optimizer, |
| 58 | loss: 'categoricalCrossentropy', |
| 59 | metrics: ['accuracy'], |
| 60 | }); |
| 61 | |
| 62 | const trainLogs = []; |
| 63 | const lossContainer = document.getElementById('lossCanvas'); |
| 64 | const accContainer = document.getElementById('accuracyCanvas'); |
| 65 | const beginMs = performance.now(); |
| 66 | // Call `model.fit` to train the model. |
| 67 | await model.fitDataset(trainDataset, { |
| 68 | epochs: params.epochs, |
| 69 | validationData: validationDataset, |
| 70 | callbacks: { |
| 71 | onEpochEnd: async (epoch, logs) => { |
| 72 | // Plot the loss and accuracy values at the end of every training epoch. |
| 73 | const secPerEpoch = |
| 74 | (performance.now() - beginMs) / (1000 * (epoch + 1)); |
| 75 | ui.status( |
| 76 | `Training model... Approximately ` + |
| 77 | `${secPerEpoch.toFixed(4)} seconds per epoch`); |
| 78 | trainLogs.push(logs); |
| 79 | tfvis.show.history(lossContainer, trainLogs, ['loss', 'val_loss']) |
| 80 | tfvis.show.history(accContainer, trainLogs, ['acc', 'val_acc']) |
| 81 | const [{xs: xTest, ys: yTest}] = await validationDataset.toArray(); |
| 82 | calculateAndDrawConfusionMatrix(model, xTest, yTest); |
| 83 | }, |
| 84 | } |
| 85 | }); |
| 86 | |
| 87 | const secPerEpoch = (performance.now() - beginMs) / (1000 * params.epochs); |
| 88 | ui.status( |
| 89 | `Model training complete: ${secPerEpoch.toFixed(4)} seconds per epoch`); |
| 90 | return model; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Run inference on manually-input Iris flower data. |
no test coverage detected