├── .gitignore ├── project ├── 2 归一化 │ ├── index.html │ └── script.js ├── 6 过拟合 │ ├── index.html │ ├── data.js │ └── script.js ├── 0 准备 │ ├── index2.html │ ├── script.js │ ├── node.js │ └── index.html ├── 1 线性回归 │ ├── index.html │ └── script.js ├── 10 加载已有模型-商标识别 │ ├── index.html │ ├── utils.js │ └── script.js ├── 8 预训练模型-图片分类 │ ├── index.html │ ├── script.js │ └── imagenet_classes.js ├── 9 迁移学习-商标识别 │ ├── index.html │ ├── utils.js │ ├── data.js │ └── script.js ├── 11 预训练模型-语音识别 │ ├── index.html │ └── script.js ├── 3 逻辑回归 │ ├── index.html │ ├── data.js │ └── script.js ├── 4 XOR │ ├── index.html │ ├── data.js │ └── script.js ├── 7 手写数字识别 │ ├── index.html │ ├── script.js │ └── data.js ├── 5 多分类 │ ├── index.html │ ├── script.js │ └── data.js ├── 12 迁移学习-声控数据采集 │ ├── index.html │ └── script.js ├── 13 加载已有数据-声控轮播图 │ ├── index.html │ └── script.js └── 14 python与js模型互转 │ └── note.md ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .cache 4 | data -------------------------------------------------------------------------------- /project/2 归一化/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/6 过拟合/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/0 准备/index2.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/1 线性回归/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /project/0 准备/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from "@tensorflow/tfjs" 2 | 3 | const a = tf.tensor('1') 4 | a.print() -------------------------------------------------------------------------------- /project/0 准备/node.js: -------------------------------------------------------------------------------- 1 | const tf = require("@tensorflow/tfjs-node") 2 | 3 | const a = tf.tensor([1, 2]) 4 | a.print() -------------------------------------------------------------------------------- /project/10 加载已有模型-商标识别/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
-------------------------------------------------------------------------------- /project/8 预训练模型-图片分类/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

-------------------------------------------------------------------------------- /project/9 迁移学习-商标识别/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

-------------------------------------------------------------------------------- /project/11 预训练模型-语音识别/index.html: -------------------------------------------------------------------------------- 1 | 2 | 8 |
-------------------------------------------------------------------------------- /project/3 逻辑回归/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | x: 4 | y: 5 | 6 |
-------------------------------------------------------------------------------- /project/4 XOR/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | x: 4 | y: 5 | 6 |
-------------------------------------------------------------------------------- /project/7 手写数字识别/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

-------------------------------------------------------------------------------- /project/5 多分类/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 花萼长度:
4 | 花萼宽度:
5 | 花瓣长度:
6 | 花瓣宽度:
7 | 8 |
-------------------------------------------------------------------------------- /project/12 迁移学习-声控数据采集/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 | 
8 | 

监听开关: 9 | -------------------------------------------------------------------------------- /project/0 准备/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | tensorflow 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "@tensorflow-models/speech-commands": "^0.4.2", 8 | "@tensorflow/tfjs-node": "^1.6.0", 9 | "@tensorflow/tfjs-vis": "^1.4.0" 10 | }, 11 | "devDependencies": {}, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "ISC", 17 | "browserslist": [ 18 | "last 1 Chrome version" 19 | ] 20 | } -------------------------------------------------------------------------------- /project/10 加载已有模型-商标识别/utils.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | 3 | export function img2x(imgEl) { 4 | return tf.tidy(() => { 5 | const input = tf.browser.fromPixels(imgEl) 6 | .toFloat() 7 | .sub(255 / 2) 8 | .div(255 / 2) 9 | .reshape([1, 224, 224, 3]); 10 | return input; 11 | }); 12 | } 13 | 14 | export function file2img(f) { 15 | return new Promise(resolve => { 16 | const reader = new FileReader(); 17 | reader.readAsDataURL(f); 18 | reader.onload = (e) => { 19 | const img = document.createElement('img'); 20 | img.src = e.target.result; 21 | img.width = 224; 22 | img.height = 224; 23 | img.onload = () => resolve(img); 24 | }; 25 | }); 26 | } -------------------------------------------------------------------------------- /project/9 迁移学习-商标识别/utils.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | 3 | export function img2x(imgEl) { 4 | return tf.tidy(() => { 5 | const input = tf.browser.fromPixels(imgEl) 6 | .toFloat() 7 | .sub(255 / 2) 8 | .div(255 / 2) 9 | .reshape([1, 224, 224, 3]); 10 | return input; 11 | }); 12 | } 13 | 14 | export function file2image(file) { 15 | return new Promise(resolve => { 16 | const reader = new FileReader(); 17 | reader.readAsDataURL(f); 18 | reader.onload = (e) => { 19 | const img = document.createElement('img'); 20 | img.src = e.target.result; 21 | img.width = 224; 22 | img.height = 224; 23 | img.onload = () => resolve(img); 24 | }; 25 | }) 26 | } -------------------------------------------------------------------------------- /project/4 XOR/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {*} numSamples 随机生成点的数量 3 | */ 4 | export function getData(numSamples) { 5 | let points = []; 6 | 7 | function genGauss(cx, cy, label) { 8 | for (let i = 0; i < numSamples / 2; i++) { 9 | let x = normalRandom(cx); 10 | let y = normalRandom(cy); 11 | points.push({ 12 | x, 13 | y, 14 | label 15 | }); 16 | } 17 | } 18 | 19 | // 这里产生四类点 20 | genGauss(2, 2, 0); 21 | genGauss(-2, -2, 0); 22 | genGauss(-2, 2, 1); 23 | genGauss(2, -2, 1); 24 | return points; 25 | } 26 | 27 | /** 28 | * @description 生成正态分布随机点 29 | * @param mean 均值 30 | * @param variance 方差,值越大点分布越分散,值越小点分布越密集 31 | */ 32 | function normalRandom(mean = 0, variance = 1) { 33 | let v1, v2, s; 34 | do { 35 | v1 = 2 * Math.random() - 1; 36 | v2 = 2 * Math.random() - 1; 37 | s = v1 * v1 + v2 * v2; 38 | } while (s > 1); 39 | 40 | let result = Math.sqrt(-2 * Math.log(s) / s) * v1; 41 | return mean + Math.sqrt(variance) * result; 42 | } -------------------------------------------------------------------------------- /project/3 逻辑回归/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 二分类数据集生成函数源码 3 | * @param {*} numSamples 随机生成点的数量 4 | */ 5 | export function getData(numSamples) { 6 | let points = []; 7 | 8 | function genGauss(cx, cy, label) { 9 | for (let i = 0; i < numSamples / 2; i++) { 10 | let x = normalRandom(cx); 11 | let y = normalRandom(cy); 12 | points.push({ 13 | x, 14 | y, 15 | label 16 | }); 17 | } 18 | } 19 | 20 | genGauss(2, 2, 1); //生成以(2,2)为中心,label为1的点 21 | genGauss(-2, -2, 0); //生成以(-2,-2)为中心,label为0的点 22 | return points; 23 | } 24 | 25 | /** 26 | * @description 生成正态分布随机点 27 | * @param mean 均值 28 | * @param variance 方差,值越大点分布越分散,值越小点分布越密集 29 | */ 30 | function normalRandom(mean = 0, variance = 1) { 31 | let v1, v2, s; 32 | do { 33 | v1 = 2 * Math.random() - 1; 34 | v2 = 2 * Math.random() - 1; 35 | s = v1 * v1 + v2 * v2; 36 | } while (s > 1); 37 | 38 | let result = Math.sqrt(-2 * Math.log(s) / s) * v1; 39 | return mean + Math.sqrt(variance) * result; 40 | } -------------------------------------------------------------------------------- /project/6 过拟合/data.js: -------------------------------------------------------------------------------- 1 | export function getData(numSamples, variance) { 2 | let points = []; 3 | 4 | function genGauss(cx, cy, label) { 5 | for (let i = 0; i < numSamples / 2; i++) { 6 | let x = normalRandom(cx, variance); 7 | let y = normalRandom(cy, variance); 8 | points.push({ x, y, label }); 9 | } 10 | } 11 | 12 | genGauss(2, 2, 1); 13 | genGauss(-2, -2, 0); 14 | return points; 15 | } 16 | 17 | /** 18 | * Samples from a normal distribution. Uses the seedrandom library as the 19 | * random generator. 20 | * 21 | * @param mean The mean. Default is 0. 22 | * @param variance The variance. Default is 1. 23 | */ 24 | function normalRandom(mean = 0, variance = 1) { 25 | let v1, v2, s; 26 | do { 27 | v1 = 2 * Math.random() - 1; 28 | v2 = 2 * Math.random() - 1; 29 | s = v1 * v1 + v2 * v2; 30 | } while (s > 1); 31 | 32 | let result = Math.sqrt(-2 * Math.log(s) / s) * v1; 33 | return mean + Math.sqrt(variance) * result; 34 | } -------------------------------------------------------------------------------- /project/1 线性回归/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | 4 | window.onload = async () => { 5 | // x、y样本数据集 6 | const xs = [1, 2, 3, 4]; 7 | const ys = [1, 3, 5, 7]; 8 | 9 | // 使用 @tensorflow/tfjs-vis 库绘制散点图 10 | tfvis.render.scatterplot( 11 | { name: '线性回归训练集' }, 12 | { values: xs.map((x, i) => ({ x, y: ys[i] })) }, 13 | { xAxisDomain: [0, 5], yAxisDomain: [0, 8] } 14 | ); 15 | 16 | // 定义模型。添加含有1个神经元的1层网络 17 | const model = tf.sequential(); 18 | model.add(tf.layers.dense({ units: 1, inputShape: [1] })); 19 | model.compile({ loss: tf.losses.meanSquaredError, optimizer: tf.train.sgd(0.1) }); 20 | 21 | const inputs = tf.tensor(xs); 22 | const labels = tf.tensor(ys); 23 | 24 | // 训练模型 25 | await model.fit(inputs, labels, { 26 | batchSize: 4, 27 | epochs: 200, 28 | callbacks: tfvis.show.fitCallbacks( 29 | { name: '训练过程' }, 30 | ['loss'] 31 | ) 32 | }); 33 | 34 | // 预测 35 | const output = model.predict(tf.tensor([5])); 36 | console.log(`如果 x 为 5,那么预测 y 为 ${output.dataSync()[0]}`); 37 | }; -------------------------------------------------------------------------------- /project/13 加载已有数据-声控轮播图/index.html: -------------------------------------------------------------------------------- 1 | 2 | 监听开关: 3 | 4 | 16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
-------------------------------------------------------------------------------- /project/9 迁移学习-商标识别/data.js: -------------------------------------------------------------------------------- 1 | import { 2 | promises 3 | } from "dns"; 4 | 5 | const IMAGE_SIZE = 224; 6 | 7 | const loadImg = src => { 8 | return new Promise(resolve => { 9 | const img = new Image() 10 | img.crossOrigin = 'anonymous' 11 | img.src = src 12 | img.width = IMAGE_SIZE; 13 | img.height = IMAGE_SIZE; 14 | img.onload = () => resolve(img) 15 | }) 16 | } 17 | 18 | // 输入数据格式 19 | export const getInputs = async() => { 20 | const imgList = [], 21 | labelList = [] 22 | for (let i = 0; i < 30; i++) { 23 | ['android', 'apple', 'windows'].forEach(label => { 24 | const src = `http://127.0.0.1:8081/brand/train/${label}-${i}.jpg`; 25 | const img = loadImg(src) 26 | imgList.push(img) 27 | labelList.push([ 28 | label === 'android' ? 1 : 0, 29 | label === 'apple' ? 1 : 0, 30 | label === 'windows' ? 1 : 0, 31 | ]) 32 | }) 33 | } 34 | const inputs = await Promise.all(imgList) 35 | return { 36 | inputs, 37 | labelList 38 | } 39 | } -------------------------------------------------------------------------------- /project/11 预训练模型-语音识别/script.js: -------------------------------------------------------------------------------- 1 | import * as speechCommands from '@tensorflow-models/speech-commands'; 2 | const MODEL_PATH = 'http://127.0.0.1:8081/speech'; 3 | 4 | window.onload = async() => { 5 | const recognizer = speechCommands.create( 6 | 'BROWSER_FFT', //傅里叶变换 7 | null, 8 | MODEL_PATH + '/model.json', 9 | MODEL_PATH + '/metadata.json' 10 | ) 11 | await recognizer.ensureModelLoaded() 12 | 13 | 14 | const labels = recognizer.wordLabels().slice(2) 15 | const resultEl = document.querySelector('#result') 16 | resultEl.innerHTML = labels.map(l => ` 17 |
${l}
18 | `).join(''); 19 | 20 | // 语音识别 21 | recognizer.listen(resilt => { 22 | const { 23 | scores 24 | } = result; 25 | const maxValue = Math.max(...scores); 26 | const index = scores.indexOf(maxValue) - 2; 27 | resultEl.innerHTML = labels.map((l, i) => ` 28 |
${l}
29 | `).join(''); 30 | }, { 31 | overlapFactor: 0.3, //控制频率,值越大,识别的次数越多 32 | probabilityThreshold: 0.9 //准确度 33 | }) 34 | } -------------------------------------------------------------------------------- /project/10 加载已有模型-商标识别/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import { 3 | img2x, 4 | file2img 5 | } from './utils'; 6 | 7 | const MODEL_PATH = 'http://127.0.0.1:8081'; 8 | const BRAND_CLASSES = ['android', 'apple', 'windows']; 9 | 10 | window.onload = async() => { 11 | const mobilenet = await tf.loadLayersModel(MODEL_PATH + '/mobilenet/web_model/model.json'); 12 | mobilenet.summary(); 13 | const layer = mobilenet.getLayer('conv_pw_13_relu'); 14 | const truncatedMobilenet = tf.model({ 15 | inputs: mobilenet.inputs, 16 | outputs: layer.output 17 | }); 18 | 19 | const model = await tf.loadLayersModel(MODEL_PATH + '/brand/web_model/model.json'); 20 | 21 | window.predict = async(file) => { 22 | const img = await file2img(file); 23 | document.body.appendChild(img); 24 | const pred = tf.tidy(() => { 25 | const x = img2x(img); 26 | const input = truncatedMobilenet.predict(x); 27 | return model.predict(input); 28 | }); 29 | 30 | const index = pred.argMax(1).dataSync()[0]; 31 | setTimeout(() => { 32 | alert(`预测结果:${BRAND_CLASSES[index]}`); 33 | }, 0); 34 | }; 35 | }; -------------------------------------------------------------------------------- /project/2 归一化/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | 4 | window.onload = async () => { 5 | // 样本数据 6 | const heights = [150, 160, 170]; 7 | const weights = [40, 50, 60]; 8 | 9 | // 绘制散点图 10 | tfvis.render.scatterplot({ 11 | name: '身高体重训练数据' 12 | }, { 13 | values: heights.map((x, i) => ({ 14 | x, 15 | y: weights[i] 16 | })) 17 | }, { 18 | xAxisDomain: [140, 180], 19 | yAxisDomain: [30, 70] 20 | }); 21 | 22 | // 归一化数据 23 | const inputs = tf.tensor(heights).sub(150).div(20); //压缩到0-1 24 | const labels = tf.tensor(weights).sub(40).div(20); //压缩到0-1 25 | 26 | // 构建模型 27 | const model = tf.sequential(); 28 | model.add(tf.layers.dense({ 29 | units: 1, 30 | inputShape: [1] 31 | })); 32 | model.compile({ 33 | loss: tf.losses.meanSquaredError, 34 | optimizer: tf.train.sgd(0.1) 35 | }); 36 | 37 | // 训练模型 38 | await model.fit(inputs, labels, { 39 | batchSize: 3, 40 | epochs: 200, 41 | callbacks: tfvis.show.fitCallbacks({ 42 | name: '训练过程' 43 | }, ['loss']) 44 | }); 45 | 46 | // 预测 反归一化 47 | const output = model.predict(tf.tensor([180]).sub(150).div(20)); 48 | console.log(`如果身高为 180cm,那么预测体重为 ${output.mul(20).add(40).dataSync()[0]}kg`); 49 | }; -------------------------------------------------------------------------------- /project/4 XOR/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { getData } from './data.js'; 4 | 5 | // 不能使用线性逻辑回归 6 | window.onload = async () => { 7 | const data = getData(400); 8 | 9 | tfvis.render.scatterplot({ 10 | name: 'XOR 训练数据' 11 | }, { 12 | values: [ 13 | data.filter(p => p.label === 1), 14 | data.filter(p => p.label === 0), 15 | ] 16 | }); 17 | 18 | // 构建多层神经网络 19 | const model = tf.sequential(); 20 | model.add(tf.layers.dense({ 21 | units: 4, 22 | inputShape: [2], 23 | activation: 'relu' 24 | })); 25 | model.add(tf.layers.dense({ 26 | units: 1, 27 | activation: 'sigmoid' 28 | })); 29 | model.compile({ 30 | loss: tf.losses.logLoss, 31 | optimizer: tf.train.adam(0.1) 32 | }); 33 | 34 | const inputs = tf.tensor(data.map(p => [p.x, p.y])); 35 | const labels = tf.tensor(data.map(p => p.label)); 36 | 37 | await model.fit(inputs, labels, { 38 | epochs: 10, 39 | callbacks: tfvis.show.fitCallbacks({ 40 | name: '训练效果' 41 | }, ['loss']) 42 | }); 43 | 44 | window.predict = (form) => { 45 | const pred = model.predict(tf.tensor([ 46 | [form.x.value * 1, form.y.value * 1] 47 | ])); 48 | console.log(`预测结果:${pred.dataSync()[0]}`); 49 | }; 50 | }; -------------------------------------------------------------------------------- /project/3 逻辑回归/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { getData } from './data.js'; 4 | 5 | window.onload = async () => { 6 | // 拿到400个数据 7 | const data = getData(400); 8 | 9 | // 绘制散点图 10 | tfvis.render.scatterplot({ 11 | name: '逻辑回归训练数据' 12 | }, { 13 | values: [ 14 | data.filter(p => p.label === 1), 15 | data.filter(p => p.label === 0), 16 | ] 17 | }); 18 | 19 | // 构建模型,主要这里是逻辑回归,使用的损失函数为对数损失 logLoss,可参考http://wiki.fast.ai/index.php/Log_Loss 20 | const model = tf.sequential(); 21 | model.add(tf.layers.dense({ 22 | units: 1, 23 | inputShape: [2], //特征数量 24 | activation: 'sigmoid' 25 | })); 26 | model.compile({ 27 | loss: tf.losses.logLoss, //对数损失,逻辑回归不适合使用MSE 28 | optimizer: tf.train.adam(0.1) //adam优化器,可以自动调节学习率 29 | }); 30 | 31 | const inputs = tf.tensor(data.map(p => [p.x, p.y])); 32 | const labels = tf.tensor(data.map(p => p.label)); 33 | 34 | // 训练模型 35 | await model.fit(inputs, labels, { 36 | batchSize: 40, 37 | epochs: 20, 38 | callbacks: tfvis.show.fitCallbacks({ 39 | name: '训练效果' 40 | }, ['loss']) 41 | }); 42 | 43 | // 编写界面输入预测值 44 | window.predict = (form) => { 45 | const pred = model.predict(tf.tensor([ 46 | [form.x.value * 1, form.y.value * 1] 47 | ])); 48 | console.log(`预测结果:${pred.dataSync()[0]}`); 49 | }; 50 | }; -------------------------------------------------------------------------------- /project/8 预训练模型-图片分类/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import { 3 | IMAGENET_CLASSES 4 | } from './imagenet_classes'; 5 | 6 | const MOBILENET_MODEL_PATH = 'http://127.0.0.1:8081/mobilenet/web_model/model.json'; 7 | 8 | // file变为img标签 9 | function file2img(file) { 10 | return new Promise(resolve => { 11 | const reader = new FileReader() 12 | reader.readAsDataURL(file) 13 | reader.onload = e => { 14 | const img = document.createElement('img'); 15 | img.src = e.target.result; 16 | img.width = 224; 17 | img.height = 224; 18 | img.onload = () => resolve(img); 19 | } 20 | }) 21 | } 22 | 23 | window.onload = async() => { 24 | const model = await tf.loadLayersModel(MOBILENET_MODEL_PATH); 25 | window.predict = async(file) => { 26 | const img = await file2img(file); 27 | document.body.appendChild(img); 28 | const pred = tf.tidy(() => { 29 | const input = tf.browser.fromPixels(img) 30 | .toFloat() 31 | .sub(255 / 2) 32 | .div(255 / 2) //转换到[-1,1] 33 | .reshape([1, 224, 224, 3]); //彩色图片 34 | return model.predict(input); 35 | }) 36 | const index = pred.argMax(1).dataSync()[0] //index的值 37 | document.getElementById('output').innerHTML = `预测结果:${IMAGENET_CLASSES[index]}` 38 | } 39 | } -------------------------------------------------------------------------------- /project/6 过拟合/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { 4 | getData 5 | } from './data'; 6 | 7 | window.onload = async() => { 8 | const data = getData(200, 2); 9 | 10 | tfvis.render.scatterplot({ 11 | name: '训练数据' 12 | }, { 13 | values: [ 14 | data.filter(p => p.label === 1), 15 | data.filter(p => p.label === 0), 16 | ] 17 | }); 18 | 19 | // 解决overfit 20 | // 1、早停 21 | // 2、正则化 22 | // 3、随机丢弃 23 | const model = tf.sequential(); 24 | model.add(tf.layers.dense({ 25 | units: 10, 26 | inputShape: [2], 27 | activation: "tanh", 28 | // kernelRegularizer: tf.regularizers.l2({ l2: 1 }) 29 | })); 30 | model.add(tf.layers.dropout({ 31 | rate: 0.9 32 | })); 33 | model.add(tf.layers.dense({ 34 | units: 1, 35 | activation: 'sigmoid' 36 | })); 37 | model.compile({ 38 | loss: tf.losses.logLoss, 39 | optimizer: tf.train.adam(0.1) 40 | }); 41 | 42 | const inputs = tf.tensor(data.map(p => [p.x, p.y])); 43 | const labels = tf.tensor(data.map(p => p.label)); 44 | 45 | await model.fit(inputs, labels, { 46 | validationSplit: 0.2, 47 | epochs: 200, 48 | callbacks: tfvis.show.fitCallbacks({ 49 | name: '训练效果' 50 | }, ['loss', 'val_loss'], { 51 | callbacks: ['onEpochEnd'] 52 | }) 53 | }); 54 | }; -------------------------------------------------------------------------------- /project/5 多分类/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { getIrisData, IRIS_CLASSES } from './data'; 4 | 5 | window.onload = async () => { 6 | // 加载数据集和验证集 7 | const [xTrain, yTrain, xTest, yTest] = getIrisData(0.15); //15%的数据用于验证集 8 | 9 | // 构建模型,这里用到的损失函数为交叉熵损失 categoricalCrossentropy,适用于多分类 10 | const model = tf.sequential(); 11 | model.add(tf.layers.dense({ 12 | units: 10, 13 | inputShape: [xTrain.shape[1]], 14 | activation: 'sigmoid' //也可以使用其他激活函数,如relu 15 | })); 16 | model.add(tf.layers.dense({ 17 | units: 3, 18 | activation: 'softmax' //这里使用softmax激活函数,算出每个类别的概率 19 | })); 20 | model.compile({ 21 | loss: 'categoricalCrossentropy', //交叉熵损失,对数损失函数的多分类版本 22 | optimizer: tf.train.adam(0.1), 23 | metrics: ['accuracy'] 24 | }); 25 | 26 | // 训练模型 27 | await model.fit(xTrain, yTrain, { 28 | epochs: 100, 29 | validationData: [xTest, yTest], 30 | callbacks: tfvis.show.fitCallbacks({ 31 | name: '训练效果' 32 | }, ['loss', 'val_loss', 'acc', 'val_acc'], { 33 | callbacks: ['onEpochEnd'] 34 | }) 35 | }); 36 | 37 | window.predict = (form) => { 38 | const input = tf.tensor([ 39 | [ 40 | form.a.value * 1, 41 | form.b.value * 1, 42 | form.c.value * 1, 43 | form.d.value * 1, 44 | ] 45 | ]); 46 | const pred = model.predict(input); 47 | console.log(`预测结果:${IRIS_CLASSES[pred.argMax(1).dataSync(0)]}`); //argmax? 48 | }; 49 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Tensorflow.js Converter 依赖**python3.6.8**版本 2 | 3 | **搭建虚拟环境:** 4 | 1. 安装conda 5 | 可以使用[清华镜像源](https://mirror.tuna.tsinghua.edu.cn/help/anaconda/),安装Miniconda 即可(注意配置环境变量) 6 | 2. 在终端检查conda命令是否可用,并创建指定python版本的虚拟环境 7 | `conda create -n [name] python=3.6.8` 创建虚拟环境 8 | `conda remove -n [name] --all` 删除虚拟环境 9 | `conda info --envs` 查看虚拟环境 10 | `conda activate [name]` 激活虚拟环境(可以发现python版本已经改变) 11 | `conda deactivate [name]` 退出虚拟环境 12 | 3. 安装tfjs converter 13 | `pip install tensorflowjs`安装 14 | `tensorflowjs_converter -h`检查是否安装成功 15 | 16 | 17 | **python与JavaScript模型的互转:** 18 | 1. 准备工作 19 | `conda activate [name]`激活 20 | `tensorflowjs_converter`检查 21 | 2. 开始转换——具体格式建议看文档(github tfjs-converter) 22 | 1)python模型转js模型 23 | `tensorflowjs_converter --input_format=keras --output_format=tf_layers_model [input_path] [output_path]` 24 | 2)js模型转python模型 25 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=keras [input_path] [output_path]` 26 | 3. 验证模型正确性 27 | 28 | **模型加速:** 29 | 1. 分片(--weight_shared_size_bytes=[size]) 30 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_layers_model --weight_shared_size_bytes=100000 [input_path] [output_path]` 31 | 在输出文件夹中会发现很多块分片后的模型,这样在加载模型时可以使用并发实现加速 32 | 2. 量化(--quantization_bytes=[n]) 33 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_layers_model --quantization_bytes=2 [input_path] [output_path]` 34 | 3. 通过转为tfjs_graph_model来加速模型——内部实现了凸优化(--output_format=tf_graph_model) 35 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_graph_model [input_path] [output_path]` 36 | 37 | **拓展学习:** 38 | 1. 举一反三,训练不同应用场景的AI模型 39 | 2. 多看官方文档 40 | 3. 使用更多的预训练模型,如目标检测、NLP、人体姿势识别 41 | 4. 做更多智能相关的开源项目或商业项目,增加技术影响力 -------------------------------------------------------------------------------- /project/14 python与js模型互转/note.md: -------------------------------------------------------------------------------- 1 | Tensorflow.js Converter 依赖**python3.6.8**版本 2 | 3 | **搭建虚拟环境:** 4 | 1. 安装conda 5 | 可以使用[清华镜像源](https://mirror.tuna.tsinghua.edu.cn/help/anaconda/),安装Miniconda 即可(注意配置环境变量) 6 | 2. 在终端检查conda命令是否可用,并创建指定python版本的虚拟环境 7 | `conda create -n [name] python=3.6.8` 创建虚拟环境 8 | `conda remove -n [name] --all` 删除虚拟环境 9 | `conda info --envs` 查看虚拟环境 10 | `conda activate [name]` 激活虚拟环境(可以发现python版本已经改变) 11 | `conda deactivate [name]` 退出虚拟环境 12 | 3. 安装tfjs converter 13 | `pip install tensorflowjs`安装 14 | `tensorflowjs_converter -h`检查是否安装成功 15 | 16 | 17 | **python与JavaScript模型的互转:** 18 | 1. 准备工作 19 | `conda activate [name]`激活 20 | `tensorflowjs_converter`检查 21 | 2. 开始转换——具体格式建议看文档(github tfjs-converter) 22 | 1)python模型转js模型 23 | `tensorflowjs_converter --input_format=keras --output_format=tf_layers_model [input_path] [output_path]` 24 | 2)js模型转python模型 25 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=keras [input_path] [output_path]` 26 | 3. 验证模型正确性 27 | 28 | **模型加速:** 29 | 1. 分片(--weight_shared_size_bytes=[size]) 30 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_layers_model --weight_shared_size_bytes=100000 [input_path] [output_path]` 31 | 在输出文件夹中会发现很多块分片后的模型,这样在加载模型时可以使用并发实现加速 32 | 2. 量化(--quantization_bytes=[n]) 33 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_layers_model --quantization_bytes=2 [input_path] [output_path]` 34 | 3. 通过转为tfjs_graph_model来加速模型——内部实现了凸优化(--output_format=tf_graph_model) 35 | `tensorflowjs_converter --input_format=tf_layers_model --output_format=tf_graph_model [input_path] [output_path]` 36 | 37 | **拓展学习:** 38 | 1. 举一反三,训练不同应用场景的AI模型 39 | 2. 多看官方文档 40 | 3. 使用更多的预训练模型,如目标检测、NLP、人体姿势识别 41 | 4. 做更多智能相关的开源项目或商业项目,增加技术影响力 -------------------------------------------------------------------------------- /project/13 加载已有数据-声控轮播图/script.js: -------------------------------------------------------------------------------- 1 | import * as speechCommands from '@tensorflow-models/speech-commands'; 2 | 3 | const MODEL_PATH = 'http://127.0.0.1:8081'; 4 | let transferRecognizer; 5 | 6 | window.onload = async() => { 7 | const recognizer = speechCommands.create( 8 | 'BROWSER_FFT', 9 | null, 10 | MODEL_PATH + '/speech/model.json', 11 | MODEL_PATH + '/speech/metadata.json', 12 | ); 13 | await recognizer.ensureModelLoaded(); 14 | transferRecognizer = recognizer.createTransfer('轮播图'); 15 | 16 | // 在这里加载已保存的声音数据 17 | const res = await fetch(MODEL_PATH + '/slider/data.bin'); 18 | const arrayBuffer = await res.arrayBuffer(); 19 | transferRecognizer.loadExamples(arrayBuffer); 20 | await transferRecognizer.train({ 21 | epochs: 30 22 | }); 23 | console.log('done'); 24 | }; 25 | 26 | window.toggle = async(checked) => { 27 | if (checked) { 28 | await transferRecognizer.listen(result => { 29 | const { 30 | scores 31 | } = result; 32 | const labels = transferRecognizer.wordLabels(); 33 | const index = scores.indexOf(Math.max(...scores)); 34 | console.log(labels[index]); //“上一张”/“下一张” 35 | window.play(labels[index]); //变换轮播图 36 | }, { 37 | overlapFactor: 0, 38 | probabilityThreshold: 0.5 39 | }); 40 | } else { 41 | transferRecognizer.stopListening(); 42 | } 43 | }; 44 | 45 | let curIndex = 0; 46 | const sliderCount = document.querySelectorAll('img').length 47 | window.play = label => { 48 | const div = document.querySelector('.slider>div'); 49 | if (label === '上一张') { 50 | if (curIndex === 0) { 51 | return; 52 | } 53 | curIndex -= 1; 54 | } else { 55 | if (curIndex === sliderCount - 1) { 56 | return; 57 | } 58 | curIndex += 1; 59 | } 60 | div.style.transition = "transform 1s" 61 | div.style.transform = `translateX(-${100 * curIndex}%)`; 62 | } -------------------------------------------------------------------------------- /project/12 迁移学习-声控数据采集/script.js: -------------------------------------------------------------------------------- 1 | import * as speechCommands from '@tensorflow-models/speech-commands'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | 4 | const MODEL_PATH = 'http://127.0.0.1:8081'; 5 | let transferRecognizer; //定义迁移学习器(迁移学习语音识别器) 6 | 7 | window.onload = async() => { 8 | const recognizer = speechCommands.create( 9 | 'BROWSER_FFT', 10 | null, 11 | MODEL_PATH + '/speech/model.json', 12 | MODEL_PATH + '/speech/metadata.json' 13 | ); 14 | await recognizer.ensureModelLoaded(); 15 | transferRecognizer = recognizer.createTransfer('轮播图'); 16 | } 17 | 18 | // 收集声音 19 | window.collect = async(btn) => { 20 | btn.disabled = true; 21 | const label = btn.innerText; 22 | await transferRecognizer.collectExample(label === '背景噪音' ? '_background_noise_' : label) 23 | btn.disabled = false; 24 | document.querySelector('$count').innerHTML = JSON.stringify(transferRecognizer.countExamples(), null, 2); 25 | } 26 | 27 | // 训练模型 28 | window.train = async() => { 29 | await transferRecognizer.train({ 30 | epochs: 30, 31 | callback: tfvis.show.fitCallbacks({ 32 | name: '训练效果' 33 | }, ['loss', 'acc'], { 34 | callbacks: ['onEpochEnd'] 35 | }) 36 | }); 37 | } 38 | 39 | window.toggle = async(checked) => { 40 | if (checked) { 41 | await transferRecognizer.listen(result => { 42 | const { 43 | scores 44 | } = result; 45 | const labels = transferRecognizer.wordLabels(); 46 | const index = scores.indexOf(Math.max(...scores)); 47 | console.log(labels[index]); 48 | }, { 49 | overlapFactor: 0, //值越大识别越频繁 50 | probabilityThreshold: 0.75 //准确度 51 | }) 52 | } else { 53 | transferRecognizer.stopListening(); 54 | } 55 | } 56 | 57 | // 存储采集到的语音数据,避免每次都要录入 58 | window.save = () => { 59 | const arrayBuffer = transferRecognizer.serializeExamples() 60 | const blob = new Blob([arrayBuffer]) 61 | const link = document.createElement('a') 62 | link.href = window.URL.createObjectURL(blob) 63 | link.download = 'data.bin' //定义下载名称 64 | link.click() 65 | } -------------------------------------------------------------------------------- /project/9 迁移学习-商标识别/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { 4 | getInputs 5 | } from './data'; 6 | import { 7 | img2x, 8 | file2img 9 | } from './utils'; 10 | 11 | const MOBILENET_MODEL_PATH = 'http://127.0.0.1:8081/mobilenet/web_model/model.json'; 12 | const NUM_CLASSES = 3; 13 | const BRAND_CLASSES = ['android', 'apple', 'windows']; 14 | 15 | window.onload = async() => { 16 | const { 17 | inputs, 18 | labels 19 | } = await getInputs(); 20 | 21 | // 可视化商标 22 | const surface = tfvis.visor().surface({ 23 | name: '输入示例', 24 | styles: { 25 | height: 250 26 | } 27 | }); 28 | inputs.forEach(img => { 29 | surface.drawArea.appendChild(img); 30 | }); 31 | 32 | // 加载mobilenet模型 33 | const mobilenet = await tf.loadLayersModel(MOBILENET_MODEL_PATH) 34 | mobilenet.summary(); //查看模型概况 35 | // 开始截断模型 36 | const layer = mobilenet.getLayer('conv_pw_13_relu'); 37 | const truncatedMobilenet = tf.model({ 38 | inputs: mobilenet.inputs, 39 | outputs: layer.output 40 | }) 41 | 42 | // 添加网络 43 | const model = tf.sequential() 44 | model.add(tf.layers.flatten({ 45 | inputShape: layer.outputShape.slice(1) //[null,7,7,256] 46 | })); 47 | model.add(tf.layers.dense({ 48 | units: 10, 49 | activation: 'relu' 50 | })); 51 | model.add(tf.layers.dense({ 52 | units: NUM_CLASSES, 53 | activation: 'softmax' 54 | })); 55 | model.compile({ 56 | loss: 'categoricalCrossentropy', 57 | optimizer: tf.train.adam() 58 | }) 59 | 60 | // 将训练数据输入到截断模型中 61 | const { 62 | xs, 63 | ys 64 | } = tf.tidy(() => { 65 | const xs = tf.concat(inputs.map(imgEl => truncatedMobilenet.predict(img2x(imgEl)))) //xs为truncatedMobilenet网络吐出的数据 66 | const ys = tf.tensor(labels) 67 | return { 68 | xs, 69 | ys 70 | } 71 | }) 72 | await model.fit(xs, ys, { 73 | epochs: 20, 74 | callbacks: tfvis.show.fitCallbacks({ 75 | name: '训练效果' 76 | }, ['loss'], { 77 | callbacks: ['onEpochEnd'] 78 | }) 79 | }); 80 | 81 | // 预测 82 | window.predict = async(file) => { 83 | const img = await file2img(file); 84 | document.body.appendChild(img); 85 | const pred = tf.tidy(() => { 86 | const x = img2x(img); 87 | const input = truncatedMobilenet.predict(x); 88 | return model.predict(input); 89 | }) 90 | const index = pred.argMax(1).dataSync()[0]; 91 | document.getElementById('output').innerHTML = `预测结果:${BRAND_CLASSES[index]}` 92 | } 93 | window.download = async() => { 94 | await model.save('downloads://model'); //建议看官方文档model.save 95 | }; 96 | } -------------------------------------------------------------------------------- /project/7 手写数字识别/script.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | import * as tfvis from '@tensorflow/tfjs-vis'; 3 | import { MnistData } from './data'; 4 | 5 | window.onload = async () => { 6 | const data = new MnistData(); 7 | await data.load(); 8 | const examples = data.nextTestBatch(20) 9 | const surface = tfvis.visor().surface({ 10 | name: '输入示例' 11 | }); 12 | 13 | // 展示样本中的手写数据 14 | for (let i = 0; i < 20; i++) { 15 | // 清除tensor内存,防止内存泄漏 16 | const imageTensor = tf.tidy(() => { 17 | return examples.xs 18 | .slice([i, 0], [1, 784]) //这里详细查看文档,tf.slice()方法是使用 19 | .reshape([28, 28, 1]); 20 | }) 21 | 22 | // 在浏览器中展示 23 | const canvas = document.createElement('canvas'); 24 | canvas.width = 28; 25 | canvas.height = 28; 26 | canvas.style = 'margin: 4px'; 27 | await tf.browser.toPixels(imageTensor, canvas); 28 | 29 | surface.drawArea.appendChild(canvas) 30 | } 31 | 32 | // 定义模型 33 | // 1. 卷积(5*5*8) 34 | // 2. 池化 35 | // 3. 卷积(5*5*16) 36 | // 4. 池化 37 | // 5. flatten 38 | // 6. softmax 39 | const model = tf.sequential() 40 | model.add(tf.layers.conv2d({ 41 | inputShape: [28, 28, 1], 42 | kernelSize: 5, 43 | filters: 8, 44 | strides: 1, 45 | activation: 'relu', 46 | kernelInitializer: 'varianceScaling' 47 | })) 48 | model.add(tf.layers.maxPool2d({ 49 | poolSize: [2, 2], 50 | strides: [2, 2] 51 | })) 52 | model.add(tf.layers.conv2d({ 53 | kernelSize: 5, 54 | filters: 16, 55 | strides: 1, 56 | activation: 'relu', 57 | kernelInitializer: 'varianceScaling' 58 | })) 59 | model.add(tf.layers.maxPool2d({ 60 | poolSize: [2, 2], 61 | strides: [2, 2] 62 | })) 63 | model.add(tf.layers.flatten()) 64 | model.add(tf.layers.dense({ 65 | units: 10, 66 | activation: 'softmax', 67 | kernelInitializer: 'varianceScaling' 68 | })) 69 | model.compile({ 70 | loss: 'categoricalCrossentropy', 71 | optimizer: tf.train.adam(), 72 | metrics: ['accuracy'] 73 | }) 74 | 75 | const [trainX, trainY] = tf.tidy(() => { 76 | const d = data.nextTrainBatch(1000) 77 | return [ 78 | d.xs.reshape([1000, 28, 28, 1]), 79 | d.labels 80 | ] 81 | }) 82 | const [testX, testY] = tf.tidy(() => { 83 | const d = data.nextTestBatch(200) 84 | return [ 85 | d.xs.reshape([200, 28, 28, 1]), 86 | d.labels 87 | ] 88 | }) 89 | 90 | // 训练模型 91 | await model.fit(trainX, trainY, { 92 | validationData: [testX, testY], 93 | batchSize: 500, 94 | epochs: 50, 95 | callbacks: tfvis.show.fitCallbacks({ 96 | name: '训练效果' 97 | }, ['loss', 'val_loss', 'acc', 'val_acc'], { 98 | callbacks: ['onEpochEnd'] 99 | }) 100 | }) 101 | 102 | // 画布支持绘制,监听mousemove方法 103 | const canvas = document.querySelector('canvas') 104 | canvas.addEventListener('mousemove', e => { 105 | if (e.buttons === 1) { 106 | const ctx = canvas.getContext('2d') 107 | ctx.fillStyle = 'rgb(255,255,255)'; 108 | ctx.fillRect(e.offsetX, e.offsetY, 10, 10); 109 | } 110 | }) 111 | // 清楚画布 112 | window.clear = () => { 113 | const ctx = canvas.getContext('2d'); 114 | ctx.fillStyle = 'rgb(0,0,0)'; 115 | ctx.fillRect(0, 0, 300, 300); 116 | } 117 | clear() 118 | 119 | // 预测 120 | window.predict = () => { 121 | const input = tf.tidy(() => { 122 | return tf.image.resizeBilinear( //tf.image.resizeBilinear改变图片尺寸 (300,300)->(28,28) 123 | tf.browser.fromPixels(canvas), [28, 28], //tf.browser.fromPixels是将canvas/image转化为tensor 124 | true 125 | ).slice([0, 0, 0], [28, 28, 1]) //将彩色通道转化为黑白通道,将rgb通道切掉 126 | .toFloat() 127 | .div(255) //归一化(0,1) 128 | .reshape([1, 28, 28, 1]); 129 | }); 130 | const pred = model.predict(input).argMax(1); 131 | document.getElementById('output').innerHTML = `预测结果为 ${pred.dataSync()[0]}` 132 | }; 133 | } -------------------------------------------------------------------------------- /project/7 手写数字识别/data.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | 3 | const IMAGE_SIZE = 784; 4 | const NUM_CLASSES = 10; 5 | const NUM_DATASET_ELEMENTS = 65000; 6 | const TRAIN_TEST_RATIO = 5 / 6; 7 | const NUM_TRAIN_ELEMENTS = Math.floor(TRAIN_TEST_RATIO * NUM_DATASET_ELEMENTS); 8 | const NUM_TEST_ELEMENTS = NUM_DATASET_ELEMENTS - NUM_TRAIN_ELEMENTS; 9 | const MNIST_IMAGES_SPRITE_PATH = 'http://127.0.0.1:8081/mnist/mnist_images.png'; 10 | const MNIST_LABELS_PATH = 'http://127.0.0.1:8081/mnist/mnist_labels_uint8'; 11 | export class MnistData { 12 | constructor() { 13 | this.shuffledTrainIndex = 0; 14 | this.shuffledTestIndex = 0; 15 | } 16 | 17 | async load() { 18 | const img = new Image(); 19 | const canvas = document.createElement('canvas'); 20 | const ctx = canvas.getContext('2d'); 21 | const imgRequest = new Promise((resolve, reject) => { 22 | img.crossOrigin = ''; 23 | img.onload = () => { 24 | img.width = img.naturalWidth; 25 | img.height = img.naturalHeight; 26 | 27 | const datasetBytesBuffer = 28 | new ArrayBuffer(NUM_DATASET_ELEMENTS * IMAGE_SIZE * 4); 29 | 30 | const chunkSize = 5000; 31 | canvas.width = img.width; 32 | canvas.height = chunkSize; 33 | 34 | for (let i = 0; i < NUM_DATASET_ELEMENTS / chunkSize; i++) { 35 | const datasetBytesView = new Float32Array( 36 | datasetBytesBuffer, i * IMAGE_SIZE * chunkSize * 4, 37 | IMAGE_SIZE * chunkSize); 38 | ctx.drawImage( 39 | img, 0, i * chunkSize, img.width, chunkSize, 0, 0, img.width, 40 | chunkSize); 41 | 42 | const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); 43 | for (let j = 0; j < imageData.data.length / 4; j++) { 44 | datasetBytesView[j] = imageData.data[j * 4] / 255; 45 | } 46 | } 47 | this.datasetImages = new Float32Array(datasetBytesBuffer); 48 | 49 | resolve(); 50 | }; 51 | img.src = MNIST_IMAGES_SPRITE_PATH; 52 | }); 53 | 54 | const labelsRequest = fetch(MNIST_LABELS_PATH); 55 | const [imgResponse, labelsResponse] = 56 | await Promise.all([imgRequest, labelsRequest]); 57 | 58 | this.datasetLabels = new Uint8Array(await labelsResponse.arrayBuffer()); 59 | this.trainIndices = tf.util.createShuffledIndices(NUM_TRAIN_ELEMENTS); 60 | this.testIndices = tf.util.createShuffledIndices(NUM_TEST_ELEMENTS); 61 | this.trainImages = this.datasetImages.slice(0, IMAGE_SIZE * NUM_TRAIN_ELEMENTS); 62 | this.testImages = this.datasetImages.slice(IMAGE_SIZE * NUM_TRAIN_ELEMENTS); 63 | this.trainLabels = this.datasetLabels.slice(0, NUM_CLASSES * NUM_TRAIN_ELEMENTS); 64 | this.testLabels = this.datasetLabels.slice(NUM_CLASSES * NUM_TRAIN_ELEMENTS); 65 | } 66 | 67 | nextTrainBatch(batchSize) { 68 | return this.nextBatch( 69 | batchSize, [this.trainImages, this.trainLabels], () => { 70 | this.shuffledTrainIndex = 71 | (this.shuffledTrainIndex + 1) % this.trainIndices.length; 72 | return this.trainIndices[this.shuffledTrainIndex]; 73 | }); 74 | } 75 | 76 | nextTestBatch(batchSize) { 77 | return this.nextBatch(batchSize, [this.testImages, this.testLabels], () => { 78 | this.shuffledTestIndex = 79 | (this.shuffledTestIndex + 1) % this.testIndices.length; 80 | return this.testIndices[this.shuffledTestIndex]; 81 | }); 82 | } 83 | 84 | nextBatch(batchSize, data, index) { 85 | const batchImagesArray = new Float32Array(batchSize * IMAGE_SIZE); 86 | const batchLabelsArray = new Uint8Array(batchSize * NUM_CLASSES); 87 | 88 | for (let i = 0; i < batchSize; i++) { 89 | const idx = index(); 90 | 91 | const image = 92 | data[0].slice(idx * IMAGE_SIZE, idx * IMAGE_SIZE + IMAGE_SIZE); 93 | batchImagesArray.set(image, i * IMAGE_SIZE); 94 | 95 | const label = 96 | data[1].slice(idx * NUM_CLASSES, idx * NUM_CLASSES + NUM_CLASSES); 97 | batchLabelsArray.set(label, i * NUM_CLASSES); 98 | } 99 | 100 | const xs = tf.tensor2d(batchImagesArray, [batchSize, IMAGE_SIZE]); 101 | const labels = tf.tensor2d(batchLabelsArray, [batchSize, NUM_CLASSES]); 102 | 103 | return { 104 | xs, 105 | labels 106 | }; 107 | } 108 | } -------------------------------------------------------------------------------- /project/5 多分类/data.js: -------------------------------------------------------------------------------- 1 | import * as tf from '@tensorflow/tfjs'; 2 | 3 | export const IRIS_CLASSES = ['山鸢尾', '变色鸢尾', '维吉尼亚鸢尾']; 4 | export const IRIS_NUM_CLASSES = IRIS_CLASSES.length; 5 | 6 | // 鸢尾花数据集 https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data 7 | const IRIS_DATA = [ 8 | [5.1, 3.5, 1.4, 0.2, 0], 9 | [4.9, 3.0, 1.4, 0.2, 0], 10 | [4.7, 3.2, 1.3, 0.2, 0], 11 | [4.6, 3.1, 1.5, 0.2, 0], 12 | [5.0, 3.6, 1.4, 0.2, 0], 13 | [5.4, 3.9, 1.7, 0.4, 0], 14 | [4.6, 3.4, 1.4, 0.3, 0], 15 | [5.0, 3.4, 1.5, 0.2, 0], 16 | [4.4, 2.9, 1.4, 0.2, 0], 17 | [4.9, 3.1, 1.5, 0.1, 0], 18 | [5.4, 3.7, 1.5, 0.2, 0], 19 | [4.8, 3.4, 1.6, 0.2, 0], 20 | [4.8, 3.0, 1.4, 0.1, 0], 21 | [4.3, 3.0, 1.1, 0.1, 0], 22 | [5.8, 4.0, 1.2, 0.2, 0], 23 | [5.7, 4.4, 1.5, 0.4, 0], 24 | [5.4, 3.9, 1.3, 0.4, 0], 25 | [5.1, 3.5, 1.4, 0.3, 0], 26 | [5.7, 3.8, 1.7, 0.3, 0], 27 | [5.1, 3.8, 1.5, 0.3, 0], 28 | [5.4, 3.4, 1.7, 0.2, 0], 29 | [5.1, 3.7, 1.5, 0.4, 0], 30 | [4.6, 3.6, 1.0, 0.2, 0], 31 | [5.1, 3.3, 1.7, 0.5, 0], 32 | [4.8, 3.4, 1.9, 0.2, 0], 33 | [5.0, 3.0, 1.6, 0.2, 0], 34 | [5.0, 3.4, 1.6, 0.4, 0], 35 | [5.2, 3.5, 1.5, 0.2, 0], 36 | [5.2, 3.4, 1.4, 0.2, 0], 37 | [4.7, 3.2, 1.6, 0.2, 0], 38 | [4.8, 3.1, 1.6, 0.2, 0], 39 | [5.4, 3.4, 1.5, 0.4, 0], 40 | [5.2, 4.1, 1.5, 0.1, 0], 41 | [5.5, 4.2, 1.4, 0.2, 0], 42 | [4.9, 3.1, 1.5, 0.1, 0], 43 | [5.0, 3.2, 1.2, 0.2, 0], 44 | [5.5, 3.5, 1.3, 0.2, 0], 45 | [4.9, 3.1, 1.5, 0.1, 0], 46 | [4.4, 3.0, 1.3, 0.2, 0], 47 | [5.1, 3.4, 1.5, 0.2, 0], 48 | [5.0, 3.5, 1.3, 0.3, 0], 49 | [4.5, 2.3, 1.3, 0.3, 0], 50 | [4.4, 3.2, 1.3, 0.2, 0], 51 | [5.0, 3.5, 1.6, 0.6, 0], 52 | [5.1, 3.8, 1.9, 0.4, 0], 53 | [4.8, 3.0, 1.4, 0.3, 0], 54 | [5.1, 3.8, 1.6, 0.2, 0], 55 | [4.6, 3.2, 1.4, 0.2, 0], 56 | [5.3, 3.7, 1.5, 0.2, 0], 57 | [5.0, 3.3, 1.4, 0.2, 0], 58 | [7.0, 3.2, 4.7, 1.4, 1], 59 | [6.4, 3.2, 4.5, 1.5, 1], 60 | [6.9, 3.1, 4.9, 1.5, 1], 61 | [5.5, 2.3, 4.0, 1.3, 1], 62 | [6.5, 2.8, 4.6, 1.5, 1], 63 | [5.7, 2.8, 4.5, 1.3, 1], 64 | [6.3, 3.3, 4.7, 1.6, 1], 65 | [4.9, 2.4, 3.3, 1.0, 1], 66 | [6.6, 2.9, 4.6, 1.3, 1], 67 | [5.2, 2.7, 3.9, 1.4, 1], 68 | [5.0, 2.0, 3.5, 1.0, 1], 69 | [5.9, 3.0, 4.2, 1.5, 1], 70 | [6.0, 2.2, 4.0, 1.0, 1], 71 | [6.1, 2.9, 4.7, 1.4, 1], 72 | [5.6, 2.9, 3.6, 1.3, 1], 73 | [6.7, 3.1, 4.4, 1.4, 1], 74 | [5.6, 3.0, 4.5, 1.5, 1], 75 | [5.8, 2.7, 4.1, 1.0, 1], 76 | [6.2, 2.2, 4.5, 1.5, 1], 77 | [5.6, 2.5, 3.9, 1.1, 1], 78 | [5.9, 3.2, 4.8, 1.8, 1], 79 | [6.1, 2.8, 4.0, 1.3, 1], 80 | [6.3, 2.5, 4.9, 1.5, 1], 81 | [6.1, 2.8, 4.7, 1.2, 1], 82 | [6.4, 2.9, 4.3, 1.3, 1], 83 | [6.6, 3.0, 4.4, 1.4, 1], 84 | [6.8, 2.8, 4.8, 1.4, 1], 85 | [6.7, 3.0, 5.0, 1.7, 1], 86 | [6.0, 2.9, 4.5, 1.5, 1], 87 | [5.7, 2.6, 3.5, 1.0, 1], 88 | [5.5, 2.4, 3.8, 1.1, 1], 89 | [5.5, 2.4, 3.7, 1.0, 1], 90 | [5.8, 2.7, 3.9, 1.2, 1], 91 | [6.0, 2.7, 5.1, 1.6, 1], 92 | [5.4, 3.0, 4.5, 1.5, 1], 93 | [6.0, 3.4, 4.5, 1.6, 1], 94 | [6.7, 3.1, 4.7, 1.5, 1], 95 | [6.3, 2.3, 4.4, 1.3, 1], 96 | [5.6, 3.0, 4.1, 1.3, 1], 97 | [5.5, 2.5, 4.0, 1.3, 1], 98 | [5.5, 2.6, 4.4, 1.2, 1], 99 | [6.1, 3.0, 4.6, 1.4, 1], 100 | [5.8, 2.6, 4.0, 1.2, 1], 101 | [5.0, 2.3, 3.3, 1.0, 1], 102 | [5.6, 2.7, 4.2, 1.3, 1], 103 | [5.7, 3.0, 4.2, 1.2, 1], 104 | [5.7, 2.9, 4.2, 1.3, 1], 105 | [6.2, 2.9, 4.3, 1.3, 1], 106 | [5.1, 2.5, 3.0, 1.1, 1], 107 | [5.7, 2.8, 4.1, 1.3, 1], 108 | [6.3, 3.3, 6.0, 2.5, 2], 109 | [5.8, 2.7, 5.1, 1.9, 2], 110 | [7.1, 3.0, 5.9, 2.1, 2], 111 | [6.3, 2.9, 5.6, 1.8, 2], 112 | [6.5, 3.0, 5.8, 2.2, 2], 113 | [7.6, 3.0, 6.6, 2.1, 2], 114 | [4.9, 2.5, 4.5, 1.7, 2], 115 | [7.3, 2.9, 6.3, 1.8, 2], 116 | [6.7, 2.5, 5.8, 1.8, 2], 117 | [7.2, 3.6, 6.1, 2.5, 2], 118 | [6.5, 3.2, 5.1, 2.0, 2], 119 | [6.4, 2.7, 5.3, 1.9, 2], 120 | [6.8, 3.0, 5.5, 2.1, 2], 121 | [5.7, 2.5, 5.0, 2.0, 2], 122 | [5.8, 2.8, 5.1, 2.4, 2], 123 | [6.4, 3.2, 5.3, 2.3, 2], 124 | [6.5, 3.0, 5.5, 1.8, 2], 125 | [7.7, 3.8, 6.7, 2.2, 2], 126 | [7.7, 2.6, 6.9, 2.3, 2], 127 | [6.0, 2.2, 5.0, 1.5, 2], 128 | [6.9, 3.2, 5.7, 2.3, 2], 129 | [5.6, 2.8, 4.9, 2.0, 2], 130 | [7.7, 2.8, 6.7, 2.0, 2], 131 | [6.3, 2.7, 4.9, 1.8, 2], 132 | [6.7, 3.3, 5.7, 2.1, 2], 133 | [7.2, 3.2, 6.0, 1.8, 2], 134 | [6.2, 2.8, 4.8, 1.8, 2], 135 | [6.1, 3.0, 4.9, 1.8, 2], 136 | [6.4, 2.8, 5.6, 2.1, 2], 137 | [7.2, 3.0, 5.8, 1.6, 2], 138 | [7.4, 2.8, 6.1, 1.9, 2], 139 | [7.9, 3.8, 6.4, 2.0, 2], 140 | [6.4, 2.8, 5.6, 2.2, 2], 141 | [6.3, 2.8, 5.1, 1.5, 2], 142 | [6.1, 2.6, 5.6, 1.4, 2], 143 | [7.7, 3.0, 6.1, 2.3, 2], 144 | [6.3, 3.4, 5.6, 2.4, 2], 145 | [6.4, 3.1, 5.5, 1.8, 2], 146 | [6.0, 3.0, 4.8, 1.8, 2], 147 | [6.9, 3.1, 5.4, 2.1, 2], 148 | [6.7, 3.1, 5.6, 2.4, 2], 149 | [6.9, 3.1, 5.1, 2.3, 2], 150 | [5.8, 2.7, 5.1, 1.9, 2], 151 | [6.8, 3.2, 5.9, 2.3, 2], 152 | [6.7, 3.3, 5.7, 2.5, 2], 153 | [6.7, 3.0, 5.2, 2.3, 2], 154 | [6.3, 2.5, 5.0, 1.9, 2], 155 | [6.5, 3.0, 5.2, 2.0, 2], 156 | [6.2, 3.4, 5.4, 2.3, 2], 157 | [5.9, 3.0, 5.1, 1.8, 2], 158 | ]; 159 | 160 | // 转化为tensor 161 | function convertToTensors(data, targets, testSplit) { 162 | const numExamples = data.length; 163 | if (numExamples !== targets.length) { 164 | throw new Error('data and split have different numbers of examples'); 165 | } 166 | 167 | const indices = []; 168 | for (let i = 0; i < numExamples; ++i) { 169 | indices.push(i); 170 | } 171 | tf.util.shuffle(indices); 172 | 173 | const shuffledData = []; 174 | const shuffledTargets = []; 175 | for (let i = 0; i < numExamples; ++i) { 176 | shuffledData.push(data[indices[i]]); 177 | shuffledTargets.push(targets[indices[i]]); 178 | } 179 | 180 | const numTestExamples = Math.round(numExamples * testSplit); 181 | const numTrainExamples = numExamples - numTestExamples; 182 | const xDims = shuffledData[0].length; 183 | const xs = tf.tensor2d(shuffledData, [numExamples, xDims]); 184 | const ys = tf.oneHot(tf.tensor1d(shuffledTargets).toInt(), IRIS_NUM_CLASSES); 185 | const xTrain = xs.slice([0, 0], [numTrainExamples, xDims]); 186 | const xTest = xs.slice([numTrainExamples, 0], [numTestExamples, xDims]); 187 | const yTrain = ys.slice([0, 0], [numTrainExamples, IRIS_NUM_CLASSES]); 188 | const yTest = ys.slice([0, 0], [numTestExamples, IRIS_NUM_CLASSES]); 189 | return [xTrain, yTrain, xTest, yTest]; 190 | } 191 | 192 | // 获取鸢尾花数据集(带分类) 193 | export function getIrisData(testSplit) { 194 | return tf.tidy(() => { 195 | const dataByClass = []; 196 | const targetsByClass = []; 197 | for (let i = 0; i < IRIS_CLASSES.length; ++i) { 198 | dataByClass.push([]); 199 | targetsByClass.push([]); 200 | } 201 | for (const example of IRIS_DATA) { 202 | const target = example[example.length - 1]; 203 | const data = example.slice(0, example.length - 1); 204 | dataByClass[target].push(data); 205 | targetsByClass[target].push(target); 206 | } 207 | 208 | const xTrains = []; 209 | const yTrains = []; 210 | const xTests = []; 211 | const yTests = []; 212 | for (let i = 0; i < IRIS_CLASSES.length; ++i) { 213 | const [xTrain, yTrain, xTest, yTest] = 214 | convertToTensors(dataByClass[i], targetsByClass[i], testSplit); 215 | xTrains.push(xTrain); 216 | yTrains.push(yTrain); 217 | xTests.push(xTest); 218 | yTests.push(yTest); 219 | } 220 | 221 | const concatAxis = 0; 222 | return [ 223 | tf.concat(xTrains, concatAxis), tf.concat(yTrains, concatAxis), 224 | tf.concat(xTests, concatAxis), tf.concat(yTests, concatAxis) 225 | ]; 226 | }); 227 | } -------------------------------------------------------------------------------- /project/8 预训练模型-图片分类/imagenet_classes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2017 Google LLC. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | export const IMAGENET_CLASSES = { 19 | 0: 'tench, Tinca tinca', 20 | 1: 'goldfish, Carassius auratus', 21 | 2: 'great white shark, white shark, man-eater, man-eating shark, ' + 22 | 'Carcharodon carcharias', 23 | 3: 'tiger shark, Galeocerdo cuvieri', 24 | 4: 'hammerhead, hammerhead shark', 25 | 5: 'electric ray, crampfish, numbfish, torpedo', 26 | 6: 'stingray', 27 | 7: 'cock', 28 | 8: 'hen', 29 | 9: 'ostrich, Struthio camelus', 30 | 10: 'brambling, Fringilla montifringilla', 31 | 11: 'goldfinch, Carduelis carduelis', 32 | 12: 'house finch, linnet, Carpodacus mexicanus', 33 | 13: 'junco, snowbird', 34 | 14: 'indigo bunting, indigo finch, indigo bird, Passerina cyanea', 35 | 15: 'robin, American robin, Turdus migratorius', 36 | 16: 'bulbul', 37 | 17: 'jay', 38 | 18: 'magpie', 39 | 19: 'chickadee', 40 | 20: 'water ouzel, dipper', 41 | 21: 'kite', 42 | 22: 'bald eagle, American eagle, Haliaeetus leucocephalus', 43 | 23: 'vulture', 44 | 24: 'great grey owl, great gray owl, Strix nebulosa', 45 | 25: 'European fire salamander, Salamandra salamandra', 46 | 26: 'common newt, Triturus vulgaris', 47 | 27: 'eft', 48 | 28: 'spotted salamander, Ambystoma maculatum', 49 | 29: 'axolotl, mud puppy, Ambystoma mexicanum', 50 | 30: 'bullfrog, Rana catesbeiana', 51 | 31: 'tree frog, tree-frog', 52 | 32: 'tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui', 53 | 33: 'loggerhead, loggerhead turtle, Caretta caretta', 54 | 34: 'leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea', 55 | 35: 'mud turtle', 56 | 36: 'terrapin', 57 | 37: 'box turtle, box tortoise', 58 | 38: 'banded gecko', 59 | 39: 'common iguana, iguana, Iguana iguana', 60 | 40: 'American chameleon, anole, Anolis carolinensis', 61 | 41: 'whiptail, whiptail lizard', 62 | 42: 'agama', 63 | 43: 'frilled lizard, Chlamydosaurus kingi', 64 | 44: 'alligator lizard', 65 | 45: 'Gila monster, Heloderma suspectum', 66 | 46: 'green lizard, Lacerta viridis', 67 | 47: 'African chameleon, Chamaeleo chamaeleon', 68 | 48: 'Komodo dragon, Komodo lizard, dragon lizard, giant lizard, ' + 69 | 'Varanus komodoensis', 70 | 49: 'African crocodile, Nile crocodile, Crocodylus niloticus', 71 | 50: 'American alligator, Alligator mississipiensis', 72 | 51: 'triceratops', 73 | 52: 'thunder snake, worm snake, Carphophis amoenus', 74 | 53: 'ringneck snake, ring-necked snake, ring snake', 75 | 54: 'hognose snake, puff adder, sand viper', 76 | 55: 'green snake, grass snake', 77 | 56: 'king snake, kingsnake', 78 | 57: 'garter snake, grass snake', 79 | 58: 'water snake', 80 | 59: 'vine snake', 81 | 60: 'night snake, Hypsiglena torquata', 82 | 61: 'boa constrictor, Constrictor constrictor', 83 | 62: 'rock python, rock snake, Python sebae', 84 | 63: 'Indian cobra, Naja naja', 85 | 64: 'green mamba', 86 | 65: 'sea snake', 87 | 66: 'horned viper, cerastes, sand viper, horned asp, Cerastes cornutus', 88 | 67: 'diamondback, diamondback rattlesnake, Crotalus adamanteus', 89 | 68: 'sidewinder, horned rattlesnake, Crotalus cerastes', 90 | 69: 'trilobite', 91 | 70: 'harvestman, daddy longlegs, Phalangium opilio', 92 | 71: 'scorpion', 93 | 72: 'black and gold garden spider, Argiope aurantia', 94 | 73: 'barn spider, Araneus cavaticus', 95 | 74: 'garden spider, Aranea diademata', 96 | 75: 'black widow, Latrodectus mactans', 97 | 76: 'tarantula', 98 | 77: 'wolf spider, hunting spider', 99 | 78: 'tick', 100 | 79: 'centipede', 101 | 80: 'black grouse', 102 | 81: 'ptarmigan', 103 | 82: 'ruffed grouse, partridge, Bonasa umbellus', 104 | 83: 'prairie chicken, prairie grouse, prairie fowl', 105 | 84: 'peacock', 106 | 85: 'quail', 107 | 86: 'partridge', 108 | 87: 'African grey, African gray, Psittacus erithacus', 109 | 88: 'macaw', 110 | 89: 'sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita', 111 | 90: 'lorikeet', 112 | 91: 'coucal', 113 | 92: 'bee eater', 114 | 93: 'hornbill', 115 | 94: 'hummingbird', 116 | 95: 'jacamar', 117 | 96: 'toucan', 118 | 97: 'drake', 119 | 98: 'red-breasted merganser, Mergus serrator', 120 | 99: 'goose', 121 | 100: 'black swan, Cygnus atratus', 122 | 101: 'tusker', 123 | 102: 'echidna, spiny anteater, anteater', 124 | 103: 'platypus, duckbill, duckbilled platypus, duck-billed platypus, ' + 125 | 'Ornithorhynchus anatinus', 126 | 104: 'wallaby, brush kangaroo', 127 | 105: 'koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus', 128 | 106: 'wombat', 129 | 107: 'jelly fish', 130 | 108: 'sea anemone, anemone', 131 | 109: 'brain coral', 132 | 110: 'flatworm, platyhelminth', 133 | 111: 'nematode, nematode worm, roundworm', 134 | 112: 'conch', 135 | 113: 'snail', 136 | 114: 'slug', 137 | 115: 'sea slug, nudibranch', 138 | 116: 'chiton, coat-of-mail shell, sea cradle, polyplacophore', 139 | 117: 'chambered nautilus, pearly nautilus, nautilus', 140 | 118: 'Dungeness crab, Cancer magister', 141 | 119: 'rock crab, Cancer irroratus', 142 | 120: 'fiddler crab', 143 | 121: 'king crab, Alaska crab, Alaskan king crab, Alaska king crab, ' + 144 | 'Paralithodes camtschatica', 145 | 122: 'American lobster, Northern lobster, Maine lobster, Homarus americanus', 146 | 123: 'spiny lobster, langouste, rock lobster, crawfish, crayfish, sea ' + 147 | 'crawfish', 148 | 124: 'crayfish, crawfish, crawdad, crawdaddy', 149 | 125: 'hermit crab', 150 | 126: 'isopod', 151 | 127: 'white stork, Ciconia ciconia', 152 | 128: 'black stork, Ciconia nigra', 153 | 129: 'spoonbill', 154 | 130: 'flamingo', 155 | 131: 'little blue heron, Egretta caerulea', 156 | 132: 'American egret, great white heron, Egretta albus', 157 | 133: 'bittern', 158 | 134: 'crane', 159 | 135: 'limpkin, Aramus pictus', 160 | 136: 'European gallinule, Porphyrio porphyrio', 161 | 137: 'American coot, marsh hen, mud hen, water hen, Fulica americana', 162 | 138: 'bustard', 163 | 139: 'ruddy turnstone, Arenaria interpres', 164 | 140: 'red-backed sandpiper, dunlin, Erolia alpina', 165 | 141: 'redshank, Tringa totanus', 166 | 142: 'dowitcher', 167 | 143: 'oystercatcher, oyster catcher', 168 | 144: 'pelican', 169 | 145: 'king penguin, Aptenodytes patagonica', 170 | 146: 'albatross, mollymawk', 171 | 147: 'grey whale, gray whale, devilfish, Eschrichtius gibbosus, ' + 172 | 'Eschrichtius robustus', 173 | 148: 'killer whale, killer, orca, grampus, sea wolf, Orcinus orca', 174 | 149: 'dugong, Dugong dugon', 175 | 150: 'sea lion', 176 | 151: 'Chihuahua', 177 | 152: 'Japanese spaniel', 178 | 153: 'Maltese dog, Maltese terrier, Maltese', 179 | 154: 'Pekinese, Pekingese, Peke', 180 | 155: 'Shih-Tzu', 181 | 156: 'Blenheim spaniel', 182 | 157: 'papillon', 183 | 158: 'toy terrier', 184 | 159: 'Rhodesian ridgeback', 185 | 160: 'Afghan hound, Afghan', 186 | 161: 'basset, basset hound', 187 | 162: 'beagle', 188 | 163: 'bloodhound, sleuthhound', 189 | 164: 'bluetick', 190 | 165: 'black-and-tan coonhound', 191 | 166: 'Walker hound, Walker foxhound', 192 | 167: 'English foxhound', 193 | 168: 'redbone', 194 | 169: 'borzoi, Russian wolfhound', 195 | 170: 'Irish wolfhound', 196 | 171: 'Italian greyhound', 197 | 172: 'whippet', 198 | 173: 'Ibizan hound, Ibizan Podenco', 199 | 174: 'Norwegian elkhound, elkhound', 200 | 175: 'otterhound, otter hound', 201 | 176: 'Saluki, gazelle hound', 202 | 177: 'Scottish deerhound, deerhound', 203 | 178: 'Weimaraner', 204 | 179: 'Staffordshire bullterrier, Staffordshire bull terrier', 205 | 180: 'American Staffordshire terrier, Staffordshire terrier, American pit ' + 206 | 'bull terrier, pit bull terrier', 207 | 181: 'Bedlington terrier', 208 | 182: 'Border terrier', 209 | 183: 'Kerry blue terrier', 210 | 184: 'Irish terrier', 211 | 185: 'Norfolk terrier', 212 | 186: 'Norwich terrier', 213 | 187: 'Yorkshire terrier', 214 | 188: 'wire-haired fox terrier', 215 | 189: 'Lakeland terrier', 216 | 190: 'Sealyham terrier, Sealyham', 217 | 191: 'Airedale, Airedale terrier', 218 | 192: 'cairn, cairn terrier', 219 | 193: 'Australian terrier', 220 | 194: 'Dandie Dinmont, Dandie Dinmont terrier', 221 | 195: 'Boston bull, Boston terrier', 222 | 196: 'miniature schnauzer', 223 | 197: 'giant schnauzer', 224 | 198: 'standard schnauzer', 225 | 199: 'Scotch terrier, Scottish terrier, Scottie', 226 | 200: 'Tibetan terrier, chrysanthemum dog', 227 | 201: 'silky terrier, Sydney silky', 228 | 202: 'soft-coated wheaten terrier', 229 | 203: 'West Highland white terrier', 230 | 204: 'Lhasa, Lhasa apso', 231 | 205: 'flat-coated retriever', 232 | 206: 'curly-coated retriever', 233 | 207: 'golden retriever', 234 | 208: 'Labrador retriever', 235 | 209: 'Chesapeake Bay retriever', 236 | 210: 'German short-haired pointer', 237 | 211: 'vizsla, Hungarian pointer', 238 | 212: 'English setter', 239 | 213: 'Irish setter, red setter', 240 | 214: 'Gordon setter', 241 | 215: 'Brittany spaniel', 242 | 216: 'clumber, clumber spaniel', 243 | 217: 'English springer, English springer spaniel', 244 | 218: 'Welsh springer spaniel', 245 | 219: 'cocker spaniel, English cocker spaniel, cocker', 246 | 220: 'Sussex spaniel', 247 | 221: 'Irish water spaniel', 248 | 222: 'kuvasz', 249 | 223: 'schipperke', 250 | 224: 'groenendael', 251 | 225: 'malinois', 252 | 226: 'briard', 253 | 227: 'kelpie', 254 | 228: 'komondor', 255 | 229: 'Old English sheepdog, bobtail', 256 | 230: 'Shetland sheepdog, Shetland sheep dog, Shetland', 257 | 231: 'collie', 258 | 232: 'Border collie', 259 | 233: 'Bouvier des Flandres, Bouviers des Flandres', 260 | 234: 'Rottweiler', 261 | 235: 'German shepherd, German shepherd dog, German police dog, alsatian', 262 | 236: 'Doberman, Doberman pinscher', 263 | 237: 'miniature pinscher', 264 | 238: 'Greater Swiss Mountain dog', 265 | 239: 'Bernese mountain dog', 266 | 240: 'Appenzeller', 267 | 241: 'EntleBucher', 268 | 242: 'boxer', 269 | 243: 'bull mastiff', 270 | 244: 'Tibetan mastiff', 271 | 245: 'French bulldog', 272 | 246: 'Great Dane', 273 | 247: 'Saint Bernard, St Bernard', 274 | 248: 'Eskimo dog, husky', 275 | 249: 'malamute, malemute, Alaskan malamute', 276 | 250: 'Siberian husky', 277 | 251: 'dalmatian, coach dog, carriage dog', 278 | 252: 'affenpinscher, monkey pinscher, monkey dog', 279 | 253: 'basenji', 280 | 254: 'pug, pug-dog', 281 | 255: 'Leonberg', 282 | 256: 'Newfoundland, Newfoundland dog', 283 | 257: 'Great Pyrenees', 284 | 258: 'Samoyed, Samoyede', 285 | 259: 'Pomeranian', 286 | 260: 'chow, chow chow', 287 | 261: 'keeshond', 288 | 262: 'Brabancon griffon', 289 | 263: 'Pembroke, Pembroke Welsh corgi', 290 | 264: 'Cardigan, Cardigan Welsh corgi', 291 | 265: 'toy poodle', 292 | 266: 'miniature poodle', 293 | 267: 'standard poodle', 294 | 268: 'Mexican hairless', 295 | 269: 'timber wolf, grey wolf, gray wolf, Canis lupus', 296 | 270: 'white wolf, Arctic wolf, Canis lupus tundrarum', 297 | 271: 'red wolf, maned wolf, Canis rufus, Canis niger', 298 | 272: 'coyote, prairie wolf, brush wolf, Canis latrans', 299 | 273: 'dingo, warrigal, warragal, Canis dingo', 300 | 274: 'dhole, Cuon alpinus', 301 | 275: 'African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus', 302 | 276: 'hyena, hyaena', 303 | 277: 'red fox, Vulpes vulpes', 304 | 278: 'kit fox, Vulpes macrotis', 305 | 279: 'Arctic fox, white fox, Alopex lagopus', 306 | 280: 'grey fox, gray fox, Urocyon cinereoargenteus', 307 | 281: 'tabby, tabby cat', 308 | 282: 'tiger cat', 309 | 283: 'Persian cat', 310 | 284: 'Siamese cat, Siamese', 311 | 285: 'Egyptian cat', 312 | 286: 'cougar, puma, catamount, mountain lion, painter, panther, ' + 313 | 'Felis concolor', 314 | 287: 'lynx, catamount', 315 | 288: 'leopard, Panthera pardus', 316 | 289: 'snow leopard, ounce, Panthera uncia', 317 | 290: 'jaguar, panther, Panthera onca, Felis onca', 318 | 291: 'lion, king of beasts, Panthera leo', 319 | 292: 'tiger, Panthera tigris', 320 | 293: 'cheetah, chetah, Acinonyx jubatus', 321 | 294: 'brown bear, bruin, Ursus arctos', 322 | 295: 'American black bear, black bear, Ursus americanus, Euarctos ' + 323 | 'americanus', 324 | 296: 'ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus', 325 | 297: 'sloth bear, Melursus ursinus, Ursus ursinus', 326 | 298: 'mongoose', 327 | 299: 'meerkat, mierkat', 328 | 300: 'tiger beetle', 329 | 301: 'ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle', 330 | 302: 'ground beetle, carabid beetle', 331 | 303: 'long-horned beetle, longicorn, longicorn beetle', 332 | 304: 'leaf beetle, chrysomelid', 333 | 305: 'dung beetle', 334 | 306: 'rhinoceros beetle', 335 | 307: 'weevil', 336 | 308: 'fly', 337 | 309: 'bee', 338 | 310: 'ant, emmet, pismire', 339 | 311: 'grasshopper, hopper', 340 | 312: 'cricket', 341 | 313: 'walking stick, walkingstick, stick insect', 342 | 314: 'cockroach, roach', 343 | 315: 'mantis, mantid', 344 | 316: 'cicada, cicala', 345 | 317: 'leafhopper', 346 | 318: 'lacewing, lacewing fly', 347 | 319: 'dragonfly, darning needle, devil\'s darning needle, sewing needle, ' + 348 | 'snake feeder, snake doctor, mosquito hawk, skeeter hawk', 349 | 320: 'damselfly', 350 | 321: 'admiral', 351 | 322: 'ringlet, ringlet butterfly', 352 | 323: 'monarch, monarch butterfly, milkweed butterfly, Danaus plexippus', 353 | 324: 'cabbage butterfly', 354 | 325: 'sulphur butterfly, sulfur butterfly', 355 | 326: 'lycaenid, lycaenid butterfly', 356 | 327: 'starfish, sea star', 357 | 328: 'sea urchin', 358 | 329: 'sea cucumber, holothurian', 359 | 330: 'wood rabbit, cottontail, cottontail rabbit', 360 | 331: 'hare', 361 | 332: 'Angora, Angora rabbit', 362 | 333: 'hamster', 363 | 334: 'porcupine, hedgehog', 364 | 335: 'fox squirrel, eastern fox squirrel, Sciurus niger', 365 | 336: 'marmot', 366 | 337: 'beaver', 367 | 338: 'guinea pig, Cavia cobaya', 368 | 339: 'sorrel', 369 | 340: 'zebra', 370 | 341: 'hog, pig, grunter, squealer, Sus scrofa', 371 | 342: 'wild boar, boar, Sus scrofa', 372 | 343: 'warthog', 373 | 344: 'hippopotamus, hippo, river horse, Hippopotamus amphibius', 374 | 345: 'ox', 375 | 346: 'water buffalo, water ox, Asiatic buffalo, Bubalus bubalis', 376 | 347: 'bison', 377 | 348: 'ram, tup', 378 | 349: 'bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky ' + 379 | 'Mountain sheep, Ovis canadensis', 380 | 350: 'ibex, Capra ibex', 381 | 351: 'hartebeest', 382 | 352: 'impala, Aepyceros melampus', 383 | 353: 'gazelle', 384 | 354: 'Arabian camel, dromedary, Camelus dromedarius', 385 | 355: 'llama', 386 | 356: 'weasel', 387 | 357: 'mink', 388 | 358: 'polecat, fitch, foulmart, foumart, Mustela putorius', 389 | 359: 'black-footed ferret, ferret, Mustela nigripes', 390 | 360: 'otter', 391 | 361: 'skunk, polecat, wood pussy', 392 | 362: 'badger', 393 | 363: 'armadillo', 394 | 364: 'three-toed sloth, ai, Bradypus tridactylus', 395 | 365: 'orangutan, orang, orangutang, Pongo pygmaeus', 396 | 366: 'gorilla, Gorilla gorilla', 397 | 367: 'chimpanzee, chimp, Pan troglodytes', 398 | 368: 'gibbon, Hylobates lar', 399 | 369: 'siamang, Hylobates syndactylus, Symphalangus syndactylus', 400 | 370: 'guenon, guenon monkey', 401 | 371: 'patas, hussar monkey, Erythrocebus patas', 402 | 372: 'baboon', 403 | 373: 'macaque', 404 | 374: 'langur', 405 | 375: 'colobus, colobus monkey', 406 | 376: 'proboscis monkey, Nasalis larvatus', 407 | 377: 'marmoset', 408 | 378: 'capuchin, ringtail, Cebus capucinus', 409 | 379: 'howler monkey, howler', 410 | 380: 'titi, titi monkey', 411 | 381: 'spider monkey, Ateles geoffroyi', 412 | 382: 'squirrel monkey, Saimiri sciureus', 413 | 383: 'Madagascar cat, ring-tailed lemur, Lemur catta', 414 | 384: 'indri, indris, Indri indri, Indri brevicaudatus', 415 | 385: 'Indian elephant, Elephas maximus', 416 | 386: 'African elephant, Loxodonta africana', 417 | 387: 'lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens', 418 | 388: 'giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca', 419 | 389: 'barracouta, snoek', 420 | 390: 'eel', 421 | 391: 'coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus ' + 422 | 'kisutch', 423 | 392: 'rock beauty, Holocanthus tricolor', 424 | 393: 'anemone fish', 425 | 394: 'sturgeon', 426 | 395: 'gar, garfish, garpike, billfish, Lepisosteus osseus', 427 | 396: 'lionfish', 428 | 397: 'puffer, pufferfish, blowfish, globefish', 429 | 398: 'abacus', 430 | 399: 'abaya', 431 | 400: 'academic gown, academic robe, judge\'s robe', 432 | 401: 'accordion, piano accordion, squeeze box', 433 | 402: 'acoustic guitar', 434 | 403: 'aircraft carrier, carrier, flattop, attack aircraft carrier', 435 | 404: 'airliner', 436 | 405: 'airship, dirigible', 437 | 406: 'altar', 438 | 407: 'ambulance', 439 | 408: 'amphibian, amphibious vehicle', 440 | 409: 'analog clock', 441 | 410: 'apiary, bee house', 442 | 411: 'apron', 443 | 412: 'ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, ' + 444 | 'dustbin, trash barrel, trash bin', 445 | 413: 'assault rifle, assault gun', 446 | 414: 'backpack, back pack, knapsack, packsack, rucksack, haversack', 447 | 415: 'bakery, bakeshop, bakehouse', 448 | 416: 'balance beam, beam', 449 | 417: 'balloon', 450 | 418: 'ballpoint, ballpoint pen, ballpen, Biro', 451 | 419: 'Band Aid', 452 | 420: 'banjo', 453 | 421: 'bannister, banister, balustrade, balusters, handrail', 454 | 422: 'barbell', 455 | 423: 'barber chair', 456 | 424: 'barbershop', 457 | 425: 'barn', 458 | 426: 'barometer', 459 | 427: 'barrel, cask', 460 | 428: 'barrow, garden cart, lawn cart, wheelbarrow', 461 | 429: 'baseball', 462 | 430: 'basketball', 463 | 431: 'bassinet', 464 | 432: 'bassoon', 465 | 433: 'bathing cap, swimming cap', 466 | 434: 'bath towel', 467 | 435: 'bathtub, bathing tub, bath, tub', 468 | 436: 'beach wagon, station wagon, wagon, estate car, beach waggon, station ' + 469 | 'waggon, waggon', 470 | 437: 'beacon, lighthouse, beacon light, pharos', 471 | 438: 'beaker', 472 | 439: 'bearskin, busby, shako', 473 | 440: 'beer bottle', 474 | 441: 'beer glass', 475 | 442: 'bell cote, bell cot', 476 | 443: 'bib', 477 | 444: 'bicycle-built-for-two, tandem bicycle, tandem', 478 | 445: 'bikini, two-piece', 479 | 446: 'binder, ring-binder', 480 | 447: 'binoculars, field glasses, opera glasses', 481 | 448: 'birdhouse', 482 | 449: 'boathouse', 483 | 450: 'bobsled, bobsleigh, bob', 484 | 451: 'bolo tie, bolo, bola tie, bola', 485 | 452: 'bonnet, poke bonnet', 486 | 453: 'bookcase', 487 | 454: 'bookshop, bookstore, bookstall', 488 | 455: 'bottlecap', 489 | 456: 'bow', 490 | 457: 'bow tie, bow-tie, bowtie', 491 | 458: 'brass, memorial tablet, plaque', 492 | 459: 'brassiere, bra, bandeau', 493 | 460: 'breakwater, groin, groyne, mole, bulwark, seawall, jetty', 494 | 461: 'breastplate, aegis, egis', 495 | 462: 'broom', 496 | 463: 'bucket, pail', 497 | 464: 'buckle', 498 | 465: 'bulletproof vest', 499 | 466: 'bullet train, bullet', 500 | 467: 'butcher shop, meat market', 501 | 468: 'cab, hack, taxi, taxicab', 502 | 469: 'caldron, cauldron', 503 | 470: 'candle, taper, wax light', 504 | 471: 'cannon', 505 | 472: 'canoe', 506 | 473: 'can opener, tin opener', 507 | 474: 'cardigan', 508 | 475: 'car mirror', 509 | 476: 'carousel, carrousel, merry-go-round, roundabout, whirligig', 510 | 477: 'carpenter\'s kit, tool kit', 511 | 478: 'carton', 512 | 479: 'car wheel', 513 | 480: 'cash machine, cash dispenser, automated teller machine, automatic ' + 514 | 'teller machine, automated teller, automatic teller, ATM', 515 | 481: 'cassette', 516 | 482: 'cassette player', 517 | 483: 'castle', 518 | 484: 'catamaran', 519 | 485: 'CD player', 520 | 486: 'cello, violoncello', 521 | 487: 'cellular telephone, cellular phone, cellphone, cell, mobile phone', 522 | 488: 'chain', 523 | 489: 'chainlink fence', 524 | 490: 'chain mail, ring mail, mail, chain armor, chain armour, ring armor, ' + 525 | 'ring armour', 526 | 491: 'chain saw, chainsaw', 527 | 492: 'chest', 528 | 493: 'chiffonier, commode', 529 | 494: 'chime, bell, gong', 530 | 495: 'china cabinet, china closet', 531 | 496: 'Christmas stocking', 532 | 497: 'church, church building', 533 | 498: 'cinema, movie theater, movie theatre, movie house, picture palace', 534 | 499: 'cleaver, meat cleaver, chopper', 535 | 500: 'cliff dwelling', 536 | 501: 'cloak', 537 | 502: 'clog, geta, patten, sabot', 538 | 503: 'cocktail shaker', 539 | 504: 'coffee mug', 540 | 505: 'coffeepot', 541 | 506: 'coil, spiral, volute, whorl, helix', 542 | 507: 'combination lock', 543 | 508: 'computer keyboard, keypad', 544 | 509: 'confectionery, confectionary, candy store', 545 | 510: 'container ship, containership, container vessel', 546 | 511: 'convertible', 547 | 512: 'corkscrew, bottle screw', 548 | 513: 'cornet, horn, trumpet, trump', 549 | 514: 'cowboy boot', 550 | 515: 'cowboy hat, ten-gallon hat', 551 | 516: 'cradle', 552 | 517: 'crane', 553 | 518: 'crash helmet', 554 | 519: 'crate', 555 | 520: 'crib, cot', 556 | 521: 'Crock Pot', 557 | 522: 'croquet ball', 558 | 523: 'crutch', 559 | 524: 'cuirass', 560 | 525: 'dam, dike, dyke', 561 | 526: 'desk', 562 | 527: 'desktop computer', 563 | 528: 'dial telephone, dial phone', 564 | 529: 'diaper, nappy, napkin', 565 | 530: 'digital clock', 566 | 531: 'digital watch', 567 | 532: 'dining table, board', 568 | 533: 'dishrag, dishcloth', 569 | 534: 'dishwasher, dish washer, dishwashing machine', 570 | 535: 'disk brake, disc brake', 571 | 536: 'dock, dockage, docking facility', 572 | 537: 'dogsled, dog sled, dog sleigh', 573 | 538: 'dome', 574 | 539: 'doormat, welcome mat', 575 | 540: 'drilling platform, offshore rig', 576 | 541: 'drum, membranophone, tympan', 577 | 542: 'drumstick', 578 | 543: 'dumbbell', 579 | 544: 'Dutch oven', 580 | 545: 'electric fan, blower', 581 | 546: 'electric guitar', 582 | 547: 'electric locomotive', 583 | 548: 'entertainment center', 584 | 549: 'envelope', 585 | 550: 'espresso maker', 586 | 551: 'face powder', 587 | 552: 'feather boa, boa', 588 | 553: 'file, file cabinet, filing cabinet', 589 | 554: 'fireboat', 590 | 555: 'fire engine, fire truck', 591 | 556: 'fire screen, fireguard', 592 | 557: 'flagpole, flagstaff', 593 | 558: 'flute, transverse flute', 594 | 559: 'folding chair', 595 | 560: 'football helmet', 596 | 561: 'forklift', 597 | 562: 'fountain', 598 | 563: 'fountain pen', 599 | 564: 'four-poster', 600 | 565: 'freight car', 601 | 566: 'French horn, horn', 602 | 567: 'frying pan, frypan, skillet', 603 | 568: 'fur coat', 604 | 569: 'garbage truck, dustcart', 605 | 570: 'gasmask, respirator, gas helmet', 606 | 571: 'gas pump, gasoline pump, petrol pump, island dispenser', 607 | 572: 'goblet', 608 | 573: 'go-kart', 609 | 574: 'golf ball', 610 | 575: 'golfcart, golf cart', 611 | 576: 'gondola', 612 | 577: 'gong, tam-tam', 613 | 578: 'gown', 614 | 579: 'grand piano, grand', 615 | 580: 'greenhouse, nursery, glasshouse', 616 | 581: 'grille, radiator grille', 617 | 582: 'grocery store, grocery, food market, market', 618 | 583: 'guillotine', 619 | 584: 'hair slide', 620 | 585: 'hair spray', 621 | 586: 'half track', 622 | 587: 'hammer', 623 | 588: 'hamper', 624 | 589: 'hand blower, blow dryer, blow drier, hair dryer, hair drier', 625 | 590: 'hand-held computer, hand-held microcomputer', 626 | 591: 'handkerchief, hankie, hanky, hankey', 627 | 592: 'hard disc, hard disk, fixed disk', 628 | 593: 'harmonica, mouth organ, harp, mouth harp', 629 | 594: 'harp', 630 | 595: 'harvester, reaper', 631 | 596: 'hatchet', 632 | 597: 'holster', 633 | 598: 'home theater, home theatre', 634 | 599: 'honeycomb', 635 | 600: 'hook, claw', 636 | 601: 'hoopskirt, crinoline', 637 | 602: 'horizontal bar, high bar', 638 | 603: 'horse cart, horse-cart', 639 | 604: 'hourglass', 640 | 605: 'iPod', 641 | 606: 'iron, smoothing iron', 642 | 607: 'jack-o\'-lantern', 643 | 608: 'jean, blue jean, denim', 644 | 609: 'jeep, landrover', 645 | 610: 'jersey, T-shirt, tee shirt', 646 | 611: 'jigsaw puzzle', 647 | 612: 'jinrikisha, ricksha, rickshaw', 648 | 613: 'joystick', 649 | 614: 'kimono', 650 | 615: 'knee pad', 651 | 616: 'knot', 652 | 617: 'lab coat, laboratory coat', 653 | 618: 'ladle', 654 | 619: 'lampshade, lamp shade', 655 | 620: 'laptop, laptop computer', 656 | 621: 'lawn mower, mower', 657 | 622: 'lens cap, lens cover', 658 | 623: 'letter opener, paper knife, paperknife', 659 | 624: 'library', 660 | 625: 'lifeboat', 661 | 626: 'lighter, light, igniter, ignitor', 662 | 627: 'limousine, limo', 663 | 628: 'liner, ocean liner', 664 | 629: 'lipstick, lip rouge', 665 | 630: 'Loafer', 666 | 631: 'lotion', 667 | 632: 'loudspeaker, speaker, speaker unit, loudspeaker system, speaker ' + 668 | 'system', 669 | 633: 'loupe, jeweler\'s loupe', 670 | 634: 'lumbermill, sawmill', 671 | 635: 'magnetic compass', 672 | 636: 'mailbag, postbag', 673 | 637: 'mailbox, letter box', 674 | 638: 'maillot', 675 | 639: 'maillot, tank suit', 676 | 640: 'manhole cover', 677 | 641: 'maraca', 678 | 642: 'marimba, xylophone', 679 | 643: 'mask', 680 | 644: 'matchstick', 681 | 645: 'maypole', 682 | 646: 'maze, labyrinth', 683 | 647: 'measuring cup', 684 | 648: 'medicine chest, medicine cabinet', 685 | 649: 'megalith, megalithic structure', 686 | 650: 'microphone, mike', 687 | 651: 'microwave, microwave oven', 688 | 652: 'military uniform', 689 | 653: 'milk can', 690 | 654: 'minibus', 691 | 655: 'miniskirt, mini', 692 | 656: 'minivan', 693 | 657: 'missile', 694 | 658: 'mitten', 695 | 659: 'mixing bowl', 696 | 660: 'mobile home, manufactured home', 697 | 661: 'Model T', 698 | 662: 'modem', 699 | 663: 'monastery', 700 | 664: 'monitor', 701 | 665: 'moped', 702 | 666: 'mortar', 703 | 667: 'mortarboard', 704 | 668: 'mosque', 705 | 669: 'mosquito net', 706 | 670: 'motor scooter, scooter', 707 | 671: 'mountain bike, all-terrain bike, off-roader', 708 | 672: 'mountain tent', 709 | 673: 'mouse, computer mouse', 710 | 674: 'mousetrap', 711 | 675: 'moving van', 712 | 676: 'muzzle', 713 | 677: 'nail', 714 | 678: 'neck brace', 715 | 679: 'necklace', 716 | 680: 'nipple', 717 | 681: 'notebook, notebook computer', 718 | 682: 'obelisk', 719 | 683: 'oboe, hautboy, hautbois', 720 | 684: 'ocarina, sweet potato', 721 | 685: 'odometer, hodometer, mileometer, milometer', 722 | 686: 'oil filter', 723 | 687: 'organ, pipe organ', 724 | 688: 'oscilloscope, scope, cathode-ray oscilloscope, CRO', 725 | 689: 'overskirt', 726 | 690: 'oxcart', 727 | 691: 'oxygen mask', 728 | 692: 'packet', 729 | 693: 'paddle, boat paddle', 730 | 694: 'paddlewheel, paddle wheel', 731 | 695: 'padlock', 732 | 696: 'paintbrush', 733 | 697: 'pajama, pyjama, pj\'s, jammies', 734 | 698: 'palace', 735 | 699: 'panpipe, pandean pipe, syrinx', 736 | 700: 'paper towel', 737 | 701: 'parachute, chute', 738 | 702: 'parallel bars, bars', 739 | 703: 'park bench', 740 | 704: 'parking meter', 741 | 705: 'passenger car, coach, carriage', 742 | 706: 'patio, terrace', 743 | 707: 'pay-phone, pay-station', 744 | 708: 'pedestal, plinth, footstall', 745 | 709: 'pencil box, pencil case', 746 | 710: 'pencil sharpener', 747 | 711: 'perfume, essence', 748 | 712: 'Petri dish', 749 | 713: 'photocopier', 750 | 714: 'pick, plectrum, plectron', 751 | 715: 'pickelhaube', 752 | 716: 'picket fence, paling', 753 | 717: 'pickup, pickup truck', 754 | 718: 'pier', 755 | 719: 'piggy bank, penny bank', 756 | 720: 'pill bottle', 757 | 721: 'pillow', 758 | 722: 'ping-pong ball', 759 | 723: 'pinwheel', 760 | 724: 'pirate, pirate ship', 761 | 725: 'pitcher, ewer', 762 | 726: 'plane, carpenter\'s plane, woodworking plane', 763 | 727: 'planetarium', 764 | 728: 'plastic bag', 765 | 729: 'plate rack', 766 | 730: 'plow, plough', 767 | 731: 'plunger, plumber\'s helper', 768 | 732: 'Polaroid camera, Polaroid Land camera', 769 | 733: 'pole', 770 | 734: 'police van, police wagon, paddy wagon, patrol wagon, wagon, black ' + 771 | 'Maria', 772 | 735: 'poncho', 773 | 736: 'pool table, billiard table, snooker table', 774 | 737: 'pop bottle, soda bottle', 775 | 738: 'pot, flowerpot', 776 | 739: 'potter\'s wheel', 777 | 740: 'power drill', 778 | 741: 'prayer rug, prayer mat', 779 | 742: 'printer', 780 | 743: 'prison, prison house', 781 | 744: 'projectile, missile', 782 | 745: 'projector', 783 | 746: 'puck, hockey puck', 784 | 747: 'punching bag, punch bag, punching ball, punchball', 785 | 748: 'purse', 786 | 749: 'quill, quill pen', 787 | 750: 'quilt, comforter, comfort, puff', 788 | 751: 'racer, race car, racing car', 789 | 752: 'racket, racquet', 790 | 753: 'radiator', 791 | 754: 'radio, wireless', 792 | 755: 'radio telescope, radio reflector', 793 | 756: 'rain barrel', 794 | 757: 'recreational vehicle, RV, R.V.', 795 | 758: 'reel', 796 | 759: 'reflex camera', 797 | 760: 'refrigerator, icebox', 798 | 761: 'remote control, remote', 799 | 762: 'restaurant, eating house, eating place, eatery', 800 | 763: 'revolver, six-gun, six-shooter', 801 | 764: 'rifle', 802 | 765: 'rocking chair, rocker', 803 | 766: 'rotisserie', 804 | 767: 'rubber eraser, rubber, pencil eraser', 805 | 768: 'rugby ball', 806 | 769: 'rule, ruler', 807 | 770: 'running shoe', 808 | 771: 'safe', 809 | 772: 'safety pin', 810 | 773: 'saltshaker, salt shaker', 811 | 774: 'sandal', 812 | 775: 'sarong', 813 | 776: 'sax, saxophone', 814 | 777: 'scabbard', 815 | 778: 'scale, weighing machine', 816 | 779: 'school bus', 817 | 780: 'schooner', 818 | 781: 'scoreboard', 819 | 782: 'screen, CRT screen', 820 | 783: 'screw', 821 | 784: 'screwdriver', 822 | 785: 'seat belt, seatbelt', 823 | 786: 'sewing machine', 824 | 787: 'shield, buckler', 825 | 788: 'shoe shop, shoe-shop, shoe store', 826 | 789: 'shoji', 827 | 790: 'shopping basket', 828 | 791: 'shopping cart', 829 | 792: 'shovel', 830 | 793: 'shower cap', 831 | 794: 'shower curtain', 832 | 795: 'ski', 833 | 796: 'ski mask', 834 | 797: 'sleeping bag', 835 | 798: 'slide rule, slipstick', 836 | 799: 'sliding door', 837 | 800: 'slot, one-armed bandit', 838 | 801: 'snorkel', 839 | 802: 'snowmobile', 840 | 803: 'snowplow, snowplough', 841 | 804: 'soap dispenser', 842 | 805: 'soccer ball', 843 | 806: 'sock', 844 | 807: 'solar dish, solar collector, solar furnace', 845 | 808: 'sombrero', 846 | 809: 'soup bowl', 847 | 810: 'space bar', 848 | 811: 'space heater', 849 | 812: 'space shuttle', 850 | 813: 'spatula', 851 | 814: 'speedboat', 852 | 815: 'spider web, spider\'s web', 853 | 816: 'spindle', 854 | 817: 'sports car, sport car', 855 | 818: 'spotlight, spot', 856 | 819: 'stage', 857 | 820: 'steam locomotive', 858 | 821: 'steel arch bridge', 859 | 822: 'steel drum', 860 | 823: 'stethoscope', 861 | 824: 'stole', 862 | 825: 'stone wall', 863 | 826: 'stopwatch, stop watch', 864 | 827: 'stove', 865 | 828: 'strainer', 866 | 829: 'streetcar, tram, tramcar, trolley, trolley car', 867 | 830: 'stretcher', 868 | 831: 'studio couch, day bed', 869 | 832: 'stupa, tope', 870 | 833: 'submarine, pigboat, sub, U-boat', 871 | 834: 'suit, suit of clothes', 872 | 835: 'sundial', 873 | 836: 'sunglass', 874 | 837: 'sunglasses, dark glasses, shades', 875 | 838: 'sunscreen, sunblock, sun blocker', 876 | 839: 'suspension bridge', 877 | 840: 'swab, swob, mop', 878 | 841: 'sweatshirt', 879 | 842: 'swimming trunks, bathing trunks', 880 | 843: 'swing', 881 | 844: 'switch, electric switch, electrical switch', 882 | 845: 'syringe', 883 | 846: 'table lamp', 884 | 847: 'tank, army tank, armored combat vehicle, armoured combat vehicle', 885 | 848: 'tape player', 886 | 849: 'teapot', 887 | 850: 'teddy, teddy bear', 888 | 851: 'television, television system', 889 | 852: 'tennis ball', 890 | 853: 'thatch, thatched roof', 891 | 854: 'theater curtain, theatre curtain', 892 | 855: 'thimble', 893 | 856: 'thresher, thrasher, threshing machine', 894 | 857: 'throne', 895 | 858: 'tile roof', 896 | 859: 'toaster', 897 | 860: 'tobacco shop, tobacconist shop, tobacconist', 898 | 861: 'toilet seat', 899 | 862: 'torch', 900 | 863: 'totem pole', 901 | 864: 'tow truck, tow car, wrecker', 902 | 865: 'toyshop', 903 | 866: 'tractor', 904 | 867: 'trailer truck, tractor trailer, trucking rig, rig, articulated ' + 905 | 'lorry, semi', 906 | 868: 'tray', 907 | 869: 'trench coat', 908 | 870: 'tricycle, trike, velocipede', 909 | 871: 'trimaran', 910 | 872: 'tripod', 911 | 873: 'triumphal arch', 912 | 874: 'trolleybus, trolley coach, trackless trolley', 913 | 875: 'trombone', 914 | 876: 'tub, vat', 915 | 877: 'turnstile', 916 | 878: 'typewriter keyboard', 917 | 879: 'umbrella', 918 | 880: 'unicycle, monocycle', 919 | 881: 'upright, upright piano', 920 | 882: 'vacuum, vacuum cleaner', 921 | 883: 'vase', 922 | 884: 'vault', 923 | 885: 'velvet', 924 | 886: 'vending machine', 925 | 887: 'vestment', 926 | 888: 'viaduct', 927 | 889: 'violin, fiddle', 928 | 890: 'volleyball', 929 | 891: 'waffle iron', 930 | 892: 'wall clock', 931 | 893: 'wallet, billfold, notecase, pocketbook', 932 | 894: 'wardrobe, closet, press', 933 | 895: 'warplane, military plane', 934 | 896: 'washbasin, handbasin, washbowl, lavabo, wash-hand basin', 935 | 897: 'washer, automatic washer, washing machine', 936 | 898: 'water bottle', 937 | 899: 'water jug', 938 | 900: 'water tower', 939 | 901: 'whiskey jug', 940 | 902: 'whistle', 941 | 903: 'wig', 942 | 904: 'window screen', 943 | 905: 'window shade', 944 | 906: 'Windsor tie', 945 | 907: 'wine bottle', 946 | 908: 'wing', 947 | 909: 'wok', 948 | 910: 'wooden spoon', 949 | 911: 'wool, woolen, woollen', 950 | 912: 'worm fence, snake fence, snake-rail fence, Virginia fence', 951 | 913: 'wreck', 952 | 914: 'yawl', 953 | 915: 'yurt', 954 | 916: 'web site, website, internet site, site', 955 | 917: 'comic book', 956 | 918: 'crossword puzzle, crossword', 957 | 919: 'street sign', 958 | 920: 'traffic light, traffic signal, stoplight', 959 | 921: 'book jacket, dust cover, dust jacket, dust wrapper', 960 | 922: 'menu', 961 | 923: 'plate', 962 | 924: 'guacamole', 963 | 925: 'consomme', 964 | 926: 'hot pot, hotpot', 965 | 927: 'trifle', 966 | 928: 'ice cream, icecream', 967 | 929: 'ice lolly, lolly, lollipop, popsicle', 968 | 930: 'French loaf', 969 | 931: 'bagel, beigel', 970 | 932: 'pretzel', 971 | 933: 'cheeseburger', 972 | 934: 'hotdog, hot dog, red hot', 973 | 935: 'mashed potato', 974 | 936: 'head cabbage', 975 | 937: 'broccoli', 976 | 938: 'cauliflower', 977 | 939: 'zucchini, courgette', 978 | 940: 'spaghetti squash', 979 | 941: 'acorn squash', 980 | 942: 'butternut squash', 981 | 943: 'cucumber, cuke', 982 | 944: 'artichoke, globe artichoke', 983 | 945: 'bell pepper', 984 | 946: 'cardoon', 985 | 947: 'mushroom', 986 | 948: 'Granny Smith', 987 | 949: 'strawberry', 988 | 950: 'orange', 989 | 951: 'lemon', 990 | 952: 'fig', 991 | 953: 'pineapple, ananas', 992 | 954: 'banana', 993 | 955: 'jackfruit, jak, jack', 994 | 956: 'custard apple', 995 | 957: 'pomegranate', 996 | 958: 'hay', 997 | 959: 'carbonara', 998 | 960: 'chocolate sauce, chocolate syrup', 999 | 961: 'dough', 1000 | 962: 'meat loaf, meatloaf', 1001 | 963: 'pizza, pizza pie', 1002 | 964: 'potpie', 1003 | 965: 'burrito', 1004 | 966: 'red wine', 1005 | 967: 'espresso', 1006 | 968: 'cup', 1007 | 969: 'eggnog', 1008 | 970: 'alp', 1009 | 971: 'bubble', 1010 | 972: 'cliff, drop, drop-off', 1011 | 973: 'coral reef', 1012 | 974: 'geyser', 1013 | 975: 'lakeside, lakeshore', 1014 | 976: 'promontory, headland, head, foreland', 1015 | 977: 'sandbar, sand bar', 1016 | 978: 'seashore, coast, seacoast, sea-coast', 1017 | 979: 'valley, vale', 1018 | 980: 'volcano', 1019 | 981: 'ballplayer, baseball player', 1020 | 982: 'groom, bridegroom', 1021 | 983: 'scuba diver', 1022 | 984: 'rapeseed', 1023 | 985: 'daisy', 1024 | 986: 'yellow lady\'s slipper, yellow lady-slipper, Cypripedium calceolus, ' + 1025 | 'Cypripedium parviflorum', 1026 | 987: 'corn', 1027 | 988: 'acorn', 1028 | 989: 'hip, rose hip, rosehip', 1029 | 990: 'buckeye, horse chestnut, conker', 1030 | 991: 'coral fungus', 1031 | 992: 'agaric', 1032 | 993: 'gyromitra', 1033 | 994: 'stinkhorn, carrion fungus', 1034 | 995: 'earthstar', 1035 | 996: 'hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola ' + 1036 | 'frondosa', 1037 | 997: 'bolete', 1038 | 998: 'ear, spike, capitulum', 1039 | 999: 'toilet tissue, toilet paper, bathroom tissue' 1040 | }; --------------------------------------------------------------------------------