未验证 提交 e24f59e9 编写于 作者: W wangqun 提交者: GitHub

Merge pull request #2 from PaddlePaddle/master

[change][D]更新兼容性提交
......@@ -6,20 +6,19 @@ Paddle.js是百度Paddle的web方向子项目,是一个运行在浏览器中
## 主要特点
### Modular
### 模块化
Web project is built on Atom system which is a versatile framework to support GPGPU operation on WebGL. It is quite modular and could be used to make computation tasks faster by utilizing WebGL.
Paddle.js项目基于Atom系统构建,该系统是一个通用框架,可支持WebGL上的GPGPU操作。 它非常模块化,可以通过利用WebGL来更快地执行计算任务。
### 浏览器覆盖范围
* PC: Chrome
* Mac: Chrome
* PC: Chrome, firefox
* Mac: Chrome, Safari
* Android: Baidu App and QQ Browser
### 支持的操作
Currently Paddle.js only supports a limited set of Paddle Ops. See the full list. If your model uses unsupported ops, the Paddle.js script will fail and produce a list of the unsupported ops in your model. Please file issues to let us know what ops you need support with.
目前,Paddle.js只支持有限的一组算子操作。如果您的模型使用不支持的操作,那么padde.js将运行失败,如果您的模型中存在不支持的op操作的列表。请提出问题,让我们知道你需要支持。
目前,Paddle.js只支持有限的一组算子操作。如果您的模型中使用了不支持的操作,那么padde.js将运行失败并提示您的模型中有哪些op算子目前还不支持。如果您的模型中存在目前Paddle.js不支持的算子,请提出问题,让我们知道你需要支持。
[查看完整列表](./src/factory/fshader/README.md)
......@@ -86,6 +85,7 @@ let result = await inst.read();
## 运行Paddle.js提供的转换器脚本
模型转换器需要输入一个Paddle格式的model,可以是Paddle Hub中的model,运行转换器将会得到paddle.js的JSON格式model。
[查看转换工具使用方法](./tools/ModelConverter/README_cn.md)
## Web友好的model格式
......@@ -103,6 +103,6 @@ Paddle.js已经将一些模型转换成了Paddle.js支持的格式。在下面
## 反馈和社区支持
- Questions, reports, and suggestions are welcome through Github Issues!
- Forum: Opinions and questions are welcome at our [PaddlePaddle Forum](https://ai.baidu.com/forum/topic/list/168)
- QQ group chat: 696965088
- 欢迎在Github Issue中提出问题,反馈和建议!
- 欢迎在我们的[PaddlePaddle Forum](https://ai.baidu.com/forum/topic/list/168)提出观点,进行讨论
- QQ群:696965088
......@@ -151,8 +151,6 @@ export default class imageFeed {
}
}
}
console.log('this is the end of reshapetorgb !!!');
console.dir(result);
return result;
};
......@@ -164,7 +162,6 @@ export default class imageFeed {
* @return {Object} 缩放后的尺寸
*/
reSize(image, params) {
console.log('execute resize!!');
// 原始图片宽高
const width = this.pixelWidth;
const height = this.pixelHeight;
......@@ -192,7 +189,6 @@ export default class imageFeed {
* 根据scale缩放图像并且缩放成目标尺寸并居中
*/
resizeAndFitTargetSize(image, params){
console.log('execute resizeAndFitTargetSize!!');
// 原始图片宽高
const width = this.pixelWidth;
const height = this.pixelHeight;
......@@ -249,7 +245,6 @@ export default class imageFeed {
sh = Math.round(sw * this.pixelHeight / this.pixelWidth);
y = Math.floor((targetHeight - sh) / 2);
}
// console.log(x, y, sw, sh);
if (center) {
this.fromPixels2DContext.drawImage(
image, x, y, sw, sh);
......@@ -327,24 +322,18 @@ export default class imageFeed {
data = this.resizeAndFitTargetSize(pixels, opt);
data2 = this.fromPixels2DContext2.getImageData(0, 0, this.pixelWidth, this.pixelHeight);
}
else if (opt.scale) { // 兼容以前的,如果有scale就是短边缩放到scale模式
else if (opt.scale) { // 直接resize到targetShape Humanseg的情况
scaleSize = this.reSize(pixels, opt);
console.dir(scaleSize);
console.dir(pixels);
data = this.getImageData(opt, 0, 0, scaleSize);
data2 = this.fromPixels2DContext2.getImageData(0, 0, this.pixelWidth, this.pixelHeight);
}
else if (opt.targetSize) { // 如果有targetSize,就是装在目标宽高里的模式 TinyYolo的情况
scaleSize = this.fitToTargetSize(pixels, opt);
data = this.getImageData(opt, 0, 0, scaleSize);
data2 = this.fromPixels2DContext2.getImageData(0, 0, this.pixelWidth, this.pixelHeight);
}
}
if (opt.gray) {
data = grayscale(data);
}
......@@ -359,6 +348,7 @@ export default class imageFeed {
else if (opt.targetShape) {
data = this.allReshapeToRGB(data, opt, scaleSize);
}
return [{data: data, shape: opt.shape || opt.targetShape, name: 'image', canvas: data2}];
}
}
......
......@@ -51,6 +51,10 @@ export default class gpu {
console.log('float extension is started or not? ' + !!this.textureFloat);
}
}
this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
// 关闭相关功能
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
......@@ -67,14 +71,22 @@ export default class gpu {
this.waits = 0;
console.log('WebGl版本是 ' + this.version);
console.log('MAX_TEXTURE_SIZE is ' + gl.getParameter(gl.MAX_TEXTURE_SIZE));
console.log('MAX_TEXTURE_IMAGE_UNITS is ' + gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
console.log('MAX_TEXTURE_SIZE is ' + this.maxTextureSize);
console.log('MAX_TEXTURE_IMAGE_UNITS is ' + this.maxTextureImageUnits);
}
getWebglVersion() {
return this.version;
}
getWebglMaxTextureSize() {
return this.maxTextureSize;
}
getWebglMaxTextureImageUnits() {
return this.maxTextureImageUnits;
}
initCache() {
// 运行次数
this.times = 0;
......@@ -145,7 +157,6 @@ export default class gpu {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, // Target, matches bind above.
0, // Level of detail.
this.downloadInternalFormat, // Internal format.
......@@ -346,6 +357,7 @@ export default class gpu {
} else {
// texture = gl.createTexture();
if (isRendered && (iLayer > 0 || (iLayer === 0 && item.tensor !== 'origin'))) {
const tData = this.cacheTextures['' + iLayer];
texture = tData[item.variable + '_' + item.tensor];
} else {
......@@ -361,6 +373,7 @@ export default class gpu {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
if (this.version == 2){
gl.texImage2D(gl.TEXTURE_2D,
0,
this.internalFormat,
......@@ -369,8 +382,27 @@ export default class gpu {
0,
this.textureFormat,
gl.FLOAT,
item.data,
0);
item.data);
}
else {
let oneSize = item.width_texture * item.height_texture;
let temp = new Float32Array(item.width_texture * item.height_texture * 4);
for (let i = 0; i < item.data.length; i++){
temp[i*4] = (item.data[i]);
temp[i*4+1] = 0;
temp[i*4+2] = 0;
temp[i*4+3] = 0;
}
gl.texImage2D(gl.TEXTURE_2D,
0,
gl.RGBA,
item.width_texture,
item.height_texture,
0,
gl.RGBA,
gl.FLOAT,
temp);
}
}
}
......@@ -389,7 +421,7 @@ export default class gpu {
// 生成帧缓存的texture
makeTexure(type, data, opts = {}) {
const gl = this.gl;
let index = this.textureBufferIndex % 2;
let index = int(mod(float(this.textureBufferIndex), 2.0));
let texture = this.textureBuffer[index];
gl.bindTexture(gl.TEXTURE_2D, texture);
......@@ -429,6 +461,7 @@ export default class gpu {
}
createPBO() {
if (this.version == 2){
const gl2 = this.gl;
const buffer = this.pbo;
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer);
......@@ -438,40 +471,38 @@ export default class gpu {
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null);
return buffer;
}
else {
let buffer = new Float32Array(this.width_texture_out * this.height_texture_out * 4);
const gl2 = this.gl;
gl2.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl2.RGBA, gl2.FLOAT, buffer);
return buffer;
}
}
downloadFoat32TensorFromBuffer(buffer) {
const gl2 = this.gl;
const size = 4 * this.width_texture_out * this.height_texture_out;
if (this.version == 2){
const pixels = new Float32Array(size);
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer);
gl2.getBufferSubData(gl2.PIXEL_PACK_BUFFER, 0, pixels);
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null);
// log.start('后处理-readloop');
// let result = [];
// let offset = 0;
// for (let h = 0; h < this.height_texture_out; h++) {
// // 纪录第1和2行数据
// let temp1 = [];
// let temp2 = [];
// for (let w = 0; w < this.width_texture_out; w++) {
// temp1.push(pixels[offset]);
// temp1.push(pixels[offset + 1]);
// temp2.push(pixels[offset + 2]);
// temp2.push(pixels[offset + 3]);
// offset += 4;
// }
// result = result.concat(temp1);
// result = result.concat(temp2);
// }
let result = [];
for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) {
result.push(pixels[4 * i]);
}
// const result = Array.prototype.slice.call(pixels);
// console.dir(['result', result]);
// log.end('后处理-readloop');
return result;
}
else {
let pixels = buffer;
let result = [];
for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) {
result.push(pixels[4 * i]);
}
return result;
}
}
getWebglError(status) {
const gl2 = this.gl;
......@@ -497,7 +528,7 @@ export default class gpu {
createAndWaitForFence() {
const gl2 = this.gl;
const isFenceEnabled = (gl2.fenceSync !== null);
const isFenceEnabled = (gl2.fenceSync != null);
let isFencePassed = () => true;
if (isFenceEnabled) {
const sync = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0);
......@@ -531,10 +562,8 @@ export default class gpu {
let pixels = new Float32Array(this.width_texture_out * this.height_texture_out * 4);
// gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
const tt2 = +Date.now();
gl.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl.RGBA, gl.FLOAT, pixels, 0);
gl.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl.RGBA, gl.FLOAT, pixels);
// console.log('本次读取数据时间是' + (+Date.now() - tt2)+ ',' + (tt2 - tt));
// log.end('后处理-readinside');
// log.start('后处理-readloop');
let result = [];
for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) {
result.push(pixels[4 * i]);
......
/* eslint-disable */
import GraphExecutor from '../executor/executor';
import IO from '../feed/imageFeed';
import Runtime from '../runtime/runtime';
import OpData from '../utils/opData';
import Factory from '../factory/fshader/factory';
......@@ -92,9 +91,14 @@ export default class Graph {
return;
}
opindex++;
// console.log(opindex);
//if (executor.opData) console.log(executor.opData.iLayer);
executor.execute(this.inst, this.isExecuted);
if (false && executor.opData && opindex >= 184){
console.log('return!');
console.dir(executor);
console.dir(executor.type);
console.dir(this);
return;
}
if (executor.next) {
const id = executor.next;
const next = this.getTensor(id);
......@@ -199,103 +203,61 @@ export default class Graph {
});
}
execute_try(temp, ops, idtoindex, executed, inline, prev){
console.log('execute_try!first look at this op');
console.log(ops[temp]);
let canrun = this.checkifcanrun(temp, ops, idtoindex, executed);
if (canrun === false) {
// console.log('canrun === false!');
var a = inline.pop();
this.execute_try(idtoindex[a.id], ops, idtoindex, executed, inline, prev);
return;
}
if (prev >=0) {
ops[prev].next = ops[temp].id;
}
ops[temp].outputsName.forEach(function(item, index) {
executed[item] = true;
})
let next = this.getNextByOp(ops, ops[temp]);
// console.log('this is its next:');
// console.dir(next);
while (next.length === 1) {
let flag = true;
for (let i = 0; i < next[0].inputsName.length; i++){
if (executed[next[0].inputsName[i]] === false) flag = false;
}
if (flag === false) {
// console.log('can not execute next now! jump to another op:');
if (inline.length === 0) return;
prev = temp;
let a = inline.pop();
// console.dir(a);
ops[temp].next = a.id;
temp = idtoindex[a.id];
this.execute_try(temp, ops, idtoindex, executed, inline, prev);
return;
}
else {
// console.log('now execute next op! it is');
ops[temp].next = next[0].id;
temp = idtoindex[next[0].id];
// console.dir(ops[temp]);
next = this.getNextByOp(ops, ops[temp]);
// console.log('its next is: ');
ops[temp].outputsName.forEach(function(item, index) {
executed[item] = true;
})
// console.dir(next);
}
}
if (next.length > 1){
// console.log('next.length > 1!!!');
for (let i = next.length - 1; i >=0 ; i--){
inline.push(next[i]);
}
var a = inline.pop();
this.execute_try(idtoindex[a.id], ops, idtoindex, executed, inline, temp);
}
return;
}
arrangeMap(ops) {
// console.log('arrangeMap!');
// console.dir(ops);
var idtoindex = {};
var executed = {};
var inline = [];
var inIndex = [];
var idtoindex = {};
let temp = 0;
// console.log('graph ops:');
// console.dir(ops);
let ops1 = ops;
ops1.forEach(function(item, index) {
idtoindex[item.id] = index;
// console.dir(item);
item.outputsName.forEach(function(i, idx){
executed[i] = false;
executed[i] = true;
})
});
//ops[0].inputsName[0] = {name : "feed"};
// ops[0].outputsName[0] = {name : "image"};
this.execute_try(temp, ops, idtoindex, executed, inline, -1);
ops1.forEach(function(item, index) {
inIndex[index] = 0;
idtoindex[item.id] = index;
if (item.inputsName.length > 1) {
item.inputsName.forEach(function(i,idx){
if (executed[i] == true) inIndex[index]++;
})
}
else inIndex[index] = item.inputsName.length;
});
this.topoSort(ops, inIndex, idtoindex);
return ops;
}
checkifcanrun(temp, ops, executed){
if (!ops[temp].inputsName) return true;
for (let i = 0; i < ops[temp].inputsName.length; i++){
if (executed[ops[temp].inputsName[i]] === false) return false;
topoSort(ops, inIndex, idtoindex){
var inline = [];
inline.push(ops[0]);
let ops_temp = ops.slice(0);
let prev = null;
let a = ops[0];
while(inline.length > 0){
if (prev != null) ops[idtoindex[prev.id]].next = a.id;
prev = a;
a = inline.pop();
for (let i = 0; i < a.outputsName.length; i++){
for (let k = 0; k < ops_temp.length; k++){
for (let j = 0; j < ops_temp[k].inputsName.length; j++){
if (ops_temp[k].inputsName[j] == a.outputsName[i]) {
inIndex[idtoindex[ops_temp[k].id]]--;
if (inIndex[idtoindex[ops_temp[k].id]] == 0){
inline.push(ops[idtoindex[ops_temp[k].id]]);
ops_temp.splice(k,1);
k--;
break;
}
}
}
}
}
}
return true;
}
/**
......@@ -348,8 +310,6 @@ export default class Graph {
* @returns {*}
*/
createOpsMap(ops) {
// console.log('ops!!');
// console.dir(ops);
return ops.map((item, idx) => {
item.idx = idx;
const graphExecutor = new GraphExecutor(item);
......@@ -372,17 +332,6 @@ export default class Graph {
});
}
getNextByOp(ops, op) {
return ops.filter((item, key) => {
for (let i = 0; i < item.inputsName.length; i++) {
for(let j = 0; j < op.outputsName.length; j++) {
if (item.inputsName[i] === op.outputsName[j]) {
return true;
}
}
}
});
}
/**
* dispose
*/
......
......@@ -109,8 +109,9 @@ export default class Loader {
const TMP_REGEX = /\-/;
let requesterArr = arr.map(item => {
if (item.name
&& item.name.match(TMP_SCHEME_REGEX) === null
&& item.name.match(TMP_REGEX) === null) {
// && item.name.match(TMP_SCHEME_REGEX) === null
// && item.name.match(TMP_REGEX) === null
) {
return this.fetchData(item.name).then(data => item.data = data);
}
return Promise.resolve();
......@@ -124,9 +125,9 @@ export default class Loader {
let marker = 0; // 读到哪个位置了
let len; // 当前op长度
arr.filter(item => {
return item.name
&& item.name.match(TMP_SCHEME_REGEX) === null
&& item.name.match(TMP_REGEX) === null;
return item.name;
// && item.name.match(TMP_SCHEME_REGEX) === null
// && item.name.match(TMP_REGEX) === null;
})
// .sort((a, b) => {
// if (a.name > b.name) {
......
......@@ -48,13 +48,9 @@ export default class Paddle {
that.graph = graph;
that.graph.data = artifacts.data;
that.graph.formatWeight(that.graph.data.vars);
const opsMap = that.graph.createOpsMap(that.graph.data.ops, that.graph.data.vars);
const opsMap = that.graph.createOpsMap(that.graph.data.ops);
const opsMap1 = that.graph.constructOpsMap(opsMap);
// console.log('opsMap1!');
// console.dir(opsMap1);
const opsMap2 = that.graph.arrangeMap(opsMap1);
// console.log('opsMap2!');
// console.dir(opsMap2);
that.graph.weightMap = opsMap2;
}
/**
......@@ -68,10 +64,10 @@ export default class Paddle {
this.feed = this.graph.feed = inputs;
// 生成op数据
if (!this.graph.isExecuted) {
this.graph.weightMap.forEach(op => {
this.graph.weightMap.forEach((op, index) => {
const type = op.type;
if (type !== 'feed' && type !== 'fetch') {
console.log(op.type);
that.graph.buildOpData(op);
}
});
......@@ -81,7 +77,6 @@ export default class Paddle {
}
updateFeed() {
this.graph.feedItem.data = this.graph.feed.input[0].data;
// Utils.img2texture(this.graph.feedItem);
}
/**
* dispose
......
......@@ -2,9 +2,6 @@
import Gpu from '../gpu/gpu';
import getMaxUniforms from '../test/getMaxUniforms';
import Factory from '../factory/fshader/factory';
// import {getTextureShapeInfo} from '../utils/opData';
// 生成factory实例
// const factory = new Factory({});
/**
* @file gpu运行时
* @author wangqun@baidu.com, yangmingming@baidu.com
......@@ -29,6 +26,14 @@ export default {
return this.gpu.getWebglVersion();
},
getWebglMaxTextureSize() {
return this.gpu.maxTextureSize();
},
getWebglMaxTextureImageUnits() {
return this.gpu.maxTextureImageUnits();
},
run(opName, opData, isRendered) {
// console.dir(['fscode', opData.fsCode]);
// let time = +Date.now();
......@@ -64,6 +69,7 @@ export default {
this.gpu.render(opData.renderData, opData.iLayer, isRendered);
// }
});
},
/**
......
......@@ -16,20 +16,29 @@ float getValueFromTensorPos_TENSOR_NAME(int r, int g, int b, int a) {
// 只用了r通道
return pixels.r;
}
// 紧凑型布局根据tensor坐标获取这个tensor位置的值
// 超限布局根据tensor坐标获取这个tensor位置的值
float getValueFromTensorPosLimit_TENSOR_NAME(int r, int g, int b, int a) {
float halfW = ceil(float(width_shape_TENSOR_NAME) / 2.0);
int x = int(mod(float(a), halfW));
float pieceW = ceil(float(width_shape_TENSOR_NAME) / 4.0);
int x = int(mod(float(a), pieceW));
int offsetY = 0;
if (a > x) {
if ((float(a) / pieceW) >= 3.0) {
offsetY = 3 * height_shape_TENSOR_NAME;
}
else if (float(a) / pieceW >= 2.0) {
offsetY = 2 * height_shape_TENSOR_NAME;
}
else if (float(a) >= pieceW) {
offsetY = height_shape_TENSOR_NAME;
}
vec4 pixels = TEXTURE2D(texture_TENSOR_NAME,
vec2(
(float(x * channel_TENSOR_NAME + g) + 0.5) / float(width_texture_TENSOR_NAME),
(float(r * 2 * height_shape_TENSOR_NAME + b + offsetY) + 0.5) / float(height_texture_TENSOR_NAME)
(float(r * 4 * height_shape_TENSOR_NAME + b + offsetY) + 0.5) / float(height_texture_TENSOR_NAME)
)
);
return pixels.r;
}
`;
......@@ -8,11 +8,13 @@ export default `
precision highp float;
precision highp int;
#else
precision mediump float;
precision mediump int;
precision highp float;
precision highp int;
#endif
varying vec2 vCoord;
varying vec4 outColor;
void setOutput(float result) {
gl_FragColor.r = result;
}
`;
......@@ -15,17 +15,18 @@ ivec4 getOutputTensorPos() {
return ivec4(b, c, y, x);
}
ivec4 getOutputTensorPosLimit() {
// 获取原始长度
vec2 outCoord = vCoord.xy * _2d_shape_texture_out;
float offsetY = floor(outCoord.y / float(height_shape_out));
int x = int(outCoord.x / float(channel_out));
if (mod(offsetY, 2.0) > 0.0) {
x += int(ceil(float(width_shape_out) / 2.0));
if (mod(offsetY, 4.0) > 0.0) {
x += int(mod(offsetY, 4.0)) * int(ceil(float(width_shape_out) / 4.0));
}
int y = int(mod(outCoord.y, float(height_shape_out)));
int c = int(mod(outCoord.x, float(channel_out)));
int b = int(outCoord.y / float(2 * height_shape_out));
int b = int(outCoord.y / float(4 * height_shape_out));
return ivec4(b, c, y, x);
}
......
......@@ -10,13 +10,13 @@ export default `
ivec4 transferFromNHWCtoNCHW( int sumVal, const int channel, const int width_shape, const int height_shape, const int total_shape) {
int n_origin = int(total_shape/(channel * width_shape * height_shape));
int new_a = sumVal % width_shape;
int new_a = int(mod(float(sumVal), float(width_shape)));
sumVal = int((sumVal - new_a) / width_shape);
int new_b = sumVal % height_shape;
int new_b = int(mod(float(sumVal), float(height_shape)));
sumVal = int((sumVal - new_b) / height_shape);
int new_g = sumVal % channel;
int new_g = int(mod(float(sumVal), float(channel)));
sumVal = int((sumVal - new_g) / channel);
int new_r = sumVal % n_origin;
int new_r = int(mod(float(sumVal), float(n_origin)));
return ivec4(new_r,new_g,new_b,new_a);
}
`;
......@@ -7,14 +7,14 @@ export default `
// start函数
void main(void) {
// 输出数据
ivec4 oPos = getOutputTensorPos();
float o = getValueFromTensorPos_origin(oPos.r, oPos.g, oPos.b, oPos.a);
ivec4 oPos = getOutputTensorPosLIMIT_OUT();
float o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
// 归一化数据
vec4 scale = getPixelsFromTexturePos_texture_scale(vec2( float(oPos.g) / float(width_texture_scale), 0.0));
vec4 bias = getPixelsFromTexturePos_texture_bias(vec2((float(oPos.g)) / float(width_texture_bias), 0.0));
vec4 mean = getPixelsFromTexturePos_texture_mean(vec2((float(oPos.g)) / float(width_texture_mean), 0.0));
vec4 variance = getPixelsFromTexturePos_texture_variance(vec2((float(oPos.g)) / float(width_texture_variance), 0.0));
vec4 scale = getPixelsFromTexturePos_texture_scale(vec2((float(oPos.g) + 0.5) / float(width_texture_scale), 0.0));
vec4 bias = getPixelsFromTexturePos_texture_bias(vec2((float(oPos.g) + 0.5) / float(width_texture_bias), 0.0));
vec4 mean = getPixelsFromTexturePos_texture_mean(vec2((float(oPos.g) + 0.5) / float(width_texture_mean), 0.0));
vec4 variance = getPixelsFromTexturePos_texture_variance(vec2((float(oPos.g) + 0.5) / float(width_texture_variance), 0.0));
float x = (o - mean[0]) / sqrt(variance[0] + epsilon);
float res = scale[0] * x + bias[0];
......
/* eslint-disable */
/**
* @file bilinear_interp的配置文件
* @author chenhaoze
*/
export default {
dep: [
{
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'origin'
}
},
{
func: 'transferFromNHWCtoNCHW',
conf:{
}
}
],
conf: [
'WIDTH_SHAPE_ORIGIN',
'HEIGHT_SHAPE_ORIGIN',
'LENGTH_SHAPE_ORIGIN',
'WIDTH_TEXTURE_ORIGIN',
'HEIGHT_TEXTURE_ORIGIN',
'CHANNEL_ORIGIN',
'WIDTH_SHAPE_OUT',
'HEIGHT_SHAPE_OUT',
'WIDTH_TEXTURE_OUT',
'HEIGHT_TEXTURE_OUT',
'CHANNEL_OUT',
'OFFSET_Y_OUT',
'MULTI_VALUE',
'BIAS_VALUE',
'ACTIVE_FUNCTION'
],
input: [
{
tensor: 'origin',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
}
]
};
/* eslint-disable */
/**
* @file bilinear_interp主函数
* @author chenhaoze
*/
export default `
// start函数
void main(void) {
// 输出数据
ivec4 oPos = getOutputTensorPos();
// 输出坐标转换为输入坐标
//int sumVal = oPos.g + oPos.a * channel_out + oPos.b * channel_out * width_shape_out + oPos.r * channel_out * width_shape_out * height_shape_out;
//oPos = transferFromNHWCtoNCHW(sumVal, channel_out, width_shape_out, height_shape_out, total_shape_out);
float o = getValueFromTensorPos_origin(oPos.r, oPos.g, oPos.b, oPos.a);
float scale_x = float(width_shape_out - 1) / float(width_shape_origin - 1);
float scale_y = float(height_shape_out - 1) / float(height_shape_origin - 1);
float x = float(oPos.a) / scale_x;
float y = float(oPos.b) / scale_y;
int x1 = int(floor(x));
int y1 = int(floor(y));
int x2 = int(ceil(x));
int y2 = int(ceil(y));
float dist_x = x - float(x1);
float dist_y = y - float(y1);
float value11 = getValueFromTensorPos_origin(oPos.r, oPos.g, y1, x1);
float value12 = getValueFromTensorPos_origin(oPos.r, oPos.g, y2, x1);
float value21 = getValueFromTensorPos_origin(oPos.r, oPos.g, y1, x2);
float value22 = getValueFromTensorPos_origin(oPos.r, oPos.g, y2, x2);
float value = (1.0 - dist_x) * (1.0 - dist_y) * value11 +
(1.0 - dist_x) * dist_y * value12 + dist_x * (1.0 - dist_y) * value21 +
dist_x * dist_y * value22;
setOutput(float(value));
}
`;
/* eslint-disable */
/**
* @file bilinear_interp参数文件
* @author chenhaoze
*/
export default `
// 输入数据
const int width_shape_origin = WIDTH_SHAPE_ORIGIN;
const int height_shape_origin = HEIGHT_SHAPE_ORIGIN;
const int length_shape_origin = LENGTH_SHAPE_ORIGIN;
const int width_texture_origin = WIDTH_TEXTURE_ORIGIN;
const int height_texture_origin = HEIGHT_TEXTURE_ORIGIN;
const int channel_origin = CHANNEL_ORIGIN;
const int total_shape_origin = TOTAL_SHAPE_ORIGIN;
const int total_shape_out = TOTAL_SHAPE_OUT;
// 输入数据
uniform sampler2D texture_origin;
`;
......@@ -11,8 +11,8 @@ void main(void) {
// int sumVal = oPos.g + oPos.a * channel_out + oPos.b * channel_out * width_shape_out + oPos.r * channel_out * width_shape_out * height_shape_out;
// ivec4 new_oPos = transferFromNHWCtoNCHW(sumVal, channel_out, width_shape_out, height_shape_out, total_shape_out);
float o = 0.0;
if (oPos[dim] > inputs_dim[0] - 1) {
oPos[dim] = oPos[dim] - inputs_dim[0];
if (oPos[dim] > inputs_dim - 1) {
oPos[dim] = oPos[dim] - inputs_dim;
o = getValueFromTensorPos_counter(oPos.r, oPos.g, oPos.b, oPos.a);
}
else {
......
......@@ -28,7 +28,7 @@ const int total_shape_origin = TOTAL_SHAPE_ORIGIN;
const int total_shape_out = TOTAL_SHAPE_OUT;
const int dim = DIM;
const int inputs_dim[1] = int[](INPUTS_DIM);
const int inputs_dim = INPUTS_DIM;
// uniform变量
......
......@@ -16,16 +16,8 @@ export default `
int temp_y = 0;
float o = 0.0;
float f = 0.0;
if (x % 2 == 1) x = x - 2;
if (y % 2 == 1) y = y - 2;
// 重排遍历顺序
//int sumVal = oPos.g + oPos.a * channel_out + oPos.b * channel_out * width_shape_out;
//int new_a = sumVal % width_shape_out;
//int new_b = int((sumVal - new_a) / width_shape_out) % height_shape_out;
//int new_g = int((((sumVal - new_a) / width_shape_out) - new_b) / height_shape_out);
//int x = new_a;
//int c = new_g;
//int y = new_b;
if (int(mod(float(x), 2.0)) == 1) x = x - 2;
if (int(mod(float(y), 2.0)) == 1) y = y - 2;
// 获取output的坐标
int oTensorChannel = int(c * groups / channel_out) * channel_origin;
int oy = y;
......@@ -43,8 +35,7 @@ export default `
}
// channel计算
for (int j = 0; j < channel_origin; j++) {
if (ox % stride_h == 0 && oy % stride_v == 0) {
if (int(mod(float(ox), float(stride_h))) == 0 && int(mod(float(oy), float(stride_v))) == 0) {
temp_x = int(floor(float(ox) / float(stride_h)));
temp_y = int(floor(float(oy) / float(stride_v)));
if (temp_x < width_shape_origin && temp_y < height_shape_origin){
......
......@@ -7,22 +7,22 @@ export default `
// start函数
void main(void) {
// 输出数据
ivec4 oPos = getOutputTensorPos();
float o = getValueFromTensorPos_origin(oPos.r, oPos.g, oPos.b, oPos.a);
ivec4 oPos = getOutputTensorPosLIMIT_OUT();
float o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
ivec4 pos_counter;
float c = 0.0;
if (axis == 1){
c = getValueFromTensorPos_counter(0, oPos.r, oPos.g, oPos.b);
c = getValueFromTensorPosLIMIT_COUNTER_counter(0, oPos.r, oPos.g, oPos.b);
}
else if (axis == 2){
c = getValueFromTensorPos_counter(0, 0, oPos.r, oPos.g);
c = getValueFromTensorPosLIMIT_COUNTER_counter(0, 0, oPos.r, oPos.g);
}
else if (axis == 3){
c = getValueFromTensorPos_counter(0, 0, 0, oPos.r);
c = getValueFromTensorPosLIMIT_COUNTER_counter(0, 0, 0, oPos.r);
}
else {
c = getValueFromTensorPos_counter(oPos.r, oPos.g, oPos.b, oPos.a);
c = getValueFromTensorPosLIMIT_COUNTER_counter(oPos.r, oPos.g, oPos.b, oPos.a);
}
float res = c + o;
setOutput(float(res));
......
......@@ -7,10 +7,10 @@ export default `
void main(void) {
float res = 0.0;
// 获取output的坐标
ivec4 out_pos = getOutputTensorPos();
ivec4 out_pos = getOutputTensorPosLIMIT_OUT();
for (int j = 0; j < width_shape_origin; j++) {
float c = getValueFromTensorPos_counter(out_pos[0], out_pos[1], j, out_pos[3]);
float o = getValueFromTensorPos_origin(out_pos[0], out_pos[1], out_pos[2], j);
float c = getValueFromTensorPosLIMIT_COUNTER_counter(out_pos[0], out_pos[1], j, out_pos[3]);
float o = getValueFromTensorPosLIMIT_COUNTER_origin(out_pos[0], out_pos[1], out_pos[2], j);
res += c * o;
}
setOutput(res);
......
......@@ -6,7 +6,7 @@
export default `
// start函数
void main(void) {
int length = int(target_value.length() / num);
int length = int(target_length / num);
ivec4 oPos = getOutputTensorPos();
// 输出坐标转换为输入坐标
//int sumVal = oPos.g + oPos.a * channel_out + oPos.b * channel_out * width_shape_out + oPos.r * channel_out * width_shape_out * height_shape_out;
......
......@@ -18,7 +18,7 @@ const int total_shape_out = TOTAL_SHAPE_OUT;
const int dim = DIM;
const int num = NUM;
const int target_value[TARGET_LENGTH] = int[](TARGET_VALUE);
const int target_length = TARGET_LENGTH;
// 输入数据
......
......@@ -19,10 +19,10 @@ void main(void) {
o = getValueFromTensorPos_origin(oPos[0], oPos[1], oPos[2], oPos[3]);
}
else if (perm_size == 2) {
o = getValueFromTensorPos_origin(oPos[0], oPos[1], oPos[min(2 + perm_0, 3)], oPos[min(2 + perm_1, 3)]);
o = getValueFromTensorPos_origin(oPos[0], oPos[1], oPos[(2 + perm_0)>3?3:(2 + perm_0)], oPos[(2 + perm_1)>3?3:(2 + perm_1)]);
}
else if (perm_size == 3) {
o = getValueFromTensorPos_origin(oPos[0], oPos[min(1 + perm_0, 3)], oPos[min(1 + perm_1, 3)], oPos[min(1 + perm_2, 3)]);
o = getValueFromTensorPos_origin(oPos[0], oPos[(1 + perm_0)>3?3:(1 + perm_0)], oPos[(1 + perm_1)>3?3:(1 + perm_1)], oPos[(1 + perm_2)>3?3:(1 + perm_2)]);
}
else if (perm_size == 4) {
o = getValueFromTensorPos_origin(oPos[perm_0], oPos[perm_1], oPos[perm_2], oPos[perm_3]);
......
......@@ -125,7 +125,6 @@ const mergeType = 'conv2d-elementwise_add';
export default class OpData {
constructor(name, input = {}, output = {}, attrs = {}) {
// console.dir(this);
this.realName = name;
this.name = name;
this.attrs = attrs;
......@@ -205,7 +204,6 @@ export default class OpData {
// 默认取第一个数据
const data = this.output[key] || [{}];
if (tensorName[key.toLowerCase()]) {
// console.dir(this);
data.forEach(item => {
item.tensorName = tensorName[key.toLowerCase()];
tensorData.push(item);
......@@ -453,7 +451,7 @@ export default class OpData {
this.attrs.target_length = dim_value.length;
this.attrs.target_value = dim_value;
// 保存 输入 tensor 对应dim 的长度
this.attrs.inputs_dim = [origin_shape[axis]];
this.attrs.inputs_dim = origin_shape[axis];
this.attrs.dim = 4 - origin_shape.length + axis;
}
......
......@@ -119,12 +119,13 @@ export default {
let offsetY = 0;
// 安卓和ios的max texture size是4096, 改造存储空间(2bh, cw / 2)
let exceedMax = false;
// FIXME:为了让mobilenet能正常执行,这里先注释掉,待群哥修复
// if (height > MAX_TEXTURE_SIZE || width > MAX_TEXTURE_SIZE) {
// height *= 2;
// width = c * (Math.ceil(w / 2));
// exceedMax = true;
// }
// trick TEXTURE_SIZE 超限问题,后续升级更优解
if (height > 4096 || width > 4096) {
//console.error('大小超限', shape);
//height *= 4;
//width = c * (Math.ceil(w / 4));
//exceedMax = true;
}
if (isPacked) {
// 紧凑布局
height = b * c * Math.ceil(h / 2);
......@@ -267,7 +268,7 @@ export default {
for (let i = 0; i < realPrintCount; i++) {
numbers.push(i * stride + ": " + data[i * stride]);
}
console.log(numbers)
console.log(numbers);
},
/*
......@@ -282,7 +283,7 @@ export default {
for (let i = 0; i < realPrintCount; i++) {
numbers.push(i + ": " + data[i]);
}
console.log(numbers)
console.log(numbers);
},
softmax(nchwData) {
......@@ -306,6 +307,44 @@ export default {
}
return result;
},
// 针对model final texture输出超限后,inst.read读取数据不对的case
formatReadData(nchwData, nchwShape) {
if (nchwShape.length < 4) {
let batch = [];
for (let i = 0; i < (4 - nchwShape.length); i++) {
batch.push(1);
}
nchwShape = batch.concat(nchwShape);
}
const shape_b = nchwShape[0];
const shape_c = nchwShape[1];
const shape_h = nchwShape[2];
const shape_w = nchwShape[3];
const texture_height = shape_b * shape_h;
const texture_width = shape_c * shape_w;
if (texture_height <= 4096 && texture_width <= 4096) {
return nchwData;
}
let pos = 0;
const formatData = [];
const pieceW = Math.ceil(shape_w / 4); // reshape后的 shape_width
for (let bIndex = 0; bIndex < shape_b; bIndex++) {
for (let cIndex = 0; cIndex < shape_c; cIndex++) {
for (let hIndex = 0; hIndex < shape_h; hIndex++) {
for (let wIndex = 0; wIndex < shape_w; wIndex++) {
pos = Math.floor(wIndex / pieceW) * pieceW * (shape_h - 1) + wIndex + hIndex * pieceW;
pos += bIndex * shape_c * shape_h * shape_w+ cIndex * shape_h * shape_w;
formatData.push(nchwData[pos]);
}
}
}
}
return formatData;
}
};
/* eslint-enable */
{0: 'tench, Tinca tinca',
1: 'goldfish, Carassius auratus',
2: 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias',
3: 'tiger shark, Galeocerdo cuvieri',
4: 'hammerhead, hammerhead shark',
5: 'electric ray, crampfish, numbfish, torpedo',
6: 'stingray',
7: 'cock',
8: 'hen',
9: 'ostrich, Struthio camelus',
10: 'brambling, Fringilla montifringilla',
11: 'goldfinch, Carduelis carduelis',
12: 'house finch, linnet, Carpodacus mexicanus',
13: 'junco, snowbird',
14: 'indigo bunting, indigo finch, indigo bird, Passerina cyanea',
15: 'robin, American robin, Turdus migratorius',
16: 'bulbul',
17: 'jay',
18: 'magpie',
19: 'chickadee',
20: 'water ouzel, dipper',
21: 'kite',
22: 'bald eagle, American eagle, Haliaeetus leucocephalus',
23: 'vulture',
24: 'great grey owl, great gray owl, Strix nebulosa',
25: 'European fire salamander, Salamandra salamandra',
26: 'common newt, Triturus vulgaris',
27: 'eft',
28: 'spotted salamander, Ambystoma maculatum',
29: 'axolotl, mud puppy, Ambystoma mexicanum',
30: 'bullfrog, Rana catesbeiana',
31: 'tree frog, tree-frog',
32: 'tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui',
33: 'loggerhead, loggerhead turtle, Caretta caretta',
34: 'leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea',
35: 'mud turtle',
36: 'terrapin',
37: 'box turtle, box tortoise',
38: 'banded gecko',
39: 'common iguana, iguana, Iguana iguana',
40: 'American chameleon, anole, Anolis carolinensis',
41: 'whiptail, whiptail lizard',
42: 'agama',
43: 'frilled lizard, Chlamydosaurus kingi',
44: 'alligator lizard',
45: 'Gila monster, Heloderma suspectum',
46: 'green lizard, Lacerta viridis',
47: 'African chameleon, Chamaeleo chamaeleon',
48: 'Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis',
49: 'African crocodile, Nile crocodile, Crocodylus niloticus',
50: 'American alligator, Alligator mississipiensis',
51: 'triceratops',
52: 'thunder snake, worm snake, Carphophis amoenus',
53: 'ringneck snake, ring-necked snake, ring snake',
54: 'hognose snake, puff adder, sand viper',
55: 'green snake, grass snake',
56: 'king snake, kingsnake',
57: 'garter snake, grass snake',
58: 'water snake',
59: 'vine snake',
60: 'night snake, Hypsiglena torquata',
61: 'boa constrictor, Constrictor constrictor',
62: 'rock python, rock snake, Python sebae',
63: 'Indian cobra, Naja naja',
64: 'green mamba',
65: 'sea snake',
66: 'horned viper, cerastes, sand viper, horned asp, Cerastes cornutus',
67: 'diamondback, diamondback rattlesnake, Crotalus adamanteus',
68: 'sidewinder, horned rattlesnake, Crotalus cerastes',
69: 'trilobite',
70: 'harvestman, daddy longlegs, Phalangium opilio',
71: 'scorpion',
72: 'black and gold garden spider, Argiope aurantia',
73: 'barn spider, Araneus cavaticus',
74: 'garden spider, Aranea diademata',
75: 'black widow, Latrodectus mactans',
76: 'tarantula',
77: 'wolf spider, hunting spider',
78: 'tick',
79: 'centipede',
80: 'black grouse',
81: 'ptarmigan',
82: 'ruffed grouse, partridge, Bonasa umbellus',
83: 'prairie chicken, prairie grouse, prairie fowl',
84: 'peacock',
85: 'quail',
86: 'partridge',
87: 'African grey, African gray, Psittacus erithacus',
88: 'macaw',
89: 'sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita',
90: 'lorikeet',
91: 'coucal',
92: 'bee eater',
93: 'hornbill',
94: 'hummingbird',
95: 'jacamar',
96: 'toucan',
97: 'drake',
98: 'red-breasted merganser, Mergus serrator',
99: 'goose',
100: 'black swan, Cygnus atratus',
101: 'tusker',
102: 'echidna, spiny anteater, anteater',
103: 'platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus',
104: 'wallaby, brush kangaroo',
105: 'koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus',
106: 'wombat',
107: 'jellyfish',
108: 'sea anemone, anemone',
109: 'brain coral',
110: 'flatworm, platyhelminth',
111: 'nematode, nematode worm, roundworm',
112: 'conch',
113: 'snail',
114: 'slug',
115: 'sea slug, nudibranch',
116: 'chiton, coat-of-mail shell, sea cradle, polyplacophore',
117: 'chambered nautilus, pearly nautilus, nautilus',
118: 'Dungeness crab, Cancer magister',
119: 'rock crab, Cancer irroratus',
120: 'fiddler crab',
121: 'king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica',
122: 'American lobster, Northern lobster, Maine lobster, Homarus americanus',
123: 'spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish',
124: 'crayfish, crawfish, crawdad, crawdaddy',
125: 'hermit crab',
126: 'isopod',
127: 'white stork, Ciconia ciconia',
128: 'black stork, Ciconia nigra',
129: 'spoonbill',
130: 'flamingo',
131: 'little blue heron, Egretta caerulea',
132: 'American egret, great white heron, Egretta albus',
133: 'bittern',
134: 'crane',
135: 'limpkin, Aramus pictus',
136: 'European gallinule, Porphyrio porphyrio',
137: 'American coot, marsh hen, mud hen, water hen, Fulica americana',
138: 'bustard',
139: 'ruddy turnstone, Arenaria interpres',
140: 'red-backed sandpiper, dunlin, Erolia alpina',
141: 'redshank, Tringa totanus',
142: 'dowitcher',
143: 'oystercatcher, oyster catcher',
144: 'pelican',
145: 'king penguin, Aptenodytes patagonica',
146: 'albatross, mollymawk',
147: 'grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus',
148: 'killer whale, killer, orca, grampus, sea wolf, Orcinus orca',
149: 'dugong, Dugong dugon',
150: 'sea lion',
151: 'Chihuahua',
152: 'Japanese spaniel',
153: 'Maltese dog, Maltese terrier, Maltese',
154: 'Pekinese, Pekingese, Peke',
155: 'Shih-Tzu',
156: 'Blenheim spaniel',
157: 'papillon',
158: 'toy terrier',
159: 'Rhodesian ridgeback',
160: 'Afghan hound, Afghan',
161: 'basset, basset hound',
162: 'beagle',
163: 'bloodhound, sleuthhound',
164: 'bluetick',
165: 'black-and-tan coonhound',
166: 'Walker hound, Walker foxhound',
167: 'English foxhound',
168: 'redbone',
169: 'borzoi, Russian wolfhound',
170: 'Irish wolfhound',
171: 'Italian greyhound',
172: 'whippet',
173: 'Ibizan hound, Ibizan Podenco',
174: 'Norwegian elkhound, elkhound',
175: 'otterhound, otter hound',
176: 'Saluki, gazelle hound',
177: 'Scottish deerhound, deerhound',
178: 'Weimaraner',
179: 'Staffordshire bullterrier, Staffordshire bull terrier',
180: 'American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier',
181: 'Bedlington terrier',
182: 'Border terrier',
183: 'Kerry blue terrier',
184: 'Irish terrier',
185: 'Norfolk terrier',
186: 'Norwich terrier',
187: 'Yorkshire terrier',
188: 'wire-haired fox terrier',
189: 'Lakeland terrier',
190: 'Sealyham terrier, Sealyham',
191: 'Airedale, Airedale terrier',
192: 'cairn, cairn terrier',
193: 'Australian terrier',
194: 'Dandie Dinmont, Dandie Dinmont terrier',
195: 'Boston bull, Boston terrier',
196: 'miniature schnauzer',
197: 'giant schnauzer',
198: 'standard schnauzer',
199: 'Scotch terrier, Scottish terrier, Scottie',
200: 'Tibetan terrier, chrysanthemum dog',
201: 'silky terrier, Sydney silky',
202: 'soft-coated wheaten terrier',
203: 'West Highland white terrier',
204: 'Lhasa, Lhasa apso',
205: 'flat-coated retriever',
206: 'curly-coated retriever',
207: 'golden retriever',
208: 'Labrador retriever',
209: 'Chesapeake Bay retriever',
210: 'German short-haired pointer',
211: 'vizsla, Hungarian pointer',
212: 'English setter',
213: 'Irish setter, red setter',
214: 'Gordon setter',
215: 'Brittany spaniel',
216: 'clumber, clumber spaniel',
217: 'English springer, English springer spaniel',
218: 'Welsh springer spaniel',
219: 'cocker spaniel, English cocker spaniel, cocker',
220: 'Sussex spaniel',
221: 'Irish water spaniel',
222: 'kuvasz',
223: 'schipperke',
224: 'groenendael',
225: 'malinois',
226: 'briard',
227: 'kelpie',
228: 'komondor',
229: 'Old English sheepdog, bobtail',
230: 'Shetland sheepdog, Shetland sheep dog, Shetland',
231: 'collie',
232: 'Border collie',
233: 'Bouvier des Flandres, Bouviers des Flandres',
234: 'Rottweiler',
235: 'German shepherd, German shepherd dog, German police dog, alsatian',
236: 'Doberman, Doberman pinscher',
237: 'miniature pinscher',
238: 'Greater Swiss Mountain dog',
239: 'Bernese mountain dog',
240: 'Appenzeller',
241: 'EntleBucher',
242: 'boxer',
243: 'bull mastiff',
244: 'Tibetan mastiff',
245: 'French bulldog',
246: 'Great Dane',
247: 'Saint Bernard, St Bernard',
248: 'Eskimo dog, husky',
249: 'malamute, malemute, Alaskan malamute',
250: 'Siberian husky',
251: 'dalmatian, coach dog, carriage dog',
252: 'affenpinscher, monkey pinscher, monkey dog',
253: 'basenji',
254: 'pug, pug-dog',
255: 'Leonberg',
256: 'Newfoundland, Newfoundland dog',
257: 'Great Pyrenees',
258: 'Samoyed, Samoyede',
259: 'Pomeranian',
260: 'chow, chow chow',
261: 'keeshond',
262: 'Brabancon griffon',
263: 'Pembroke, Pembroke Welsh corgi',
264: 'Cardigan, Cardigan Welsh corgi',
265: 'toy poodle',
266: 'miniature poodle',
267: 'standard poodle',
268: 'Mexican hairless',
269: 'timber wolf, grey wolf, gray wolf, Canis lupus',
270: 'white wolf, Arctic wolf, Canis lupus tundrarum',
271: 'red wolf, maned wolf, Canis rufus, Canis niger',
272: 'coyote, prairie wolf, brush wolf, Canis latrans',
273: 'dingo, warrigal, warragal, Canis dingo',
274: 'dhole, Cuon alpinus',
275: 'African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus',
276: 'hyena, hyaena',
277: 'red fox, Vulpes vulpes',
278: 'kit fox, Vulpes macrotis',
279: 'Arctic fox, white fox, Alopex lagopus',
280: 'grey fox, gray fox, Urocyon cinereoargenteus',
281: 'tabby, tabby cat',
282: 'tiger cat',
283: 'Persian cat',
284: 'Siamese cat, Siamese',
285: 'Egyptian cat',
286: 'cougar, puma, catamount, mountain lion, painter, panther, Felis concolor',
287: 'lynx, catamount',
288: 'leopard, Panthera pardus',
289: 'snow leopard, ounce, Panthera uncia',
290: 'jaguar, panther, Panthera onca, Felis onca',
291: 'lion, king of beasts, Panthera leo',
292: 'tiger, Panthera tigris',
293: 'cheetah, chetah, Acinonyx jubatus',
294: 'brown bear, bruin, Ursus arctos',
295: 'American black bear, black bear, Ursus americanus, Euarctos americanus',
296: 'ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus',
297: 'sloth bear, Melursus ursinus, Ursus ursinus',
298: 'mongoose',
299: 'meerkat, mierkat',
300: 'tiger beetle',
301: 'ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle',
302: 'ground beetle, carabid beetle',
303: 'long-horned beetle, longicorn, longicorn beetle',
304: 'leaf beetle, chrysomelid',
305: 'dung beetle',
306: 'rhinoceros beetle',
307: 'weevil',
308: 'fly',
309: 'bee',
310: 'ant, emmet, pismire',
311: 'grasshopper, hopper',
312: 'cricket',
313: 'walking stick, walkingstick, stick insect',
314: 'cockroach, roach',
315: 'mantis, mantid',
316: 'cicada, cicala',
317: 'leafhopper',
318: 'lacewing, lacewing fly',
319: "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
320: 'damselfly',
321: 'admiral',
322: 'ringlet, ringlet butterfly',
323: 'monarch, monarch butterfly, milkweed butterfly, Danaus plexippus',
324: 'cabbage butterfly',
325: 'sulphur butterfly, sulfur butterfly',
326: 'lycaenid, lycaenid butterfly',
327: 'starfish, sea star',
328: 'sea urchin',
329: 'sea cucumber, holothurian',
330: 'wood rabbit, cottontail, cottontail rabbit',
331: 'hare',
332: 'Angora, Angora rabbit',
333: 'hamster',
334: 'porcupine, hedgehog',
335: 'fox squirrel, eastern fox squirrel, Sciurus niger',
336: 'marmot',
337: 'beaver',
338: 'guinea pig, Cavia cobaya',
339: 'sorrel',
340: 'zebra',
341: 'hog, pig, grunter, squealer, Sus scrofa',
342: 'wild boar, boar, Sus scrofa',
343: 'warthog',
344: 'hippopotamus, hippo, river horse, Hippopotamus amphibius',
345: 'ox',
346: 'water buffalo, water ox, Asiatic buffalo, Bubalus bubalis',
347: 'bison',
348: 'ram, tup',
349: 'bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis',
350: 'ibex, Capra ibex',
351: 'hartebeest',
352: 'impala, Aepyceros melampus',
353: 'gazelle',
354: 'Arabian camel, dromedary, Camelus dromedarius',
355: 'llama',
356: 'weasel',
357: 'mink',
358: 'polecat, fitch, foulmart, foumart, Mustela putorius',
359: 'black-footed ferret, ferret, Mustela nigripes',
360: 'otter',
361: 'skunk, polecat, wood pussy',
362: 'badger',
363: 'armadillo',
364: 'three-toed sloth, ai, Bradypus tridactylus',
365: 'orangutan, orang, orangutang, Pongo pygmaeus',
366: 'gorilla, Gorilla gorilla',
367: 'chimpanzee, chimp, Pan troglodytes',
368: 'gibbon, Hylobates lar',
369: 'siamang, Hylobates syndactylus, Symphalangus syndactylus',
370: 'guenon, guenon monkey',
371: 'patas, hussar monkey, Erythrocebus patas',
372: 'baboon',
373: 'macaque',
374: 'langur',
375: 'colobus, colobus monkey',
376: 'proboscis monkey, Nasalis larvatus',
377: 'marmoset',
378: 'capuchin, ringtail, Cebus capucinus',
379: 'howler monkey, howler',
380: 'titi, titi monkey',
381: 'spider monkey, Ateles geoffroyi',
382: 'squirrel monkey, Saimiri sciureus',
383: 'Madagascar cat, ring-tailed lemur, Lemur catta',
384: 'indri, indris, Indri indri, Indri brevicaudatus',
385: 'Indian elephant, Elephas maximus',
386: 'African elephant, Loxodonta africana',
387: 'lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens',
388: 'giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca',
389: 'barracouta, snoek',
390: 'eel',
391: 'coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch',
392: 'rock beauty, Holocanthus tricolor',
393: 'anemone fish',
394: 'sturgeon',
395: 'gar, garfish, garpike, billfish, Lepisosteus osseus',
396: 'lionfish',
397: 'puffer, pufferfish, blowfish, globefish',
398: 'abacus',
399: 'abaya',
400: "academic gown, academic robe, judge's robe",
401: 'accordion, piano accordion, squeeze box',
402: 'acoustic guitar',
403: 'aircraft carrier, carrier, flattop, attack aircraft carrier',
404: 'airliner',
405: 'airship, dirigible',
406: 'altar',
407: 'ambulance',
408: 'amphibian, amphibious vehicle',
409: 'analog clock',
410: 'apiary, bee house',
411: 'apron',
412: 'ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin',
413: 'assault rifle, assault gun',
414: 'backpack, back pack, knapsack, packsack, rucksack, haversack',
415: 'bakery, bakeshop, bakehouse',
416: 'balance beam, beam',
417: 'balloon',
418: 'ballpoint, ballpoint pen, ballpen, Biro',
419: 'Band Aid',
420: 'banjo',
421: 'bannister, banister, balustrade, balusters, handrail',
422: 'barbell',
423: 'barber chair',
424: 'barbershop',
425: 'barn',
426: 'barometer',
427: 'barrel, cask',
428: 'barrow, garden cart, lawn cart, wheelbarrow',
429: 'baseball',
430: 'basketball',
431: 'bassinet',
432: 'bassoon',
433: 'bathing cap, swimming cap',
434: 'bath towel',
435: 'bathtub, bathing tub, bath, tub',
436: 'beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon',
437: 'beacon, lighthouse, beacon light, pharos',
438: 'beaker',
439: 'bearskin, busby, shako',
440: 'beer bottle',
441: 'beer glass',
442: 'bell cote, bell cot',
443: 'bib',
444: 'bicycle-built-for-two, tandem bicycle, tandem',
445: 'bikini, two-piece',
446: 'binder, ring-binder',
447: 'binoculars, field glasses, opera glasses',
448: 'birdhouse',
449: 'boathouse',
450: 'bobsled, bobsleigh, bob',
451: 'bolo tie, bolo, bola tie, bola',
452: 'bonnet, poke bonnet',
453: 'bookcase',
454: 'bookshop, bookstore, bookstall',
455: 'bottlecap',
456: 'bow',
457: 'bow tie, bow-tie, bowtie',
458: 'brass, memorial tablet, plaque',
459: 'brassiere, bra, bandeau',
460: 'breakwater, groin, groyne, mole, bulwark, seawall, jetty',
461: 'breastplate, aegis, egis',
462: 'broom',
463: 'bucket, pail',
464: 'buckle',
465: 'bulletproof vest',
466: 'bullet train, bullet',
467: 'butcher shop, meat market',
468: 'cab, hack, taxi, taxicab',
469: 'caldron, cauldron',
470: 'candle, taper, wax light',
471: 'cannon',
472: 'canoe',
473: 'can opener, tin opener',
474: 'cardigan',
475: 'car mirror',
476: 'carousel, carrousel, merry-go-round, roundabout, whirligig',
477: "carpenter's kit, tool kit",
478: 'carton',
479: 'car wheel',
480: 'cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM',
481: 'cassette',
482: 'cassette player',
483: 'castle',
484: 'catamaran',
485: 'CD player',
486: 'cello, violoncello',
487: 'cellular telephone, cellular phone, cellphone, cell, mobile phone',
488: 'chain',
489: 'chainlink fence',
490: 'chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour',
491: 'chain saw, chainsaw',
492: 'chest',
493: 'chiffonier, commode',
494: 'chime, bell, gong',
495: 'china cabinet, china closet',
496: 'Christmas stocking',
497: 'church, church building',
498: 'cinema, movie theater, movie theatre, movie house, picture palace',
499: 'cleaver, meat cleaver, chopper',
500: 'cliff dwelling',
501: 'cloak',
502: 'clog, geta, patten, sabot',
503: 'cocktail shaker',
504: 'coffee mug',
505: 'coffeepot',
506: 'coil, spiral, volute, whorl, helix',
507: 'combination lock',
508: 'computer keyboard, keypad',
509: 'confectionery, confectionary, candy store',
510: 'container ship, containership, container vessel',
511: 'convertible',
512: 'corkscrew, bottle screw',
513: 'cornet, horn, trumpet, trump',
514: 'cowboy boot',
515: 'cowboy hat, ten-gallon hat',
516: 'cradle',
517: 'crane',
518: 'crash helmet',
519: 'crate',
520: 'crib, cot',
521: 'Crock Pot',
522: 'croquet ball',
523: 'crutch',
524: 'cuirass',
525: 'dam, dike, dyke',
526: 'desk',
527: 'desktop computer',
528: 'dial telephone, dial phone',
529: 'diaper, nappy, napkin',
530: 'digital clock',
531: 'digital watch',
532: 'dining table, board',
533: 'dishrag, dishcloth',
534: 'dishwasher, dish washer, dishwashing machine',
535: 'disk brake, disc brake',
536: 'dock, dockage, docking facility',
537: 'dogsled, dog sled, dog sleigh',
538: 'dome',
539: 'doormat, welcome mat',
540: 'drilling platform, offshore rig',
541: 'drum, membranophone, tympan',
542: 'drumstick',
543: 'dumbbell',
544: 'Dutch oven',
545: 'electric fan, blower',
546: 'electric guitar',
547: 'electric locomotive',
548: 'entertainment center',
549: 'envelope',
550: 'espresso maker',
551: 'face powder',
552: 'feather boa, boa',
553: 'file, file cabinet, filing cabinet',
554: 'fireboat',
555: 'fire engine, fire truck',
556: 'fire screen, fireguard',
557: 'flagpole, flagstaff',
558: 'flute, transverse flute',
559: 'folding chair',
560: 'football helmet',
561: 'forklift',
562: 'fountain',
563: 'fountain pen',
564: 'four-poster',
565: 'freight car',
566: 'French horn, horn',
567: 'frying pan, frypan, skillet',
568: 'fur coat',
569: 'garbage truck, dustcart',
570: 'gasmask, respirator, gas helmet',
571: 'gas pump, gasoline pump, petrol pump, island dispenser',
572: 'goblet',
573: 'go-kart',
574: 'golf ball',
575: 'golfcart, golf cart',
576: 'gondola',
577: 'gong, tam-tam',
578: 'gown',
579: 'grand piano, grand',
580: 'greenhouse, nursery, glasshouse',
581: 'grille, radiator grille',
582: 'grocery store, grocery, food market, market',
583: 'guillotine',
584: 'hair slide',
585: 'hair spray',
586: 'half track',
587: 'hammer',
588: 'hamper',
589: 'hand blower, blow dryer, blow drier, hair dryer, hair drier',
590: 'hand-held computer, hand-held microcomputer',
591: 'handkerchief, hankie, hanky, hankey',
592: 'hard disc, hard disk, fixed disk',
593: 'harmonica, mouth organ, harp, mouth harp',
594: 'harp',
595: 'harvester, reaper',
596: 'hatchet',
597: 'holster',
598: 'home theater, home theatre',
599: 'honeycomb',
600: 'hook, claw',
601: 'hoopskirt, crinoline',
602: 'horizontal bar, high bar',
603: 'horse cart, horse-cart',
604: 'hourglass',
605: 'iPod',
606: 'iron, smoothing iron',
607: "jack-o'-lantern",
608: 'jean, blue jean, denim',
609: 'jeep, landrover',
610: 'jersey, T-shirt, tee shirt',
611: 'jigsaw puzzle',
612: 'jinrikisha, ricksha, rickshaw',
613: 'joystick',
614: 'kimono',
615: 'knee pad',
616: 'knot',
617: 'lab coat, laboratory coat',
618: 'ladle',
619: 'lampshade, lamp shade',
620: 'laptop, laptop computer',
621: 'lawn mower, mower',
622: 'lens cap, lens cover',
623: 'letter opener, paper knife, paperknife',
624: 'library',
625: 'lifeboat',
626: 'lighter, light, igniter, ignitor',
627: 'limousine, limo',
628: 'liner, ocean liner',
629: 'lipstick, lip rouge',
630: 'Loafer',
631: 'lotion',
632: 'loudspeaker, speaker, speaker unit, loudspeaker system, speaker system',
633: "loupe, jeweler's loupe",
634: 'lumbermill, sawmill',
635: 'magnetic compass',
636: 'mailbag, postbag',
637: 'mailbox, letter box',
638: 'maillot',
639: 'maillot, tank suit',
640: 'manhole cover',
641: 'maraca',
642: 'marimba, xylophone',
643: 'mask',
644: 'matchstick',
645: 'maypole',
646: 'maze, labyrinth',
647: 'measuring cup',
648: 'medicine chest, medicine cabinet',
649: 'megalith, megalithic structure',
650: 'microphone, mike',
651: 'microwave, microwave oven',
652: 'military uniform',
653: 'milk can',
654: 'minibus',
655: 'miniskirt, mini',
656: 'minivan',
657: 'missile',
658: 'mitten',
659: 'mixing bowl',
660: 'mobile home, manufactured home',
661: 'Model T',
662: 'modem',
663: 'monastery',
664: 'monitor',
665: 'moped',
666: 'mortar',
667: 'mortarboard',
668: 'mosque',
669: 'mosquito net',
670: 'motor scooter, scooter',
671: 'mountain bike, all-terrain bike, off-roader',
672: 'mountain tent',
673: 'mouse, computer mouse',
674: 'mousetrap',
675: 'moving van',
676: 'muzzle',
677: 'nail',
678: 'neck brace',
679: 'necklace',
680: 'nipple',
681: 'notebook, notebook computer',
682: 'obelisk',
683: 'oboe, hautboy, hautbois',
684: 'ocarina, sweet potato',
685: 'odometer, hodometer, mileometer, milometer',
686: 'oil filter',
687: 'organ, pipe organ',
688: 'oscilloscope, scope, cathode-ray oscilloscope, CRO',
689: 'overskirt',
690: 'oxcart',
691: 'oxygen mask',
692: 'packet',
693: 'paddle, boat paddle',
694: 'paddlewheel, paddle wheel',
695: 'padlock',
696: 'paintbrush',
697: "pajama, pyjama, pj's, jammies",
698: 'palace',
699: 'panpipe, pandean pipe, syrinx',
700: 'paper towel',
701: 'parachute, chute',
702: 'parallel bars, bars',
703: 'park bench',
704: 'parking meter',
705: 'passenger car, coach, carriage',
706: 'patio, terrace',
707: 'pay-phone, pay-station',
708: 'pedestal, plinth, footstall',
709: 'pencil box, pencil case',
710: 'pencil sharpener',
711: 'perfume, essence',
712: 'Petri dish',
713: 'photocopier',
714: 'pick, plectrum, plectron',
715: 'pickelhaube',
716: 'picket fence, paling',
717: 'pickup, pickup truck',
718: 'pier',
719: 'piggy bank, penny bank',
720: 'pill bottle',
721: 'pillow',
722: 'ping-pong ball',
723: 'pinwheel',
724: 'pirate, pirate ship',
725: 'pitcher, ewer',
726: "plane, carpenter's plane, woodworking plane",
727: 'planetarium',
728: 'plastic bag',
729: 'plate rack',
730: 'plow, plough',
731: "plunger, plumber's helper",
732: 'Polaroid camera, Polaroid Land camera',
733: 'pole',
734: 'police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria',
735: 'poncho',
736: 'pool table, billiard table, snooker table',
737: 'pop bottle, soda bottle',
738: 'pot, flowerpot',
739: "potter's wheel",
740: 'power drill',
741: 'prayer rug, prayer mat',
742: 'printer',
743: 'prison, prison house',
744: 'projectile, missile',
745: 'projector',
746: 'puck, hockey puck',
747: 'punching bag, punch bag, punching ball, punchball',
748: 'purse',
749: 'quill, quill pen',
750: 'quilt, comforter, comfort, puff',
751: 'racer, race car, racing car',
752: 'racket, racquet',
753: 'radiator',
754: 'radio, wireless',
755: 'radio telescope, radio reflector',
756: 'rain barrel',
757: 'recreational vehicle, RV, R.V.',
758: 'reel',
759: 'reflex camera',
760: 'refrigerator, icebox',
761: 'remote control, remote',
762: 'restaurant, eating house, eating place, eatery',
763: 'revolver, six-gun, six-shooter',
764: 'rifle',
765: 'rocking chair, rocker',
766: 'rotisserie',
767: 'rubber eraser, rubber, pencil eraser',
768: 'rugby ball',
769: 'rule, ruler',
770: 'running shoe',
771: 'safe',
772: 'safety pin',
773: 'saltshaker, salt shaker',
774: 'sandal',
775: 'sarong',
776: 'sax, saxophone',
777: 'scabbard',
778: 'scale, weighing machine',
779: 'school bus',
780: 'schooner',
781: 'scoreboard',
782: 'screen, CRT screen',
783: 'screw',
784: 'screwdriver',
785: 'seat belt, seatbelt',
786: 'sewing machine',
787: 'shield, buckler',
788: 'shoe shop, shoe-shop, shoe store',
789: 'shoji',
790: 'shopping basket',
791: 'shopping cart',
792: 'shovel',
793: 'shower cap',
794: 'shower curtain',
795: 'ski',
796: 'ski mask',
797: 'sleeping bag',
798: 'slide rule, slipstick',
799: 'sliding door',
800: 'slot, one-armed bandit',
801: 'snorkel',
802: 'snowmobile',
803: 'snowplow, snowplough',
804: 'soap dispenser',
805: 'soccer ball',
806: 'sock',
807: 'solar dish, solar collector, solar furnace',
808: 'sombrero',
809: 'soup bowl',
810: 'space bar',
811: 'space heater',
812: 'space shuttle',
813: 'spatula',
814: 'speedboat',
815: "spider web, spider's web",
816: 'spindle',
817: 'sports car, sport car',
818: 'spotlight, spot',
819: 'stage',
820: 'steam locomotive',
821: 'steel arch bridge',
822: 'steel drum',
823: 'stethoscope',
824: 'stole',
825: 'stone wall',
826: 'stopwatch, stop watch',
827: 'stove',
828: 'strainer',
829: 'streetcar, tram, tramcar, trolley, trolley car',
830: 'stretcher',
831: 'studio couch, day bed',
832: 'stupa, tope',
833: 'submarine, pigboat, sub, U-boat',
834: 'suit, suit of clothes',
835: 'sundial',
836: 'sunglass',
837: 'sunglasses, dark glasses, shades',
838: 'sunscreen, sunblock, sun blocker',
839: 'suspension bridge',
840: 'swab, swob, mop',
841: 'sweatshirt',
842: 'swimming trunks, bathing trunks',
843: 'swing',
844: 'switch, electric switch, electrical switch',
845: 'syringe',
846: 'table lamp',
847: 'tank, army tank, armored combat vehicle, armoured combat vehicle',
848: 'tape player',
849: 'teapot',
850: 'teddy, teddy bear',
851: 'television, television system',
852: 'tennis ball',
853: 'thatch, thatched roof',
854: 'theater curtain, theatre curtain',
855: 'thimble',
856: 'thresher, thrasher, threshing machine',
857: 'throne',
858: 'tile roof',
859: 'toaster',
860: 'tobacco shop, tobacconist shop, tobacconist',
861: 'toilet seat',
862: 'torch',
863: 'totem pole',
864: 'tow truck, tow car, wrecker',
865: 'toyshop',
866: 'tractor',
867: 'trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi',
868: 'tray',
869: 'trench coat',
870: 'tricycle, trike, velocipede',
871: 'trimaran',
872: 'tripod',
873: 'triumphal arch',
874: 'trolleybus, trolley coach, trackless trolley',
875: 'trombone',
876: 'tub, vat',
877: 'turnstile',
878: 'typewriter keyboard',
879: 'umbrella',
880: 'unicycle, monocycle',
881: 'upright, upright piano',
882: 'vacuum, vacuum cleaner',
883: 'vase',
884: 'vault',
885: 'velvet',
886: 'vending machine',
887: 'vestment',
888: 'viaduct',
889: 'violin, fiddle',
890: 'volleyball',
891: 'waffle iron',
892: 'wall clock',
893: 'wallet, billfold, notecase, pocketbook',
894: 'wardrobe, closet, press',
895: 'warplane, military plane',
896: 'washbasin, handbasin, washbowl, lavabo, wash-hand basin',
897: 'washer, automatic washer, washing machine',
898: 'water bottle',
899: 'water jug',
900: 'water tower',
901: 'whiskey jug',
902: 'whistle',
903: 'wig',
904: 'window screen',
905: 'window shade',
906: 'Windsor tie',
907: 'wine bottle',
908: 'wing',
909: 'wok',
910: 'wooden spoon',
911: 'wool, woolen, woollen',
912: 'worm fence, snake fence, snake-rail fence, Virginia fence',
913: 'wreck',
914: 'yawl',
915: 'yurt',
916: 'web site, website, internet site, site',
917: 'comic book',
918: 'crossword puzzle, crossword',
919: 'street sign',
920: 'traffic light, traffic signal, stoplight',
921: 'book jacket, dust cover, dust jacket, dust wrapper',
922: 'menu',
923: 'plate',
924: 'guacamole',
925: 'consomme',
926: 'hot pot, hotpot',
927: 'trifle',
928: 'ice cream, icecream',
929: 'ice lolly, lolly, lollipop, popsicle',
930: 'French loaf',
931: 'bagel, beigel',
932: 'pretzel',
933: 'cheeseburger',
934: 'hotdog, hot dog, red hot',
935: 'mashed potato',
936: 'head cabbage',
937: 'broccoli',
938: 'cauliflower',
939: 'zucchini, courgette',
940: 'spaghetti squash',
941: 'acorn squash',
942: 'butternut squash',
943: 'cucumber, cuke',
944: 'artichoke, globe artichoke',
945: 'bell pepper',
946: 'cardoon',
947: 'mushroom',
948: 'Granny Smith',
949: 'strawberry',
950: 'orange',
951: 'lemon',
952: 'fig',
953: 'pineapple, ananas',
954: 'banana',
955: 'jackfruit, jak, jack',
956: 'custard apple',
957: 'pomegranate',
958: 'hay',
959: 'carbonara',
960: 'chocolate sauce, chocolate syrup',
961: 'dough',
962: 'meat loaf, meatloaf',
963: 'pizza, pizza pie',
964: 'potpie',
965: 'burrito',
966: 'red wine',
967: 'espresso',
968: 'cup',
969: 'eggnog',
970: 'alp',
971: 'bubble',
972: 'cliff, drop, drop-off',
973: 'coral reef',
974: 'geyser',
975: 'lakeside, lakeshore',
976: 'promontory, headland, head, foreland',
977: 'sandbar, sand bar',
978: 'seashore, coast, seacoast, sea-coast',
979: 'valley, vale',
980: 'volcano',
981: 'ballplayer, baseball player',
982: 'groom, bridegroom',
983: 'scuba diver',
984: 'rapeseed',
985: 'daisy',
986: "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
987: 'corn',
988: 'acorn',
989: 'hip, rose hip, rosehip',
990: 'buckeye, horse chestnut, conker',
991: 'coral fungus',
992: 'agaric',
993: 'gyromitra',
994: 'stinkhorn, carrion fungus',
995: 'earthstar',
996: 'hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa',
997: 'bolete',
998: 'ear, spike, capitulum',
999: 'toilet tissue, toilet paper, bathroom tissue'}
{
"0": "tench, Tinca tinca",
"1": "goldfish, Carassius auratus",
"2": "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias",
"3": "tiger shark, Galeocerdo cuvieri",
"4": "hammerhead, hammerhead shark",
"5": "electric ray, crampfish, numbfish, torpedo",
"6": "stingray",
"7": "cock",
"8": "hen",
"9": "ostrich, Struthio camelus",
"10": "brambling, Fringilla montifringilla",
"11": "goldfinch, Carduelis carduelis",
"12": "house finch, linnet, Carpodacus mexicanus",
"13": "junco, snowbird",
"14": "indigo bunting, indigo finch, indigo bird, Passerina cyanea",
"15": "robin, American robin, Turdus migratorius",
"16": "bulbul",
"17": "jay",
"18": "magpie",
"19": "chickadee",
"20": "water ouzel, dipper",
"21": "kite",
"22": "bald eagle, American eagle, Haliaeetus leucocephalus",
"23": "vulture",
"24": "great grey owl, great gray owl, Strix nebulosa",
"25": "European fire salamander, Salamandra salamandra",
"26": "common newt, Triturus vulgaris",
"27": "eft",
"28": "spotted salamander, Ambystoma maculatum",
"29": "axolotl, mud puppy, Ambystoma mexicanum",
"30": "bullfrog, Rana catesbeiana",
"31": "tree frog, tree-frog",
"32": "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui",
"33": "loggerhead, loggerhead turtle, Caretta caretta",
"34": "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea",
"35": "mud turtle",
"36": "terrapin",
"37": "box turtle, box tortoise",
"38": "banded gecko",
"39": "common iguana, iguana, Iguana iguana",
"40": "American chameleon, anole, Anolis carolinensis",
"41": "whiptail, whiptail lizard",
"42": "agama",
"43": "frilled lizard, Chlamydosaurus kingi",
"44": "alligator lizard",
"45": "Gila monster, Heloderma suspectum",
"46": "green lizard, Lacerta viridis",
"47": "African chameleon, Chamaeleo chamaeleon",
"48": "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis",
"49": "African crocodile, Nile crocodile, Crocodylus niloticus",
"50": "American alligator, Alligator mississipiensis",
"51": "triceratops",
"52": "thunder snake, worm snake, Carphophis amoenus",
"53": "ringneck snake, ring-necked snake, ring snake",
"54": "hognose snake, puff adder, sand viper",
"55": "green snake, grass snake",
"56": "king snake, kingsnake",
"57": "garter snake, grass snake",
"58": "water snake",
"59": "vine snake",
"60": "night snake, Hypsiglena torquata",
"61": "boa constrictor, Constrictor constrictor",
"62": "rock python, rock snake, Python sebae",
"63": "Indian cobra, Naja naja",
"64": "green mamba",
"65": "sea snake",
"66": "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus",
"67": "diamondback, diamondback rattlesnake, Crotalus adamanteus",
"68": "sidewinder, horned rattlesnake, Crotalus cerastes",
"69": "trilobite",
"70": "harvestman, daddy longlegs, Phalangium opilio",
"71": "scorpion",
"72": "black and gold garden spider, Argiope aurantia",
"73": "barn spider, Araneus cavaticus",
"74": "garden spider, Aranea diademata",
"75": "black widow, Latrodectus mactans",
"76": "tarantula",
"77": "wolf spider, hunting spider",
"78": "tick",
"79": "centipede",
"80": "black grouse",
"81": "ptarmigan",
"82": "ruffed grouse, partridge, Bonasa umbellus",
"83": "prairie chicken, prairie grouse, prairie fowl",
"84": "peacock",
"85": "quail",
"86": "partridge",
"87": "African grey, African gray, Psittacus erithacus",
"88": "macaw",
"89": "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita",
"90": "lorikeet",
"91": "coucal",
"92": "bee eater",
"93": "hornbill",
"94": "hummingbird",
"95": "jacamar",
"96": "toucan",
"97": "drake",
"98": "red-breasted merganser, Mergus serrator",
"99": "goose",
"100": "black swan, Cygnus atratus",
"101": "tusker",
"102": "echidna, spiny anteater, anteater",
"103": "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus",
"104": "wallaby, brush kangaroo",
"105": "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus",
"106": "wombat",
"107": "jellyfish",
"108": "sea anemone, anemone",
"109": "brain coral",
"110": "flatworm, platyhelminth",
"111": "nematode, nematode worm, roundworm",
"112": "conch",
"113": "snail",
"114": "slug",
"115": "sea slug, nudibranch",
"116": "chiton, coat-of-mail shell, sea cradle, polyplacophore",
"117": "chambered nautilus, pearly nautilus, nautilus",
"118": "Dungeness crab, Cancer magister",
"119": "rock crab, Cancer irroratus",
"120": "fiddler crab",
"121": "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica",
"122": "American lobster, Northern lobster, Maine lobster, Homarus americanus",
"123": "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish",
"124": "crayfish, crawfish, crawdad, crawdaddy",
"125": "hermit crab",
"126": "isopod",
"127": "white stork, Ciconia ciconia",
"128": "black stork, Ciconia nigra",
"129": "spoonbill",
"130": "flamingo",
"131": "little blue heron, Egretta caerulea",
"132": "American egret, great white heron, Egretta albus",
"133": "bittern",
"134": "crane",
"135": "limpkin, Aramus pictus",
"136": "European gallinule, Porphyrio porphyrio",
"137": "American coot, marsh hen, mud hen, water hen, Fulica americana",
"138": "bustard",
"139": "ruddy turnstone, Arenaria interpres",
"140": "red-backed sandpiper, dunlin, Erolia alpina",
"141": "redshank, Tringa totanus",
"142": "dowitcher",
"143": "oystercatcher, oyster catcher",
"144": "pelican",
"145": "king penguin, Aptenodytes patagonica",
"146": "albatross, mollymawk",
"147": "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus",
"148": "killer whale, killer, orca, grampus, sea wolf, Orcinus orca",
"149": "dugong, Dugong dugon",
"150": "sea lion",
"151": "Chihuahua",
"152": "Japanese spaniel",
"153": "Maltese dog, Maltese terrier, Maltese",
"154": "Pekinese, Pekingese, Peke",
"155": "Shih-Tzu",
"156": "Blenheim spaniel",
"157": "papillon",
"158": "toy terrier",
"159": "Rhodesian ridgeback",
"160": "Afghan hound, Afghan",
"161": "basset, basset hound",
"162": "beagle",
"163": "bloodhound, sleuthhound",
"164": "bluetick",
"165": "black-and-tan coonhound",
"166": "Walker hound, Walker foxhound",
"167": "English foxhound",
"168": "redbone",
"169": "borzoi, Russian wolfhound",
"170": "Irish wolfhound",
"171": "Italian greyhound",
"172": "whippet",
"173": "Ibizan hound, Ibizan Podenco",
"174": "Norwegian elkhound, elkhound",
"175": "otterhound, otter hound",
"176": "Saluki, gazelle hound",
"177": "Scottish deerhound, deerhound",
"178": "Weimaraner",
"179": "Staffordshire bullterrier, Staffordshire bull terrier",
"180": "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier",
"181": "Bedlington terrier",
"182": "Border terrier",
"183": "Kerry blue terrier",
"184": "Irish terrier",
"185": "Norfolk terrier",
"186": "Norwich terrier",
"187": "Yorkshire terrier",
"188": "wire-haired fox terrier",
"189": "Lakeland terrier",
"190": "Sealyham terrier, Sealyham",
"191": "Airedale, Airedale terrier",
"192": "cairn, cairn terrier",
"193": "Australian terrier",
"194": "Dandie Dinmont, Dandie Dinmont terrier",
"195": "Boston bull, Boston terrier",
"196": "miniature schnauzer",
"197": "giant schnauzer",
"198": "standard schnauzer",
"199": "Scotch terrier, Scottish terrier, Scottie",
"200": "Tibetan terrier, chrysanthemum dog",
"201": "silky terrier, Sydney silky",
"202": "soft-coated wheaten terrier",
"203": "West Highland white terrier",
"204": "Lhasa, Lhasa apso",
"205": "flat-coated retriever",
"206": "curly-coated retriever",
"207": "golden retriever",
"208": "Labrador retriever",
"209": "Chesapeake Bay retriever",
"210": "German short-haired pointer",
"211": "vizsla, Hungarian pointer",
"212": "English setter",
"213": "Irish setter, red setter",
"214": "Gordon setter",
"215": "Brittany spaniel",
"216": "clumber, clumber spaniel",
"217": "English springer, English springer spaniel",
"218": "Welsh springer spaniel",
"219": "cocker spaniel, English cocker spaniel, cocker",
"220": "Sussex spaniel",
"221": "Irish water spaniel",
"222": "kuvasz",
"223": "schipperke",
"224": "groenendael",
"225": "malinois",
"226": "briard",
"227": "kelpie",
"228": "komondor",
"229": "Old English sheepdog, bobtail",
"230": "Shetland sheepdog, Shetland sheep dog, Shetland",
"231": "collie",
"232": "Border collie",
"233": "Bouvier des Flandres, Bouviers des Flandres",
"234": "Rottweiler",
"235": "German shepherd, German shepherd dog, German police dog, alsatian",
"236": "Doberman, Doberman pinscher",
"237": "miniature pinscher",
"238": "Greater Swiss Mountain dog",
"239": "Bernese mountain dog",
"240": "Appenzeller",
"241": "EntleBucher",
"242": "boxer",
"243": "bull mastiff",
"244": "Tibetan mastiff",
"245": "French bulldog",
"246": "Great Dane",
"247": "Saint Bernard, St Bernard",
"248": "Eskimo dog, husky",
"249": "malamute, malemute, Alaskan malamute",
"250": "Siberian husky",
"251": "dalmatian, coach dog, carriage dog",
"252": "affenpinscher, monkey pinscher, monkey dog",
"253": "basenji",
"254": "pug, pug-dog",
"255": "Leonberg",
"256": "Newfoundland, Newfoundland dog",
"257": "Great Pyrenees",
"258": "Samoyed, Samoyede",
"259": "Pomeranian",
"260": "chow, chow chow",
"261": "keeshond",
"262": "Brabancon griffon",
"263": "Pembroke, Pembroke Welsh corgi",
"264": "Cardigan, Cardigan Welsh corgi",
"265": "toy poodle",
"266": "miniature poodle",
"267": "standard poodle",
"268": "Mexican hairless",
"269": "timber wolf, grey wolf, gray wolf, Canis lupus",
"270": "white wolf, Arctic wolf, Canis lupus tundrarum",
"271": "red wolf, maned wolf, Canis rufus, Canis niger",
"272": "coyote, prairie wolf, brush wolf, Canis latrans",
"273": "dingo, warrigal, warragal, Canis dingo",
"274": "dhole, Cuon alpinus",
"275": "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus",
"276": "hyena, hyaena",
"277": "red fox, Vulpes vulpes",
"278": "kit fox, Vulpes macrotis",
"279": "Arctic fox, white fox, Alopex lagopus",
"280": "grey fox, gray fox, Urocyon cinereoargenteus",
"281": "tabby, tabby cat",
"282": "tiger cat",
"283": "Persian cat",
"284": "Siamese cat, Siamese",
"285": "Egyptian cat",
"286": "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor",
"287": "lynx, catamount",
"288": "leopard, Panthera pardus",
"289": "snow leopard, ounce, Panthera uncia",
"290": "jaguar, panther, Panthera onca, Felis onca",
"291": "lion, king of beasts, Panthera leo",
"292": "tiger, Panthera tigris",
"293": "cheetah, chetah, Acinonyx jubatus",
"294": "brown bear, bruin, Ursus arctos",
"295": "American black bear, black bear, Ursus americanus, Euarctos americanus",
"296": "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus",
"297": "sloth bear, Melursus ursinus, Ursus ursinus",
"298": "mongoose",
"299": "meerkat, mierkat",
"300": "tiger beetle",
"301": "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle",
"302": "ground beetle, carabid beetle",
"303": "long-horned beetle, longicorn, longicorn beetle",
"304": "leaf beetle, chrysomelid",
"305": "dung beetle",
"306": "rhinoceros beetle",
"307": "weevil",
"308": "fly",
"309": "bee",
"310": "ant, emmet, pismire",
"311": "grasshopper, hopper",
"312": "cricket",
"313": "walking stick, walkingstick, stick insect",
"314": "cockroach, roach",
"315": "mantis, mantid",
"316": "cicada, cicala",
"317": "leafhopper",
"318": "lacewing, lacewing fly",
"319": "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk",
"320": "damselfly",
"321": "admiral",
"322": "ringlet, ringlet butterfly",
"323": "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus",
"324": "cabbage butterfly",
"325": "sulphur butterfly, sulfur butterfly",
"326": "lycaenid, lycaenid butterfly",
"327": "starfish, sea star",
"328": "sea urchin",
"329": "sea cucumber, holothurian",
"330": "wood rabbit, cottontail, cottontail rabbit",
"331": "hare",
"332": "Angora, Angora rabbit",
"333": "hamster",
"334": "porcupine, hedgehog",
"335": "fox squirrel, eastern fox squirrel, Sciurus niger",
"336": "marmot",
"337": "beaver",
"338": "guinea pig, Cavia cobaya",
"339": "sorrel",
"340": "zebra",
"341": "hog, pig, grunter, squealer, Sus scrofa",
"342": "wild boar, boar, Sus scrofa",
"343": "warthog",
"344": "hippopotamus, hippo, river horse, Hippopotamus amphibius",
"345": "ox",
"346": "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis",
"347": "bison",
"348": "ram, tup",
"349": "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis",
"350": "ibex, Capra ibex",
"351": "hartebeest",
"352": "impala, Aepyceros melampus",
"353": "gazelle",
"354": "Arabian camel, dromedary, Camelus dromedarius",
"355": "llama",
"356": "weasel",
"357": "mink",
"358": "polecat, fitch, foulmart, foumart, Mustela putorius",
"359": "black-footed ferret, ferret, Mustela nigripes",
"360": "otter",
"361": "skunk, polecat, wood pussy",
"362": "badger",
"363": "armadillo",
"364": "three-toed sloth, ai, Bradypus tridactylus",
"365": "orangutan, orang, orangutang, Pongo pygmaeus",
"366": "gorilla, Gorilla gorilla",
"367": "chimpanzee, chimp, Pan troglodytes",
"368": "gibbon, Hylobates lar",
"369": "siamang, Hylobates syndactylus, Symphalangus syndactylus",
"370": "guenon, guenon monkey",
"371": "patas, hussar monkey, Erythrocebus patas",
"372": "baboon",
"373": "macaque",
"374": "langur",
"375": "colobus, colobus monkey",
"376": "proboscis monkey, Nasalis larvatus",
"377": "marmoset",
"378": "capuchin, ringtail, Cebus capucinus",
"379": "howler monkey, howler",
"380": "titi, titi monkey",
"381": "spider monkey, Ateles geoffroyi",
"382": "squirrel monkey, Saimiri sciureus",
"383": "Madagascar cat, ring-tailed lemur, Lemur catta",
"384": "indri, indris, Indri indri, Indri brevicaudatus",
"385": "Indian elephant, Elephas maximus",
"386": "African elephant, Loxodonta africana",
"387": "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens",
"388": "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca",
"389": "barracouta, snoek",
"390": "eel",
"391": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
"392": "rock beauty, Holocanthus tricolor",
"393": "anemone fish",
"394": "sturgeon",
"395": "gar, garfish, garpike, billfish, Lepisosteus osseus",
"396": "lionfish",
"397": "puffer, pufferfish, blowfish, globefish",
"398": "abacus",
"399": "abaya",
"400": "academic gown, academic robe, judge's robe",
"401": "accordion, piano accordion, squeeze box",
"402": "acoustic guitar",
"403": "aircraft carrier, carrier, flattop, attack aircraft carrier",
"404": "airliner",
"405": "airship, dirigible",
"406": "altar",
"407": "ambulance",
"408": "amphibian, amphibious vehicle",
"409": "analog clock",
"410": "apiary, bee house",
"411": "apron",
"412": "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin",
"413": "assault rifle, assault gun",
"414": "backpack, back pack, knapsack, packsack, rucksack, haversack",
"415": "bakery, bakeshop, bakehouse",
"416": "balance beam, beam",
"417": "balloon",
"418": "ballpoint, ballpoint pen, ballpen, Biro",
"419": "Band Aid",
"420": "banjo",
"421": "bannister, banister, balustrade, balusters, handrail",
"422": "barbell",
"423": "barber chair",
"424": "barbershop",
"425": "barn",
"426": "barometer",
"427": "barrel, cask",
"428": "barrow, garden cart, lawn cart, wheelbarrow",
"429": "baseball",
"430": "basketball",
"431": "bassinet",
"432": "bassoon",
"433": "bathing cap, swimming cap",
"434": "bath towel",
"435": "bathtub, bathing tub, bath, tub",
"436": "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon",
"437": "beacon, lighthouse, beacon light, pharos",
"438": "beaker",
"439": "bearskin, busby, shako",
"440": "beer bottle",
"441": "beer glass",
"442": "bell cote, bell cot",
"443": "bib",
"444": "bicycle-built-for-two, tandem bicycle, tandem",
"445": "bikini, two-piece",
"446": "binder, ring-binder",
"447": "binoculars, field glasses, opera glasses",
"448": "birdhouse",
"449": "boathouse",
"450": "bobsled, bobsleigh, bob",
"451": "bolo tie, bolo, bola tie, bola",
"452": "bonnet, poke bonnet",
"453": "bookcase",
"454": "bookshop, bookstore, bookstall",
"455": "bottlecap",
"456": "bow",
"457": "bow tie, bow-tie, bowtie",
"458": "brass, memorial tablet, plaque",
"459": "brassiere, bra, bandeau",
"460": "breakwater, groin, groyne, mole, bulwark, seawall, jetty",
"461": "breastplate, aegis, egis",
"462": "broom",
"463": "bucket, pail",
"464": "buckle",
"465": "bulletproof vest",
"466": "bullet train, bullet",
"467": "butcher shop, meat market",
"468": "cab, hack, taxi, taxicab",
"469": "caldron, cauldron",
"470": "candle, taper, wax light",
"471": "cannon",
"472": "canoe",
"473": "can opener, tin opener",
"474": "cardigan",
"475": "car mirror",
"476": "carousel, carrousel, merry-go-round, roundabout, whirligig",
"477": "carpenter's kit, tool kit",
"478": "carton",
"479": "car wheel",
"480": "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM",
"481": "cassette",
"482": "cassette player",
"483": "castle",
"484": "catamaran",
"485": "CD player",
"486": "cello, violoncello",
"487": "cellular telephone, cellular phone, cellphone, cell, mobile phone",
"488": "chain",
"489": "chainlink fence",
"490": "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour",
"491": "chain saw, chainsaw",
"492": "chest",
"493": "chiffonier, commode",
"494": "chime, bell, gong",
"495": "china cabinet, china closet",
"496": "Christmas stocking",
"497": "church, church building",
"498": "cinema, movie theater, movie theatre, movie house, picture palace",
"499": "cleaver, meat cleaver, chopper",
"500": "cliff dwelling",
"501": "cloak",
"502": "clog, geta, patten, sabot",
"503": "cocktail shaker",
"504": "coffee mug",
"505": "coffeepot",
"506": "coil, spiral, volute, whorl, helix",
"507": "combination lock",
"508": "computer keyboard, keypad",
"509": "confectionery, confectionary, candy store",
"510": "container ship, containership, container vessel",
"511": "convertible",
"512": "corkscrew, bottle screw",
"513": "cornet, horn, trumpet, trump",
"514": "cowboy boot",
"515": "cowboy hat, ten-gallon hat",
"516": "cradle",
"517": "crane",
"518": "crash helmet",
"519": "crate",
"520": "crib, cot",
"521": "Crock Pot",
"522": "croquet ball",
"523": "crutch",
"524": "cuirass",
"525": "dam, dike, dyke",
"526": "desk",
"527": "desktop computer",
"528": "dial telephone, dial phone",
"529": "diaper, nappy, napkin",
"530": "digital clock",
"531": "digital watch",
"532": "dining table, board",
"533": "dishrag, dishcloth",
"534": "dishwasher, dish washer, dishwashing machine",
"535": "disk brake, disc brake",
"536": "dock, dockage, docking facility",
"537": "dogsled, dog sled, dog sleigh",
"538": "dome",
"539": "doormat, welcome mat",
"540": "drilling platform, offshore rig",
"541": "drum, membranophone, tympan",
"542": "drumstick",
"543": "dumbbell",
"544": "Dutch oven",
"545": "electric fan, blower",
"546": "electric guitar",
"547": "electric locomotive",
"548": "entertainment center",
"549": "envelope",
"550": "espresso maker",
"551": "face powder",
"552": "feather boa, boa",
"553": "file, file cabinet, filing cabinet",
"554": "fireboat",
"555": "fire engine, fire truck",
"556": "fire screen, fireguard",
"557": "flagpole, flagstaff",
"558": "flute, transverse flute",
"559": "folding chair",
"560": "football helmet",
"561": "forklift",
"562": "fountain",
"563": "fountain pen",
"564": "four-poster",
"565": "freight car",
"566": "French horn, horn",
"567": "frying pan, frypan, skillet",
"568": "fur coat",
"569": "garbage truck, dustcart",
"570": "gasmask, respirator, gas helmet",
"571": "gas pump, gasoline pump, petrol pump, island dispenser",
"572": "goblet",
"573": "go-kart",
"574": "golf ball",
"575": "golfcart, golf cart",
"576": "gondola",
"577": "gong, tam-tam",
"578": "gown",
"579": "grand piano, grand",
"580": "greenhouse, nursery, glasshouse",
"581": "grille, radiator grille",
"582": "grocery store, grocery, food market, market",
"583": "guillotine",
"584": "hair slide",
"585": "hair spray",
"586": "half track",
"587": "hammer",
"588": "hamper",
"589": "hand blower, blow dryer, blow drier, hair dryer, hair drier",
"590": "hand-held computer, hand-held microcomputer",
"591": "handkerchief, hankie, hanky, hankey",
"592": "hard disc, hard disk, fixed disk",
"593": "harmonica, mouth organ, harp, mouth harp",
"594": "harp",
"595": "harvester, reaper",
"596": "hatchet",
"597": "holster",
"598": "home theater, home theatre",
"599": "honeycomb",
"600": "hook, claw",
"601": "hoopskirt, crinoline",
"602": "horizontal bar, high bar",
"603": "horse cart, horse-cart",
"604": "hourglass",
"605": "iPod",
"606": "iron, smoothing iron",
"607": "jack-o'-lantern",
"608": "jean, blue jean, denim",
"609": "jeep, landrover",
"610": "jersey, T-shirt, tee shirt",
"611": "jigsaw puzzle",
"612": "jinrikisha, ricksha, rickshaw",
"613": "joystick",
"614": "kimono",
"615": "knee pad",
"616": "knot",
"617": "lab coat, laboratory coat",
"618": "ladle",
"619": "lampshade, lamp shade",
"620": "laptop, laptop computer",
"621": "lawn mower, mower",
"622": "lens cap, lens cover",
"623": "letter opener, paper knife, paperknife",
"624": "library",
"625": "lifeboat",
"626": "lighter, light, igniter, ignitor",
"627": "limousine, limo",
"628": "liner, ocean liner",
"629": "lipstick, lip rouge",
"630": "Loafer",
"631": "lotion",
"632": "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system",
"633": "loupe, jeweler's loupe",
"634": "lumbermill, sawmill",
"635": "magnetic compass",
"636": "mailbag, postbag",
"637": "mailbox, letter box",
"638": "maillot",
"639": "maillot, tank suit",
"640": "manhole cover",
"641": "maraca",
"642": "marimba, xylophone",
"643": "mask",
"644": "matchstick",
"645": "maypole",
"646": "maze, labyrinth",
"647": "measuring cup",
"648": "medicine chest, medicine cabinet",
"649": "megalith, megalithic structure",
"650": "microphone, mike",
"651": "microwave, microwave oven",
"652": "military uniform",
"653": "milk can",
"654": "minibus",
"655": "miniskirt, mini",
"656": "minivan",
"657": "missile",
"658": "mitten",
"659": "mixing bowl",
"660": "mobile home, manufactured home",
"661": "Model T",
"662": "modem",
"663": "monastery",
"664": "monitor",
"665": "moped",
"666": "mortar",
"667": "mortarboard",
"668": "mosque",
"669": "mosquito net",
"670": "motor scooter, scooter",
"671": "mountain bike, all-terrain bike, off-roader",
"672": "mountain tent",
"673": "mouse, computer mouse",
"674": "mousetrap",
"675": "moving van",
"676": "muzzle",
"677": "nail",
"678": "neck brace",
"679": "necklace",
"680": "nipple",
"681": "notebook, notebook computer",
"682": "obelisk",
"683": "oboe, hautboy, hautbois",
"684": "ocarina, sweet potato",
"685": "odometer, hodometer, mileometer, milometer",
"686": "oil filter",
"687": "organ, pipe organ",
"688": "oscilloscope, scope, cathode-ray oscilloscope, CRO",
"689": "overskirt",
"690": "oxcart",
"691": "oxygen mask",
"692": "packet",
"693": "paddle, boat paddle",
"694": "paddlewheel, paddle wheel",
"695": "padlock",
"696": "paintbrush",
"697": "pajama, pyjama, pj's, jammies",
"698": "palace",
"699": "panpipe, pandean pipe, syrinx",
"700": "paper towel",
"701": "parachute, chute",
"702": "parallel bars, bars",
"703": "park bench",
"704": "parking meter",
"705": "passenger car, coach, carriage",
"706": "patio, terrace",
"707": "pay-phone, pay-station",
"708": "pedestal, plinth, footstall",
"709": "pencil box, pencil case",
"710": "pencil sharpener",
"711": "perfume, essence",
"712": "Petri dish",
"713": "photocopier",
"714": "pick, plectrum, plectron",
"715": "pickelhaube",
"716": "picket fence, paling",
"717": "pickup, pickup truck",
"718": "pier",
"719": "piggy bank, penny bank",
"720": "pill bottle",
"721": "pillow",
"722": "ping-pong ball",
"723": "pinwheel",
"724": "pirate, pirate ship",
"725": "pitcher, ewer",
"726": "plane, carpenter's plane, woodworking plane",
"727": "planetarium",
"728": "plastic bag",
"729": "plate rack",
"730": "plow, plough",
"731": "plunger, plumber's helper",
"732": "Polaroid camera, Polaroid Land camera",
"733": "pole",
"734": "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria",
"735": "poncho",
"736": "pool table, billiard table, snooker table",
"737": "pop bottle, soda bottle",
"738": "pot, flowerpot",
"739": "potter's wheel",
"740": "power drill",
"741": "prayer rug, prayer mat",
"742": "printer",
"743": "prison, prison house",
"744": "projectile, missile",
"745": "projector",
"746": "puck, hockey puck",
"747": "punching bag, punch bag, punching ball, punchball",
"748": "purse",
"749": "quill, quill pen",
"750": "quilt, comforter, comfort, puff",
"751": "racer, race car, racing car",
"752": "racket, racquet",
"753": "radiator",
"754": "radio, wireless",
"755": "radio telescope, radio reflector",
"756": "rain barrel",
"757": "recreational vehicle, RV, R.V.",
"758": "reel",
"759": "reflex camera",
"760": "refrigerator, icebox",
"761": "remote control, remote",
"762": "restaurant, eating house, eating place, eatery",
"763": "revolver, six-gun, six-shooter",
"764": "rifle",
"765": "rocking chair, rocker",
"766": "rotisserie",
"767": "rubber eraser, rubber, pencil eraser",
"768": "rugby ball",
"769": "rule, ruler",
"770": "running shoe",
"771": "safe",
"772": "safety pin",
"773": "saltshaker, salt shaker",
"774": "sandal",
"775": "sarong",
"776": "sax, saxophone",
"777": "scabbard",
"778": "scale, weighing machine",
"779": "school bus",
"780": "schooner",
"781": "scoreboard",
"782": "screen, CRT screen",
"783": "screw",
"784": "screwdriver",
"785": "seat belt, seatbelt",
"786": "sewing machine",
"787": "shield, buckler",
"788": "shoe shop, shoe-shop, shoe store",
"789": "shoji",
"790": "shopping basket",
"791": "shopping cart",
"792": "shovel",
"793": "shower cap",
"794": "shower curtain",
"795": "ski",
"796": "ski mask",
"797": "sleeping bag",
"798": "slide rule, slipstick",
"799": "sliding door",
"800": "slot, one-armed bandit",
"801": "snorkel",
"802": "snowmobile",
"803": "snowplow, snowplough",
"804": "soap dispenser",
"805": "soccer ball",
"806": "sock",
"807": "solar dish, solar collector, solar furnace",
"808": "sombrero",
"809": "soup bowl",
"810": "space bar",
"811": "space heater",
"812": "space shuttle",
"813": "spatula",
"814": "speedboat",
"815": "spider web, spider's web",
"816": "spindle",
"817": "sports car, sport car",
"818": "spotlight, spot",
"819": "stage",
"820": "steam locomotive",
"821": "steel arch bridge",
"822": "steel drum",
"823": "stethoscope",
"824": "stole",
"825": "stone wall",
"826": "stopwatch, stop watch",
"827": "stove",
"828": "strainer",
"829": "streetcar, tram, tramcar, trolley, trolley car",
"830": "stretcher",
"831": "studio couch, day bed",
"832": "stupa, tope",
"833": "submarine, pigboat, sub, U-boat",
"834": "suit, suit of clothes",
"835": "sundial",
"836": "sunglass",
"837": "sunglasses, dark glasses, shades",
"838": "sunscreen, sunblock, sun blocker",
"839": "suspension bridge",
"840": "swab, swob, mop",
"841": "sweatshirt",
"842": "swimming trunks, bathing trunks",
"843": "swing",
"844": "switch, electric switch, electrical switch",
"845": "syringe",
"846": "table lamp",
"847": "tank, army tank, armored combat vehicle, armoured combat vehicle",
"848": "tape player",
"849": "teapot",
"850": "teddy, teddy bear",
"851": "television, television system",
"852": "tennis ball",
"853": "thatch, thatched roof",
"854": "theater curtain, theatre curtain",
"855": "thimble",
"856": "thresher, thrasher, threshing machine",
"857": "throne",
"858": "tile roof",
"859": "toaster",
"860": "tobacco shop, tobacconist shop, tobacconist",
"861": "toilet seat",
"862": "torch",
"863": "totem pole",
"864": "tow truck, tow car, wrecker",
"865": "toyshop",
"866": "tractor",
"867": "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi",
"868": "tray",
"869": "trench coat",
"870": "tricycle, trike, velocipede",
"871": "trimaran",
"872": "tripod",
"873": "triumphal arch",
"874": "trolleybus, trolley coach, trackless trolley",
"875": "trombone",
"876": "tub, vat",
"877": "turnstile",
"878": "typewriter keyboard",
"879": "umbrella",
"880": "unicycle, monocycle",
"881": "upright, upright piano",
"882": "vacuum, vacuum cleaner",
"883": "vase",
"884": "vault",
"885": "velvet",
"886": "vending machine",
"887": "vestment",
"888": "viaduct",
"889": "violin, fiddle",
"890": "volleyball",
"891": "waffle iron",
"892": "wall clock",
"893": "wallet, billfold, notecase, pocketbook",
"894": "wardrobe, closet, press",
"895": "warplane, military plane",
"896": "washbasin, handbasin, washbowl, lavabo, wash-hand basin",
"897": "washer, automatic washer, washing machine",
"898": "water bottle",
"899": "water jug",
"900": "water tower",
"901": "whiskey jug",
"902": "whistle",
"903": "wig",
"904": "window screen",
"905": "window shade",
"906": "Windsor tie",
"907": "wine bottle",
"908": "wing",
"909": "wok",
"910": "wooden spoon",
"911": "wool, woolen, woollen",
"912": "worm fence, snake fence, snake-rail fence, Virginia fence",
"913": "wreck",
"914": "yawl",
"915": "yurt",
"916": "web site, website, internet site, site",
"917": "comic book",
"918": "crossword puzzle, crossword",
"919": "street sign",
"920": "traffic light, traffic signal, stoplight",
"921": "book jacket, dust cover, dust jacket, dust wrapper",
"922": "menu",
"923": "plate",
"924": "guacamole",
"925": "consomme",
"926": "hot pot, hotpot",
"927": "trifle",
"928": "ice cream, icecream",
"929": "ice lolly, lolly, lollipop, popsicle",
"930": "French loaf",
"931": "bagel, beigel",
"932": "pretzel",
"933": "cheeseburger",
"934": "hotdog, hot dog, red hot",
"935": "mashed potato",
"936": "head cabbage",
"937": "broccoli",
"938": "cauliflower",
"939": "zucchini, courgette",
"940": "spaghetti squash",
"941": "acorn squash",
"942": "butternut squash",
"943": "cucumber, cuke",
"944": "artichoke, globe artichoke",
"945": "bell pepper",
"946": "cardoon",
"947": "mushroom",
"948": "Granny Smith",
"949": "strawberry",
"950": "orange",
"951": "lemon",
"952": "fig",
"953": "pineapple, ananas",
"954": "banana",
"955": "jackfruit, jak, jack",
"956": "custard apple",
"957": "pomegranate",
"958": "hay",
"959": "carbonara",
"960": "chocolate sauce, chocolate syrup",
"961": "dough",
"962": "meat loaf, meatloaf",
"963": "pizza, pizza pie",
"964": "potpie",
"965": "burrito",
"966": "red wine",
"967": "espresso",
"968": "cup",
"969": "eggnog",
"970": "alp",
"971": "bubble",
"972": "cliff, drop, drop-off",
"973": "coral reef",
"974": "geyser",
"975": "lakeside, lakeshore",
"976": "promontory, headland, head, foreland",
"977": "sandbar, sand bar",
"978": "seashore, coast, seacoast, sea-coast",
"979": "valley, vale",
"980": "volcano",
"981": "ballplayer, baseball player",
"982": "groom, bridegroom",
"983": "scuba diver",
"984": "rapeseed",
"985": "daisy",
"986": "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum",
"987": "corn",
"988": "acorn",
"989": "hip, rose hip, rosehip",
"990": "buckeye, horse chestnut, conker",
"991": "coral fungus",
"992": "agaric",
"993": "gyromitra",
"994": "stinkhorn, carrion fungus",
"995": "earthstar",
"996": "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa",
"997": "bolete",
"998": "ear, spike, capitulum",
"999": "toilet tissue, toilet paper, bathroom tissue"
}
\ No newline at end of file
......@@ -126,7 +126,6 @@
2,
2
]
},
}
]
}
......@@ -22,7 +22,7 @@ const unitPath = {
'split': 'model.test.split.json'
};
// 制定运行的 op
const modelType = 'split';
const modelType = 'conv2d';
// 制定运行的 op
const unitData = unitPath[modelType];
......@@ -63,13 +63,13 @@ async function run() {
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape();
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
console.log('result');
console.log(result);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
console.log('NCHW RESULT');
console.log(nchwResult);
console.log(formatData);
}
run();
......@@ -112,6 +112,7 @@ function nchwShape2nhwcShape(nchw) {
}
batchNCHW = batch.concat(nchw);
}
const N = batchNCHW[0];
const C = batchNCHW[1];
const H = batchNCHW[2];
......
# PaddleJS Model Converter
PaddleJS Model Converter 是适用于 PaddleJS 的模型转换工具,其作用是将 PaddlePaddle 模型(或称为 fluid 模型)转化为 PaddleJS 模型这种浏览器友好的格式,以供在 PaddleJS 和浏览器中加载预测使用。此外,PaddleJS Model Converter 还提供了强大的模型优化能力,帮助开发者对模型结构进行优化,提高运行时性能。
## 1. 使用教程
### 1.1. 环境搭建
#### Python 版本确认
确认运行平台的 Python 环境与版本是否满足要求,若使用 Python3 ,则可能需要将后续命令中的 `python` 换成 `python3`
- Python3: 3.5.1+ / 3.6 / 3.7
- Python2: 2.7.15+
#### 安装虚拟环境
*由于开发环境可能安装了多个版本的 Python,相关依赖包可能存在不同的版本,为避免产生冲突,**强烈建议**使用 Python 虚拟环境执行转换工具所需的各项命令,以免产生各种问题。若不使用虚拟环境或已安装虚拟环境,可跳过该步骤。*
以 Anaconda 为例:
前往 [Anaconda](https://www.anaconda.com/) 主页,选择对应平台、Python 版本的 Anaconda 按照官方提示,进行安装;
安装完毕后,在命令行执行以下命令,创建Python 虚拟环境:
``` bash
conda create --name <your_env_name>
```
执行以下命令,切换至虚拟环境
``` bash
# Linux 或 macOS下请执行
source activate <your_env_name>
# Windows 下请执行
activate <your_env_name>
```
#### 安装依赖
- 如果`不需要`使用优化模型的能力,执行命令:
``` bash
python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
```
- 如果`需要`使用优化模型的能力,执行命令:
``` bash
python -m pip install paddlepaddle paddlelite -i https://mirror.baidu.com/pypi/simple
```
### 1.2. 快速上手
- 如果待转换的 fluid 模型为`合并参数文件`,即一个模型对应一个参数文件:
``` bash
python convertToPaddleJSModel.py --modelPath=<fluid_model_file_path> --paramPath=<fluid_param_file_path> --outputDir=<paddlejs_model_directory>
```
- 如果待转换的 fluid 模型为`分片参数文件`,即一个模型文件对应多个参数文件:
``` bash
# 注意,使用这种方式调用转换器,需要保证 inputDir 中,模型文件名为'__model__'
python convertToPaddleJSModel.py --inputDir=<fluid_model_directory> --outputDir=<paddlejs_model_directory>
````
模型转换器将生成以下两种类型的文件以供 PaddleJS 使用:
- model.json (模型结构与参数清单)
- chunk_\*.dat (二进制参数文件集合)
## 2. 详细文档
参数 | 描述
:-: | :-:
--inputDir | fluid 模型所在目录,当且仅当使用分片参数文件时使用该参数,将忽略 `modelPath` 和 `paramPath` 参数,且模型文件名必须为`__model__`
--modelPath | fluid 模型文件所在路径,使用合并参数文件时使用该参数
--paramPath | fluid 参数文件所在路径,使用合并参数文件时使用该参数
--outputDir | `必要参数`, paddleJS 模型输出路径
--optimize | 是否进行模型优化, `0` 为关闭优化,`1` 为开启优化(需安装 PaddleLite ),默认关闭优化
--logModelInfo | 是否打印模型结构信息, `0` 为不打印, `1` 为打印,默认不打印
--sliceDataSize | 分片输出 PaddleJS 参数文件时,每片文件的大小,单位:KB,默认 4096
## 3. 其他信息
若需要转换的模型为 `TensorFlow/Caffe/ONNX` 格式,可使用 PaddlePaddle 项目下的 `X2Paddle`工具,将其他格式的模型转为 fluid 模型后,再使用本工具转化为 PaddleJS 模型。
详细请参考 [X2Paddle 项目](https://github.com/PaddlePaddle/X2Paddle)
\ No newline at end of file
......@@ -2,199 +2,110 @@
# -*- coding: UTF-8 -*-
import json
import paddle.fluid as fluid
import paddle
import numpy as np
import collections
import math
import sys as sys
import sys
import os
import struct
import argparse
import shutil
import stat
import traceback
import numpy as np
import paddle.fluid as fluid
#常量控制
#抽样打印数据数量
logDataCount = 50
# 输入模型所在目录
modelDir = "humanseg/"
modelDir = None
# 输入模型名
modelName = "model"
modelName = None
# 输入参数名,当且仅当所有模型参数被保存在一个单独的二进制文件中,它才需要被指定,若为分片模型,请设置为None
paramsName = None
# 模型feed shape
inputShape = (1, 3, 192, 192)
# 输入数据
inputData = np.full(inputShape, 1, "float32")
# 是否打印模型信息
enableLogModelInfo = False
# 输出模型目录
outputDir = "../dist/model/humanseg/"
# 权重分片扩展名
extensionName = ".dat"
# 输出各var数据
outputVarData = False
# 确认fluid的版本号
print(paddle.__version__)
# 采样输出list数据,采样的个数logDataCount为常量
def stridePrint1(data):
dataCount = len(data)
stride = math.floor(dataCount / logDataCount)
if stride == 0:
stride = 1
nums = []
# outputCount = logDataCount
# if dataCount < logDataCount:
# outputCount = dataCount
# for i in range(outputCount):
# # nums.append(str(i) + ": " + str(data[i]))
# nums.append(data[i])
for i in range(0, logDataCount):
item = data[i * stride]
nums.append(str(i * stride) + ": " + str(item))
print(nums)
def stridePrint(tensor):
length = len(tensor)
# if length < 3000:
# print(tensor)
# return
size = 20
stride = math.floor(length / size)
if stride == 0:
stride = 1
size = math.floor(length / stride)
nums = []
for i in range(0, size):
item = tensor[i * stride]
nums.append(str(i * stride) + ": " + str(item))
print(nums)
# 对字典进行排序,返回有序字典,默认升序
def sortDict(oldDict, reverse = False):
outputDir = None
# 分片文件大小,单位:KB
sliceDataSize = 4 * 1024
# paddlepaddle运行程序实例
program = None
# 存放模型结构
modelInfo = {"vars": [], "ops": []}
# 存放参数数值(未排序)
paramValuesDict = {}
def logModel(info):
""" 打印信息 """
if enableLogModelInfo:
print(info)
def sortDict(oldDict, reverse=False):
""" 对字典进行排序,返回有序字典,默认升序 """
# 获得排序后的key list
keys = sorted(oldDict.keys(), reverse = reverse)
keys = sorted(oldDict.keys(), reverse=reverse)
orderDict = collections.OrderedDict()
# 遍历 key 列表
for key in keys:
orderDict[key] = oldDict[key]
return orderDict
def dumpModelToJsonFile():
""" 导出模型数据到json文件 """
print("Dumping model structure to json file...")
if not os.path.exists(outputDir):
os.makedirs(outputDir)
outputModelPath = os.path.join(outputDir, "model.json")
with open(outputModelPath, 'w') as outputFile:
json.dump(modelInfo, outputFile, indent=4, separators=(", ", ": "), sort_keys=True)
print("Dumping model structure to json file successfully")
# 将权重数据分片输出到文件,默认分片策略为按4M分片
def sliceDataToBinaryFile(weightValueList, sliceMethod = 0):
# TODO: 分片这里不太对,待修改
totalWeightCount = len(weightValueList)
countPerSlice = 0
# sliceCount = 0
if sliceMethod == 0:
# 分片策略 0:按4M分片
countPerSlice = int(4 * 1024 * 1024 / 4)
# sliceCount = math.ceil(totalWeightCount / countPerSlice)
else:
# 分片策略 1:按<=4M等分
# TODO: 待实现
countPerSlice = 0
# sliceCount = 0
def sliceDataToBinaryFile(paramValueList):
""" 将参数数据分片输出到文件,默认分片策略为按4M分片 """
totalParamValuesCount = len(paramValueList)
countPerSlice = int(sliceDataSize * 1024 / 4)
if not os.path.exists(outputDir):
os.makedirs(outputDir)
currentChunkIndex = 0
currentWeightIndex = 0
currentParamDataIndex = 0
while currentWeightIndex < totalWeightCount - 1:
remainCount = totalWeightCount - currentWeightIndex
while currentParamDataIndex < totalParamValuesCount - 1:
remainCount = totalParamValuesCount - currentParamDataIndex
if remainCount < countPerSlice:
countPerSlice = remainCount
chunkPath = outputDir + 'chunk_%s' % (currentChunkIndex + 1) + extensionName
chunkPath = os.path.join(outputDir, 'chunk_%s.dat' % (currentChunkIndex + 1))
file = open(chunkPath, 'wb')
for i in weightValueList[currentWeightIndex : currentWeightIndex + countPerSlice]:
for i in paramValueList[currentParamDataIndex : currentParamDataIndex + countPerSlice]:
byte = struct.pack('f', float(i))
file.write(byte)
file.close()
currentWeightIndex = currentWeightIndex + countPerSlice
currentParamDataIndex = currentParamDataIndex + countPerSlice
currentChunkIndex = currentChunkIndex + 1
# for debug
print("第" + str(currentChunkIndex + 1) + "片权重输出完毕,输出个数:" + str(countPerSlice) + " 剩余个数:" + str(totalWeightCount - currentWeightIndex))
print("Output No." + str(currentChunkIndex)+ " binary file, remain " + str(totalParamValuesCount - currentParamDataIndex) + " param values.")
print("Slicing data to binary files successfully. (" + str(currentChunkIndex)+ " output files and " + str(currentParamDataIndex) + " param values)")
# for debug
print("========权重输出完毕,共" + str(currentWeightIndex) + "个数据," + str(currentChunkIndex) + "个分片文件" + "========")
def reorderParamsValue():
""" 对参数文件中的数值,按照variable.name字母序排序,返回排序后组合完成的value list """
paramValuesOrderDict = sortDict(paramValuesDict)
paramValues = []
for value in paramValuesOrderDict.values():
paramValues += value
return paramValues
# 处理fluid的OP type与PaddleJS的OP type不对应情况
def mapToPaddleJSTypeName(fluidOPName):
""" 处理fluid的OP type与PaddleJS的OP type不对应情况 """
if fluidOPName == "batch_norm":
return "batchnorm"
return fluidOPName
# 将shape扩充为4维
def padToFourDimShape(shape):
fourDimShape = []
if len(shape) == 4:
fourDimShape = shape
elif len(shape) < 4:
for i in range(0, 4 - len(shape)):
fourDimShape.append(1)
fourDimShape = fourDimShape + shape
else:
return []
return fourDimShape
# for debug,将NCHW排布的数据转为NHWC排布的数据
def convertNCHW2NHWC(data, shape):
fourDimShape = padToFourDimShape(shape)
N = fourDimShape[0]
C = fourDimShape[1]
H = fourDimShape[2]
W = fourDimShape[3]
print(fourDimShape)
HXW = H * W
CXHXW = C * H * W
def organizeModelVariableInfo():
""" 组织参数信息 """
print("Organizing model variables info...")
index = 0
nhwcData = []
for n in range(0, N):
for h in range(0, H):
for w in range(0, W):
for c in range(0, C):
nhwcData.append(data[n * CXHXW + c * HXW + h * W + w])
index = index + 1
return nhwcData
# for debug 输出特定varName对应的数据
def writeTempOutputData(name):
# FIXME:待完善
return
dataList = np.array(fluid.global_scope().find_var(name).get_tensor()).flatten().tolist()
path = '/Users/bluebird/baidu/fluid_tools/check-temp/filter.txt'
if os.path.exists(path):
os.remove()
file = open(path,'a')
for a in range(0, len(dataList)):
file.write(str(dataList[a]))
file.write(",")
file.close()
def convertToPaddleJSModel():
# 1. 初始化fluid运行环境和配置
exe = fluid.Executor(fluid.CPUPlace())
[prog, feed_target_names, fetch_targets] = fluid.io.load_inference_model(dirname=modelDir, executor=exe, model_filename=modelName, params_filename=paramsName)
out = exe.run(prog, feed={feed_target_names[0]: inputData}, fetch_list=fetch_targets, return_numpy=False)
print(out)
index = 0
# 存放模型结构
modelInfo = {"vars": [], "ops": []}
# 存放var信息(未排序)
varInfoDict = {}
# 存放权重数值(未排序)
weightValueDict = {}
# 2. 获取program中所有的var,遍历并获取所有未排序的var信息和权重数值
vars = list(prog.list_vars())
# 获取program中所有的var,遍历并获取所有未排序的var信息和参数数值
vars = list(program.list_vars())
for v in vars:
# 跳过feed和fetch
if "feed" == v.name:
......@@ -202,10 +113,6 @@ def convertToPaddleJSModel():
if "fetch" == v.name:
continue
print("Var index:" + str(index) + " name:" + v.name)
print(v)
index += 1
varShape = list(v.shape)
# FIXME:start paddlejs 不支持shape中为-1,这里需要手动过滤一下,支持了以后可以删除
......@@ -220,40 +127,37 @@ def convertToPaddleJSModel():
# 存放variable信息,在dump成json时排序
varInfo = {}
varInfo["shape"] = varShape
# 数据是否是持久化数据,如weight为持久化数据,op的output不是持久化数据
# 数据是否是持久化数据,如tensor为持久化数据,op的output不是持久化数据
# 只输出持久化数据,paddlejs中也仅读取持久化数据
varInfo["persistable"] = v.persistable
varInfoDict[v.name] = varInfo
# for debug,输出var变量
if outputVarData:
writeTempOutputData(v.name)
logModel("[Var index:" + str(index) + " name:" + v.name + "]")
jsonDumpsIndentStr = json.dumps(varInfo, indent=2)
logModel(jsonDumpsIndentStr)
logModel("")
index += 1
# persistable数据存入weightDict,等待排序
# persistable数据存入paramValuesDict,等待排序
if v.persistable:
data = np.array(fluid.global_scope().find_var(v.name).get_tensor()).flatten().tolist()
weightValueDict[v.name] = data
paramValuesDict[v.name] = data
# 3. 对var信息dict,按照key(var名)进行字母顺序排序
# 对var信息dict,按照key(var名)进行字母顺序排序
varInfoOrderDict = sortDict(varInfoDict)
# 4. 将var信息按照顺序,添加到model info的vars中
# 将var信息按照顺序,添加到model info的vars中
for key, value in varInfoOrderDict.items():
value["name"] = key
modelInfo["vars"].append(value)
print("Organizing model variables info successfully.")
# 5. 对权重数值dict,按照key(权重名)进行字母顺序排序,并组合到一起
weightValueOrderDict = sortDict(weightValueDict)
weightValues = []
for key, value in weightValueOrderDict.items():
weightValues += value
# 6. 分片输出权重
sliceDataToBinaryFile(weightValues)
# 7. 获取program中所有的op,按op顺序加入到model info
ops = prog.current_block().ops
def organizeModelOpInfo():
""" 组织模型OP结构信息 """
print("Organizing model operators info...")
ops = program.current_block().ops
feedOutputName = None
index = 0
for op in ops:
opInfo = {}
......@@ -267,9 +171,7 @@ def convertToPaddleJSModel():
if len(value) <= 0:
continue
if value[0] == feedOutputName:
# FIXME:workaround,PaddleJSfeed 输入必须是image,且为单输入
# 这里修改feed后面的OP的input为image,建立前后关联
# 这里可能会有问题
# FIXME:workaround,PaddleJSfeed 输入必须是image,且为单输入,这里修改feed后面的OP的input为image,建立前后关联
inputs[name] = ["image"]
else:
inputs[name] = value
......@@ -282,8 +184,7 @@ def convertToPaddleJSModel():
if len(value) <= 0:
continue
if op.type == "feed":
# FIXME:workaround,PaddleJSfeed 输入必须是image,且为单输入
# 这里可能会有问题
# FIXME:workaround,PaddleJSfeed 输入必须是image,且为单输入,这里保存原始的输出名,以便映射
feedOutputName = value[0]
outputs[name] = ["image"]
else:
......@@ -302,12 +203,65 @@ def convertToPaddleJSModel():
# 存入modelInfo
modelInfo["ops"].append(opInfo)
logModel("[OP index:" + str(index) + " type:" + op.type + "]")
jsonDumpsIndentStr = json.dumps(opInfo, indent=2)
logModel(jsonDumpsIndentStr)
logModel("")
index += 1
print("Organizing model operators info successfully.")
# 8. 模型信息按照key字母顺序导出到json
outputModelPath = outputDir + "model.json"
with open(outputModelPath, 'w') as outputFile:
json.dump(modelInfo, outputFile, indent = 4, separators=(", ", ": "), sort_keys = True)
print("========模型结构输出完毕========")
convertToPaddleJSModel()
def convertToPaddleJSModel():
""" 转换fluid modle为paddleJS model """
# 初始化fluid运行环境和配置
exe = fluid.Executor(fluid.CPUPlace())
result = fluid.io.load_inference_model(dirname=modelDir, executor=exe, model_filename=modelName, params_filename=paramsName)
global program
program = result[0]
# 获取program中所有的op,按op顺序加入到model info
organizeModelOpInfo()
# 获取program中所有的var,按照字母顺序加入到model info,同时读取参数数值
organizeModelVariableInfo()
# 导出模型文件到json
dumpModelToJsonFile()
# 对参数数值dict,按照key(参数名)进行字母顺序排序,并组合到一起
paramValues = reorderParamsValue()
# 导出分片参数文件
sliceDataToBinaryFile(paramValues)
if __name__ == "__main__":
try:
p = argparse.ArgumentParser(description='模型转换参数解析')
p.add_argument('--inputDir', help='fluid模型所在目录。当且仅当使用分片参数文件时使用该参数。将过滤modelPath和paramsPath参数,且模型文件名必须为`__model__`', required=False)
p.add_argument('--modelPath', help='fluid模型文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument('--paramPath', help='fluid参数文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument("--outputDir", help='paddleJS模型输出路径,必要参数', required=True)
p.add_argument("--logModelInfo", type=int, default=0, help='是否输出模型结构信息,非必要参数,0为不输出,1为输出,默认不输出', required=False)
p.add_argument("--sliceDataSize", type=int, default=4096, help='分片输出参数文件时,每片文件的大小,单位:KB,非必要参数,默认4096KB', required=False)
args = p.parse_args()
modelDir = args.inputDir
modelPath = args.modelPath
paramPath = args.paramPath
if not modelDir:
modelDir, modelName = os.path.split(modelPath)
paramDir, paramsName = os.path.split(paramPath)
if paramDir != modelDir:
print("\033[31mModel and param file should be put in a same directory!\033[0m")
raise Exception()
outputDir = args.outputDir
sliceDataSize = args.sliceDataSize
if args.logModelInfo == 1:
enableLogModelInfo = True
convertToPaddleJSModel()
except Exception as identifier:
print("\033[31mA fetal error occured. Failed to convert model.\033[0m")
print(traceback.format_exc())
pass
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
import os
import argparse
import shutil
import stat
import traceback
def cleanTempModel(optimizedModelTempDir):
""" 清理opt优化完的临时模型文件 """
if os.path.exists(optimizedModelTempDir):
print("Cleaning optimized temporary model...")
shutil.rmtree(optimizedModelTempDir, onerror=grantWritePermission)
def grantWritePermission(func, path, execinfo):
""" 文件授权 """
os.chmod(path, stat.S_IWRITE)
func(path)
if __name__ == "__main__":
"""
Example:
'python convertToPaddleJSModel.py --modelPath=../infer_model/MobileNetV2/__model__ --paramPath=../infer_model/MobileNetV2/params --outputDir=../jsmodel --optimize=1'
"""
try:
p = argparse.ArgumentParser(description='转化为PaddleJS模型参数解析')
p.add_argument('--inputDir', help='fluid模型所在目录。当且仅当使用分片参数文件时使用该参数。将过滤modelPath和paramsPath参数,且模型文件名必须为`__model__`', required=False)
p.add_argument('--modelPath', help='fluid模型文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument('--paramPath', help='fluid参数文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument("--outputDir", help='paddleJS模型输出路径,必要参数', required=True)
p.add_argument("--optimize", type=int, default=0, help='是否进行模型优化,非必要参数,0为关闭优化,1为开启优化,默认关闭优化', required=False)
p.add_argument("--logModelInfo", type=int, default=0, help='是否输出模型结构信息,非必要参数,0为不输出,1为输出,默认不输出', required=False)
p.add_argument("--sliceDataSize", type=int, default=4096, help='分片输出参数文件时,每片文件的大小,单位:KB,非必要参数,默认4096KB', required=False)
args = p.parse_args()
# TODO: 由于PaddleLite和PaddlePaddle存在包冲突,因此将整个模型转换工具拆成两个python文件,由一个入口python文件通过命令行调用
optimizeCmd = " optimizeModel.py"
convertCmd = " convertModel.py"
inputDir = args.inputDir
modelPath = args.modelPath
paramPath = args.paramPath
outputDir = args.outputDir
enableOptimization = args.optimize
enableLogModelInfo = args.logModelInfo
sliceDataSize = args.sliceDataSize
optimizedModelTempDir = None
if enableOptimization == 1:
optimizedModelTempDir = os.path.join(outputDir, "optimize")
if inputDir:
optimizeCmd = optimizeCmd + " --inputDir=" + inputDir
convertCmd = convertCmd + " --inputDir=" + optimizedModelTempDir
else:
optimizeCmd = optimizeCmd + " --modelPath=" + modelPath + " --paramPath=" + paramPath
# optimizeModelPath, modelName = os.path.split(modelPath)
# optimizeParamPath, paramName = os.path.split(paramPath)
optimizeModelPath = os.path.join(optimizedModelTempDir, "model")
optimizeParamPath = os.path.join(optimizedModelTempDir, "params")
convertCmd = convertCmd + " --modelPath=" + optimizeModelPath + " --paramPath=" + optimizeParamPath
optimizeCmd = optimizeCmd + " --outputDir=" + optimizedModelTempDir
else:
if inputDir:
convertCmd = convertCmd + " --inputDir=" + inputDir
else:
convertCmd = convertCmd + " --modelPath=" + modelPath + " --paramPath=" + paramPath
convertCmd = convertCmd + " --outputDir=" + outputDir + " --sliceDataSize=" + str(sliceDataSize) + " --logModelInfo=" + str(args.logModelInfo)
print("============Convert Model Args=============")
if inputDir:
print("inputDir: " + inputDir)
else:
print("modelPath: " + modelPath)
print("paramPath: " + paramPath)
print("outputDir: " + outputDir)
print("enableOptimizeModel: " + str(enableOptimization))
print("enableLogModelInfo: " + str(enableLogModelInfo))
print("sliceDataSize:" + str(sliceDataSize))
pythonCmd = "python"
print("Starting...")
if enableOptimization:
print("Optimizing model...")
os.system(pythonCmd + optimizeCmd)
print("\033[32m\nOptimizing model successfully.\033[0m")
else:
print("\033[33mYou choosed not to optimize model, consequently, optimizing model is skiped.\033[0m")
print("Converting model...")
os.system(pythonCmd + convertCmd)
print("\033[32mConverting model successfully.\033[0m")
if enableOptimization:
cleanTempModel(optimizedModelTempDir)
print("Temporary files has been deleted successfully.")
print("\033[32m============ALL DONE============\033[0m")
except Exception as identifier:
print("\033[31mA fetal error occured. Failed to convert model.\033[0m")
print(traceback.format_exc())
pass
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import collections
import argparse
import traceback
import paddlelite.lite as lite
def optimizeModel(inputDir, modelPath, paramPath, outputDir):
""" 使用opt python接口执行模型优化 """
opt = lite.Opt()
if inputDir:
# 分片参数文件优化
opt.set_model_dir(inputDir)
else:
# 合并参数文件优化
opt.set_model_file(modelPath)
opt.set_param_file(paramPath)
opt.set_valid_places("arm")
opt.set_model_type("protobuf")
opt.set_optimize_out(outputDir)
optimize_passes = [
"lite_conv_elementwise_fuse_pass",
"lite_conv_bn_fuse_pass",
"lite_conv_elementwise_fuse_pass",
"lite_conv_activation_fuse_pass",
"lite_var_conv_2d_activation_fuse_pass",
"lite_fc_fuse_pass",
"lite_shuffle_channel_fuse_pass",
"lite_transpose_softmax_transpose_fuse_pass",
"lite_interpolate_fuse_pass",
"identity_scale_eliminate_pass",
"elementwise_mul_constant_eliminate_pass",
"lite_sequence_pool_concat_fuse_pass",
"lite_elementwise_add_activation_fuse_pass",
"static_kernel_pick_pass",
"variable_place_inference_pass",
"argument_type_display_pass",
"type_target_cast_pass",
"variable_place_inference_pass",
"argument_type_display_pass",
"io_copy_kernel_pick_pass",
"argument_type_display_pass",
"variable_place_inference_pass",
"argument_type_display_pass",
"type_precision_cast_pass",
"variable_place_inference_pass",
"argument_type_display_pass",
"type_layout_cast_pass",
"argument_type_display_pass",
"variable_place_inference_pass",
"argument_type_display_pass",
"runtime_context_assign_pass",
"argument_type_display_pass"
]
opt.set_passes_internal(optimize_passes)
opt.run()
if __name__ == "__main__":
try:
p = argparse.ArgumentParser('模型优化参数解析')
p.add_argument('--inputDir', help='fluid模型所在目录。当且仅当使用分片参数文件时使用该参数。将过滤modelPath和paramsPath参数,且模型文件名必须为`__model__`', required=False)
p.add_argument('--modelPath', help='fluid模型文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument('--paramPath', help='fluid参数文件所在路径,使用合并参数文件时使用该参数', required=False)
p.add_argument("--outputDir", help='优化后fluid模型目录,必要参数', required=True)
args = p.parse_args()
inputDir = args.inputDir
modelPath = args.modelPath
paramPath = args.paramPath
outputDir = args.outputDir
optimizeModel(inputDir, modelPath, paramPath, outputDir)
except Exception as identifier:
print("\033[31mA fetal error occured. Failed to optimize model.\033[0m")
print(traceback.format_exc())
pass
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册