| 169 | * [numExamplesPerClass * 10, 28, 28, 1]. |
| 170 | */ |
| 171 | export function sampleFromMnistData(numExamplesPerClass) { |
| 172 | tf.util.assert( |
| 173 | numExamplesPerClass <= mnistNumExamples / 10, |
| 174 | `Requested too many examples per class ` + |
| 175 | `(${numExamplesPerClass} > ${mnistNumExamples / 10})`); |
| 176 | |
| 177 | tf.util.shuffle(mnistIndices); |
| 178 | const indicesByClass = []; |
| 179 | for (let i = 0; i < NUM_CLASSES; ++i) { |
| 180 | indicesByClass.push([]); |
| 181 | } |
| 182 | |
| 183 | for (let i = 0; i < mnistIndices.length; ++i) { |
| 184 | if (indicesByClass[mnistLabels[mnistIndices[i]]].length >= |
| 185 | numExamplesPerClass) { |
| 186 | continue; |
| 187 | } |
| 188 | indicesByClass[mnistLabels[mnistIndices[i]]].push(mnistIndices[i]); |
| 189 | |
| 190 | let minLength = Infinity; |
| 191 | indicesByClass.forEach(indicesArray => { |
| 192 | if (indicesArray.length < minLength) { |
| 193 | minLength = indicesArray.length; |
| 194 | } |
| 195 | }); |
| 196 | if (minLength >= numExamplesPerClass) { |
| 197 | break; |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | return tf.tidy(() => { |
| 202 | let rowsToCombine = []; |
| 203 | indicesByClass.forEach(classIndices => { |
| 204 | const classImages = tf.gather(mnistImages, classIndices); |
| 205 | const rowOfExamples = tf.concat(classImages.unstack(), 0); |
| 206 | rowsToCombine.push(rowOfExamples); |
| 207 | }); |
| 208 | return tf.concat(rowsToCombine, 1); |
| 209 | }); |
| 210 | } |