()
| 107 | } |
| 108 | |
| 109 | async function run() { |
| 110 | const args = parseArguments(); |
| 111 | if (args.gpu) { |
| 112 | // Use GPU bindings. |
| 113 | require('@tensorflow/tfjs-node-gpu'); |
| 114 | } else { |
| 115 | // Use CPU bindings. |
| 116 | require('@tensorflow/tfjs-node'); |
| 117 | } |
| 118 | |
| 119 | console.log('Loading model...'); |
| 120 | if (args.modelJsonUrl.indexOf('http://') === -1 && |
| 121 | args.modelJsonUrl.indexOf('https://') === -1 && |
| 122 | args.modelJsonUrl.indexOf('file://') === -1) { |
| 123 | args.modelJsonUrl = `file://${args.modelJsonUrl}`; |
| 124 | } |
| 125 | const model = await tf.loadLayersModel(args.modelJsonUrl); |
| 126 | console.log('Model loading complete.'); |
| 127 | |
| 128 | if (!fs.existsSync(args.outputDir)) { |
| 129 | shelljs.mkdir('-p', args.outputDir); |
| 130 | } |
| 131 | |
| 132 | if (args.inputImage != null && args.inputImage !== '') { |
| 133 | // Compute the internal activations of the conv layers' outputs. |
| 134 | const imageHeight = model.inputs[0].shape[1]; |
| 135 | const imageWidth = model.inputs[0].shape[2]; |
| 136 | const x = await utils.readImageTensorFromFile( |
| 137 | args.inputImage, imageHeight, imageWidth); |
| 138 | const layerNames = args.convLayerNames.split(','); |
| 139 | const {modelOutput, layerName2FilePaths, layerName2ImageDims} = |
| 140 | await filters.writeInternalActivationAndGetOutput( |
| 141 | model, layerNames, x, args.filters, args.outputDir); |
| 142 | |
| 143 | // Calculate internal activations and final output of the model. |
| 144 | const topNum = 10; |
| 145 | const {values: topKVals, indices: topKIndices} = |
| 146 | tf.topk(modelOutput, topNum); |
| 147 | const probScores = Array.from(await topKVals.data()); |
| 148 | const indices = Array.from(await topKIndices.data()); |
| 149 | const classNames = |
| 150 | indices.map(index => imagenetClasses.IMAGENET_CLASSES[index]); |
| 151 | |
| 152 | console.log(`Top-${topNum} classes:`); |
| 153 | for (let i = 0; i < topNum; ++i) { |
| 154 | console.log( |
| 155 | ` ${classNames[i]} (index=${indices[i]}): ` + |
| 156 | `${probScores[i].toFixed(4)}`); |
| 157 | } |
| 158 | |
| 159 | // Save the original input image and the top-10 classification results. |
| 160 | const origImagePath = |
| 161 | path.join(args.outputDir, path.basename(args.inputImage)); |
| 162 | shelljs.cp(args.inputImage, origImagePath); |
| 163 | |
| 164 | // Calculate Grad-CAM heatmap. |
| 165 | const xWithCAMOverlay = cam.gradClassActivationMap(model, indices[0], x); |
| 166 | const camImagePath = path.join(args.outputDir, 'cam.png'); |
no test coverage detected