()
| 66 | } |
| 67 | |
| 68 | async function main() { |
| 69 | const args = parseArgs(); |
| 70 | if (args.gpu) { |
| 71 | tf = require('@tensorflow/tfjs-node-gpu'); |
| 72 | } else { |
| 73 | tf = require('@tensorflow/tfjs-node'); |
| 74 | } |
| 75 | |
| 76 | let dataset; |
| 77 | let model; |
| 78 | if (args.dataset === 'fashion-mnist') { |
| 79 | dataset = new FashionMnistDataset(); |
| 80 | model = createFashionMnistModel(); |
| 81 | } else if (args.dataset === 'mnist') { |
| 82 | dataset = new MnistDataset(); |
| 83 | model = createMnistModel(); |
| 84 | } else { |
| 85 | throw new Error(`Unrecognized dataset name: ${args.dataset}`); |
| 86 | } |
| 87 | await dataset.loadData(); |
| 88 | const {images: trainImages, labels: trainLabels} = dataset.getTrainData(); |
| 89 | |
| 90 | model.summary(); |
| 91 | |
| 92 | await model.fit(trainImages, trainLabels, { |
| 93 | epochs: args.epochs, |
| 94 | batchSize: args.batchSize, |
| 95 | validationSplit: args.validationSplit, |
| 96 | callbacks: tf.callbacks.earlyStopping({patience: 20}) |
| 97 | }); |
| 98 | |
| 99 | const {images: testImages, labels: testLabels} = dataset.getTestData(); |
| 100 | const evalOutput = model.evaluate(testImages, testLabels); |
| 101 | |
| 102 | console.log( |
| 103 | `\nEvaluation result:\n` + |
| 104 | ` Loss = ${evalOutput[0].dataSync()[0].toFixed(6)}; `+ |
| 105 | `Accuracy = ${evalOutput[1].dataSync()[0].toFixed(6)}`); |
| 106 | |
| 107 | const modelSavePath = path.join(args.modelSavePath, args.dataset, 'original'); |
| 108 | if (modelSavePath != null) { |
| 109 | if (!fs.existsSync(path.dirname(modelSavePath))) { |
| 110 | shelljs.mkdir('-p', path.dirname(modelSavePath)); |
| 111 | } |
| 112 | await model.save(`file://${modelSavePath}`); |
| 113 | console.log(`Saved model to path: ${modelSavePath}`); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | if (require.main === module) { |
| 118 | main(); |
no test coverage detected