提交 55dbbb8f 编写于 作者: W wangqun

[change][d]修复了一些兼容性问题,比如精度问题

修复了一些兼容性问题,比如精度问题,多余demo删除
上级 e24f59e9
...@@ -29,57 +29,33 @@ Currently Paddle.js only supports a limited set of Paddle Ops. See the full list ...@@ -29,57 +29,33 @@ Currently Paddle.js only supports a limited set of Paddle Ops. See the full list
## Loading and running in the browser ## Loading and running in the browser
If the original model was a SavedModel, use paddle.load().
```bash ```bash
import Paddle from 'paddlejs'; import {runner as Paddlejs} from 'paddlejs';
let feed = io.process({ const paddlejs = new Paddlejs({
input: document.getElementById('image'), modelPath: 'model/mobilenetv2', // model path
params: { fileCount: 4, // model data file count
gapFillWith: '#000', // What to use to fill the square part after zooming feedShape: { // input shape
targetSize: { fw: 256,
height: fw, fh: 256
width: fh
}, },
targetShape: [1, 3, fh, fw], // Target shape changed its name to be compatible with previous logic fetchShape: [1, 1, 1920, 10], // output shape
// shape: [3, 608, 608], // Preset sensor shape fill: '#fff', // fill color when resize image
mean: [117.001, 114.697, 97.404], // Preset mean needBatch: true, // whether need to complete the shape to 4 dimension
// std: [0.229, 0.224, 0.225] // Preset std inputType: 'image' // whether is image or video
} });
});
// load paddlejs model and preheat
const MODEL_CONFIG = { await paddlejs.loadModel();
dir: `/${path}/`, // model URL
main: 'model.json', // main graph // run model
}; await paddlejs.predict(img, postProcess);
const paddle = new Paddle({ function postProcee(data) {
urlConf: MODEL_CONFIG, // data is predicted result
options: { console.log(data);
multipart: true, }
dataType: 'binary',
options: {
fileCount: 1, // How many model have been cut
getFileName(i) {
return 'chunk_' + i + '.dat';
}
}
}
});
model = await paddle.load();
//
let inst = model.execute({
input: feed
});
// There should be a fetch execution call or a fetch output
let result = await inst.read();
``` ```
......
...@@ -28,52 +28,31 @@ Paddle.js项目基于Atom系统构建,该系统是一个通用框架,可支 ...@@ -28,52 +28,31 @@ Paddle.js项目基于Atom系统构建,该系统是一个通用框架,可支
```bash ```bash
import Paddle from 'paddlejs'; import {runner as Paddlejs} from 'paddlejs';
let feed = io.process({ const paddlejs = new Paddlejs({
input: document.getElementById('image'), modelPath: 'model/mobilenetv2', // model path
params: { fileCount: 4, // model data file count
gapFillWith: '#000', // What to use to fill the square part after zooming feedShape: { // input shape
targetSize: { fw: 256,
height: fw, fh: 256
width: fh
}, },
targetShape: [1, 3, fh, fw], // Target shape changed its name to be compatible with previous logic fetchShape: [1, 1, 1920, 10], // output shape
// shape: [3, 608, 608], // Preset sensor shape fill: '#fff', // fill color when resize image
mean: [117.001, 114.697, 97.404], // Preset mean needBatch: true, // whether need to complete the shape to 4 dimension
// std: [0.229, 0.224, 0.225] // Preset std inputType: 'image' // whether is image or video
} });
});
const MODEL_CONFIG = {
dir: `/${path}/`, // model URL
main: 'model.json', // main graph
};
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: 1, // How many model have been cut
getFileName(i) {
return 'chunk_' + i + '.dat';
}
}
}
});
model = await paddle.load();
// run model // load paddlejs model and preheat
let inst = model.execute({ await paddlejs.loadModel();
input: feed
});
// There should be a fetch execution call or a fetch output // run model
let result = await inst.read(); await paddlejs.predict(img, postProcess);
function postProcee(data) {
// data为预测结果
console.log(data);
}
``` ```
...@@ -85,7 +64,6 @@ let result = await inst.read(); ...@@ -85,7 +64,6 @@ let result = await inst.read();
## 运行Paddle.js提供的转换器脚本 ## 运行Paddle.js提供的转换器脚本
模型转换器需要输入一个Paddle格式的model,可以是Paddle Hub中的model,运行转换器将会得到paddle.js的JSON格式model。 模型转换器需要输入一个Paddle格式的model,可以是Paddle Hub中的model,运行转换器将会得到paddle.js的JSON格式model。
[查看转换工具使用方法](./tools/ModelConverter/README_cn.md)
## Web友好的model格式 ## Web友好的model格式
......
// babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
]
};
<template lang="pug">
div
config
</template>
<script lang="ts">
import Vue from "vue";
import config from "./config.vue";
export default Vue.extend({
data() {
return {
bundler: "Parcel",
};
},
components: {
'config': config
},
methods() {
}
});
</script>
<style lang="less" scoped>
.container {
color: green;
}
.text {
color: red;
}
</style>
<template lang="pug">
div
el-row(type=flex justify="start" align="middle")
el-col(:span="8")
el-row.model-row(align="middle" type="flex")
el-col(:span="6")
div model:
el-col(:span="18")
el-select(v-model="modelSeleted" placeHolder="please selete" @change="changeModel")
el-option(v-for="(modelItem, index) in modelList" :key="index" :label="modelItem.name" :value="modelItem")
el-row.model-row(align="middle" type="flex")
el-col(:span="6")
div run times:
el-col(:span="18")
el-input(v-model="times" placeHolde="请输入运行次数" @change="getTimes")
el-button.model-row(type="primary" @click="run") run
el-col.model-row.model-stage(:span="12")
el-steps(align-center :space="200" :active="stage" finish-status="success")
el-step(title="start")
el-step(title="load model")
el-step(title="preheat")
el-step(title="run model")
el-row.model-table(type=flex justify="space-between" :gutter="30")
el-col(:span="7")
header.model-header general data
el-table.model-row(:data="tableData" max-height="100%" border)
el-table-column(prop="name" label="type")
el-table-column(prop="t" label="name")
el-col(:span="7")
header.model-header op data
el-table.model-row(:data="ops" max-height="100%" border)
el-table-column(prop="name" label="type")
el-table-column(prop="time" label="time")
el-col.model-detail(:span="7")
header.model-header details
//- el-divider(direction="vertical" content-position="left")
el-table.model-row(:data="progress" max-height="1500" border :row-class-name="tableRowClassName")
el-table-column(prop="index" label="index")
el-table-column(prop="name" label="name")
el-table-column(prop="time" label="time")
</template>
<script>
import Vue from 'vue';
import 'regenerator-runtime/runtime'
import 'babel-polyfill'
import Paddle from '../../src/executor/runner';
import Utils from '../../src/utils/utils';
export default Vue.extend({
data() {
return {
modelList: [
{
name: 'mobileNetV2',
fileCount: 4,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 1000, 10, 1],
fill: '#fff',
targetSize: { height: 224, width: 224 },
},
{
name: 'mobileNetV2Opt',
fileCount: 4,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 1000, 10, 1],
fill: '#fff',
targetSize: { height: 224, width: 224 },
},
{
name: 'wine',
fileCount: 3,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 40, 10, 1],
fill: '#fff',
targetSize: { height: 224, width: 224 },
},
{
name: 'gesture_detect',
fileCount: 2,
feedShape: {
fw: 256,
fh: 256
},
fetchShape: [1, 1920, 10 , 1],
fill: '#fff',
targetSize: { height: 256, width: 256 },
},
{
name: 'gesture_rec',
fileCount: 1,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 9, 1, 1],
fill: '#fff',
targetSize: { height: 224, width: 224 },
},
{
name: 'humanseg',
fileCount: 1,
feedShape: {
fw: 192,
fh: 192
},
fetchShape: [1, 2, 192, 192],
fill: '#fff',
targetSize: { height: 224, width: 224 },
}
],
modelSeleted: '',
modelPathPrefix: 'https://paddlejs.cdn.bcebos.com/models/',
modelPath: '',
curModel: null,
progressText: '',
times: null,
stage: null,
loadT: '--',
preheatT: '--',
remainOthersT: '--',
bestT: '--',
progress: [],
ops: [],
paddle: null,
gl: null,
test: null,
opCount: '--'
}
},
computed: {
tableData() {
return [
{name: 'load time', t: this.loadT},
{name: 'preheat time', t: this.preheatT},
{name: 'subsequent average time', t: this.remainOthersT},
{name: 'best time', t: this.bestT},
{name: 'op count', t: this.opCount},
]
}
},
methods: {
tableRowClassName({row}) {
return row.name === 'total' && 'detail-index-row';
},
// arraySpanMethod({row, columnIndex}) {
// return [row.name === 'total' && columnIndex === 0 ? this.opCount: 1, 1];
// },
changeModel(value) {
console.log(value);
this.modelSeleted = value.name;
this.modelPath = this.modelPathPrefix + value.name;
console.log(this.modelPath);
this.curModel = {...value, modelPath: this.modelPath};
},
async loadModel() {
this.stage = 1;
this.progressText = '模型加载中';
const paddle = this.paddle = new Paddle({
...this.curModel,
needPostProcess: false,
needPreheat: false,
fileDownload: false,
});
const start = Date.now();
await paddle.loadModel();
this.loadT = Date.now() - start;
this.stage = 2;
this.gl = paddle.model.graph.inst.gpu.gl;
},
async preheat() {
const start = Date.now();
await this.paddle.preheat();
this.preheatT = Date.now() - start;
this.stage = 3;
},
getTimes(val) {
if (!val || !this.curModel) {
return;
}
},
clear() {
this.loadT = '--' ;
this.preheatT = '--' ;
this.remainOthersT = '--' ;
this.bestT = '--' ;
this.progress = [] ;
this.ops = [] ;
this.opCount = '--';
},
async predict() {
const totalTimes = +this.times;
let curTimes = 1;
let remainWholeT = 0;
let progress = [];
let totaltimeList = [];
let opCount = 0;
const ops = [];
while(curTimes <= totalTimes) {
const start = Date.now();
await this.paddle.runWithFeed(this.paddle.preheatFeed);
const t = Date.now() - start;
remainWholeT += t;
// this.remainOthersT = +(remainWholeT / (curTimes - 2).toFixed(4));
const {queryList} = this.paddle.model.graph;
const quertyResults = this.query(queryList);
if (!opCount) {
opCount = quertyResults.length;
}
progress.push({
index: curTimes,
time: t,
name: 'total'
});
for (let item of quertyResults) {
progress.push({
index: curTimes,
time: item.time,
name: item.name
});
}
totaltimeList.push(t);
ops.push(this.getOpPerf(quertyResults, this.aggregate, {}));
curTimes++;
}
const len = totaltimeList.length;
totaltimeList.sort((a, b) => a - b);
this.bestT = totaltimeList[0];
const opInfos = this.getOpPerf(ops, this.merge);
this.opCount = opCount;
this.remainOthersT = (remainWholeT / this.times).toFixed(4);
this.progress = progress;
this.ops = Object.keys(opInfos).map(opname => {
return {
name: opname,
time: opInfos[opname].time
};
});
this.stage = 4;
},
async run() {
this.clear();
await this.loadModel();
await this.preheat();
await this.predict();
},
query(queryList) {
const result = queryList.map(item => {
const {name, query, count} = item;
const time = Utils.getQueryTime(this.gl, query) / 1000000;
return {name, count, time: +(time.toFixed(4))};
})
return result.filter(item => item.name !== 'feed');
},
aggregate(acc, cur) {
const {name, time, count} = cur;
let now = {...acc};
if (!acc[name]) {
now[name] = {time, count};
return now;
}
const item = now[cur.name];
item.time += time;
item.count++;
return now;
},
getOpPerf(queryList, reduceF, acc) {
let timeRes = acc ? queryList.reduce(reduceF, acc) : queryList.reduce(reduceF);
for(let key of Object.keys(timeRes)) {
const item = timeRes[key];
const {time, count, name} = item;
if (name === 'feed') {
return item;
}
item.time = +(time / count).toFixed(4);
item.count = 1;
}
return timeRes;
},
merge(acc, cur) {
for (let name of Object.keys(cur)) {
const {time, count} = cur[name];
acc[name].time += time;
acc[name].count += count;
}
return acc;
}
}
})
</script>
<style lang="less" scoped>
.model-row {
margin-top: 20px;
}
.model-stage {
margin-top: 50px;
}
.model-header {
text-align: center;
}
.model-table {
margin-top: 50px;
}
</style>
<style>
.el-table .detail-index-row {
background-color: #f0f9eb;
}
</style>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PaddleJS benchmark</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
</head>
<body>
<div id="app"></div>
<script src="./index.js"></script>
</body>
</html>
// index.js
import Vue from 'vue'
import App from './app.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);
const vm = new Vue({render: h => h(App)})
vm.$mount('#app')
import WarpAffine from './warpAffine';
class DetectProcess {
constructor(result, canvas) {
this.modelResult = result;
this.output_size = 10;
this.anchor_num = 1920;
this.detectResult = new Array(14).fill('').map(() => []);
this.hasHand = 0;
this.originCanvas = canvas;
let ctx = this.originCanvas.getContext('2d');
this.originImageData = ctx.getImageData(0, 0, 256, 256);
}
async outputBox(results) {
let splitT = Date.now();
this.getMaxIndex();
// console.info('getMaxIndex:', Date.now() - splitT);
// debugger;
splitT = Date.now();
if (this.maxIndex === -1) {
this.hasHand = 0;
return false;
}
this.hasHand = 1;
await this.splitAnchors(results);
// console.info('splitAnchors:', Date.now() - splitT);
// debugger;
splitT = Date.now();
this.decodeAnchor();
this.decodeKp(); // 求关键点
this.decodeBox(); // 求手势框
// console.info('求关键点跟手势框', Date.now() - splitT);
// debugger;
return this.box;
}
async outputFeed(paddle) {
let oft = Date.now();
this.decodeTriangle();
// console.info('decodeTriangle', Date.now() - oft);
oft = Date.now();
this.decodeSource();
// console.info('decodeSource', Date.now() - oft);
oft = Date.now();
this.outputResult();
// console.info('outputResult', Date.now() - oft);
oft = Date.now();
this.getaffinetransform(); // 提取仿射变化矩阵
// console.info('getaffinetransform', Date.now() - oft);
oft = Date.now();
await this.warpAffine(); // 对图片进行仿射变换
// console.info('warpAffine', Date.now() - oft);
oft = Date.now();
this.allReshapeToRGB(paddle);
// console.info('allReshapeToRGB', Date.now() - oft);
oft = Date.now();
return this.feed;
}
async splitAnchors(results) {
window.results = results;
let anchors = new Array(this.anchor_num).fill('').map(() => []);
let output_size = this.output_size;
let anchor_num = this.anchor_num;
for (let i = 0; i < anchor_num; i++) {
anchors[i] = [];
let tmp0 = results[i * 4];
let tmp1 = results[i * 4 + 1];
let tmp2 = results[i * 4 + 2];
let tmp3 = results[i * 4 + 3];
anchors[i][0] = tmp0 - tmp2 / 2.0;
anchors[i][1] = tmp1 - tmp3 / 2.0;
anchors[i][2] = tmp0 + tmp2 / 2.0;
anchors[i][3] = tmp1 + tmp3 / 2.0;
if (anchors[i][0] < 0) anchors[i][0] = 0;
if (anchors[i][0] > 1) anchors[i][0] = 1;
if (anchors[i][1] < 0) anchors[i][1] = 0;
if (anchors[i][1] > 1) anchors[i][1] = 1;
if (anchors[i][2] < 0) anchors[i][2] = 0;
if (anchors[i][2] > 1) anchors[i][2] = 1;
if (anchors[i][3] < 0) anchors[i][3] = 0;
if (anchors[i][3] > 1) anchors[i][3] = 1;
}
window.anchors = this.anchors = anchors;
}
getMaxIndex() {
let maxIndex = -1;
let maxConf = -1;
let curConf = -2.0;
let output_size = 10;
for (let i = 0; i < this.anchor_num; i++) {
curConf = sigm(this.modelResult[i * output_size + 1]);
if (curConf > 0.55 && curConf > maxConf) {
maxConf = curConf;
maxIndex = i;
}
}
this.maxIndex = maxIndex;
function sigm(value) {
return 1.0 / (1.0 + Math.exp(0.0 - value));
}
}
decodeAnchor() {
let index = this.maxIndex;
let anchors = this.anchors;
this.pxmin = anchors[index][0];
this.pymin = anchors[index][1];
this.pxmax = anchors[index][2];
this.pymax = anchors[index][3];
}
decodeKp() {
let modelResult = this.modelResult;
let index = this.maxIndex;
let px = (this.pxmin + this.pxmax) / 2;
let py = (this.pymin + this.pymax) / 2;
let pw = this.pxmax - this.pxmin;
let ph = this.pymax - this.pymin;
let prior_var = 0.1
let kp = [[], [], []];
kp[0][0] = (modelResult[index * this.output_size + 6] * pw * prior_var + px) * 256;
kp[0][1] = (modelResult[index * this.output_size + 8] * ph * prior_var + py) * 256;
kp[2][0] = (modelResult[index *this. output_size + 7] * pw * prior_var + px) * 256;
kp[2][1] = (modelResult[index * this.output_size + 9] * ph * prior_var + py) * 256;
this.kp = kp;
}
decodeBox() {
let modelResult = this.modelResult;
let output_size = this.output_size || 10;
let pw = this.pxmax - this.pxmin;
let ph = this.pymax - this.pymin;
let px = this.pxmin + pw / 2;
let py = this.pymin + ph / 2;
let prior_var = 0.1;
let index = this.maxIndex;
let ox = modelResult[output_size * index + 2];
let oy = modelResult[output_size * index + 3];
let ow = modelResult[output_size * index + 4];
let oh = modelResult[output_size * index + 5];
let tx = ox * prior_var * pw + px;
let ty = oy * prior_var * ph + py;
let tw = this.tw = Math.pow(2.71828182, prior_var * ow) * pw;
let th = this.th = Math.pow(2.71828182, prior_var * oh) * ph;
let box = [[], [], [], []];
box[0][0] = parseInt((tx - tw / 2) * 256);
box[0][1] = parseInt((ty - th / 2) * 256);
box[1][0] = parseInt((tx + tw / 2) * 256);
box[1][1] = parseInt((ty - th / 2) * 256);
box[2][0] = parseInt((tx + tw / 2) * 256);
box[2][1] = parseInt((ty + th / 2) * 256);
box[3][0] = parseInt((tx - tw / 2) * 256);
box[3][1] = parseInt((ty + th / 2) * 256);
this.box = box;
}
decodeTriangle() {
let box_enlarge = 1.04;
let side = Math.max(this.tw * 256, this.th * 256) * (box_enlarge);
let dir_v = [[], []];
let kp = this.kp;
let triangle = [[], [], []];
let dir_v_r = [];
dir_v[0] = kp[2][0] - kp[0][0];
dir_v[1] = kp[2][1] - kp[0][1];
let sq = Math.sqrt(Math.pow(dir_v[0], 2) + Math.pow(dir_v[1], 2)) || 1;
dir_v[0] = dir_v[0] / sq;
dir_v[1] = dir_v[1] / sq;
dir_v_r[0] = dir_v[0] * 0 + dir_v[1] * 1;
dir_v_r[1] = dir_v[0] * -1 + dir_v[1] * 0;
triangle[0][0] = kp[2][0];
triangle[0][1] = kp[2][1];
triangle[1][0] = kp[2][0] + dir_v[0] * side;
triangle[1][1] = kp[2][1] + dir_v[1] * side;
triangle[2][0] = kp[2][0] + dir_v_r[0] * side;
triangle[2][1] = kp[2][1] + dir_v_r[1] * side;
this.triangle = triangle;
}
decodeSource() {
let kp = this.kp;
let box_shift = 0.0; // 为什么c语言是乘以0.0
let tmp0 = (kp[0][0] - kp[2][0]) * box_shift;
let tmp1 = (kp[0][1] - kp[2][1]) * box_shift;
let source = [[], [], []];
for (let i = 0; i < 3; i++) {
source[i][0] = this.triangle[i][0] - tmp0;
source[i][1] = this.triangle[i][1] - tmp1;
}
this.source = source;
}
outputResult(){
// let detectResult = [[], [], [], []];
for (let i = 0; i < 4; i++) {
this.detectResult[i][0] = this.box[i][0];
this.detectResult[i][1] = this.box[i][1];
}
// 王超的检测模型只保留0、2两个点。
this.detectResult[4][0] = this.kp[0][0];
this.detectResult[4][1] = this.kp[0][1];
this.detectResult[6][0] = this.kp[2][0];
this.detectResult[6][1] = this.kp[2][1];
for (let i = 0; i < 3; i++) {
this.detectResult[i + 11][0] = this.source[i][0];
this.detectResult[i + 11][1] = this.source[i][1];
}
// let point1 = document.getElementById('point1');
// let point2 = document.getElementById('point2');
// let point3 = document.getElementById('point3');
// [point1, point2, point3].forEach((item, index) => {
// item.style.top = this.detectResult[11 + index][1] + 'px';
// item.style.left = this.detectResult[11 + index][0] + 'px';
// })
}
getaffinetransform() {
/*
* 图像上的原始坐标点。需要对所有坐标进行归一化,_x = (x - 128) / 128, _y = (128 - y) / 128
* 坐标矩阵
* x1 x2 x3
* y1 y2 y3
* z1 z2 z3
*/
let originPoints = [].concat(this.detectResult[11][0] / 128 -1)
.concat(this.detectResult[12][0] / 128 -1)
.concat(this.detectResult[13][0] / 128 -1)
.concat(1 - this.detectResult[11][1] / 128)
.concat(1 - this.detectResult[12][1] / 128)
.concat(1 - this.detectResult[13][1] / 128)
.concat([1, 1, 1]);
// originPoints = [0, 0, -1, .1, 1.1, 0.1, 1, 1, 1];
let matrixA = new Matrix(3, 3, originPoints);
// 转化后的点[128, 128, 0, 128, 0, 128] [0, 0, -1, 0, 1, 0]
let matrixB = new Matrix(2, 3, [0, 0, -1, 0, -1, 0]);
// M * A = B => M = B * A逆
let _matrixA = inverseMatrix(matrixA.data);
_matrixA = new Matrix(3, 3, _matrixA);
let M = Matrix_Product(matrixB, _matrixA);
this.mtr = M;
}
async warpAffine() {
let wat = Date.now();
let ctx = this.originCanvas.getContext('2d');
this.originImageData = ctx.getImageData(0, 0, 256, 256);
// console.info('=====before getImageData:', Date.now() - wat);
wat = Date.now();
let imageDataArr = await WarpAffine.main({
imageData: this.originImageData,
mtr: this.mtr.data,
input: {
width: 256,
height: 256
},
output: {
width: 224,
height: 224
}
});
// console.info('=====warpAffine main:', Date.now() - wat);
wat = Date.now();
this.imageData = new ImageData(Uint8ClampedArray.from(imageDataArr), 224, 224)
// console.info('=====after getImageData:', Date.now() - wat);
}
allReshapeToRGB(paddle) {
let data = paddle.io.allReshapeToRGB(this.imageData, {
gapFillWith: "#000",
mean: [0, 0, 0],
scale: 224,
std: [1, 1, 1],
targetShape: [1, 3, 224, 224],
targetSize: {
width: 224,
height: 224
},
normalizeType: 1
})
this.feed = [{
data: data,
shape: [1, 3, 224, 224],
name: 'image',
canvas: this.originImageData
}];
}
}
class Matrix {
constructor(row, col, arr = []){
this.row = row; //行
this.col = col; //列
if (arr[0] && arr[0] instanceof Array) {
this.data = arr;
}
else {
this.data = [];
let _arr = [].concat(arr);
let Matrix = new Array(row); //创建row个元素的空数组
for(let i = 0; i < row; i++){ //对第一层数组遍历
Matrix[i] = new Array(col).fill(''); //每一行创建col列的空数组
Matrix[i].forEach((item, index, cur) => {
cur[index] = _arr.shift() || 0;
});
}
this.data = Matrix; //将矩阵保存到this.data上
}
}
}
function Matrix_Product(A, B){
let tempMatrix = new Matrix(A.row, B.col);
if(A.col == B.row){
for(let i = 0;i < A.row;i++){
for(let j = 0; j < B.col; j++){
tempMatrix.data[i][j] = 0;
for(let n = 0; n < A.col; n++){
tempMatrix.data[i][j] += A.data[i][n] * B.data[n][j];
}
tempMatrix.data[i][j] = tempMatrix.data[i][j].toFixed(5);
}
}
return tempMatrix;
}
}
// 求行列式
function determinant(matrix) {
var order = matrix.length,
cofactor,
result = 0;
if (order == 1) {
return matrix[0][0];
}
for (var i = 0; i < order; i++) {
cofactor = [];
for (var j = 0; j < order-1; j++) {
cofactor[j] = [];
for (var k = 0; k < order - 1; k++) {
cofactor[j][k] = matrix[j+1][ k<i ? k : k+1 ];
}
}
result += matrix[0][i] * Math.pow(-1, i) * determinant(cofactor);
}
return result;
}
// 矩阵数乘
function scalarMultiply(num, matrix) {
var row = matrix.length,
col = matrix[0].length,
result = [];
for (var i = 0; i < row; i++) {
result[i] = [];
for (var j = 0; j < col; j++) {
result[i][j] = num * matrix[i][j];
}
}
return result;
}
// 矩阵转置
function transpose(matrix) {
var row = matrix.length,
col = matrix[0].length,
result = [];
for (var i = 0; i < col; i++) {
result[i] = [];
for (var j = 0; j < row; j++) {
result[i][j] = matrix[j][i];
}
}
return result;
}
// 矢量内积
function dotProduct(vector1, vector2) {
var n = Math.min(vector1.length, vector2.length),
result = 0;
for (var i = 0; i < n; i++) {
result += vector1[i] * vector2[i];
}
return result;
}
// 矩阵乘法
function multiply(matrix1, matrix2) {
if (matrix1[0].length !== matrix2.length) {
return false;
}
var row = matrix1.length,
col = matrix2[0].length,
matrix2_t = transpose(matrix2);
result = [];
for (var i = 0; i < row; i++) {
result[i] = [];
for (var j = 0; j < col; j++) {
result[i][j] = dotProduct(matrix1[i], matrix2_t[j]);
}
}
return result;
}
// 求逆矩阵
function inverseMatrix(matrix) {
if (determinant(matrix) === 0) {
return false;
}
// 求代数余子式
function cofactor(matrix, row, col) {
var order = matrix.length,
new_matrix = [],
_row, _col;
for (var i = 0; i < order-1; i++) {
new_matrix[i] = [];
_row = i < row ? i : i + 1;
for (var j = 0; j < order-1; j++) {
_col = j < col ? j : j + 1;
new_matrix[i][j] = matrix[_row][_col];
}
}
return Math.pow(-1, row + col) * determinant(new_matrix);
}
var order = matrix.length,
adjoint = [];
for (var i = 0; i < order; i++) {
adjoint[i] = [];
for (var j = 0; j < order; j++) {
adjoint[i][j] = cofactor(matrix, j, i);
}
}
return scalarMultiply(1/determinant(matrix), adjoint);
}
export default DetectProcess;
export default class LMProcess {
constructor(result) {
/*
* result[0] :是否为手
* result[1:43]: 手的21个关键点
* result[43:49]: 几中手势分类,包含但不限于石头剪刀布,为了提升准确度
* this.kp decode result得出的21个手指关键点,this.kp[8]为食指
* this.conf 是否为手,越大,越可能是手
*/
this.input_n = 1;
this.input_h = 224;
this.input_w = 224;
this.input_c = 3;
this.class_dim = 6;
this.points_num = 1;
this.result = result;
}
sigm(value) {
return 1.0 / (1.0 + Math.exp(0.0 - value));
}
decodeConf() {
this.conf = this.sigm(this.result[0]);
}
decodeKp() {
// 21个关键点,下标1开始
let offset = 1;
let result = this.result;
this.kp = [];
for (let i = 0; i < this.points_num; i++) {
let arr = [];
arr.push((result[offset + i * 2] + 0.5) * this.input_h);
arr.push((result[offset + i * 2 + 1] + 0.5) * this.input_h);
this.kp.push(arr);
}
this.forefinger = this.kp[0];
}
softMax() {
let max = 0;
let sum = 0;
let offset = 2;
let class_dim = this.class_dim = 7;
let result = this.result;
let output_softmax = new Array(7).fill(null);
for (let i = 0; i < class_dim; i++) {
if (max < result[i + offset])
max = result[i + offset];
}
for (let i = 0; i < class_dim; i++) {
output_softmax[i] = Math.exp(result[i + offset] - max);
sum += output_softmax[i];
}
for (let i = 0; i < class_dim; i++) {
output_softmax[i] /= sum;
}
this.output_softmax = output_softmax;
}
output() {
this.decodeKp();
this.softMax();
let label_index = 0;
let max_pro = this.output_softmax[0];
for (let i = 1; i < this.class_dim; i++) {
if (max_pro < this.output_softmax[i]) {
label_index = i;
max_pro = this.output_softmax[i];
}
}
// 最后一位:有无手
if (label_index != 0 && label_index != this.class_dim - 1 && max_pro > 0.95) {
let ges = ['其他', '布', '剪刀', '石头', '1', 'ok'];
this.type = ges[label_index];
} else {
this.type = 'other';
}
}
}
0.015625,0.015625,0.179645,0.179645
0.046875,0.015625,0.179645,0.179645
0.078125,0.015625,0.179645,0.179645
0.109375,0.015625,0.179645,0.179645
0.140625,0.015625,0.179645,0.179645
0.171875,0.015625,0.179645,0.179645
0.203125,0.015625,0.179645,0.179645
0.234375,0.015625,0.179645,0.179645
0.265625,0.015625,0.179645,0.179645
0.296875,0.015625,0.179645,0.179645
0.328125,0.015625,0.179645,0.179645
0.359375,0.015625,0.179645,0.179645
0.390625,0.015625,0.179645,0.179645
0.421875,0.015625,0.179645,0.179645
0.453125,0.015625,0.179645,0.179645
0.484375,0.015625,0.179645,0.179645
0.515625,0.015625,0.179645,0.179645
0.546875,0.015625,0.179645,0.179645
0.578125,0.015625,0.179645,0.179645
0.609375,0.015625,0.179645,0.179645
0.640625,0.015625,0.179645,0.179645
0.671875,0.015625,0.179645,0.179645
0.703125,0.015625,0.179645,0.179645
0.734375,0.015625,0.179645,0.179645
0.765625,0.015625,0.179645,0.179645
0.796875,0.015625,0.179645,0.179645
0.828125,0.015625,0.179645,0.179645
0.859375,0.015625,0.179645,0.179645
0.890625,0.015625,0.179645,0.179645
0.921875,0.015625,0.179645,0.179645
0.953125,0.015625,0.179645,0.179645
0.984375,0.015625,0.179645,0.179645
0.015625,0.046875,0.179645,0.179645
0.046875,0.046875,0.179645,0.179645
0.078125,0.046875,0.179645,0.179645
0.109375,0.046875,0.179645,0.179645
0.140625,0.046875,0.179645,0.179645
0.171875,0.046875,0.179645,0.179645
0.203125,0.046875,0.179645,0.179645
0.234375,0.046875,0.179645,0.179645
0.265625,0.046875,0.179645,0.179645
0.296875,0.046875,0.179645,0.179645
0.328125,0.046875,0.179645,0.179645
0.359375,0.046875,0.179645,0.179645
0.390625,0.046875,0.179645,0.179645
0.421875,0.046875,0.179645,0.179645
0.453125,0.046875,0.179645,0.179645
0.484375,0.046875,0.179645,0.179645
0.515625,0.046875,0.179645,0.179645
0.546875,0.046875,0.179645,0.179645
0.578125,0.046875,0.179645,0.179645
0.609375,0.046875,0.179645,0.179645
0.640625,0.046875,0.179645,0.179645
0.671875,0.046875,0.179645,0.179645
0.703125,0.046875,0.179645,0.179645
0.734375,0.046875,0.179645,0.179645
0.765625,0.046875,0.179645,0.179645
0.796875,0.046875,0.179645,0.179645
0.828125,0.046875,0.179645,0.179645
0.859375,0.046875,0.179645,0.179645
0.890625,0.046875,0.179645,0.179645
0.921875,0.046875,0.179645,0.179645
0.953125,0.046875,0.179645,0.179645
0.984375,0.046875,0.179645,0.179645
0.015625,0.078125,0.179645,0.179645
0.046875,0.078125,0.179645,0.179645
0.078125,0.078125,0.179645,0.179645
0.109375,0.078125,0.179645,0.179645
0.140625,0.078125,0.179645,0.179645
0.171875,0.078125,0.179645,0.179645
0.203125,0.078125,0.179645,0.179645
0.234375,0.078125,0.179645,0.179645
0.265625,0.078125,0.179645,0.179645
0.296875,0.078125,0.179645,0.179645
0.328125,0.078125,0.179645,0.179645
0.359375,0.078125,0.179645,0.179645
0.390625,0.078125,0.179645,0.179645
0.421875,0.078125,0.179645,0.179645
0.453125,0.078125,0.179645,0.179645
0.484375,0.078125,0.179645,0.179645
0.515625,0.078125,0.179645,0.179645
0.546875,0.078125,0.179645,0.179645
0.578125,0.078125,0.179645,0.179645
0.609375,0.078125,0.179645,0.179645
0.640625,0.078125,0.179645,0.179645
0.671875,0.078125,0.179645,0.179645
0.703125,0.078125,0.179645,0.179645
0.734375,0.078125,0.179645,0.179645
0.765625,0.078125,0.179645,0.179645
0.796875,0.078125,0.179645,0.179645
0.828125,0.078125,0.179645,0.179645
0.859375,0.078125,0.179645,0.179645
0.890625,0.078125,0.179645,0.179645
0.921875,0.078125,0.179645,0.179645
0.953125,0.078125,0.179645,0.179645
0.984375,0.078125,0.179645,0.179645
0.015625,0.109375,0.179645,0.179645
0.046875,0.109375,0.179645,0.179645
0.078125,0.109375,0.179645,0.179645
0.109375,0.109375,0.179645,0.179645
0.140625,0.109375,0.179645,0.179645
0.171875,0.109375,0.179645,0.179645
0.203125,0.109375,0.179645,0.179645
0.234375,0.109375,0.179645,0.179645
0.265625,0.109375,0.179645,0.179645
0.296875,0.109375,0.179645,0.179645
0.328125,0.109375,0.179645,0.179645
0.359375,0.109375,0.179645,0.179645
0.390625,0.109375,0.179645,0.179645
0.421875,0.109375,0.179645,0.179645
0.453125,0.109375,0.179645,0.179645
0.484375,0.109375,0.179645,0.179645
0.515625,0.109375,0.179645,0.179645
0.546875,0.109375,0.179645,0.179645
0.578125,0.109375,0.179645,0.179645
0.609375,0.109375,0.179645,0.179645
0.640625,0.109375,0.179645,0.179645
0.671875,0.109375,0.179645,0.179645
0.703125,0.109375,0.179645,0.179645
0.734375,0.109375,0.179645,0.179645
0.765625,0.109375,0.179645,0.179645
0.796875,0.109375,0.179645,0.179645
0.828125,0.109375,0.179645,0.179645
0.859375,0.109375,0.179645,0.179645
0.890625,0.109375,0.179645,0.179645
0.921875,0.109375,0.179645,0.179645
0.953125,0.109375,0.179645,0.179645
0.984375,0.109375,0.179645,0.179645
0.015625,0.140625,0.179645,0.179645
0.046875,0.140625,0.179645,0.179645
0.078125,0.140625,0.179645,0.179645
0.109375,0.140625,0.179645,0.179645
0.140625,0.140625,0.179645,0.179645
0.171875,0.140625,0.179645,0.179645
0.203125,0.140625,0.179645,0.179645
0.234375,0.140625,0.179645,0.179645
0.265625,0.140625,0.179645,0.179645
0.296875,0.140625,0.179645,0.179645
0.328125,0.140625,0.179645,0.179645
0.359375,0.140625,0.179645,0.179645
0.390625,0.140625,0.179645,0.179645
0.421875,0.140625,0.179645,0.179645
0.453125,0.140625,0.179645,0.179645
0.484375,0.140625,0.179645,0.179645
0.515625,0.140625,0.179645,0.179645
0.546875,0.140625,0.179645,0.179645
0.578125,0.140625,0.179645,0.179645
0.609375,0.140625,0.179645,0.179645
0.640625,0.140625,0.179645,0.179645
0.671875,0.140625,0.179645,0.179645
0.703125,0.140625,0.179645,0.179645
0.734375,0.140625,0.179645,0.179645
0.765625,0.140625,0.179645,0.179645
0.796875,0.140625,0.179645,0.179645
0.828125,0.140625,0.179645,0.179645
0.859375,0.140625,0.179645,0.179645
0.890625,0.140625,0.179645,0.179645
0.921875,0.140625,0.179645,0.179645
0.953125,0.140625,0.179645,0.179645
0.984375,0.140625,0.179645,0.179645
0.015625,0.171875,0.179645,0.179645
0.046875,0.171875,0.179645,0.179645
0.078125,0.171875,0.179645,0.179645
0.109375,0.171875,0.179645,0.179645
0.140625,0.171875,0.179645,0.179645
0.171875,0.171875,0.179645,0.179645
0.203125,0.171875,0.179645,0.179645
0.234375,0.171875,0.179645,0.179645
0.265625,0.171875,0.179645,0.179645
0.296875,0.171875,0.179645,0.179645
0.328125,0.171875,0.179645,0.179645
0.359375,0.171875,0.179645,0.179645
0.390625,0.171875,0.179645,0.179645
0.421875,0.171875,0.179645,0.179645
0.453125,0.171875,0.179645,0.179645
0.484375,0.171875,0.179645,0.179645
0.515625,0.171875,0.179645,0.179645
0.546875,0.171875,0.179645,0.179645
0.578125,0.171875,0.179645,0.179645
0.609375,0.171875,0.179645,0.179645
0.640625,0.171875,0.179645,0.179645
0.671875,0.171875,0.179645,0.179645
0.703125,0.171875,0.179645,0.179645
0.734375,0.171875,0.179645,0.179645
0.765625,0.171875,0.179645,0.179645
0.796875,0.171875,0.179645,0.179645
0.828125,0.171875,0.179645,0.179645
0.859375,0.171875,0.179645,0.179645
0.890625,0.171875,0.179645,0.179645
0.921875,0.171875,0.179645,0.179645
0.953125,0.171875,0.179645,0.179645
0.984375,0.171875,0.179645,0.179645
0.015625,0.203125,0.179645,0.179645
0.046875,0.203125,0.179645,0.179645
0.078125,0.203125,0.179645,0.179645
0.109375,0.203125,0.179645,0.179645
0.140625,0.203125,0.179645,0.179645
0.171875,0.203125,0.179645,0.179645
0.203125,0.203125,0.179645,0.179645
0.234375,0.203125,0.179645,0.179645
0.265625,0.203125,0.179645,0.179645
0.296875,0.203125,0.179645,0.179645
0.328125,0.203125,0.179645,0.179645
0.359375,0.203125,0.179645,0.179645
0.390625,0.203125,0.179645,0.179645
0.421875,0.203125,0.179645,0.179645
0.453125,0.203125,0.179645,0.179645
0.484375,0.203125,0.179645,0.179645
0.515625,0.203125,0.179645,0.179645
0.546875,0.203125,0.179645,0.179645
0.578125,0.203125,0.179645,0.179645
0.609375,0.203125,0.179645,0.179645
0.640625,0.203125,0.179645,0.179645
0.671875,0.203125,0.179645,0.179645
0.703125,0.203125,0.179645,0.179645
0.734375,0.203125,0.179645,0.179645
0.765625,0.203125,0.179645,0.179645
0.796875,0.203125,0.179645,0.179645
0.828125,0.203125,0.179645,0.179645
0.859375,0.203125,0.179645,0.179645
0.890625,0.203125,0.179645,0.179645
0.921875,0.203125,0.179645,0.179645
0.953125,0.203125,0.179645,0.179645
0.984375,0.203125,0.179645,0.179645
0.015625,0.234375,0.179645,0.179645
0.046875,0.234375,0.179645,0.179645
0.078125,0.234375,0.179645,0.179645
0.109375,0.234375,0.179645,0.179645
0.140625,0.234375,0.179645,0.179645
0.171875,0.234375,0.179645,0.179645
0.203125,0.234375,0.179645,0.179645
0.234375,0.234375,0.179645,0.179645
0.265625,0.234375,0.179645,0.179645
0.296875,0.234375,0.179645,0.179645
0.328125,0.234375,0.179645,0.179645
0.359375,0.234375,0.179645,0.179645
0.390625,0.234375,0.179645,0.179645
0.421875,0.234375,0.179645,0.179645
0.453125,0.234375,0.179645,0.179645
0.484375,0.234375,0.179645,0.179645
0.515625,0.234375,0.179645,0.179645
0.546875,0.234375,0.179645,0.179645
0.578125,0.234375,0.179645,0.179645
0.609375,0.234375,0.179645,0.179645
0.640625,0.234375,0.179645,0.179645
0.671875,0.234375,0.179645,0.179645
0.703125,0.234375,0.179645,0.179645
0.734375,0.234375,0.179645,0.179645
0.765625,0.234375,0.179645,0.179645
0.796875,0.234375,0.179645,0.179645
0.828125,0.234375,0.179645,0.179645
0.859375,0.234375,0.179645,0.179645
0.890625,0.234375,0.179645,0.179645
0.921875,0.234375,0.179645,0.179645
0.953125,0.234375,0.179645,0.179645
0.984375,0.234375,0.179645,0.179645
0.015625,0.265625,0.179645,0.179645
0.046875,0.265625,0.179645,0.179645
0.078125,0.265625,0.179645,0.179645
0.109375,0.265625,0.179645,0.179645
0.140625,0.265625,0.179645,0.179645
0.171875,0.265625,0.179645,0.179645
0.203125,0.265625,0.179645,0.179645
0.234375,0.265625,0.179645,0.179645
0.265625,0.265625,0.179645,0.179645
0.296875,0.265625,0.179645,0.179645
0.328125,0.265625,0.179645,0.179645
0.359375,0.265625,0.179645,0.179645
0.390625,0.265625,0.179645,0.179645
0.421875,0.265625,0.179645,0.179645
0.453125,0.265625,0.179645,0.179645
0.484375,0.265625,0.179645,0.179645
0.515625,0.265625,0.179645,0.179645
0.546875,0.265625,0.179645,0.179645
0.578125,0.265625,0.179645,0.179645
0.609375,0.265625,0.179645,0.179645
0.640625,0.265625,0.179645,0.179645
0.671875,0.265625,0.179645,0.179645
0.703125,0.265625,0.179645,0.179645
0.734375,0.265625,0.179645,0.179645
0.765625,0.265625,0.179645,0.179645
0.796875,0.265625,0.179645,0.179645
0.828125,0.265625,0.179645,0.179645
0.859375,0.265625,0.179645,0.179645
0.890625,0.265625,0.179645,0.179645
0.921875,0.265625,0.179645,0.179645
0.953125,0.265625,0.179645,0.179645
0.984375,0.265625,0.179645,0.179645
0.015625,0.296875,0.179645,0.179645
0.046875,0.296875,0.179645,0.179645
0.078125,0.296875,0.179645,0.179645
0.109375,0.296875,0.179645,0.179645
0.140625,0.296875,0.179645,0.179645
0.171875,0.296875,0.179645,0.179645
0.203125,0.296875,0.179645,0.179645
0.234375,0.296875,0.179645,0.179645
0.265625,0.296875,0.179645,0.179645
0.296875,0.296875,0.179645,0.179645
0.328125,0.296875,0.179645,0.179645
0.359375,0.296875,0.179645,0.179645
0.390625,0.296875,0.179645,0.179645
0.421875,0.296875,0.179645,0.179645
0.453125,0.296875,0.179645,0.179645
0.484375,0.296875,0.179645,0.179645
0.515625,0.296875,0.179645,0.179645
0.546875,0.296875,0.179645,0.179645
0.578125,0.296875,0.179645,0.179645
0.609375,0.296875,0.179645,0.179645
0.640625,0.296875,0.179645,0.179645
0.671875,0.296875,0.179645,0.179645
0.703125,0.296875,0.179645,0.179645
0.734375,0.296875,0.179645,0.179645
0.765625,0.296875,0.179645,0.179645
0.796875,0.296875,0.179645,0.179645
0.828125,0.296875,0.179645,0.179645
0.859375,0.296875,0.179645,0.179645
0.890625,0.296875,0.179645,0.179645
0.921875,0.296875,0.179645,0.179645
0.953125,0.296875,0.179645,0.179645
0.984375,0.296875,0.179645,0.179645
0.015625,0.328125,0.179645,0.179645
0.046875,0.328125,0.179645,0.179645
0.078125,0.328125,0.179645,0.179645
0.109375,0.328125,0.179645,0.179645
0.140625,0.328125,0.179645,0.179645
0.171875,0.328125,0.179645,0.179645
0.203125,0.328125,0.179645,0.179645
0.234375,0.328125,0.179645,0.179645
0.265625,0.328125,0.179645,0.179645
0.296875,0.328125,0.179645,0.179645
0.328125,0.328125,0.179645,0.179645
0.359375,0.328125,0.179645,0.179645
0.390625,0.328125,0.179645,0.179645
0.421875,0.328125,0.179645,0.179645
0.453125,0.328125,0.179645,0.179645
0.484375,0.328125,0.179645,0.179645
0.515625,0.328125,0.179645,0.179645
0.546875,0.328125,0.179645,0.179645
0.578125,0.328125,0.179645,0.179645
0.609375,0.328125,0.179645,0.179645
0.640625,0.328125,0.179645,0.179645
0.671875,0.328125,0.179645,0.179645
0.703125,0.328125,0.179645,0.179645
0.734375,0.328125,0.179645,0.179645
0.765625,0.328125,0.179645,0.179645
0.796875,0.328125,0.179645,0.179645
0.828125,0.328125,0.179645,0.179645
0.859375,0.328125,0.179645,0.179645
0.890625,0.328125,0.179645,0.179645
0.921875,0.328125,0.179645,0.179645
0.953125,0.328125,0.179645,0.179645
0.984375,0.328125,0.179645,0.179645
0.015625,0.359375,0.179645,0.179645
0.046875,0.359375,0.179645,0.179645
0.078125,0.359375,0.179645,0.179645
0.109375,0.359375,0.179645,0.179645
0.140625,0.359375,0.179645,0.179645
0.171875,0.359375,0.179645,0.179645
0.203125,0.359375,0.179645,0.179645
0.234375,0.359375,0.179645,0.179645
0.265625,0.359375,0.179645,0.179645
0.296875,0.359375,0.179645,0.179645
0.328125,0.359375,0.179645,0.179645
0.359375,0.359375,0.179645,0.179645
0.390625,0.359375,0.179645,0.179645
0.421875,0.359375,0.179645,0.179645
0.453125,0.359375,0.179645,0.179645
0.484375,0.359375,0.179645,0.179645
0.515625,0.359375,0.179645,0.179645
0.546875,0.359375,0.179645,0.179645
0.578125,0.359375,0.179645,0.179645
0.609375,0.359375,0.179645,0.179645
0.640625,0.359375,0.179645,0.179645
0.671875,0.359375,0.179645,0.179645
0.703125,0.359375,0.179645,0.179645
0.734375,0.359375,0.179645,0.179645
0.765625,0.359375,0.179645,0.179645
0.796875,0.359375,0.179645,0.179645
0.828125,0.359375,0.179645,0.179645
0.859375,0.359375,0.179645,0.179645
0.890625,0.359375,0.179645,0.179645
0.921875,0.359375,0.179645,0.179645
0.953125,0.359375,0.179645,0.179645
0.984375,0.359375,0.179645,0.179645
0.015625,0.390625,0.179645,0.179645
0.046875,0.390625,0.179645,0.179645
0.078125,0.390625,0.179645,0.179645
0.109375,0.390625,0.179645,0.179645
0.140625,0.390625,0.179645,0.179645
0.171875,0.390625,0.179645,0.179645
0.203125,0.390625,0.179645,0.179645
0.234375,0.390625,0.179645,0.179645
0.265625,0.390625,0.179645,0.179645
0.296875,0.390625,0.179645,0.179645
0.328125,0.390625,0.179645,0.179645
0.359375,0.390625,0.179645,0.179645
0.390625,0.390625,0.179645,0.179645
0.421875,0.390625,0.179645,0.179645
0.453125,0.390625,0.179645,0.179645
0.484375,0.390625,0.179645,0.179645
0.515625,0.390625,0.179645,0.179645
0.546875,0.390625,0.179645,0.179645
0.578125,0.390625,0.179645,0.179645
0.609375,0.390625,0.179645,0.179645
0.640625,0.390625,0.179645,0.179645
0.671875,0.390625,0.179645,0.179645
0.703125,0.390625,0.179645,0.179645
0.734375,0.390625,0.179645,0.179645
0.765625,0.390625,0.179645,0.179645
0.796875,0.390625,0.179645,0.179645
0.828125,0.390625,0.179645,0.179645
0.859375,0.390625,0.179645,0.179645
0.890625,0.390625,0.179645,0.179645
0.921875,0.390625,0.179645,0.179645
0.953125,0.390625,0.179645,0.179645
0.984375,0.390625,0.179645,0.179645
0.015625,0.421875,0.179645,0.179645
0.046875,0.421875,0.179645,0.179645
0.078125,0.421875,0.179645,0.179645
0.109375,0.421875,0.179645,0.179645
0.140625,0.421875,0.179645,0.179645
0.171875,0.421875,0.179645,0.179645
0.203125,0.421875,0.179645,0.179645
0.234375,0.421875,0.179645,0.179645
0.265625,0.421875,0.179645,0.179645
0.296875,0.421875,0.179645,0.179645
0.328125,0.421875,0.179645,0.179645
0.359375,0.421875,0.179645,0.179645
0.390625,0.421875,0.179645,0.179645
0.421875,0.421875,0.179645,0.179645
0.453125,0.421875,0.179645,0.179645
0.484375,0.421875,0.179645,0.179645
0.515625,0.421875,0.179645,0.179645
0.546875,0.421875,0.179645,0.179645
0.578125,0.421875,0.179645,0.179645
0.609375,0.421875,0.179645,0.179645
0.640625,0.421875,0.179645,0.179645
0.671875,0.421875,0.179645,0.179645
0.703125,0.421875,0.179645,0.179645
0.734375,0.421875,0.179645,0.179645
0.765625,0.421875,0.179645,0.179645
0.796875,0.421875,0.179645,0.179645
0.828125,0.421875,0.179645,0.179645
0.859375,0.421875,0.179645,0.179645
0.890625,0.421875,0.179645,0.179645
0.921875,0.421875,0.179645,0.179645
0.953125,0.421875,0.179645,0.179645
0.984375,0.421875,0.179645,0.179645
0.015625,0.453125,0.179645,0.179645
0.046875,0.453125,0.179645,0.179645
0.078125,0.453125,0.179645,0.179645
0.109375,0.453125,0.179645,0.179645
0.140625,0.453125,0.179645,0.179645
0.171875,0.453125,0.179645,0.179645
0.203125,0.453125,0.179645,0.179645
0.234375,0.453125,0.179645,0.179645
0.265625,0.453125,0.179645,0.179645
0.296875,0.453125,0.179645,0.179645
0.328125,0.453125,0.179645,0.179645
0.359375,0.453125,0.179645,0.179645
0.390625,0.453125,0.179645,0.179645
0.421875,0.453125,0.179645,0.179645
0.453125,0.453125,0.179645,0.179645
0.484375,0.453125,0.179645,0.179645
0.515625,0.453125,0.179645,0.179645
0.546875,0.453125,0.179645,0.179645
0.578125,0.453125,0.179645,0.179645
0.609375,0.453125,0.179645,0.179645
0.640625,0.453125,0.179645,0.179645
0.671875,0.453125,0.179645,0.179645
0.703125,0.453125,0.179645,0.179645
0.734375,0.453125,0.179645,0.179645
0.765625,0.453125,0.179645,0.179645
0.796875,0.453125,0.179645,0.179645
0.828125,0.453125,0.179645,0.179645
0.859375,0.453125,0.179645,0.179645
0.890625,0.453125,0.179645,0.179645
0.921875,0.453125,0.179645,0.179645
0.953125,0.453125,0.179645,0.179645
0.984375,0.453125,0.179645,0.179645
0.015625,0.484375,0.179645,0.179645
0.046875,0.484375,0.179645,0.179645
0.078125,0.484375,0.179645,0.179645
0.109375,0.484375,0.179645,0.179645
0.140625,0.484375,0.179645,0.179645
0.171875,0.484375,0.179645,0.179645
0.203125,0.484375,0.179645,0.179645
0.234375,0.484375,0.179645,0.179645
0.265625,0.484375,0.179645,0.179645
0.296875,0.484375,0.179645,0.179645
0.328125,0.484375,0.179645,0.179645
0.359375,0.484375,0.179645,0.179645
0.390625,0.484375,0.179645,0.179645
0.421875,0.484375,0.179645,0.179645
0.453125,0.484375,0.179645,0.179645
0.484375,0.484375,0.179645,0.179645
0.515625,0.484375,0.179645,0.179645
0.546875,0.484375,0.179645,0.179645
0.578125,0.484375,0.179645,0.179645
0.609375,0.484375,0.179645,0.179645
0.640625,0.484375,0.179645,0.179645
0.671875,0.484375,0.179645,0.179645
0.703125,0.484375,0.179645,0.179645
0.734375,0.484375,0.179645,0.179645
0.765625,0.484375,0.179645,0.179645
0.796875,0.484375,0.179645,0.179645
0.828125,0.484375,0.179645,0.179645
0.859375,0.484375,0.179645,0.179645
0.890625,0.484375,0.179645,0.179645
0.921875,0.484375,0.179645,0.179645
0.953125,0.484375,0.179645,0.179645
0.984375,0.484375,0.179645,0.179645
0.015625,0.515625,0.179645,0.179645
0.046875,0.515625,0.179645,0.179645
0.078125,0.515625,0.179645,0.179645
0.109375,0.515625,0.179645,0.179645
0.140625,0.515625,0.179645,0.179645
0.171875,0.515625,0.179645,0.179645
0.203125,0.515625,0.179645,0.179645
0.234375,0.515625,0.179645,0.179645
0.265625,0.515625,0.179645,0.179645
0.296875,0.515625,0.179645,0.179645
0.328125,0.515625,0.179645,0.179645
0.359375,0.515625,0.179645,0.179645
0.390625,0.515625,0.179645,0.179645
0.421875,0.515625,0.179645,0.179645
0.453125,0.515625,0.179645,0.179645
0.484375,0.515625,0.179645,0.179645
0.515625,0.515625,0.179645,0.179645
0.546875,0.515625,0.179645,0.179645
0.578125,0.515625,0.179645,0.179645
0.609375,0.515625,0.179645,0.179645
0.640625,0.515625,0.179645,0.179645
0.671875,0.515625,0.179645,0.179645
0.703125,0.515625,0.179645,0.179645
0.734375,0.515625,0.179645,0.179645
0.765625,0.515625,0.179645,0.179645
0.796875,0.515625,0.179645,0.179645
0.828125,0.515625,0.179645,0.179645
0.859375,0.515625,0.179645,0.179645
0.890625,0.515625,0.179645,0.179645
0.921875,0.515625,0.179645,0.179645
0.953125,0.515625,0.179645,0.179645
0.984375,0.515625,0.179645,0.179645
0.015625,0.546875,0.179645,0.179645
0.046875,0.546875,0.179645,0.179645
0.078125,0.546875,0.179645,0.179645
0.109375,0.546875,0.179645,0.179645
0.140625,0.546875,0.179645,0.179645
0.171875,0.546875,0.179645,0.179645
0.203125,0.546875,0.179645,0.179645
0.234375,0.546875,0.179645,0.179645
0.265625,0.546875,0.179645,0.179645
0.296875,0.546875,0.179645,0.179645
0.328125,0.546875,0.179645,0.179645
0.359375,0.546875,0.179645,0.179645
0.390625,0.546875,0.179645,0.179645
0.421875,0.546875,0.179645,0.179645
0.453125,0.546875,0.179645,0.179645
0.484375,0.546875,0.179645,0.179645
0.515625,0.546875,0.179645,0.179645
0.546875,0.546875,0.179645,0.179645
0.578125,0.546875,0.179645,0.179645
0.609375,0.546875,0.179645,0.179645
0.640625,0.546875,0.179645,0.179645
0.671875,0.546875,0.179645,0.179645
0.703125,0.546875,0.179645,0.179645
0.734375,0.546875,0.179645,0.179645
0.765625,0.546875,0.179645,0.179645
0.796875,0.546875,0.179645,0.179645
0.828125,0.546875,0.179645,0.179645
0.859375,0.546875,0.179645,0.179645
0.890625,0.546875,0.179645,0.179645
0.921875,0.546875,0.179645,0.179645
0.953125,0.546875,0.179645,0.179645
0.984375,0.546875,0.179645,0.179645
0.015625,0.578125,0.179645,0.179645
0.046875,0.578125,0.179645,0.179645
0.078125,0.578125,0.179645,0.179645
0.109375,0.578125,0.179645,0.179645
0.140625,0.578125,0.179645,0.179645
0.171875,0.578125,0.179645,0.179645
0.203125,0.578125,0.179645,0.179645
0.234375,0.578125,0.179645,0.179645
0.265625,0.578125,0.179645,0.179645
0.296875,0.578125,0.179645,0.179645
0.328125,0.578125,0.179645,0.179645
0.359375,0.578125,0.179645,0.179645
0.390625,0.578125,0.179645,0.179645
0.421875,0.578125,0.179645,0.179645
0.453125,0.578125,0.179645,0.179645
0.484375,0.578125,0.179645,0.179645
0.515625,0.578125,0.179645,0.179645
0.546875,0.578125,0.179645,0.179645
0.578125,0.578125,0.179645,0.179645
0.609375,0.578125,0.179645,0.179645
0.640625,0.578125,0.179645,0.179645
0.671875,0.578125,0.179645,0.179645
0.703125,0.578125,0.179645,0.179645
0.734375,0.578125,0.179645,0.179645
0.765625,0.578125,0.179645,0.179645
0.796875,0.578125,0.179645,0.179645
0.828125,0.578125,0.179645,0.179645
0.859375,0.578125,0.179645,0.179645
0.890625,0.578125,0.179645,0.179645
0.921875,0.578125,0.179645,0.179645
0.953125,0.578125,0.179645,0.179645
0.984375,0.578125,0.179645,0.179645
0.015625,0.609375,0.179645,0.179645
0.046875,0.609375,0.179645,0.179645
0.078125,0.609375,0.179645,0.179645
0.109375,0.609375,0.179645,0.179645
0.140625,0.609375,0.179645,0.179645
0.171875,0.609375,0.179645,0.179645
0.203125,0.609375,0.179645,0.179645
0.234375,0.609375,0.179645,0.179645
0.265625,0.609375,0.179645,0.179645
0.296875,0.609375,0.179645,0.179645
0.328125,0.609375,0.179645,0.179645
0.359375,0.609375,0.179645,0.179645
0.390625,0.609375,0.179645,0.179645
0.421875,0.609375,0.179645,0.179645
0.453125,0.609375,0.179645,0.179645
0.484375,0.609375,0.179645,0.179645
0.515625,0.609375,0.179645,0.179645
0.546875,0.609375,0.179645,0.179645
0.578125,0.609375,0.179645,0.179645
0.609375,0.609375,0.179645,0.179645
0.640625,0.609375,0.179645,0.179645
0.671875,0.609375,0.179645,0.179645
0.703125,0.609375,0.179645,0.179645
0.734375,0.609375,0.179645,0.179645
0.765625,0.609375,0.179645,0.179645
0.796875,0.609375,0.179645,0.179645
0.828125,0.609375,0.179645,0.179645
0.859375,0.609375,0.179645,0.179645
0.890625,0.609375,0.179645,0.179645
0.921875,0.609375,0.179645,0.179645
0.953125,0.609375,0.179645,0.179645
0.984375,0.609375,0.179645,0.179645
0.015625,0.640625,0.179645,0.179645
0.046875,0.640625,0.179645,0.179645
0.078125,0.640625,0.179645,0.179645
0.109375,0.640625,0.179645,0.179645
0.140625,0.640625,0.179645,0.179645
0.171875,0.640625,0.179645,0.179645
0.203125,0.640625,0.179645,0.179645
0.234375,0.640625,0.179645,0.179645
0.265625,0.640625,0.179645,0.179645
0.296875,0.640625,0.179645,0.179645
0.328125,0.640625,0.179645,0.179645
0.359375,0.640625,0.179645,0.179645
0.390625,0.640625,0.179645,0.179645
0.421875,0.640625,0.179645,0.179645
0.453125,0.640625,0.179645,0.179645
0.484375,0.640625,0.179645,0.179645
0.515625,0.640625,0.179645,0.179645
0.546875,0.640625,0.179645,0.179645
0.578125,0.640625,0.179645,0.179645
0.609375,0.640625,0.179645,0.179645
0.640625,0.640625,0.179645,0.179645
0.671875,0.640625,0.179645,0.179645
0.703125,0.640625,0.179645,0.179645
0.734375,0.640625,0.179645,0.179645
0.765625,0.640625,0.179645,0.179645
0.796875,0.640625,0.179645,0.179645
0.828125,0.640625,0.179645,0.179645
0.859375,0.640625,0.179645,0.179645
0.890625,0.640625,0.179645,0.179645
0.921875,0.640625,0.179645,0.179645
0.953125,0.640625,0.179645,0.179645
0.984375,0.640625,0.179645,0.179645
0.015625,0.671875,0.179645,0.179645
0.046875,0.671875,0.179645,0.179645
0.078125,0.671875,0.179645,0.179645
0.109375,0.671875,0.179645,0.179645
0.140625,0.671875,0.179645,0.179645
0.171875,0.671875,0.179645,0.179645
0.203125,0.671875,0.179645,0.179645
0.234375,0.671875,0.179645,0.179645
0.265625,0.671875,0.179645,0.179645
0.296875,0.671875,0.179645,0.179645
0.328125,0.671875,0.179645,0.179645
0.359375,0.671875,0.179645,0.179645
0.390625,0.671875,0.179645,0.179645
0.421875,0.671875,0.179645,0.179645
0.453125,0.671875,0.179645,0.179645
0.484375,0.671875,0.179645,0.179645
0.515625,0.671875,0.179645,0.179645
0.546875,0.671875,0.179645,0.179645
0.578125,0.671875,0.179645,0.179645
0.609375,0.671875,0.179645,0.179645
0.640625,0.671875,0.179645,0.179645
0.671875,0.671875,0.179645,0.179645
0.703125,0.671875,0.179645,0.179645
0.734375,0.671875,0.179645,0.179645
0.765625,0.671875,0.179645,0.179645
0.796875,0.671875,0.179645,0.179645
0.828125,0.671875,0.179645,0.179645
0.859375,0.671875,0.179645,0.179645
0.890625,0.671875,0.179645,0.179645
0.921875,0.671875,0.179645,0.179645
0.953125,0.671875,0.179645,0.179645
0.984375,0.671875,0.179645,0.179645
0.015625,0.703125,0.179645,0.179645
0.046875,0.703125,0.179645,0.179645
0.078125,0.703125,0.179645,0.179645
0.109375,0.703125,0.179645,0.179645
0.140625,0.703125,0.179645,0.179645
0.171875,0.703125,0.179645,0.179645
0.203125,0.703125,0.179645,0.179645
0.234375,0.703125,0.179645,0.179645
0.265625,0.703125,0.179645,0.179645
0.296875,0.703125,0.179645,0.179645
0.328125,0.703125,0.179645,0.179645
0.359375,0.703125,0.179645,0.179645
0.390625,0.703125,0.179645,0.179645
0.421875,0.703125,0.179645,0.179645
0.453125,0.703125,0.179645,0.179645
0.484375,0.703125,0.179645,0.179645
0.515625,0.703125,0.179645,0.179645
0.546875,0.703125,0.179645,0.179645
0.578125,0.703125,0.179645,0.179645
0.609375,0.703125,0.179645,0.179645
0.640625,0.703125,0.179645,0.179645
0.671875,0.703125,0.179645,0.179645
0.703125,0.703125,0.179645,0.179645
0.734375,0.703125,0.179645,0.179645
0.765625,0.703125,0.179645,0.179645
0.796875,0.703125,0.179645,0.179645
0.828125,0.703125,0.179645,0.179645
0.859375,0.703125,0.179645,0.179645
0.890625,0.703125,0.179645,0.179645
0.921875,0.703125,0.179645,0.179645
0.953125,0.703125,0.179645,0.179645
0.984375,0.703125,0.179645,0.179645
0.015625,0.734375,0.179645,0.179645
0.046875,0.734375,0.179645,0.179645
0.078125,0.734375,0.179645,0.179645
0.109375,0.734375,0.179645,0.179645
0.140625,0.734375,0.179645,0.179645
0.171875,0.734375,0.179645,0.179645
0.203125,0.734375,0.179645,0.179645
0.234375,0.734375,0.179645,0.179645
0.265625,0.734375,0.179645,0.179645
0.296875,0.734375,0.179645,0.179645
0.328125,0.734375,0.179645,0.179645
0.359375,0.734375,0.179645,0.179645
0.390625,0.734375,0.179645,0.179645
0.421875,0.734375,0.179645,0.179645
0.453125,0.734375,0.179645,0.179645
0.484375,0.734375,0.179645,0.179645
0.515625,0.734375,0.179645,0.179645
0.546875,0.734375,0.179645,0.179645
0.578125,0.734375,0.179645,0.179645
0.609375,0.734375,0.179645,0.179645
0.640625,0.734375,0.179645,0.179645
0.671875,0.734375,0.179645,0.179645
0.703125,0.734375,0.179645,0.179645
0.734375,0.734375,0.179645,0.179645
0.765625,0.734375,0.179645,0.179645
0.796875,0.734375,0.179645,0.179645
0.828125,0.734375,0.179645,0.179645
0.859375,0.734375,0.179645,0.179645
0.890625,0.734375,0.179645,0.179645
0.921875,0.734375,0.179645,0.179645
0.953125,0.734375,0.179645,0.179645
0.984375,0.734375,0.179645,0.179645
0.015625,0.765625,0.179645,0.179645
0.046875,0.765625,0.179645,0.179645
0.078125,0.765625,0.179645,0.179645
0.109375,0.765625,0.179645,0.179645
0.140625,0.765625,0.179645,0.179645
0.171875,0.765625,0.179645,0.179645
0.203125,0.765625,0.179645,0.179645
0.234375,0.765625,0.179645,0.179645
0.265625,0.765625,0.179645,0.179645
0.296875,0.765625,0.179645,0.179645
0.328125,0.765625,0.179645,0.179645
0.359375,0.765625,0.179645,0.179645
0.390625,0.765625,0.179645,0.179645
0.421875,0.765625,0.179645,0.179645
0.453125,0.765625,0.179645,0.179645
0.484375,0.765625,0.179645,0.179645
0.515625,0.765625,0.179645,0.179645
0.546875,0.765625,0.179645,0.179645
0.578125,0.765625,0.179645,0.179645
0.609375,0.765625,0.179645,0.179645
0.640625,0.765625,0.179645,0.179645
0.671875,0.765625,0.179645,0.179645
0.703125,0.765625,0.179645,0.179645
0.734375,0.765625,0.179645,0.179645
0.765625,0.765625,0.179645,0.179645
0.796875,0.765625,0.179645,0.179645
0.828125,0.765625,0.179645,0.179645
0.859375,0.765625,0.179645,0.179645
0.890625,0.765625,0.179645,0.179645
0.921875,0.765625,0.179645,0.179645
0.953125,0.765625,0.179645,0.179645
0.984375,0.765625,0.179645,0.179645
0.015625,0.796875,0.179645,0.179645
0.046875,0.796875,0.179645,0.179645
0.078125,0.796875,0.179645,0.179645
0.109375,0.796875,0.179645,0.179645
0.140625,0.796875,0.179645,0.179645
0.171875,0.796875,0.179645,0.179645
0.203125,0.796875,0.179645,0.179645
0.234375,0.796875,0.179645,0.179645
0.265625,0.796875,0.179645,0.179645
0.296875,0.796875,0.179645,0.179645
0.328125,0.796875,0.179645,0.179645
0.359375,0.796875,0.179645,0.179645
0.390625,0.796875,0.179645,0.179645
0.421875,0.796875,0.179645,0.179645
0.453125,0.796875,0.179645,0.179645
0.484375,0.796875,0.179645,0.179645
0.515625,0.796875,0.179645,0.179645
0.546875,0.796875,0.179645,0.179645
0.578125,0.796875,0.179645,0.179645
0.609375,0.796875,0.179645,0.179645
0.640625,0.796875,0.179645,0.179645
0.671875,0.796875,0.179645,0.179645
0.703125,0.796875,0.179645,0.179645
0.734375,0.796875,0.179645,0.179645
0.765625,0.796875,0.179645,0.179645
0.796875,0.796875,0.179645,0.179645
0.828125,0.796875,0.179645,0.179645
0.859375,0.796875,0.179645,0.179645
0.890625,0.796875,0.179645,0.179645
0.921875,0.796875,0.179645,0.179645
0.953125,0.796875,0.179645,0.179645
0.984375,0.796875,0.179645,0.179645
0.015625,0.828125,0.179645,0.179645
0.046875,0.828125,0.179645,0.179645
0.078125,0.828125,0.179645,0.179645
0.109375,0.828125,0.179645,0.179645
0.140625,0.828125,0.179645,0.179645
0.171875,0.828125,0.179645,0.179645
0.203125,0.828125,0.179645,0.179645
0.234375,0.828125,0.179645,0.179645
0.265625,0.828125,0.179645,0.179645
0.296875,0.828125,0.179645,0.179645
0.328125,0.828125,0.179645,0.179645
0.359375,0.828125,0.179645,0.179645
0.390625,0.828125,0.179645,0.179645
0.421875,0.828125,0.179645,0.179645
0.453125,0.828125,0.179645,0.179645
0.484375,0.828125,0.179645,0.179645
0.515625,0.828125,0.179645,0.179645
0.546875,0.828125,0.179645,0.179645
0.578125,0.828125,0.179645,0.179645
0.609375,0.828125,0.179645,0.179645
0.640625,0.828125,0.179645,0.179645
0.671875,0.828125,0.179645,0.179645
0.703125,0.828125,0.179645,0.179645
0.734375,0.828125,0.179645,0.179645
0.765625,0.828125,0.179645,0.179645
0.796875,0.828125,0.179645,0.179645
0.828125,0.828125,0.179645,0.179645
0.859375,0.828125,0.179645,0.179645
0.890625,0.828125,0.179645,0.179645
0.921875,0.828125,0.179645,0.179645
0.953125,0.828125,0.179645,0.179645
0.984375,0.828125,0.179645,0.179645
0.015625,0.859375,0.179645,0.179645
0.046875,0.859375,0.179645,0.179645
0.078125,0.859375,0.179645,0.179645
0.109375,0.859375,0.179645,0.179645
0.140625,0.859375,0.179645,0.179645
0.171875,0.859375,0.179645,0.179645
0.203125,0.859375,0.179645,0.179645
0.234375,0.859375,0.179645,0.179645
0.265625,0.859375,0.179645,0.179645
0.296875,0.859375,0.179645,0.179645
0.328125,0.859375,0.179645,0.179645
0.359375,0.859375,0.179645,0.179645
0.390625,0.859375,0.179645,0.179645
0.421875,0.859375,0.179645,0.179645
0.453125,0.859375,0.179645,0.179645
0.484375,0.859375,0.179645,0.179645
0.515625,0.859375,0.179645,0.179645
0.546875,0.859375,0.179645,0.179645
0.578125,0.859375,0.179645,0.179645
0.609375,0.859375,0.179645,0.179645
0.640625,0.859375,0.179645,0.179645
0.671875,0.859375,0.179645,0.179645
0.703125,0.859375,0.179645,0.179645
0.734375,0.859375,0.179645,0.179645
0.765625,0.859375,0.179645,0.179645
0.796875,0.859375,0.179645,0.179645
0.828125,0.859375,0.179645,0.179645
0.859375,0.859375,0.179645,0.179645
0.890625,0.859375,0.179645,0.179645
0.921875,0.859375,0.179645,0.179645
0.953125,0.859375,0.179645,0.179645
0.984375,0.859375,0.179645,0.179645
0.015625,0.890625,0.179645,0.179645
0.046875,0.890625,0.179645,0.179645
0.078125,0.890625,0.179645,0.179645
0.109375,0.890625,0.179645,0.179645
0.140625,0.890625,0.179645,0.179645
0.171875,0.890625,0.179645,0.179645
0.203125,0.890625,0.179645,0.179645
0.234375,0.890625,0.179645,0.179645
0.265625,0.890625,0.179645,0.179645
0.296875,0.890625,0.179645,0.179645
0.328125,0.890625,0.179645,0.179645
0.359375,0.890625,0.179645,0.179645
0.390625,0.890625,0.179645,0.179645
0.421875,0.890625,0.179645,0.179645
0.453125,0.890625,0.179645,0.179645
0.484375,0.890625,0.179645,0.179645
0.515625,0.890625,0.179645,0.179645
0.546875,0.890625,0.179645,0.179645
0.578125,0.890625,0.179645,0.179645
0.609375,0.890625,0.179645,0.179645
0.640625,0.890625,0.179645,0.179645
0.671875,0.890625,0.179645,0.179645
0.703125,0.890625,0.179645,0.179645
0.734375,0.890625,0.179645,0.179645
0.765625,0.890625,0.179645,0.179645
0.796875,0.890625,0.179645,0.179645
0.828125,0.890625,0.179645,0.179645
0.859375,0.890625,0.179645,0.179645
0.890625,0.890625,0.179645,0.179645
0.921875,0.890625,0.179645,0.179645
0.953125,0.890625,0.179645,0.179645
0.984375,0.890625,0.179645,0.179645
0.015625,0.921875,0.179645,0.179645
0.046875,0.921875,0.179645,0.179645
0.078125,0.921875,0.179645,0.179645
0.109375,0.921875,0.179645,0.179645
0.140625,0.921875,0.179645,0.179645
0.171875,0.921875,0.179645,0.179645
0.203125,0.921875,0.179645,0.179645
0.234375,0.921875,0.179645,0.179645
0.265625,0.921875,0.179645,0.179645
0.296875,0.921875,0.179645,0.179645
0.328125,0.921875,0.179645,0.179645
0.359375,0.921875,0.179645,0.179645
0.390625,0.921875,0.179645,0.179645
0.421875,0.921875,0.179645,0.179645
0.453125,0.921875,0.179645,0.179645
0.484375,0.921875,0.179645,0.179645
0.515625,0.921875,0.179645,0.179645
0.546875,0.921875,0.179645,0.179645
0.578125,0.921875,0.179645,0.179645
0.609375,0.921875,0.179645,0.179645
0.640625,0.921875,0.179645,0.179645
0.671875,0.921875,0.179645,0.179645
0.703125,0.921875,0.179645,0.179645
0.734375,0.921875,0.179645,0.179645
0.765625,0.921875,0.179645,0.179645
0.796875,0.921875,0.179645,0.179645
0.828125,0.921875,0.179645,0.179645
0.859375,0.921875,0.179645,0.179645
0.890625,0.921875,0.179645,0.179645
0.921875,0.921875,0.179645,0.179645
0.953125,0.921875,0.179645,0.179645
0.984375,0.921875,0.179645,0.179645
0.015625,0.953125,0.179645,0.179645
0.046875,0.953125,0.179645,0.179645
0.078125,0.953125,0.179645,0.179645
0.109375,0.953125,0.179645,0.179645
0.140625,0.953125,0.179645,0.179645
0.171875,0.953125,0.179645,0.179645
0.203125,0.953125,0.179645,0.179645
0.234375,0.953125,0.179645,0.179645
0.265625,0.953125,0.179645,0.179645
0.296875,0.953125,0.179645,0.179645
0.328125,0.953125,0.179645,0.179645
0.359375,0.953125,0.179645,0.179645
0.390625,0.953125,0.179645,0.179645
0.421875,0.953125,0.179645,0.179645
0.453125,0.953125,0.179645,0.179645
0.484375,0.953125,0.179645,0.179645
0.515625,0.953125,0.179645,0.179645
0.546875,0.953125,0.179645,0.179645
0.578125,0.953125,0.179645,0.179645
0.609375,0.953125,0.179645,0.179645
0.640625,0.953125,0.179645,0.179645
0.671875,0.953125,0.179645,0.179645
0.703125,0.953125,0.179645,0.179645
0.734375,0.953125,0.179645,0.179645
0.765625,0.953125,0.179645,0.179645
0.796875,0.953125,0.179645,0.179645
0.828125,0.953125,0.179645,0.179645
0.859375,0.953125,0.179645,0.179645
0.890625,0.953125,0.179645,0.179645
0.921875,0.953125,0.179645,0.179645
0.953125,0.953125,0.179645,0.179645
0.984375,0.953125,0.179645,0.179645
0.015625,0.984375,0.179645,0.179645
0.046875,0.984375,0.179645,0.179645
0.078125,0.984375,0.179645,0.179645
0.109375,0.984375,0.179645,0.179645
0.140625,0.984375,0.179645,0.179645
0.171875,0.984375,0.179645,0.179645
0.203125,0.984375,0.179645,0.179645
0.234375,0.984375,0.179645,0.179645
0.265625,0.984375,0.179645,0.179645
0.296875,0.984375,0.179645,0.179645
0.328125,0.984375,0.179645,0.179645
0.359375,0.984375,0.179645,0.179645
0.390625,0.984375,0.179645,0.179645
0.421875,0.984375,0.179645,0.179645
0.453125,0.984375,0.179645,0.179645
0.484375,0.984375,0.179645,0.179645
0.515625,0.984375,0.179645,0.179645
0.546875,0.984375,0.179645,0.179645
0.578125,0.984375,0.179645,0.179645
0.609375,0.984375,0.179645,0.179645
0.640625,0.984375,0.179645,0.179645
0.671875,0.984375,0.179645,0.179645
0.703125,0.984375,0.179645,0.179645
0.734375,0.984375,0.179645,0.179645
0.765625,0.984375,0.179645,0.179645
0.796875,0.984375,0.179645,0.179645
0.828125,0.984375,0.179645,0.179645
0.859375,0.984375,0.179645,0.179645
0.890625,0.984375,0.179645,0.179645
0.921875,0.984375,0.179645,0.179645
0.953125,0.984375,0.179645,0.179645
0.984375,0.984375,0.179645,0.179645
0.03125,0.03125,0.275391,0.275391
0.03125,0.03125,0.345554,0.345554
0.09375,0.03125,0.275391,0.275391
0.09375,0.03125,0.345554,0.345554
0.15625,0.03125,0.275391,0.275391
0.15625,0.03125,0.345554,0.345554
0.21875,0.03125,0.275391,0.275391
0.21875,0.03125,0.345554,0.345554
0.28125,0.03125,0.275391,0.275391
0.28125,0.03125,0.345554,0.345554
0.34375,0.03125,0.275391,0.275391
0.34375,0.03125,0.345554,0.345554
0.40625,0.03125,0.275391,0.275391
0.40625,0.03125,0.345554,0.345554
0.46875,0.03125,0.275391,0.275391
0.46875,0.03125,0.345554,0.345554
0.53125,0.03125,0.275391,0.275391
0.53125,0.03125,0.345554,0.345554
0.59375,0.03125,0.275391,0.275391
0.59375,0.03125,0.345554,0.345554
0.65625,0.03125,0.275391,0.275391
0.65625,0.03125,0.345554,0.345554
0.71875,0.03125,0.275391,0.275391
0.71875,0.03125,0.345554,0.345554
0.78125,0.03125,0.275391,0.275391
0.78125,0.03125,0.345554,0.345554
0.84375,0.03125,0.275391,0.275391
0.84375,0.03125,0.345554,0.345554
0.90625,0.03125,0.275391,0.275391
0.90625,0.03125,0.345554,0.345554
0.96875,0.03125,0.275391,0.275391
0.96875,0.03125,0.345554,0.345554
0.03125,0.09375,0.275391,0.275391
0.03125,0.09375,0.345554,0.345554
0.09375,0.09375,0.275391,0.275391
0.09375,0.09375,0.345554,0.345554
0.15625,0.09375,0.275391,0.275391
0.15625,0.09375,0.345554,0.345554
0.21875,0.09375,0.275391,0.275391
0.21875,0.09375,0.345554,0.345554
0.28125,0.09375,0.275391,0.275391
0.28125,0.09375,0.345554,0.345554
0.34375,0.09375,0.275391,0.275391
0.34375,0.09375,0.345554,0.345554
0.40625,0.09375,0.275391,0.275391
0.40625,0.09375,0.345554,0.345554
0.46875,0.09375,0.275391,0.275391
0.46875,0.09375,0.345554,0.345554
0.53125,0.09375,0.275391,0.275391
0.53125,0.09375,0.345554,0.345554
0.59375,0.09375,0.275391,0.275391
0.59375,0.09375,0.345554,0.345554
0.65625,0.09375,0.275391,0.275391
0.65625,0.09375,0.345554,0.345554
0.71875,0.09375,0.275391,0.275391
0.71875,0.09375,0.345554,0.345554
0.78125,0.09375,0.275391,0.275391
0.78125,0.09375,0.345554,0.345554
0.84375,0.09375,0.275391,0.275391
0.84375,0.09375,0.345554,0.345554
0.90625,0.09375,0.275391,0.275391
0.90625,0.09375,0.345554,0.345554
0.96875,0.09375,0.275391,0.275391
0.96875,0.09375,0.345554,0.345554
0.03125,0.15625,0.275391,0.275391
0.03125,0.15625,0.345554,0.345554
0.09375,0.15625,0.275391,0.275391
0.09375,0.15625,0.345554,0.345554
0.15625,0.15625,0.275391,0.275391
0.15625,0.15625,0.345554,0.345554
0.21875,0.15625,0.275391,0.275391
0.21875,0.15625,0.345554,0.345554
0.28125,0.15625,0.275391,0.275391
0.28125,0.15625,0.345554,0.345554
0.34375,0.15625,0.275391,0.275391
0.34375,0.15625,0.345554,0.345554
0.40625,0.15625,0.275391,0.275391
0.40625,0.15625,0.345554,0.345554
0.46875,0.15625,0.275391,0.275391
0.46875,0.15625,0.345554,0.345554
0.53125,0.15625,0.275391,0.275391
0.53125,0.15625,0.345554,0.345554
0.59375,0.15625,0.275391,0.275391
0.59375,0.15625,0.345554,0.345554
0.65625,0.15625,0.275391,0.275391
0.65625,0.15625,0.345554,0.345554
0.71875,0.15625,0.275391,0.275391
0.71875,0.15625,0.345554,0.345554
0.78125,0.15625,0.275391,0.275391
0.78125,0.15625,0.345554,0.345554
0.84375,0.15625,0.275391,0.275391
0.84375,0.15625,0.345554,0.345554
0.90625,0.15625,0.275391,0.275391
0.90625,0.15625,0.345554,0.345554
0.96875,0.15625,0.275391,0.275391
0.96875,0.15625,0.345554,0.345554
0.03125,0.21875,0.275391,0.275391
0.03125,0.21875,0.345554,0.345554
0.09375,0.21875,0.275391,0.275391
0.09375,0.21875,0.345554,0.345554
0.15625,0.21875,0.275391,0.275391
0.15625,0.21875,0.345554,0.345554
0.21875,0.21875,0.275391,0.275391
0.21875,0.21875,0.345554,0.345554
0.28125,0.21875,0.275391,0.275391
0.28125,0.21875,0.345554,0.345554
0.34375,0.21875,0.275391,0.275391
0.34375,0.21875,0.345554,0.345554
0.40625,0.21875,0.275391,0.275391
0.40625,0.21875,0.345554,0.345554
0.46875,0.21875,0.275391,0.275391
0.46875,0.21875,0.345554,0.345554
0.53125,0.21875,0.275391,0.275391
0.53125,0.21875,0.345554,0.345554
0.59375,0.21875,0.275391,0.275391
0.59375,0.21875,0.345554,0.345554
0.65625,0.21875,0.275391,0.275391
0.65625,0.21875,0.345554,0.345554
0.71875,0.21875,0.275391,0.275391
0.71875,0.21875,0.345554,0.345554
0.78125,0.21875,0.275391,0.275391
0.78125,0.21875,0.345554,0.345554
0.84375,0.21875,0.275391,0.275391
0.84375,0.21875,0.345554,0.345554
0.90625,0.21875,0.275391,0.275391
0.90625,0.21875,0.345554,0.345554
0.96875,0.21875,0.275391,0.275391
0.96875,0.21875,0.345554,0.345554
0.03125,0.28125,0.275391,0.275391
0.03125,0.28125,0.345554,0.345554
0.09375,0.28125,0.275391,0.275391
0.09375,0.28125,0.345554,0.345554
0.15625,0.28125,0.275391,0.275391
0.15625,0.28125,0.345554,0.345554
0.21875,0.28125,0.275391,0.275391
0.21875,0.28125,0.345554,0.345554
0.28125,0.28125,0.275391,0.275391
0.28125,0.28125,0.345554,0.345554
0.34375,0.28125,0.275391,0.275391
0.34375,0.28125,0.345554,0.345554
0.40625,0.28125,0.275391,0.275391
0.40625,0.28125,0.345554,0.345554
0.46875,0.28125,0.275391,0.275391
0.46875,0.28125,0.345554,0.345554
0.53125,0.28125,0.275391,0.275391
0.53125,0.28125,0.345554,0.345554
0.59375,0.28125,0.275391,0.275391
0.59375,0.28125,0.345554,0.345554
0.65625,0.28125,0.275391,0.275391
0.65625,0.28125,0.345554,0.345554
0.71875,0.28125,0.275391,0.275391
0.71875,0.28125,0.345554,0.345554
0.78125,0.28125,0.275391,0.275391
0.78125,0.28125,0.345554,0.345554
0.84375,0.28125,0.275391,0.275391
0.84375,0.28125,0.345554,0.345554
0.90625,0.28125,0.275391,0.275391
0.90625,0.28125,0.345554,0.345554
0.96875,0.28125,0.275391,0.275391
0.96875,0.28125,0.345554,0.345554
0.03125,0.34375,0.275391,0.275391
0.03125,0.34375,0.345554,0.345554
0.09375,0.34375,0.275391,0.275391
0.09375,0.34375,0.345554,0.345554
0.15625,0.34375,0.275391,0.275391
0.15625,0.34375,0.345554,0.345554
0.21875,0.34375,0.275391,0.275391
0.21875,0.34375,0.345554,0.345554
0.28125,0.34375,0.275391,0.275391
0.28125,0.34375,0.345554,0.345554
0.34375,0.34375,0.275391,0.275391
0.34375,0.34375,0.345554,0.345554
0.40625,0.34375,0.275391,0.275391
0.40625,0.34375,0.345554,0.345554
0.46875,0.34375,0.275391,0.275391
0.46875,0.34375,0.345554,0.345554
0.53125,0.34375,0.275391,0.275391
0.53125,0.34375,0.345554,0.345554
0.59375,0.34375,0.275391,0.275391
0.59375,0.34375,0.345554,0.345554
0.65625,0.34375,0.275391,0.275391
0.65625,0.34375,0.345554,0.345554
0.71875,0.34375,0.275391,0.275391
0.71875,0.34375,0.345554,0.345554
0.78125,0.34375,0.275391,0.275391
0.78125,0.34375,0.345554,0.345554
0.84375,0.34375,0.275391,0.275391
0.84375,0.34375,0.345554,0.345554
0.90625,0.34375,0.275391,0.275391
0.90625,0.34375,0.345554,0.345554
0.96875,0.34375,0.275391,0.275391
0.96875,0.34375,0.345554,0.345554
0.03125,0.40625,0.275391,0.275391
0.03125,0.40625,0.345554,0.345554
0.09375,0.40625,0.275391,0.275391
0.09375,0.40625,0.345554,0.345554
0.15625,0.40625,0.275391,0.275391
0.15625,0.40625,0.345554,0.345554
0.21875,0.40625,0.275391,0.275391
0.21875,0.40625,0.345554,0.345554
0.28125,0.40625,0.275391,0.275391
0.28125,0.40625,0.345554,0.345554
0.34375,0.40625,0.275391,0.275391
0.34375,0.40625,0.345554,0.345554
0.40625,0.40625,0.275391,0.275391
0.40625,0.40625,0.345554,0.345554
0.46875,0.40625,0.275391,0.275391
0.46875,0.40625,0.345554,0.345554
0.53125,0.40625,0.275391,0.275391
0.53125,0.40625,0.345554,0.345554
0.59375,0.40625,0.275391,0.275391
0.59375,0.40625,0.345554,0.345554
0.65625,0.40625,0.275391,0.275391
0.65625,0.40625,0.345554,0.345554
0.71875,0.40625,0.275391,0.275391
0.71875,0.40625,0.345554,0.345554
0.78125,0.40625,0.275391,0.275391
0.78125,0.40625,0.345554,0.345554
0.84375,0.40625,0.275391,0.275391
0.84375,0.40625,0.345554,0.345554
0.90625,0.40625,0.275391,0.275391
0.90625,0.40625,0.345554,0.345554
0.96875,0.40625,0.275391,0.275391
0.96875,0.40625,0.345554,0.345554
0.03125,0.46875,0.275391,0.275391
0.03125,0.46875,0.345554,0.345554
0.09375,0.46875,0.275391,0.275391
0.09375,0.46875,0.345554,0.345554
0.15625,0.46875,0.275391,0.275391
0.15625,0.46875,0.345554,0.345554
0.21875,0.46875,0.275391,0.275391
0.21875,0.46875,0.345554,0.345554
0.28125,0.46875,0.275391,0.275391
0.28125,0.46875,0.345554,0.345554
0.34375,0.46875,0.275391,0.275391
0.34375,0.46875,0.345554,0.345554
0.40625,0.46875,0.275391,0.275391
0.40625,0.46875,0.345554,0.345554
0.46875,0.46875,0.275391,0.275391
0.46875,0.46875,0.345554,0.345554
0.53125,0.46875,0.275391,0.275391
0.53125,0.46875,0.345554,0.345554
0.59375,0.46875,0.275391,0.275391
0.59375,0.46875,0.345554,0.345554
0.65625,0.46875,0.275391,0.275391
0.65625,0.46875,0.345554,0.345554
0.71875,0.46875,0.275391,0.275391
0.71875,0.46875,0.345554,0.345554
0.78125,0.46875,0.275391,0.275391
0.78125,0.46875,0.345554,0.345554
0.84375,0.46875,0.275391,0.275391
0.84375,0.46875,0.345554,0.345554
0.90625,0.46875,0.275391,0.275391
0.90625,0.46875,0.345554,0.345554
0.96875,0.46875,0.275391,0.275391
0.96875,0.46875,0.345554,0.345554
0.03125,0.53125,0.275391,0.275391
0.03125,0.53125,0.345554,0.345554
0.09375,0.53125,0.275391,0.275391
0.09375,0.53125,0.345554,0.345554
0.15625,0.53125,0.275391,0.275391
0.15625,0.53125,0.345554,0.345554
0.21875,0.53125,0.275391,0.275391
0.21875,0.53125,0.345554,0.345554
0.28125,0.53125,0.275391,0.275391
0.28125,0.53125,0.345554,0.345554
0.34375,0.53125,0.275391,0.275391
0.34375,0.53125,0.345554,0.345554
0.40625,0.53125,0.275391,0.275391
0.40625,0.53125,0.345554,0.345554
0.46875,0.53125,0.275391,0.275391
0.46875,0.53125,0.345554,0.345554
0.53125,0.53125,0.275391,0.275391
0.53125,0.53125,0.345554,0.345554
0.59375,0.53125,0.275391,0.275391
0.59375,0.53125,0.345554,0.345554
0.65625,0.53125,0.275391,0.275391
0.65625,0.53125,0.345554,0.345554
0.71875,0.53125,0.275391,0.275391
0.71875,0.53125,0.345554,0.345554
0.78125,0.53125,0.275391,0.275391
0.78125,0.53125,0.345554,0.345554
0.84375,0.53125,0.275391,0.275391
0.84375,0.53125,0.345554,0.345554
0.90625,0.53125,0.275391,0.275391
0.90625,0.53125,0.345554,0.345554
0.96875,0.53125,0.275391,0.275391
0.96875,0.53125,0.345554,0.345554
0.03125,0.59375,0.275391,0.275391
0.03125,0.59375,0.345554,0.345554
0.09375,0.59375,0.275391,0.275391
0.09375,0.59375,0.345554,0.345554
0.15625,0.59375,0.275391,0.275391
0.15625,0.59375,0.345554,0.345554
0.21875,0.59375,0.275391,0.275391
0.21875,0.59375,0.345554,0.345554
0.28125,0.59375,0.275391,0.275391
0.28125,0.59375,0.345554,0.345554
0.34375,0.59375,0.275391,0.275391
0.34375,0.59375,0.345554,0.345554
0.40625,0.59375,0.275391,0.275391
0.40625,0.59375,0.345554,0.345554
0.46875,0.59375,0.275391,0.275391
0.46875,0.59375,0.345554,0.345554
0.53125,0.59375,0.275391,0.275391
0.53125,0.59375,0.345554,0.345554
0.59375,0.59375,0.275391,0.275391
0.59375,0.59375,0.345554,0.345554
0.65625,0.59375,0.275391,0.275391
0.65625,0.59375,0.345554,0.345554
0.71875,0.59375,0.275391,0.275391
0.71875,0.59375,0.345554,0.345554
0.78125,0.59375,0.275391,0.275391
0.78125,0.59375,0.345554,0.345554
0.84375,0.59375,0.275391,0.275391
0.84375,0.59375,0.345554,0.345554
0.90625,0.59375,0.275391,0.275391
0.90625,0.59375,0.345554,0.345554
0.96875,0.59375,0.275391,0.275391
0.96875,0.59375,0.345554,0.345554
0.03125,0.65625,0.275391,0.275391
0.03125,0.65625,0.345554,0.345554
0.09375,0.65625,0.275391,0.275391
0.09375,0.65625,0.345554,0.345554
0.15625,0.65625,0.275391,0.275391
0.15625,0.65625,0.345554,0.345554
0.21875,0.65625,0.275391,0.275391
0.21875,0.65625,0.345554,0.345554
0.28125,0.65625,0.275391,0.275391
0.28125,0.65625,0.345554,0.345554
0.34375,0.65625,0.275391,0.275391
0.34375,0.65625,0.345554,0.345554
0.40625,0.65625,0.275391,0.275391
0.40625,0.65625,0.345554,0.345554
0.46875,0.65625,0.275391,0.275391
0.46875,0.65625,0.345554,0.345554
0.53125,0.65625,0.275391,0.275391
0.53125,0.65625,0.345554,0.345554
0.59375,0.65625,0.275391,0.275391
0.59375,0.65625,0.345554,0.345554
0.65625,0.65625,0.275391,0.275391
0.65625,0.65625,0.345554,0.345554
0.71875,0.65625,0.275391,0.275391
0.71875,0.65625,0.345554,0.345554
0.78125,0.65625,0.275391,0.275391
0.78125,0.65625,0.345554,0.345554
0.84375,0.65625,0.275391,0.275391
0.84375,0.65625,0.345554,0.345554
0.90625,0.65625,0.275391,0.275391
0.90625,0.65625,0.345554,0.345554
0.96875,0.65625,0.275391,0.275391
0.96875,0.65625,0.345554,0.345554
0.03125,0.71875,0.275391,0.275391
0.03125,0.71875,0.345554,0.345554
0.09375,0.71875,0.275391,0.275391
0.09375,0.71875,0.345554,0.345554
0.15625,0.71875,0.275391,0.275391
0.15625,0.71875,0.345554,0.345554
0.21875,0.71875,0.275391,0.275391
0.21875,0.71875,0.345554,0.345554
0.28125,0.71875,0.275391,0.275391
0.28125,0.71875,0.345554,0.345554
0.34375,0.71875,0.275391,0.275391
0.34375,0.71875,0.345554,0.345554
0.40625,0.71875,0.275391,0.275391
0.40625,0.71875,0.345554,0.345554
0.46875,0.71875,0.275391,0.275391
0.46875,0.71875,0.345554,0.345554
0.53125,0.71875,0.275391,0.275391
0.53125,0.71875,0.345554,0.345554
0.59375,0.71875,0.275391,0.275391
0.59375,0.71875,0.345554,0.345554
0.65625,0.71875,0.275391,0.275391
0.65625,0.71875,0.345554,0.345554
0.71875,0.71875,0.275391,0.275391
0.71875,0.71875,0.345554,0.345554
0.78125,0.71875,0.275391,0.275391
0.78125,0.71875,0.345554,0.345554
0.84375,0.71875,0.275391,0.275391
0.84375,0.71875,0.345554,0.345554
0.90625,0.71875,0.275391,0.275391
0.90625,0.71875,0.345554,0.345554
0.96875,0.71875,0.275391,0.275391
0.96875,0.71875,0.345554,0.345554
0.03125,0.78125,0.275391,0.275391
0.03125,0.78125,0.345554,0.345554
0.09375,0.78125,0.275391,0.275391
0.09375,0.78125,0.345554,0.345554
0.15625,0.78125,0.275391,0.275391
0.15625,0.78125,0.345554,0.345554
0.21875,0.78125,0.275391,0.275391
0.21875,0.78125,0.345554,0.345554
0.28125,0.78125,0.275391,0.275391
0.28125,0.78125,0.345554,0.345554
0.34375,0.78125,0.275391,0.275391
0.34375,0.78125,0.345554,0.345554
0.40625,0.78125,0.275391,0.275391
0.40625,0.78125,0.345554,0.345554
0.46875,0.78125,0.275391,0.275391
0.46875,0.78125,0.345554,0.345554
0.53125,0.78125,0.275391,0.275391
0.53125,0.78125,0.345554,0.345554
0.59375,0.78125,0.275391,0.275391
0.59375,0.78125,0.345554,0.345554
0.65625,0.78125,0.275391,0.275391
0.65625,0.78125,0.345554,0.345554
0.71875,0.78125,0.275391,0.275391
0.71875,0.78125,0.345554,0.345554
0.78125,0.78125,0.275391,0.275391
0.78125,0.78125,0.345554,0.345554
0.84375,0.78125,0.275391,0.275391
0.84375,0.78125,0.345554,0.345554
0.90625,0.78125,0.275391,0.275391
0.90625,0.78125,0.345554,0.345554
0.96875,0.78125,0.275391,0.275391
0.96875,0.78125,0.345554,0.345554
0.03125,0.84375,0.275391,0.275391
0.03125,0.84375,0.345554,0.345554
0.09375,0.84375,0.275391,0.275391
0.09375,0.84375,0.345554,0.345554
0.15625,0.84375,0.275391,0.275391
0.15625,0.84375,0.345554,0.345554
0.21875,0.84375,0.275391,0.275391
0.21875,0.84375,0.345554,0.345554
0.28125,0.84375,0.275391,0.275391
0.28125,0.84375,0.345554,0.345554
0.34375,0.84375,0.275391,0.275391
0.34375,0.84375,0.345554,0.345554
0.40625,0.84375,0.275391,0.275391
0.40625,0.84375,0.345554,0.345554
0.46875,0.84375,0.275391,0.275391
0.46875,0.84375,0.345554,0.345554
0.53125,0.84375,0.275391,0.275391
0.53125,0.84375,0.345554,0.345554
0.59375,0.84375,0.275391,0.275391
0.59375,0.84375,0.345554,0.345554
0.65625,0.84375,0.275391,0.275391
0.65625,0.84375,0.345554,0.345554
0.71875,0.84375,0.275391,0.275391
0.71875,0.84375,0.345554,0.345554
0.78125,0.84375,0.275391,0.275391
0.78125,0.84375,0.345554,0.345554
0.84375,0.84375,0.275391,0.275391
0.84375,0.84375,0.345554,0.345554
0.90625,0.84375,0.275391,0.275391
0.90625,0.84375,0.345554,0.345554
0.96875,0.84375,0.275391,0.275391
0.96875,0.84375,0.345554,0.345554
0.03125,0.90625,0.275391,0.275391
0.03125,0.90625,0.345554,0.345554
0.09375,0.90625,0.275391,0.275391
0.09375,0.90625,0.345554,0.345554
0.15625,0.90625,0.275391,0.275391
0.15625,0.90625,0.345554,0.345554
0.21875,0.90625,0.275391,0.275391
0.21875,0.90625,0.345554,0.345554
0.28125,0.90625,0.275391,0.275391
0.28125,0.90625,0.345554,0.345554
0.34375,0.90625,0.275391,0.275391
0.34375,0.90625,0.345554,0.345554
0.40625,0.90625,0.275391,0.275391
0.40625,0.90625,0.345554,0.345554
0.46875,0.90625,0.275391,0.275391
0.46875,0.90625,0.345554,0.345554
0.53125,0.90625,0.275391,0.275391
0.53125,0.90625,0.345554,0.345554
0.59375,0.90625,0.275391,0.275391
0.59375,0.90625,0.345554,0.345554
0.65625,0.90625,0.275391,0.275391
0.65625,0.90625,0.345554,0.345554
0.71875,0.90625,0.275391,0.275391
0.71875,0.90625,0.345554,0.345554
0.78125,0.90625,0.275391,0.275391
0.78125,0.90625,0.345554,0.345554
0.84375,0.90625,0.275391,0.275391
0.84375,0.90625,0.345554,0.345554
0.90625,0.90625,0.275391,0.275391
0.90625,0.90625,0.345554,0.345554
0.96875,0.90625,0.275391,0.275391
0.96875,0.90625,0.345554,0.345554
0.03125,0.96875,0.275391,0.275391
0.03125,0.96875,0.345554,0.345554
0.09375,0.96875,0.275391,0.275391
0.09375,0.96875,0.345554,0.345554
0.15625,0.96875,0.275391,0.275391
0.15625,0.96875,0.345554,0.345554
0.21875,0.96875,0.275391,0.275391
0.21875,0.96875,0.345554,0.345554
0.28125,0.96875,0.275391,0.275391
0.28125,0.96875,0.345554,0.345554
0.34375,0.96875,0.275391,0.275391
0.34375,0.96875,0.345554,0.345554
0.40625,0.96875,0.275391,0.275391
0.40625,0.96875,0.345554,0.345554
0.46875,0.96875,0.275391,0.275391
0.46875,0.96875,0.345554,0.345554
0.53125,0.96875,0.275391,0.275391
0.53125,0.96875,0.345554,0.345554
0.59375,0.96875,0.275391,0.275391
0.59375,0.96875,0.345554,0.345554
0.65625,0.96875,0.275391,0.275391
0.65625,0.96875,0.345554,0.345554
0.71875,0.96875,0.275391,0.275391
0.71875,0.96875,0.345554,0.345554
0.78125,0.96875,0.275391,0.275391
0.78125,0.96875,0.345554,0.345554
0.84375,0.96875,0.275391,0.275391
0.84375,0.96875,0.345554,0.345554
0.90625,0.96875,0.275391,0.275391
0.90625,0.96875,0.345554,0.345554
0.96875,0.96875,0.275391,0.275391
0.96875,0.96875,0.345554,0.345554
0.0625,0.0625,0.433594,0.433594
0.0625,0.0625,0.506556,0.506556
0.0625,0.0625,0.591797,0.591797
0.0625,0.0625,0.666219,0.666219
0.0625,0.0625,0.75,0.75
0.0625,0.0625,0.866025,0.866025
0.1875,0.0625,0.433594,0.433594
0.1875,0.0625,0.506556,0.506556
0.1875,0.0625,0.591797,0.591797
0.1875,0.0625,0.666219,0.666219
0.1875,0.0625,0.75,0.75
0.1875,0.0625,0.866025,0.866025
0.3125,0.0625,0.433594,0.433594
0.3125,0.0625,0.506556,0.506556
0.3125,0.0625,0.591797,0.591797
0.3125,0.0625,0.666219,0.666219
0.3125,0.0625,0.75,0.75
0.3125,0.0625,0.866025,0.866025
0.4375,0.0625,0.433594,0.433594
0.4375,0.0625,0.506556,0.506556
0.4375,0.0625,0.591797,0.591797
0.4375,0.0625,0.666219,0.666219
0.4375,0.0625,0.75,0.75
0.4375,0.0625,0.866025,0.866025
0.5625,0.0625,0.433594,0.433594
0.5625,0.0625,0.506556,0.506556
0.5625,0.0625,0.591797,0.591797
0.5625,0.0625,0.666219,0.666219
0.5625,0.0625,0.75,0.75
0.5625,0.0625,0.866025,0.866025
0.6875,0.0625,0.433594,0.433594
0.6875,0.0625,0.506556,0.506556
0.6875,0.0625,0.591797,0.591797
0.6875,0.0625,0.666219,0.666219
0.6875,0.0625,0.75,0.75
0.6875,0.0625,0.866025,0.866025
0.8125,0.0625,0.433594,0.433594
0.8125,0.0625,0.506556,0.506556
0.8125,0.0625,0.591797,0.591797
0.8125,0.0625,0.666219,0.666219
0.8125,0.0625,0.75,0.75
0.8125,0.0625,0.866025,0.866025
0.9375,0.0625,0.433594,0.433594
0.9375,0.0625,0.506556,0.506556
0.9375,0.0625,0.591797,0.591797
0.9375,0.0625,0.666219,0.666219
0.9375,0.0625,0.75,0.75
0.9375,0.0625,0.866025,0.866025
0.0625,0.1875,0.433594,0.433594
0.0625,0.1875,0.506556,0.506556
0.0625,0.1875,0.591797,0.591797
0.0625,0.1875,0.666219,0.666219
0.0625,0.1875,0.75,0.75
0.0625,0.1875,0.866025,0.866025
0.1875,0.1875,0.433594,0.433594
0.1875,0.1875,0.506556,0.506556
0.1875,0.1875,0.591797,0.591797
0.1875,0.1875,0.666219,0.666219
0.1875,0.1875,0.75,0.75
0.1875,0.1875,0.866025,0.866025
0.3125,0.1875,0.433594,0.433594
0.3125,0.1875,0.506556,0.506556
0.3125,0.1875,0.591797,0.591797
0.3125,0.1875,0.666219,0.666219
0.3125,0.1875,0.75,0.75
0.3125,0.1875,0.866025,0.866025
0.4375,0.1875,0.433594,0.433594
0.4375,0.1875,0.506556,0.506556
0.4375,0.1875,0.591797,0.591797
0.4375,0.1875,0.666219,0.666219
0.4375,0.1875,0.75,0.75
0.4375,0.1875,0.866025,0.866025
0.5625,0.1875,0.433594,0.433594
0.5625,0.1875,0.506556,0.506556
0.5625,0.1875,0.591797,0.591797
0.5625,0.1875,0.666219,0.666219
0.5625,0.1875,0.75,0.75
0.5625,0.1875,0.866025,0.866025
0.6875,0.1875,0.433594,0.433594
0.6875,0.1875,0.506556,0.506556
0.6875,0.1875,0.591797,0.591797
0.6875,0.1875,0.666219,0.666219
0.6875,0.1875,0.75,0.75
0.6875,0.1875,0.866025,0.866025
0.8125,0.1875,0.433594,0.433594
0.8125,0.1875,0.506556,0.506556
0.8125,0.1875,0.591797,0.591797
0.8125,0.1875,0.666219,0.666219
0.8125,0.1875,0.75,0.75
0.8125,0.1875,0.866025,0.866025
0.9375,0.1875,0.433594,0.433594
0.9375,0.1875,0.506556,0.506556
0.9375,0.1875,0.591797,0.591797
0.9375,0.1875,0.666219,0.666219
0.9375,0.1875,0.75,0.75
0.9375,0.1875,0.866025,0.866025
0.0625,0.3125,0.433594,0.433594
0.0625,0.3125,0.506556,0.506556
0.0625,0.3125,0.591797,0.591797
0.0625,0.3125,0.666219,0.666219
0.0625,0.3125,0.75,0.75
0.0625,0.3125,0.866025,0.866025
0.1875,0.3125,0.433594,0.433594
0.1875,0.3125,0.506556,0.506556
0.1875,0.3125,0.591797,0.591797
0.1875,0.3125,0.666219,0.666219
0.1875,0.3125,0.75,0.75
0.1875,0.3125,0.866025,0.866025
0.3125,0.3125,0.433594,0.433594
0.3125,0.3125,0.506556,0.506556
0.3125,0.3125,0.591797,0.591797
0.3125,0.3125,0.666219,0.666219
0.3125,0.3125,0.75,0.75
0.3125,0.3125,0.866025,0.866025
0.4375,0.3125,0.433594,0.433594
0.4375,0.3125,0.506556,0.506556
0.4375,0.3125,0.591797,0.591797
0.4375,0.3125,0.666219,0.666219
0.4375,0.3125,0.75,0.75
0.4375,0.3125,0.866025,0.866025
0.5625,0.3125,0.433594,0.433594
0.5625,0.3125,0.506556,0.506556
0.5625,0.3125,0.591797,0.591797
0.5625,0.3125,0.666219,0.666219
0.5625,0.3125,0.75,0.75
0.5625,0.3125,0.866025,0.866025
0.6875,0.3125,0.433594,0.433594
0.6875,0.3125,0.506556,0.506556
0.6875,0.3125,0.591797,0.591797
0.6875,0.3125,0.666219,0.666219
0.6875,0.3125,0.75,0.75
0.6875,0.3125,0.866025,0.866025
0.8125,0.3125,0.433594,0.433594
0.8125,0.3125,0.506556,0.506556
0.8125,0.3125,0.591797,0.591797
0.8125,0.3125,0.666219,0.666219
0.8125,0.3125,0.75,0.75
0.8125,0.3125,0.866025,0.866025
0.9375,0.3125,0.433594,0.433594
0.9375,0.3125,0.506556,0.506556
0.9375,0.3125,0.591797,0.591797
0.9375,0.3125,0.666219,0.666219
0.9375,0.3125,0.75,0.75
0.9375,0.3125,0.866025,0.866025
0.0625,0.4375,0.433594,0.433594
0.0625,0.4375,0.506556,0.506556
0.0625,0.4375,0.591797,0.591797
0.0625,0.4375,0.666219,0.666219
0.0625,0.4375,0.75,0.75
0.0625,0.4375,0.866025,0.866025
0.1875,0.4375,0.433594,0.433594
0.1875,0.4375,0.506556,0.506556
0.1875,0.4375,0.591797,0.591797
0.1875,0.4375,0.666219,0.666219
0.1875,0.4375,0.75,0.75
0.1875,0.4375,0.866025,0.866025
0.3125,0.4375,0.433594,0.433594
0.3125,0.4375,0.506556,0.506556
0.3125,0.4375,0.591797,0.591797
0.3125,0.4375,0.666219,0.666219
0.3125,0.4375,0.75,0.75
0.3125,0.4375,0.866025,0.866025
0.4375,0.4375,0.433594,0.433594
0.4375,0.4375,0.506556,0.506556
0.4375,0.4375,0.591797,0.591797
0.4375,0.4375,0.666219,0.666219
0.4375,0.4375,0.75,0.75
0.4375,0.4375,0.866025,0.866025
0.5625,0.4375,0.433594,0.433594
0.5625,0.4375,0.506556,0.506556
0.5625,0.4375,0.591797,0.591797
0.5625,0.4375,0.666219,0.666219
0.5625,0.4375,0.75,0.75
0.5625,0.4375,0.866025,0.866025
0.6875,0.4375,0.433594,0.433594
0.6875,0.4375,0.506556,0.506556
0.6875,0.4375,0.591797,0.591797
0.6875,0.4375,0.666219,0.666219
0.6875,0.4375,0.75,0.75
0.6875,0.4375,0.866025,0.866025
0.8125,0.4375,0.433594,0.433594
0.8125,0.4375,0.506556,0.506556
0.8125,0.4375,0.591797,0.591797
0.8125,0.4375,0.666219,0.666219
0.8125,0.4375,0.75,0.75
0.8125,0.4375,0.866025,0.866025
0.9375,0.4375,0.433594,0.433594
0.9375,0.4375,0.506556,0.506556
0.9375,0.4375,0.591797,0.591797
0.9375,0.4375,0.666219,0.666219
0.9375,0.4375,0.75,0.75
0.9375,0.4375,0.866025,0.866025
0.0625,0.5625,0.433594,0.433594
0.0625,0.5625,0.506556,0.506556
0.0625,0.5625,0.591797,0.591797
0.0625,0.5625,0.666219,0.666219
0.0625,0.5625,0.75,0.75
0.0625,0.5625,0.866025,0.866025
0.1875,0.5625,0.433594,0.433594
0.1875,0.5625,0.506556,0.506556
0.1875,0.5625,0.591797,0.591797
0.1875,0.5625,0.666219,0.666219
0.1875,0.5625,0.75,0.75
0.1875,0.5625,0.866025,0.866025
0.3125,0.5625,0.433594,0.433594
0.3125,0.5625,0.506556,0.506556
0.3125,0.5625,0.591797,0.591797
0.3125,0.5625,0.666219,0.666219
0.3125,0.5625,0.75,0.75
0.3125,0.5625,0.866025,0.866025
0.4375,0.5625,0.433594,0.433594
0.4375,0.5625,0.506556,0.506556
0.4375,0.5625,0.591797,0.591797
0.4375,0.5625,0.666219,0.666219
0.4375,0.5625,0.75,0.75
0.4375,0.5625,0.866025,0.866025
0.5625,0.5625,0.433594,0.433594
0.5625,0.5625,0.506556,0.506556
0.5625,0.5625,0.591797,0.591797
0.5625,0.5625,0.666219,0.666219
0.5625,0.5625,0.75,0.75
0.5625,0.5625,0.866025,0.866025
0.6875,0.5625,0.433594,0.433594
0.6875,0.5625,0.506556,0.506556
0.6875,0.5625,0.591797,0.591797
0.6875,0.5625,0.666219,0.666219
0.6875,0.5625,0.75,0.75
0.6875,0.5625,0.866025,0.866025
0.8125,0.5625,0.433594,0.433594
0.8125,0.5625,0.506556,0.506556
0.8125,0.5625,0.591797,0.591797
0.8125,0.5625,0.666219,0.666219
0.8125,0.5625,0.75,0.75
0.8125,0.5625,0.866025,0.866025
0.9375,0.5625,0.433594,0.433594
0.9375,0.5625,0.506556,0.506556
0.9375,0.5625,0.591797,0.591797
0.9375,0.5625,0.666219,0.666219
0.9375,0.5625,0.75,0.75
0.9375,0.5625,0.866025,0.866025
0.0625,0.6875,0.433594,0.433594
0.0625,0.6875,0.506556,0.506556
0.0625,0.6875,0.591797,0.591797
0.0625,0.6875,0.666219,0.666219
0.0625,0.6875,0.75,0.75
0.0625,0.6875,0.866025,0.866025
0.1875,0.6875,0.433594,0.433594
0.1875,0.6875,0.506556,0.506556
0.1875,0.6875,0.591797,0.591797
0.1875,0.6875,0.666219,0.666219
0.1875,0.6875,0.75,0.75
0.1875,0.6875,0.866025,0.866025
0.3125,0.6875,0.433594,0.433594
0.3125,0.6875,0.506556,0.506556
0.3125,0.6875,0.591797,0.591797
0.3125,0.6875,0.666219,0.666219
0.3125,0.6875,0.75,0.75
0.3125,0.6875,0.866025,0.866025
0.4375,0.6875,0.433594,0.433594
0.4375,0.6875,0.506556,0.506556
0.4375,0.6875,0.591797,0.591797
0.4375,0.6875,0.666219,0.666219
0.4375,0.6875,0.75,0.75
0.4375,0.6875,0.866025,0.866025
0.5625,0.6875,0.433594,0.433594
0.5625,0.6875,0.506556,0.506556
0.5625,0.6875,0.591797,0.591797
0.5625,0.6875,0.666219,0.666219
0.5625,0.6875,0.75,0.75
0.5625,0.6875,0.866025,0.866025
0.6875,0.6875,0.433594,0.433594
0.6875,0.6875,0.506556,0.506556
0.6875,0.6875,0.591797,0.591797
0.6875,0.6875,0.666219,0.666219
0.6875,0.6875,0.75,0.75
0.6875,0.6875,0.866025,0.866025
0.8125,0.6875,0.433594,0.433594
0.8125,0.6875,0.506556,0.506556
0.8125,0.6875,0.591797,0.591797
0.8125,0.6875,0.666219,0.666219
0.8125,0.6875,0.75,0.75
0.8125,0.6875,0.866025,0.866025
0.9375,0.6875,0.433594,0.433594
0.9375,0.6875,0.506556,0.506556
0.9375,0.6875,0.591797,0.591797
0.9375,0.6875,0.666219,0.666219
0.9375,0.6875,0.75,0.75
0.9375,0.6875,0.866025,0.866025
0.0625,0.8125,0.433594,0.433594
0.0625,0.8125,0.506556,0.506556
0.0625,0.8125,0.591797,0.591797
0.0625,0.8125,0.666219,0.666219
0.0625,0.8125,0.75,0.75
0.0625,0.8125,0.866025,0.866025
0.1875,0.8125,0.433594,0.433594
0.1875,0.8125,0.506556,0.506556
0.1875,0.8125,0.591797,0.591797
0.1875,0.8125,0.666219,0.666219
0.1875,0.8125,0.75,0.75
0.1875,0.8125,0.866025,0.866025
0.3125,0.8125,0.433594,0.433594
0.3125,0.8125,0.506556,0.506556
0.3125,0.8125,0.591797,0.591797
0.3125,0.8125,0.666219,0.666219
0.3125,0.8125,0.75,0.75
0.3125,0.8125,0.866025,0.866025
0.4375,0.8125,0.433594,0.433594
0.4375,0.8125,0.506556,0.506556
0.4375,0.8125,0.591797,0.591797
0.4375,0.8125,0.666219,0.666219
0.4375,0.8125,0.75,0.75
0.4375,0.8125,0.866025,0.866025
0.5625,0.8125,0.433594,0.433594
0.5625,0.8125,0.506556,0.506556
0.5625,0.8125,0.591797,0.591797
0.5625,0.8125,0.666219,0.666219
0.5625,0.8125,0.75,0.75
0.5625,0.8125,0.866025,0.866025
0.6875,0.8125,0.433594,0.433594
0.6875,0.8125,0.506556,0.506556
0.6875,0.8125,0.591797,0.591797
0.6875,0.8125,0.666219,0.666219
0.6875,0.8125,0.75,0.75
0.6875,0.8125,0.866025,0.866025
0.8125,0.8125,0.433594,0.433594
0.8125,0.8125,0.506556,0.506556
0.8125,0.8125,0.591797,0.591797
0.8125,0.8125,0.666219,0.666219
0.8125,0.8125,0.75,0.75
0.8125,0.8125,0.866025,0.866025
0.9375,0.8125,0.433594,0.433594
0.9375,0.8125,0.506556,0.506556
0.9375,0.8125,0.591797,0.591797
0.9375,0.8125,0.666219,0.666219
0.9375,0.8125,0.75,0.75
0.9375,0.8125,0.866025,0.866025
0.0625,0.9375,0.433594,0.433594
0.0625,0.9375,0.506556,0.506556
0.0625,0.9375,0.591797,0.591797
0.0625,0.9375,0.666219,0.666219
0.0625,0.9375,0.75,0.75
0.0625,0.9375,0.866025,0.866025
0.1875,0.9375,0.433594,0.433594
0.1875,0.9375,0.506556,0.506556
0.1875,0.9375,0.591797,0.591797
0.1875,0.9375,0.666219,0.666219
0.1875,0.9375,0.75,0.75
0.1875,0.9375,0.866025,0.866025
0.3125,0.9375,0.433594,0.433594
0.3125,0.9375,0.506556,0.506556
0.3125,0.9375,0.591797,0.591797
0.3125,0.9375,0.666219,0.666219
0.3125,0.9375,0.75,0.75
0.3125,0.9375,0.866025,0.866025
0.4375,0.9375,0.433594,0.433594
0.4375,0.9375,0.506556,0.506556
0.4375,0.9375,0.591797,0.591797
0.4375,0.9375,0.666219,0.666219
0.4375,0.9375,0.75,0.75
0.4375,0.9375,0.866025,0.866025
0.5625,0.9375,0.433594,0.433594
0.5625,0.9375,0.506556,0.506556
0.5625,0.9375,0.591797,0.591797
0.5625,0.9375,0.666219,0.666219
0.5625,0.9375,0.75,0.75
0.5625,0.9375,0.866025,0.866025
0.6875,0.9375,0.433594,0.433594
0.6875,0.9375,0.506556,0.506556
0.6875,0.9375,0.591797,0.591797
0.6875,0.9375,0.666219,0.666219
0.6875,0.9375,0.75,0.75
0.6875,0.9375,0.866025,0.866025
0.8125,0.9375,0.433594,0.433594
0.8125,0.9375,0.506556,0.506556
0.8125,0.9375,0.591797,0.591797
0.8125,0.9375,0.666219,0.666219
0.8125,0.9375,0.75,0.75
0.8125,0.9375,0.866025,0.866025
0.9375,0.9375,0.433594,0.433594
0.9375,0.9375,0.506556,0.506556
0.9375,0.9375,0.591797,0.591797
0.9375,0.9375,0.666219,0.666219
0.9375,0.9375,0.75,0.75
0.9375,0.9375,0.866025,0.866025
// import 'babel-polyfill';
// import Paddlejs from '../../src/executor/runner';
import {runner as Paddlejs} from 'paddlejs';
import Camera from '../../src/executor/camera';
import DetectProcess from './DetectProcess';
import LMProcess from './LMProcess';
import WarpAffine from './warpAffine';
let image = '';
let camera = null;
let anchorResults = null;
const TYPE = 'video';
let rect = null;
let paddlejs = null;
let paddlejs2 = null;
const rectDom = document.getElementById('rect');
let video = document.getElementById('video');
const videoSelect = document.getElementById('videoSelect');
let upload = document.getElementById("uploadImg");
let loadingDom = document.getElementById("isLoading");
async function init() {
paddlejs = new Paddlejs({
modelPath: 'https://paddlejs.cdn.bcebos.com/models/gesture/gesture_detect',
fileCount: 2,
feedShape: {
fw: 256,
fh: 256
},
fetchShape: [1, 1, 1920, 10],
needBatch: true,
fill: '#fff',
targetSize: { height: 256, width: 256 },
needPostProcess: false
});
const waitPaddle1 = paddlejs.loadModel();
paddlejs2 = new Paddlejs({
modelPath: 'https://paddlejs.cdn.bcebos.com/models/gesture/gesture_rec',
fileCount: 1,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 1, 1, 9],
fill: '#fff',
targetSize: { height: 224, width: 224 },
needBatch: true,
needPostProcess: false
})
const waitPaddle2 = paddlejs2.loadModel();
WarpAffine.init({
width: 224,
height: 224
});
const waitAnchor = fetch(require('./anchor_small.txt')).then(async (res) => {
anchorResults = await res.text();
anchorResults = anchorResults.replace(/\s+/g, ',').split(',').map(item => +item);
});
Promise.all([waitPaddle1, waitPaddle2, waitAnchor]).then(() => {
loadingDom.classList.add('hidden');
})
}
init();
const imageDom = document.getElementById('image');
const content = document.getElementById('txt');
const videoToolDom = document.getElementById('video-tool');
(function main() {
// 采用图片模式
if (TYPE === 'image') {
video.remove();
videoToolDom.remove();
loadingDom.remove();
video = null;
}
// 采用视频模式
else if (TYPE === 'video') {
imageDom.remove();
upload.remove();
upload = null;
}
})()
if (video) {
camera = new Camera({
// 用来显示摄像头图像的dom
videoDom: video,
});
/* 获取摄像头并开始视频流 */
camera.getDevices().then(devices => {
if (devices.length) {
camera.run(devices[0].deviceId);
devices.forEach((element, index) => {
let option = document.createElement('option');
option.value = element.deviceId;
option.text = (index + 1);
videoSelect.appendChild(option);
});
videoSelect.onchange = () => {
camera.run(videoSelect.value);
};
}
else {
camera.run();
}
});
}
/* 循环跑模型 */
let loopFlag = true;
async function loop() {
let input = camera.curVideo;
if (loopFlag) {
// setTimeout(async () => {
await run(input);
// }, 100);
}
}
const startBtn = document.getElementById('start');
const endBtn = document.getElementById('end');
/* 视频开始播放时,开始模型预热 */
video && video.addEventListener('play', async function (e) {
startBtn.disabled = false;
startBtn.innerText = '开始测试';
});
/* 点击开始按钮,开始正式跑模型 */
document.getElementById('tool').addEventListener('click', function(e) {
if (e.target.id === 'start') {
loopFlag = true;
startBtn.disabled = true;
endBtn.disabled = false;
loop();
}
if (e.target.id === 'end') {
loopFlag = false;
endBtn.disabled = true;
startBtn.disabled = false;
}
})
/* 模型执行函数 */
async function run(input) {
rect = video.getBoundingClientRect();
await paddlejs.predict(input, postProcess);
}
function selectImage(file) {
if (!file.files || !file.files[0]) {
return;
}
content.innerText = "识别中。。。";
let reader = new FileReader();
reader.onload = function (evt) {
let img = document.getElementById('image');
img.src = evt.target.result;
img.onload = async function() {
rect = img.getBoundingClientRect();
paddlejs.predict(img, postProcess);
};
image = evt.target.result;
}
reader.readAsDataURL(file.files[0]);
}
// 第一个模型的后处理
async function postProcess(data) {
let post = new DetectProcess(data, paddlejs.io.fromPixels2DContext.canvas);
let box = await post.outputBox(anchorResults);
if (!box) {
console.info('box为空')
rectDom.style.border = 'none';
content.innerText = "识别不到手";
TYPE === 'video' && loop();
return;
}
content.innerText = "...";
calculateBox();
// TYPE === 'video' && loop();
let feed = await post.outputFeed(paddlejs);
// 第一个模型的后处理可以直接拿到feed
paddlejs2.runWithFeed(feed, function (data) {
// 开始第二个模型的后处理
TYPE === 'video' && loop();
let lmProcess = new LMProcess(data);
lmProcess.output();
content.innerText = "您出的是" + lmProcess.type;
});
function calculateBox() {
let offsetX = 0;
let offsetY = 0;
if (rect.width < rect.height) {
offsetX = rect.height - rect.width;
}
if (rect.width > rect.height) {
offsetY = rect.width - rect.height;
}
let height = Math.abs(box[3][1] - box[0][1]);
let width = Math.abs(box[1][0] - box[0][0]);
let widthRatio = (rect.width + offsetX) / 256;
let heightRatio = (rect.height + offsetY) / 256;
let transformStr = `translate(${box[0][0] * widthRatio - offsetX / 2}px,
${box[0][1] * heightRatio - offsetY / 2}px) scale(${widthRatio * width / 100},
${heightRatio * height / 100})
`;
let cssObj = rectDom.style;
cssObj.transform = transformStr;
cssObj.border = "2px solid red";
let rectStyle = {
width: width + 'px',
height: height + 'px',
left: box[0][0] + 'px',
top: box[0][1] + 'px',
}
}
}
if (upload) {
upload.onchange = async function () {
selectImage(this);
};
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>paddle web demo</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style>
body {
margin: 0 auto;
position: fixed;
width: 100%;
height: 100%;
}
#rect {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
transform-origin: 0 0;
/* transition: transform .1s linear; */
}
.wrapper {
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
}
video {
width: 100%;
}
.point {
position: absolute;
width: 5px;
height: 5px;
}
#camera-btn {
display: none;
}
#videoSelect::before {
content: "请选择设备摄像头:";
}
#video-tool {
display: flex;
justify-content: space-around;
}
#isLoading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .5);
}
#isLoading .loading-text {
color: #fff;
font-size: 24px;
}
.center {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.hidden {
display: none;
}
.show {
display: block;
}
.flex {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: -moz-box;
display: -moz-flex;
display: flex;
}
.flex-space-around {
-webkit-box-pack: justify;
-moz-box-pack: justify;
-ms-box-pack: justify;
-webkit-justify-content: space-around;
-moz-justify-content: space-around;
justify-content: space-around;
}
</style>
</head>
<body>
<div class="wrapper center">
<img id="image" src="https://m.baidu.com/se/static/img/iphone/logo.png" width="256">
<video id="video"></video>
<div id="rect"></div>
<div id="tool">
<input type="file" id="uploadImg">
<div id="video-tool" class="flex">
<div>设备摄像头:<select id="videoSelect"></select></div>
<button id="start" type="btn" disabled>模型loading中</button>
<button id="end" type="btn" disabled>停止测试</button>
</div>
</div>
<div id="txt">...</div>
</div>
<div id="isLoading">
<p class="loading-text center">loading中……</p>
</div>
<!-- <div style="position:relative;display:inline-block;;">
<canvas id="canvas-square" style="display:block;border: 1px solid black;"></canvas>
<div id="rect2" style="position:absolute;"></div>
<div id="point1" class="point" style="background:#ff0000;"></div>
<div id="point2" class="point" style="background:#00ff00;"></div>
<div id="point3" class="point" style="background:#0000ff;"></div>
</div> -->
<!-- <canvas id="canvas-warpAffine" style="display:inline-block;"></canvas> -->
<script src="index.es6"></script>
</body>
</html>
\ No newline at end of file
const VSHADER_SOURCE = `attribute vec4 a_Position;
attribute vec2 a_TexCoord;
uniform mat4 translation;
varying vec2 v_TexCoord;
void main() {
gl_Position = translation * a_Position;
v_TexCoord = a_TexCoord;
}`;
const FSHADER_SOURCE = `precision mediump float;
uniform sampler2D u_Sampler;
varying vec2 v_TexCoord;
void main() {
gl_FragColor = texture2D(u_Sampler, v_TexCoord);
}`;
let imgData = null;
let mtrData = null;
let gl = null;
function init(output) {
var canvas = document.createElement('canvas');
canvas.width = output.width;
canvas.height = output.height;
gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
// 初始化之前先加载图片
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
return;
}
}
function main(opt) {
const {
imageData,
mtr,
output,
input
} = opt;
mtrData = mtr;
imgData = imageData;
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const n = initVertexBuffers(gl);
initTextures(gl, n, 0);
let outputData = new Uint8Array(output.width * output.height * 4);
gl.readPixels(0, 0, output.width, output.height, gl.RGBA, gl.UNSIGNED_BYTE, outputData);
return outputData;
}
function initVertexBuffers(gl) {
// 顶点坐标和纹理图像坐标
const vertices = new Float32Array([
// webgl坐标,纹理坐标
-1.0, 1.0, 0.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 0.0, 0.0,
1.0, 1.0, 0.0, 1.0, 1.0,
1.0, -1.0, 0.0, 1.0, 0.0
]);
const FSIZE = vertices.BYTES_PER_ELEMENT;
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const aPosition = gl.getAttribLocation(gl.program, 'a_Position');
const aTexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
var xformMatrix = new Float32Array([
mtrData[0][0], mtrData[1][0], 0.0, 0.0,
mtrData[0][1], mtrData[1][1], 0.0, 0.0,
0.0, 0.0, 0.0, 1.0,
mtrData[0][2], mtrData[1][2], 0.0, 1.0
]);
var translation = gl.getUniformLocation(gl.program, 'translation');
gl.uniformMatrix4fv(translation, false, xformMatrix);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, FSIZE * 5, 0);
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, FSIZE * 5, FSIZE * 3);
gl.enableVertexAttribArray(aTexCoord);
return 4;
}
function initTextures(gl, n, index) {
// 创建纹理对象
const texture = gl.createTexture();
const uSampler = gl.getUniformLocation(gl.program, 'u_Sampler');
// WebGL纹理坐标中的纵轴方向和PNG,JPG等图片容器的Y轴方向是反的,所以先反转Y轴
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
// 激活纹理单元,开启index号纹理单元
gl.activeTexture(gl[`TEXTURE${index}`]);
// 绑定纹理对象
gl.bindTexture(gl.TEXTURE_2D, texture);
// 配置纹理对象的参数
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// 将纹理图像分配给纹理对象
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imgData);
// 将纹理单元编号传给着色器
gl.uniform1i(uSampler, index);
// 绘制
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
return;
}
function initShaders(gl, vshader, fshader) {
var vertexShader = createShader(gl, vshader, gl.VERTEX_SHADER);
var fragmentShader = createShader(gl, fshader, gl.FRAGMENT_SHADER);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
if (!program) {
console.log('无法创建程序对象');
return false;
}
gl.linkProgram(program);
gl.useProgram(program);
gl.program = program;
return true;
}
function createShader(gl, sourceCode, type) {
// Compiles either a shader of type gl.VERTEX_SHADER or gl.FRAGMENT_SHADER
var shader = gl.createShader(type);
gl.shaderSource(shader, sourceCode);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
var info = gl.getShaderInfoLog(shader);
throw 'Could not compile WebGL program. \n\n' + info;
}
return shader;
}
export default {
main,
init
};
.wrapper {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
margin-bottom: 10px;
width: 100%;
}
#video {
width: 45%;
min-width: 310px;
border: 2px solid #aaa;
transform: rotateY(180deg);
}
#myCanvas2 {
width: 45%;
min-width: 310px;
border: 2px solid #aaa;
transform: rotateY(180deg);
}
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
import Utils from '../../src/utils/utils';
import Camera from '../../src/executor/camera';
import Runner from '../../src/executor/runner';
import cv from '../../opencv.js';
function thresholdMask(img, threshBg, threshFg) {
for (let i = 0; i < img.data.length / 4; i++) {
let tmp = (img.data[i * 4 + 3] - threshBg * 255.0) / (threshFg - threshBg);
if (tmp < 0) {
img.data[i * 4 + 3] = 0;
}
else if (tmp > 255) {
img.data[i * 4 + 3] = 255;
}
else {
img.data[i * 4 + 3] = tmp;
}
}
}
if (location.protocol === 'http:') {
location.href = location.href.replace('http://', 'https://');
}
/**
* @file model demo 入口文件
* @author zhuxingyu01@baidu.com
*
*/
// 模型feed数据
const feedShape = {
'humanseg': {
fw: 192,
fh: 192
}
};
// 模型fetch数据
const fetchShape = {
'humanseg': [1, 2, 192, 192]
};
const modelType = 'humanseg';
const {fw, fh} = feedShape[modelType];
const outputShape = fetchShape[modelType];
// 统计参数
let loaded = false;
let model = {};
window.statistic = [];
var video = document.getElementById('video');
const videoSelect = document.getElementById('videoSelect');
let camera = new Camera({
// 用来显示摄像头图像的dom
videoDom: video,
constraints: {
video: {
width: {min: 200, ideal: 480, max: 1080},
height: {min: 300, ideal: 720, max: 1620}
}
}
});
camera.getDevices().then(devices => {
if (devices.length) {
camera.run(devices[0].deviceId);
devices.forEach((element, index) => {
let option = document.createElement('option');
option.value = element.deviceId;
option.text = (index + 1);
videoSelect.appendChild(option);
});
videoSelect.onchange = () => {
camera.run(videoSelect.value);
};
}
else {
camera.run();
}
});
let loopFlag = true;
async function loop() {
let input = camera.curVideo;
if (loopFlag) {
await run(input);
await loop();
}
}
let startBtn = document.getElementById('start');
let endBtn = document.getElementById('end');
video.addEventListener('play', async function (e) {
await run();
startBtn.disabled = false;
startBtn.innerText = '开始测试';
})
// document.addEventListener("DOMContentLoaded", async function () {
// // await run();
// // startBtn.disabled = false;
// });
document.getElementById('tool').addEventListener('click', function(e) {
if (e.target.id === 'start') {
loopFlag = true;
startBtn.disabled = true;
endBtn.disabled = false;
loop();
}
if (e.target.id === 'end') {
loopFlag = false;
endBtn.disabled = true;
startBtn.disabled = false;
}
})
async function run(input) {
let start = Date.now();
const io = new IO();
let feed = input
? io.process({
input: input,
params: {
gapFillWith: '#000', // 缩放后用什么填充不足方形部分
scale: 192, // 缩放尺寸
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
mean: [122.675, 116.669, 104.008],
std: [1.0, 1.0, 1.0],
bgr: true
}
})
: [{
data: new Float32Array(3 * fh * fw),
name: 'image',
shape: [1, 3, fh, fw]
}];
const path = 'https://paddlejs.cdn.bcebos.com/models/humanseg';
if (!loaded) {
const MODEL_CONFIG = {
dir: `${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
loaded = true;
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: 1, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_' + i + '.dat';
}
},
feed
}
});
model = await paddle.load();
}
let inst = model.execute({
input: feed
});
if (!input) {
return;
}
let result = await inst.read();
let N = outputShape[0];
let C = outputShape[1];
let H = outputShape[2];
let W = outputShape[3];
let nhwcShape = [N, H, W, C];
// console.dir(result);
let nchwData = Utils.nhwc2nchw(result, nhwcShape);
// Utils.stridePrint(nchwData);
// Utils.continuousPrint(nchwData);
let myCanvas = document.getElementById('myCanvas');
let img = document.getElementById('video');
myCanvas.width = 192;
myCanvas.height = 192;
let ctx = myCanvas.getContext("2d");
ctx.drawImage(img, 0, 0, 192, 192);
let imageData = ctx.getImageData(0,0,192,192);
let myCanvas2 = document.getElementById('myCanvas2');
myCanvas2.width = img.videoWidth;
myCanvas2.height = img.videoHeight;
let ctx2 = myCanvas2.getContext("2d");
var myImageData = ctx2.createImageData(192, 192);
for (let i = 0; i < 36864; i++) {
myImageData.data[i * 4] = (imageData.data[i * 4] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 1] = (imageData.data[i * 4 + 1] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 2] = (imageData.data[i * 4 + 2] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 3] = nchwData[36864 + i] * 255;
}
ctx.putImageData(myImageData, 0, 0);
let logit = cv.imread(myCanvas);
let dst = new cv.Mat();
let ksize = new cv.Size(5, 5);
let anchor = new cv.Point(-1, -1);
cv.blur(logit, dst, ksize, anchor, cv.BORDER_DEFAULT);
thresholdMask(dst, 0.2, 0.8);
for (let i = 0; i < 36864; i++) {
myImageData.data[i * 4 + 3] = dst.data[i * 4 + 3];
}
ctx.putImageData(myImageData, 0, 0);
ctx2.drawImage(myCanvas, 0, 0, img.videoWidth, img.videoHeight);
let temp = ctx2.getImageData(0, 0, img.videoWidth, img.videoHeight);
myCanvas.width = img.videoWidth;
myCanvas.height = img.videoHeight;
ctx.drawImage(img, 0, 0);
let origin = ctx.getImageData(0, 0, img.videoWidth, img.videoHeight);
for (let i = 0; i < img.videoHeight * img.videoWidth; i++) {
temp.data[i * 4] = origin.data[i * 4];
temp.data[i * 4 + 1] = origin.data[i * 4 + 1];
temp.data[i * 4 + 2] = origin.data[i * 4 + 2];
}
ctx.clearRect(0, 0, img.videoWidth, img.videoHeight);
ctx2.clearRect(0, 0, img.videoWidth, img.videoHeight);
ctx2.putImageData(temp, 0, 0);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>paddle web demo</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="wrapper">
<video id="video"></video>
<canvas id="myCanvas2"></canvas>
</div>
<div id="tool">
<select id="videoSelect"></select>
<button id="start" type="btn" disabled>模型loading中</button>
<button id="end" type="btn" disabled>停止测试</button>
</div>
<canvas style="display: none;" id="myCanvas"></canvas>
<script src="index.es6"></script>
</body>
</html>
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
import Utils from '../../src/utils/utils';
import cv from '../../opencv.js';
const fileDownload = require('js-file-download');
/**
* @file model demo 入口文件
* @author chenhaoze@baidu.com
*
*/
// 模型feed数据
const feedShape = {
'humanseg': {
fw: 192,
fh: 192
}
};
// 模型fetch数据
const fetchShape = {
'humanseg': [1, 2, 192, 192]
};
const modelType = 'humanseg';
const {fw, fh} = feedShape[modelType];
const outputShape = fetchShape[modelType];
let canvas1;
let canvas2;
let ctx;
let ctx2;
// 统计参数
let loaded = false;
let model = {};
window.statistic = [];
async function run(input) {
const io = new IO();
let feed = io.process({
input: input,
params: {
gapFillWith: '#000', // 缩放后用什么填充不足方形部分
scale: 192, // 缩放尺寸
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
mean: [122.675, 116.669, 104.008],
std: [1.0, 1.0, 1.0],
bgr: true
}
});
const path = 'https://paddlejs.cdn.bcebos.com/models/humanseg';
if (!loaded) {
const MODEL_CONFIG = {
dir: `${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
loaded = true;
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: 1, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_' + i + '.dat';
}
},
feed
}
});
model = await paddle.load();
}
let inst = model.execute({
input: feed
});
let result = await inst.read();
let N = outputShape[0];
let C = outputShape[1];
let H = outputShape[2];
let W = outputShape[3];
let nhwcShape = [N, H, W, C];
// console.dir(result);
let nchwData = Utils.nhwc2nchw(result, nhwcShape);
// Utils.stridePrint(nchwData);
// Utils.continuousPrint(nchwData);
// let [w1, h1, width, height] = calSize(img);
let img = document.getElementById('image');
canvas1.width = 192;
canvas1.height = 192;
ctx.drawImage(img, 0, 0, 192, 192);
let imageData = ctx.getImageData(0, 0, 192, 192);
canvas2.width = img.naturalWidth;
canvas2.height = img.naturalHeight;
var myImageData = ctx2.createImageData(192, 192);
for (let i = 0; i < 36864; i++) {
myImageData.data[i * 4] = (imageData.data[i * 4] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 1] = (imageData.data[i * 4 + 1] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 2] = (imageData.data[i * 4 + 2] - 255) * nchwData[36864 + i] + 255;
myImageData.data[i * 4 + 3] = nchwData[36864 + i] * 255;
}
ctx.putImageData(myImageData, 0, 0);
let logit = cv.imread(myCanvas);
let dst = new cv.Mat();
let ksize = new cv.Size(5, 5);
let anchor = new cv.Point(-1, -1);
cv.blur(logit, dst, ksize, anchor, cv.BORDER_DEFAULT);
thresholdMask(dst, 0.4, 0.8);
for (let i = 0; i < 36864; i++) {
myImageData.data[i * 4 + 3] = dst.data[i * 4 + 3];
}
ctx.putImageData(myImageData, 0, 0);
ctx2.drawImage(myCanvas, 0, 0, img.naturalWidth, img.naturalHeight);
let temp = ctx2.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
myCanvas.width = img.naturalWidth;
myCanvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
let origin = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
for (let i = 0; i < img.naturalHeight * img.naturalWidth; i++) {
temp.data[i * 4] = origin.data[i * 4];
temp.data[i * 4 + 1] = origin.data[i * 4 + 1];
temp.data[i * 4 + 2] = origin.data[i * 4 + 2];
}
ctx.clearRect(0, 0, img.naturalWidth, img.naturalHeight);
ctx2.putImageData(temp, 0, 0);
}
function thresholdMask(img, threshBg, threshFg) {
for (let i = 0; i < img.data.length; i++) {
let tmp = (img.data[i] - threshBg * 255.0) / (threshFg - threshBg);
if (tmp < 0) {
img.data[i] = 0;
}
else if (tmp > 255) {
img.data[i] = 255;
}
else {
img.data[i] = tmp;
}
}
}
var image = '';
function selectImage(file) {
if (!file.files || !file.files[0]) {
return;
}
let reader = new FileReader();
reader.onload = function (evt) {
let img = document.getElementById('image');
img.src = evt.target.result;
img.onload = function () {
run(img);
};
image = evt.target.result;
};
reader.readAsDataURL(file.files[0]);
}
// selectImage
document.getElementById('uploadImg').onchange = function () {
selectImage(this);
};
window.onload = function () {
canvas1 = document.getElementById('myCanvas');
ctx = canvas1.getContext('2d');
canvas2 = document.getElementById('myCanvas2');
ctx2 = canvas2.getContext('2d');
};
\ No newline at end of file
...@@ -4,31 +4,14 @@ ...@@ -4,31 +4,14 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>paddle web demo</title> <title>paddle web demo</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style>
.image-wrap {
position: relative;
}
#myDiv {
position: absolute;
border: 1px solid #f71111;
box-sizing: border-box;
}
</style>
</head> </head>
<body> <body>
<div class="image-wrap"> <img id="image" src="https://m.baidu.com/se/static/img/iphone/logo.png" style="max-width: 100%;"><canvas id="myCanvas2"></canvas>
<img id="mobilenet"> <input type="file" id="uploadImg">
</div>
<p>原图片</p>
<div class="image-wrap">
<img id="image" src="pic.png">
<div id="myDiv"></div>
</div>
<p>画布</p> <p>画布</p>
<canvas id="myCanvas"></canvas> <canvas id="myCanvas"></canvas>
<input type="file" id="uploadImg">
<div id="txt"></div> <div id="txt"></div>
<script src="index.es6"></script> <script src="index.es6"></script>
</body> </body>
</html> </html>
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
/**
* @file model demo mnist 入口文件
* @author wangqun@baidu.com
*
*/
const pic = document.getElementById('pic');
const io = new IO();
let model = {};
async function run() {
let feed = io.process({
input: pic,
params: {
targetShape: [1, 3, 320, 320], // 目标形状 为了兼容之前的逻辑所以改个名
scale: 256, // 缩放尺寸
width: 224, height: 224, // 压缩宽高
shape: [3, 224, 224], // 预设tensor形状
mean: [0.485, 0.456, 0.406], // 预设期望
std: [0.229, 0.224, 0.225] // 预设方差
}});
console.dir(['feed', feed]);
const path = 'model/mnist';
const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: false,
dataType: 'json'
}
});
model = await paddle.load();
let inst = model.execute({
input: feed
});
// 其实这里应该有个fetch的执行调用或者fetch的输出
let result = await inst.read();
// let inst = model.execute({input: cat});
// let res = inst.read();
console.dir(['result', result]);
// var fileDownload = require('js-file-download');
// fileDownload(res, 'result.csv');
}
run();
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>paddle web demo</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
</head>
<body>
<div>
<img id="pic" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAcABwBAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APn+vTPDHwP8TeJ9DtdXiuLCzt7kbo0uWcOU7NgKRgjkc81i+O/hvrPgW8xco1zp7ELHfIm1HYqCRjJIPUc9cHFcbSgEnABJ9BXaafH8Rrrw3NpdjBrkmjohLQLE/l7c5OOPUHgV6Fcw3um/sxXNt4hZo7qW5X7FDdLtlRfOU7QG5zgSH/dPpXhFel/Bzxj4a8H6vfzeILZy86ILe6WLzPI27i3HUZ+XkA9PQ16Pc/Hfw7pM91LaXusa20wDRxSQRQww9eAdob35DfWuNg+Ny67Dfab430SDUNLuQxjW2UK8BwcAZPPOPmyCOvPSvH6KKKK//9k=" >
</div>
<script src="index.es6"></script>
</body>
</html>
...@@ -51,11 +51,11 @@ async function run(input) { ...@@ -51,11 +51,11 @@ async function run(input) {
} }
}); });
const path = 'model/mobileNet'; const path = 'https://paddlejs.cdn.bcebos.com/models/mobileNetV2';
if (!loaded) { if (!loaded) {
const MODEL_CONFIG = { const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹 dir: `${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件 main: 'model.json', // 主文件
}; };
loaded = true; loaded = true;
...@@ -86,10 +86,8 @@ async function run(input) { ...@@ -86,10 +86,8 @@ async function run(input) {
let C = outputShape[1]; let C = outputShape[1];
let H = outputShape[2]; let H = outputShape[2];
let W = outputShape[3]; let W = outputShape[3];
console.log(outputShape);
let nhwcShape = [N, H, W, C]; let nhwcShape = [N, H, W, C];
console.log(nhwcShape); console.log(nhwcShape);
console.log(result.length);
let nchwData = Utils.nhwc2nchw(result, nhwcShape); let nchwData = Utils.nhwc2nchw(result, nhwcShape);
Utils.stridePrint(nchwData); Utils.stridePrint(nchwData);
......
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
import Utils from '../../src/utils/utils';
// 获取map表
import Map from '../../test/data/map';
/**
* @file model demo 入口文件
* @author wangqun@baidu.com
*
*/
// 模型feed数据
const feedShape = {
'mobilenetv2': {
fw: 224,
fh: 224
}
};
// 模型fetch数据
const fetchShape = {
'mobilenetv2': [1, 1000, 1, 1]
};
const modelType = 'mobilenetv2';
const {fw, fh} = feedShape[modelType];
const outputShape = fetchShape[modelType];
// 统计参数
let loaded = false;
let model = {};
window.statistic = [];
async function run(input) {
// const input = document.getElementById('mobilenet');
const io = new IO();
let feed = io.process({
input: input,
params: {
gapFillWith: '#000', // 缩放后用什么填充不足方形部分
targetSize: {
height: fh,
width: fw
},
scale: 256, // 缩放尺寸
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
mean: [0.485, 0.456, 0.406],
std: [0.229, 0.224, 0.225]
}
});
const path = 'https://paddlejs.cdn.bcebos.com/models/mobileNetV2Opt';
if (!loaded) {
const MODEL_CONFIG = {
dir: `${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
loaded = true;
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: 4, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_' + i + '.dat';
}
},
feed
}
});
model = await paddle.load();
}
let inst = model.execute({
input: feed
});
let result = await inst.read();
let N = outputShape[0];
let C = outputShape[1];
let H = outputShape[2];
let W = outputShape[3];
let nhwcShape = [N, H, W, C];
console.log(nhwcShape);
let nchwData = Utils.nhwc2nchw(result, nhwcShape);
Utils.stridePrint(nchwData);
Utils.continuousPrint(nchwData);
// for test
// fileDownload(nchwData, "paddlejs-0.txt");
let maxItem = Utils.getMaxItem(nchwData);
console.log(maxItem);
document.getElementById('txt').innerHTML = Map['' + maxItem.index];
console.log('识别出的结果是' + Map['' + maxItem.index]);
};
var image = '';
function selectImage(file) {
if (!file.files || !file.files[0]) {
return;
}
let reader = new FileReader();
reader.onload = function (evt) {
let img = document.getElementById('image');
img.src = evt.target.result;
img.onload = function() {
run(img);
};
image = evt.target.result;
}
reader.readAsDataURL(file.files[0]);
}
// selectImage
document.getElementById("uploadImg").onchange = function () {
selectImage(this);
};
.detector-area {
width: 580px;
height: 400px;
background-color: #fafafa;
overflow: hidden;
text-align: center;
position: relative;
img {
height: 100%;
max-width: 100%;
}
.detector-result-container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: #00000080;
display: none;
.result {
opacity: 0.8;
color: #fff;
font-size: 40px;
text-align: center;
#name {
padding: 30px;
display: inline-block;
border: 2px #fff solid;
margin-top: 80px;
}
#percent {
padding-top: 20px;
}
}
}
}
#txt {
font-size: 30px;
color: #fff;
}
/**
* @file terrorModel 验证 fluid
* @author zhangjingyuan02
*
*/
import 'babel-polyfill'; import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle'; import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed'; import IO from '../../src/feed/imageFeed';
import Utils from '../../src/utils/utils'; import Utils from '../../src/utils/utils';
// 获取map表 const fileDownload = require('js-file-download');
import Map from '../../test/data/map';
/**
* @file model demo 入口文件
* @author wangqun@baidu.com
*
*/
// 模型feed数据 // 模型feed数据
const feedShape = { const feedShape = {
'608': { '608': {
...@@ -28,12 +29,20 @@ const feedShape = { ...@@ -28,12 +29,20 @@ const feedShape = {
fh: 320 fh: 320
} }
}; };
const modelType = 'separate'; const modelType = 'separate';
const {fw, fh} = feedShape[modelType]; const {fw, fh} = feedShape[modelType];
// 统计参数 // 统计参数
let loaded = false; let loaded = false;
let model = {}; let model = null;
window.statistic = [];
// 模型名字
const modelName = 'terrorModel';
// 模型网络输出shape
const outputShape = [1, 15, 1, 1];
// 模型分片
const fileCount = 3;
async function run(input) { async function run(input) {
// const input = document.getElementById('mobilenet'); // const input = document.getElementById('mobilenet');
const io = new IO(); const io = new IO();
...@@ -42,14 +51,18 @@ async function run(input) { ...@@ -42,14 +51,18 @@ async function run(input) {
params: { params: {
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名 targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
scale: 256, // 缩放尺寸 scale: 256, // 缩放尺寸
width: 224, height: 224, // 压缩宽高 width: 224,
height: 224, // 压缩宽高
shape: [3, 224, 224], // 预设tensor形状 shape: [3, 224, 224], // 预设tensor形状
mean: [0.485, 0.456, 0.406], // 预设期望 mean: [0.485, 0.456, 0.406], // 预设期望
std: [0.229, 0.224, 0.225] // 预设方差 std: [0.229, 0.224, 0.225] // 预设方差
}}); }
});
// 生成 fluid 数据
generareFluidData(feed);
console.dir(['feed', feed]); const path = `model/${modelName}`;
const path = 'model/huangfan';
if (!loaded) { if (!loaded) {
const MODEL_CONFIG = { const MODEL_CONFIG = {
...@@ -57,38 +70,55 @@ async function run(input) { ...@@ -57,38 +70,55 @@ async function run(input) {
main: 'model.json', // 主文件 main: 'model.json', // 主文件
}; };
loaded = true; loaded = true;
const paddle = new Paddle({ const paddle = new Paddle({
urlConf: MODEL_CONFIG, urlConf: MODEL_CONFIG,
options: { options: {
multipart: false, multipart: true,
dataType: 'json' dataType: 'binary',
options: {
fileCount: 3, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_' + i + '.dat';
}
},
feed
} }
}); });
model = await paddle.load(); model = await paddle.load();
} }
let inst = model.execute({ let inst = model.execute({
input: feed input: feed
}); });
// 其实这里应该有个fetch的执行调用或者fetch的输出
let result = await inst.read(); let result = await inst.read();
console.dir(['result', result]); let shape = model.graph.currentShape;
let maxItem = Utils.getMaxItem(result); shape = [1, 15, 1, 1];
document.getElementById('txt').innerHTML = Map['' + maxItem.index]; shape = Utils.padToFourDimShape(shape);
console.log('识别出的结果是' + Map['' + maxItem.index]); let N = shape[0];
// console.dir(['每个op耗时', window.statistic]); let C = shape[1];
// let total = statistic.reduce((all, cur) => { let H = shape[2];
// return all + cur.runTime; let W = shape[3];
// }, 0); const nhwc = [N, H, W, C];
// console.log('op total = ' + total);
let nchwData = Utils.nhwc2nchw(result, nhwc);
const formatData = Utils.formatReadData(nchwData, shape);
fileDownload(formatData, 'data.txt');
}
function generareFluidData(feed) {
let data = new Float32Array(3 * 224 * 224);
for (let i = 0; i < 3 * 224 * 224; i++) {
data = 1.0 + 0.0;
}
data = Utils.nchw2nhwc(data, [1, 3, 224, 224]);
for (let i = 0; i < 3 * 224 * 224; i++) {
feed[0].data[i] = 1;
}
} }
var image = '';
function selectImage(file) { function selectImage(file) {
if (!file.files || !file.files[0]) { if (!file.files || !file.files[0]) {
return; return;
...@@ -100,7 +130,6 @@ function selectImage(file) { ...@@ -100,7 +130,6 @@ function selectImage(file) {
img.onload = function () { img.onload = function () {
run(img); run(img);
}; };
image = evt.target.result;
}; };
reader.readAsDataURL(file.files[0]); reader.readAsDataURL(file.files[0]);
} }
......
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
import Utils from '../../src/utils/utils';
const fileDownload = require('js-file-download');
/**
* @file Terror model 入口文件
* @author zhangjingyuan02
*
*/
// 模型feed数据
const feedShape = {
'terrorModel': {
fw: 224,
fh: 224
}
};
// 统计参数
let loaded = false;
let model = null;
// 模型名字
const modelName = 'terrorModel';
// 模型网络输出shape
const outputShape = [1, 15, 1, 1];
// 模型分片
const fileCount = 3;
const {fw, fh} = feedShape[modelName];
async function run(input) {
// const input = document.getElementById('mobilenet');
const io = new IO();
let feed = io.process({
input: input,
params: {
gapFillWith: '#000', // 缩放后用什么填充不足方形部分
targetSize: {
height: fh,
width: fw
},
scale: 256, // 缩放尺寸
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
mean: [0.485, 0.456, 0.406],
std: [0.229, 0.224, 0.225]
}
});
const path = `model/${modelName}`;
if (!loaded) {
const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
loaded = true;
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: fileCount, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_' + i + '.dat';
}
},
feed
}
});
model = await paddle.load();
}
let inst = model.execute({
input: feed
});
let result = await inst.read();
let N = outputShape[0];
let C = outputShape[1];
let H = outputShape[2];
let W = outputShape[3];
let nhwcShape = [N, H, W, C];
let nchwData = Utils.nhwc2nchw(result, nhwcShape);
// 模型后置处理, infer的时候需要
nchwData = Utils.softmax(nchwData);
// 打印数据
Utils.stridePrint(nchwData);
Utils.continuousPrint(nchwData);
// 生成详细类别得分
const score12List = convertTo12class(nchwData);
const detailClass = [
'正常', '警察部队', '血腥', '尸体', '爆炸火灾', '杀人', '暴乱',
'暴恐人物', '军事武器', '暴恐旗帜', '血腥动物或动物尸体', '车祸'
];
// 详细分类得分
const class12Score = [];
detailClass.forEach((name, index) => {
class12Score.push({
name,
score: score12List[index]
});
});
// 生成简单类别得分
const twoClass = ['正常', '暴恐'];
const score2List = convertTo2class(nchwData);
// 简单分类得分
const class2Score = [];
twoClass.forEach((name, index) => {
class2Score.push({
name,
score: score2List[index]
});
});
// 展示结果
const maxItem = Utils.getMaxItem(score12List);
const resName = detailClass[maxItem.index];
const resPercent = toPercent(maxItem.value);
document.querySelector('.result #name').innerHTML = resName;
document.querySelector('.result #percent').innerHTML = resPercent;
document.querySelector('.detector-result-container').style.display = 'block';
}
// 小数转百分比
function toPercent(data) {
let str = Number(data * 100).toFixed(3);
return str += '%';
}
function convertTo12class(scores) {
return [
scores[0] + scores[12], scores[10], scores[3], scores[2],
scores[8], scores[1] + scores[7], scores[9], scores[5] + scores[6],
scores[11], scores[4], scores[13], scores[14]
];
}
function convertTo2class(scores) {
const totalScore = scores.reduce((acc, cur) => acc += cur, 0);
let normalScore = scores[0] + scores[10] + scores[11] + scores[12] + scores[13];
let terrorScore = totalScore - normalScore;
return [
normalScore,
terrorScore
];
}
function selectImage(file) {
if (!file.files || !file.files[0]) {
return;
}
let reader = new FileReader();
reader.onload = function (evt) {
let img = document.getElementById('image');
img.src = evt.target.result;
img.onload = function () {
run(img);
};
};
reader.readAsDataURL(file.files[0]);
}
// selectImage
document.getElementById('uploadImg').onchange = function () {
selectImage(this);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>paddle web demo - terrorModel</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link href="custom.less" rel="stylesheet">
</head>
<body>
<div class="detector-area">
<img id="image" src="https://m.baidu.com/se/static/img/iphone/logo.png" >
<div class="detector-result-container">
<div class="result">
<div id="name"></div>
<div id="percent"></div>
</div>
</div>
</div>
<input type="file" id="uploadImg">
<script src="index.es6"></script>
</body>
</html>
...@@ -54,7 +54,7 @@ const feedShape = { ...@@ -54,7 +54,7 @@ const feedShape = {
}; };
// 模型路径 // 模型路径
const modelPath = { const modelPath = {
'tinyYolo': 'model/tinyYolo' 'tinyYolo': 'https://paddlejs.cdn.bcebos.com/models/tinyYolo'
}; };
const modelType = 'tinyYolo'; const modelType = 'tinyYolo';
const path = modelPath[modelType]; const path = modelPath[modelType];
...@@ -86,7 +86,7 @@ async function run(input) { ...@@ -86,7 +86,7 @@ async function run(input) {
// log.end('预处理'); // log.end('预处理');
if (!loaded) { if (!loaded) {
const MODEL_CONFIG = { const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹 dir: `${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件 main: 'model.json', // 主文件
}; };
loaded = true; loaded = true;
...@@ -98,7 +98,7 @@ async function run(input) { ...@@ -98,7 +98,7 @@ async function run(input) {
options: { options: {
fileCount: 1, // 切成了多少文件 fileCount: 1, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称 getFileName(i) { // 获取第i个文件的名称
return 'chunk_0.dat'; return `chunk_${i}.dat`;
} }
} }
} }
......
...@@ -45,7 +45,7 @@ const feedShape = { ...@@ -45,7 +45,7 @@ const feedShape = {
} }
}; };
const modelPath = { const modelPath = {
'tinyYolo': 'model/tinyYolo' 'tinyYolo': 'https://paddlejs.cdn.bcebos.com/models/tinyYolo'
}; };
const modelType = 'tinyYolo'; const modelType = 'tinyYolo';
const path = modelPath[modelType]; const path = modelPath[modelType];
...@@ -55,7 +55,8 @@ const runner = new Runner({ ...@@ -55,7 +55,8 @@ const runner = new Runner({
modelName: modelType, // '608' | '320' | '320fused' | 'separate' modelName: modelType, // '608' | '320' | '320fused' | 'separate'
modelPath: path, modelPath: path,
feedShape: feedShape[modelType], feedShape: feedShape[modelType],
outputShapes: outputShapes[modelType] outputShapes: outputShapes[modelType],
inputType: 'video'
}); });
startBtn.disabled = true; startBtn.disabled = true;
runner.preheat() runner.preheat()
...@@ -95,7 +96,7 @@ const handleDiv = function (data) { ...@@ -95,7 +96,7 @@ const handleDiv = function (data) {
} }
startBtn.addEventListener('click', function () { startBtn.addEventListener('click', function () {
startBtn.disabled = true; startBtn.disabled = true;
runner.startStream(() => camera.curVideo, handleDiv); runner.predict(() => camera.curVideo, handleDiv);
}); });
stopBtn.addEventListener('click', function () { stopBtn.addEventListener('click', function () {
startBtn.disabled = false; startBtn.disabled = false;
......
<template lang="pug">
div
page
</template>
<script lang="ts">
import Vue from "vue";
import page from "./page.vue";
export default Vue.extend({
data() {
return {
bundler: "Parcel",
};
},
components: {
'page': page
}
});
</script>
<style lang="less" scoped>
.container {
color: green;
}
.text {
color: red;
}
</style>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PaddleJS benchmark</title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
</head>
<body>
<div id="app"></div>
<script src="./index.js"></script>
</body>
</html>
import Vue from 'vue';
import App from './app.vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
const vm = new Vue({render: h => h(App)});
vm.$mount('#app');
<template lang="pug">
div.page
div.imglist
el-carousel(:interval="4000" type="card" @change="change" height="400px" :autoplay="autoPlay")
el-carousel-item(v-for="(item, index) in imgList" :key="item")
img.img(:src="item" :ref="'img' + index")
span.result-text(v-if="result[index]") {{ result[index] }}
el-button(type="primary" @click="predict").predict 点击识别此图
div.loading(v-if="isLoading || isPredicting")
span.loading-text {{ isLoading ? 'loading...' : '识别中……'}}
</template>
<script>
import Vue from 'vue';
import 'regenerator-runtime/runtime'
import 'babel-polyfill'
import Paddlejs from '../../src/executor/runner';
import Utils from '../../src/utils/utils';
import postProcess from './postProcess'
export default Vue.extend({
data() {
return {
modelConf: {
modelPath: 'https://paddlejs.cdn.bcebos.com/models/wine',
fileCount: 3,
feedShape: {
fw: 224,
fh: 224
},
fetchShape: [1, 40, 1, 1],
fill: '#000',
scale: 256,
targetSize: { height: 224, width: 224 },
mean: [0.485, 0.456, 0.406],
std: [0.229, 0.224, 0.225],
needBatch: true
},
imgList: [
require('./imgs/1.jpg'),
require('./imgs/2.jpg'),
require('./imgs/3.jpg'),
require('./imgs/4.jpg'),
require('./imgs/5.jpg'),
require('./imgs/6.jpg'),
require('./imgs/7.jpg')
],
result: {},
curImgIndex: 0,
autoPlay: true,
isLoading: true,
isPredicting: false,
paddlejs: null
}
},
methods: {
change(index) {
this.curImgIndex = index;
},
async predict() {
console.log('开始预测')
this.autoPlay = false;
this.isPredicting = true;
const curIndex = this.curImgIndex;
const imgDom = this.$refs['img' + this.curImgIndex][0];
await this.predictModel(imgDom, curIndex);
this.isPredicting = false;
},
load() {
const paddlejs = this.paddlejs = new Paddlejs(this.modelConf);
paddlejs.loadModel().then(() => {
this.isLoading = false;
})
},
async predictModel(img, curIndex) {
await this.paddlejs.predict(img, (data) => this.process(data, curIndex));
},
process(data, curIndex) {
const result = postProcess(data);
console.log(result)
this.result[curIndex] = result || '无结果'
}
},
mounted() {
this.load();
}
})
</script>
<style>
.page {
padding-top: 50px;
text-align: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 1px solid #f1f1f1;
}
.img {
width: 100%;
}
.loading {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .7);
color: #fff;
z-index: 2;
font-size: 32px;
}
.imglist {
margin-bottom: 50px;
}
.predict {
}
.result-text {
font-weight: bold;
}
</style>
\ No newline at end of file
// index.js
import Map from '../../test/data/wine.map.json';
import Utils from '../../src/utils/utils';
export default function postProcess(data) {
let maxItem = Utils.getMaxItem(data);
return Map[maxItem.index];
}
/* eslint-disable */
import 'babel-polyfill';
import Paddle from '../../src/paddle/paddle';
import IO from '../../src/feed/imageFeed';
// import Logger from '../../tools/logger';
// window.log = new Logger();
// // 统计参数
// window.badCases = [];
// 后处理测试用例
// let tempPic = [demoPic, demoPic2, demoPic3, demoPic4, demoPic5];
/**
* @file model demo 入口文件
* @author wangqun@baidu.com
*
*/
// 模型输出shape
const outputShapes = {
'608': {
from: [19, 19, 25, 1],
to: [19, 19, 5, 5]
},
'320': {
from: [10, 10, 25, 1],
to: [10, 10, 5, 5]
},
'320fused': {
from: [10, 10, 25, 1],
to: [10, 10, 5, 5]
},
'separate': {
from: [10, 10, 25, 1],
to: [10, 10, 5, 5]
}
};
// 模型feed数据
const feedShape = {
'608': {
fw: 608,
fh: 608
},
'320': {
fw: 320,
fh: 320
},
'320fused': {
fw: 320,
fh: 320
},
'separate': {
fw: 320,
fh: 320
}
};
// 模型路径
const modelPath = {
'separate': 'model/tinyYolo'
};
const modelType = 'separate';
const path = modelPath[modelType];
// 统计参数
let loaded = false;
let model = {};
window.statistic = [];
const {fw, fh} = feedShape[modelType];
// 第一遍执行比较慢 所以预热一下
async function run(input) {
// const input = document.getElementById('mobilenet');
//log.start('总耗时');
const io = new IO();
// log.start('预处理');
let feed = io.process({
input: input,
params: {
gapFillWith: '#000', // 缩放后用什么填充不足方形部分
targetSize: {
height: fw,
width: fh
},
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
// shape: [3, 608, 608], // 预设tensor形状
mean: [117.001, 114.697, 97.404], // 预设期望
// std: [0.229, 0.224, 0.225] // 预设方差
}
});
// log.end('预处理');
if (!loaded) {
const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹
main: 'model.json', // 主文件
};
loaded = true;
const paddle = new Paddle({
urlConf: MODEL_CONFIG,
options: {
multipart: true,
dataType: 'binary',
options: {
fileCount: 1, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称
return 'chunk_0.dat';
}
},
feed
}
});
model = await paddle.load();
}
let inst = model.execute({
input: feed
});
// 其实这里应该有个fetch的执行调用或者fetch的输出
let result = await inst.read();
// log.end('运行耗时');
// log.end('后处理-读取数据');
console.dir(['result', result]);
//log.start('后处理-形状调整');
const newData = [];
let newIndex = -1;
const [w, h, c, b] = outputShapes[modelType].from;
// c channel
for (let i = 0; i < c; i++) {
// height channel
for (let j = 0; j < h; j++) {
// width channel
for (let k = 0; k < w; k++) {
// position: (0, 0, 0, 0)
const index = j * (c * h) + k * c + i;
// const index = j * (i * k) + k * i + i;
newData[++newIndex] = result[index];
}
}
}
// log.end('后处理-形状调整');
// log.start('后处理-画框');
testRun(newData, input);
// log.end('后处理-画框');
// log.end('后处理');
// log.end('总耗时');
}
var image = '';
function selectImage(file) {
if (!file.files || !file.files[0]) {
return;
}
let reader = new FileReader();
reader.onload = function (evt) {
let img = document.getElementById('image');
img.src = evt.target.result;
img.onload = function() {
//log.during('每次执行的时间间隔');
run(img);
};
image = evt.target.result;
}
reader.readAsDataURL(file.files[0]);
}
// selectImage
document.getElementById("uploadImg").onchange = function () {
selectImage(this);
};
/* 后处理图片 by zhangmiao06 */
let preTestRun = (index) => {
let img = document.getElementById('image');
img.src = tempPic[index];
img.onload = function() {
testRun(testOutput.data[index], img);
};
};
let testRun = (data, img) => {
// console.log('ori', data);
const {from, to} = outputShapes[modelType];
// let shape = [1, 25, 19, 19];
let shape = [].concat(from).reverse();
// 1.从一维数组到1*25*19*19
let formatData = reshapeMany({
data: data,
reshapeShape: shape
});
// console.log('一维到多维', formatData);
// 2.从1*25*19*19 到 19*19*25*1
let formatData2 = transpose({
data: formatData,
shape: shape,
transposeShape: [2, 3, 1, 0]
});
// console.log('transpose', formatData2);
// 3.从19*19*25*1到19*19*5*5
let formatData3 = reshape({
data: formatData2,
shape: from,
reshapeShape: to
});
// console.log('reshape', formatData3);
// 4.运算
let finalData = handleFinal(formatData3, shape, img);
// console.log('final', finalData);
// 5.处理画布
// handleCanvas(finalData, img);
handleDiv(finalData, img);
};
// sigmoid
let sigmoid = (x) => {
if (x < -100) {
return 0.0;
}
return 1 / (1 + Math.exp(-x));
}
// transpose
let transpose = (data) => {
let shape = data.shape;
let transposeShape = data.transposeShape;
let formatData = data.data;
let formatData2 = [];
for(let n = 0; n < shape[transposeShape[0]]; n++) {
let nData = [];
for(let c = 0; c < shape[transposeShape[1]]; c++) {
let cData = [];
for(let row = 0; row < shape[transposeShape[2]]; row++) {
let rowData = [];
for(let col = 0; col < shape[transposeShape[3]]; col++) {
let tempArr = [n, c, row, col];
let newN = n;
let newC = c;
let newW = row;
let newH = col;
transposeShape.forEach((item, index)=> {
switch(item) {
case 0:
newN = tempArr[index];
break;
case 1:
newC = tempArr[index];
break;
case 2:
newW = tempArr[index];
break;
case 3:
newH = tempArr[index];
}
});
rowData.push(formatData[newN][newC][newW][newH]);
}
cData.push(rowData);
}
nData.push(cData);
}
formatData2.push(nData);
}
return formatData2;
};
// reshape
let reshape = (data) =>{
let formatData2 = data.data;
let shape = data.shape;
let reshapeShape = data.reshapeShape;
// 1.变成一维
let tempData = reshapeOne({
data: formatData2,
shape: shape
});
// 2.变成多维
let formatData3 = reshapeMany({
data: tempData,
reshapeShape: reshapeShape
});
return formatData3;
};
// 变成一维
let reshapeOne = (data) => {
let formatData2 = data.data;
let shape = data.shape;
let tempData = [];
for(let n = 0; n < shape[0]; n++) {
for(let c = 0; c < shape[1]; c++) {
for(let row = 0; row < shape[2]; row++) {
for(let col = 0; col < shape[3]; col++) {
tempData.push(formatData2[n][c][row][col]);
}
}
}
}
return tempData;
};
// 变成多维
let reshapeMany = (data) => {
let tempData = data.data;
let reshapeShape = data.reshapeShape;
let formatData3 = [];
for(let n = 0; n < reshapeShape[0]; n++) {
let nData = [];
for(let c = 0; c < reshapeShape[1]; c++) {
let cData = [];
for(let row = 0; row < reshapeShape[2]; row++) {
let rowData = [];
for(let col = 0; col < reshapeShape[3]; col++) {
let tempN = n * reshapeShape[1] * reshapeShape[2] * reshapeShape[3];
let tempC = c * reshapeShape[2] * reshapeShape[3];
let tempRow = row * reshapeShape[3];
rowData.push(tempData[tempN + tempC + tempRow + col]);
}
cData.push(rowData);
}
nData.push(cData);
}
formatData3.push(nData);
}
return formatData3;
};
let calSize = (img) => {
let w1 = img.width;
let h1 = img.height;
let wh1 = Math.max(w1, h1);
// let factor = 608.0 / wh1;
let factor = fw / wh1;
let width = Math.round(w1 * factor);
let height = Math.round(h1 * factor);
return [w1, h1, width, height];
};
// 处理运算
let handleFinal = (formatData3, shape, img) => {
let finalData = [];
let c = shape[2];
let [w1, h1, width, height] = calSize(img);
let factorX = Math.max(width, height) / width;
let factorY = Math.max(width, height) / height;
let maxProb = 0.0;
let anchors = [[1.603231, 2.094468], [6.041143, 7.080126], [2.882459, 3.518061], [4.266906, 5.178857], [9.041765, 10.66308]];
for(let i = 0; i < shape[2]; i++) {
for(let j = 0; j < shape[3]; j++) {
for(let k = 0; k < anchors.length; k++) {
let [a1, a2, a3, a4, prob] = formatData3[i][j][k];
prob = sigmoid(prob);
if (prob > maxProb && prob >= 0.5) {
let ctx = (j + sigmoid(a1)) / c * factorX;
let cty = (i + sigmoid(a2)) / c * factorY;
let col = Math.exp(a3) * anchors[k][0] / c * factorX;
let row = Math.exp(a4) * anchors[k][1] / c * factorY;
let x = (ctx - (col / 2));
let y = (cty - (row / 2));
finalData.push([x * w1, y * h1, col * w1, row * h1, prob]);
}
}
}
}
return finalData;
};
// 处理画布
let handleCanvas = (finalData, img) => {
let myCanvas = document.getElementById('myCanvas');
let [w1, h1, width, height] = calSize(img);
myCanvas.width = w1;
myCanvas.height = h1;
let ctx = myCanvas.getContext("2d");
ctx.drawImage(img, 0, 0, w1, h1);
finalData.forEach((demoArr,index) => {
let [demoLeft, demoTop, demoWidth, demoHeight, prob] = demoArr;
ctx.beginPath();
ctx.strokeStyle="red";
ctx.moveTo(demoLeft, demoTop);
ctx.lineTo(demoLeft + demoWidth, demoTop);
ctx.lineTo(demoLeft + demoWidth, demoTop + demoHeight);
ctx.lineTo(demoLeft, demoTop + demoHeight);
ctx.closePath();
ctx.stroke();
});
};
let handleDiv = (finalData, img) => {
if (finalData.length < 1) {
return false;
}
let myCanvas = document.getElementById('myDiv');
let maxIndex = 0;
if (finalData.length > 1) {
for(let i = 1; i < finalData.length; i++) {
if (finalData[i].prob > finalData[maxIndex].prob) {
maxIndex = i;
}
}
}
let [demoLeft, demoTop, demoWidth, demoHeight, prob] = finalData[maxIndex];
myCanvas.style.width = demoWidth;
myCanvas.style.height = demoHeight;
myCanvas.style.left = demoLeft;
myCanvas.style.top = demoTop;
};
// preTestRun(0);
// run(document.getElementById('pic'));
/* eslint-enable */
\ No newline at end of file
module.exports = {
testEnvironment: 'node',
transform: {
// 将.js后缀的文件使用babel-jest处理
'^.+\\.(js|es6)$': 'babel-jest'
},
moduleFileExtensions: ['js', 'json', 'jsx', 'node', 'es6'],
testMatch: [ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)*(spec|test).[jt]s?(x)" ]
};
...@@ -5,24 +5,31 @@ ...@@ -5,24 +5,31 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"server": "parcel ./src/index.html", "server": "parcel ./src/index.html",
"mnistdemo": "parcel ./examples/mnist/index.html",
"mobilenet": "parcel ./examples/mobileNet/index.html", "mobilenet": "parcel ./examples/mobileNet/index.html",
"mobilenetOpt": "parcel ./examples/mobileNetOpt/index.html",
"wine": "parcel ./examples/wine/index.html --port 1234",
"tinyYolo": "parcel ./examples/tinyYolo/index.html", "tinyYolo": "parcel ./examples/tinyYolo/index.html",
"huangfan": "parcel ./examples/huangfan/index.html", "huangfan": "parcel ./examples/huangfan/index.html",
"terrorModel": "parcel ./examples/terrorModel/index.html", "terrorModel": "parcel ./examples/terrorModel/index.html",
"humanseg": "parcel ./examples/humanseg/index.html", "humanseg": "parcel ./examples/humanseg/index.html",
"humanStream": "parcel ./examples/humanStream/index.html --port 1234 --https", "humanStream": "parcel ./examples/humanStream/index.html --port 1234 --https",
"gesture": "parcel ./examples/gesture/index.html --port 8888 --https",
"benchmark": "parcel ./examples/benchmark/index.html",
"yolo": "parcel ./examples/yolo/index.html", "yolo": "parcel ./examples/yolo/index.html",
"videoDemo": "parcel ./examples/videoDemo.html --port 8123 --https", "videoDemo": "parcel ./examples/tinyYolo/videoDemo.html --port 8123 --https",
"unitTest": "parcel ./test/unitTest.html", "unitTest": "parcel ./test/unitTest.html",
"test": "echo \"Error: no test specified\" && exit 1", "test": "jest",
"build": "webpack -w" "build": "parcel build ./examples/humanStream/index.html",
"demo": "parcel ./examples/demo/index.html",
"pub": "webpack"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.7.2", "@babel/core": "^7.9.6",
"@babel/preset-env": "^7.7.1", "@babel/preset-env": "^7.9.6",
"axios": "^0.19.2", "@vue/component-compiler-utils": "^3.1.2",
"axios": "^0.17.1",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-jest": "^26.0.1",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5", "babel-plugin-transform-decorators-legacy": "^1.3.5",
...@@ -32,19 +39,32 @@ ...@@ -32,19 +39,32 @@
"babel-preset-react": "^6.24.1", "babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1", "babel-preset-stage-0": "^6.24.1",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"gl": "^4.5.0",
"jest": "^26.0.1",
"less": "^3.11.1", "less": "^3.11.1",
"parcel-bundler": "^1.10.3", "parcel-bundler": "^1.10.3",
"pre-push": "^0.1.1",
"pug": "^3.0.0",
"typescript": "^3.9.5",
"vue-template-compiler": "^2.6.11",
"webpack-cli": "^3.3.6" "webpack-cli": "^3.3.6"
}, },
"keywords": [], "keywords": [],
"pre-push": [
"test"
],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@babel/plugin-transform-runtime": "^7.6.2", "@babel/plugin-transform-runtime": "^7.6.2",
"@babel/runtime": "^7.7.2", "@babel/runtime": "^7.7.2",
"element-ui": "^2.13.2",
"extract-text-webpack-plugin": "^4.0.0-beta.0", "extract-text-webpack-plugin": "^4.0.0-beta.0",
"js-file-download": "^0.4.10", "js-file-download": "^0.4.10",
"paddlejs": "^1.0.0-beta.0",
"vconsole": "^3.3.2", "vconsole": "^3.3.2",
"vue": "^2.6.11",
"vue-hot-reload-api": "^2.3.4",
"webpack": "^4.39.2", "webpack": "^4.39.2",
"webpack-zepto": "0.0.1" "webpack-zepto": "0.0.1"
} }
......
...@@ -23,6 +23,9 @@ export default class Camera { ...@@ -23,6 +23,9 @@ export default class Camera {
if(navigator.mediaDevices) { if(navigator.mediaDevices) {
this.haveDevice = true; this.haveDevice = true;
} }
if (option.constraints) {
this.constraints = option.constraints;
}
} }
// 访问用户媒体设备的兼容方法 // 访问用户媒体设备的兼容方法
...@@ -49,6 +52,9 @@ export default class Camera { ...@@ -49,6 +52,9 @@ export default class Camera {
video: true video: true
}; };
} }
else if (this.constraints) {
constraints = this.constraints;
}
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// 最新的标准API // 最新的标准API
......
...@@ -14,12 +14,19 @@ import DataFeed from '../feed/dataFeed'; ...@@ -14,12 +14,19 @@ import DataFeed from '../feed/dataFeed';
import PostProcess from './postProcess'; import PostProcess from './postProcess';
import Logger from '../../tools/logger'; import Logger from '../../tools/logger';
import Paddle from '../paddle/paddle'; import Paddle from '../paddle/paddle';
import Utils from '../utils/utils';
// const fileDownload = require('js-file-download');
window.log = new Logger(); window.log = new Logger();
export default class Runner { export default class Runner {
// 加载模型&预热 // 加载模型&预热
constructor(options) { constructor(options) {
this.modelConfig = options; // models[options.modelName]; const opts = {
needPostProcess: false,
needPreheat: true,
inputType: 'image'
};
this.modelConfig = Object.assign(opts, options); // models[options.modelName];
this.flags = { this.flags = {
isRunning: false, isRunning: false,
isPreheating: false, isPreheating: false,
...@@ -27,57 +34,67 @@ export default class Runner { ...@@ -27,57 +34,67 @@ export default class Runner {
}; };
this.buffer = new Float32Array(); this.buffer = new Float32Array();
this.io = new IO(); this.io = new IO();
this.postProcess = new PostProcess(options); this.model = null;
this.preheatFeed = null;
if (this.modelConfig.needPostProcess) {
this.postProcess = new PostProcess(options);
}
} }
// 预热 用用空数据跑一遍 async loadModel() {
async preheat() { const options = this.modelConfig;
this.flags.isPreheating = true; let path = options.modelPath;
let {fh, fw} = this.modelConfig.feedShape;
let path = this.modelConfig.modelPath;
let feed = [{
data: new Float32Array(3 * fh * fw),
name: 'image',
shape: [1, 3, fh, fw]
}];
if (path.charAt(path.length - 1) !== '/') {
path += '/';
}
const MODEL_CONFIG = { const MODEL_CONFIG = {
dir: `/${path}/`, // 存放模型的文件夹 dir: path.indexOf('http') === 0 ? path : `/${path}`, // 存放模型的文件夹
main: 'model.json', // 主文件 main: 'model.json', // 主文件
}; };
// const graphModel = new Graph();
// this.model = await graphModel.loadGraphModel(MODEL_CONFIG, {
// multipart: true,
// dataType: 'binary',
// binaryOption: {
// fileCount: 1, // 切成了多少文件
// getFileName(i) { // 获取第i个文件的名称
// return 'chunk_0.dat';
// }
// },
// feed
// });
const paddle = new Paddle({ const paddle = new Paddle({
urlConf: MODEL_CONFIG, urlConf: MODEL_CONFIG,
options: { options: {
multipart: true, multipart: true,
dataType: 'binary', dataType: 'binary',
options: { options: {
fileCount: 1, // 切成了多少文件 fileCount: options.fileCount, // 切成了多少文件
getFileName(i) { // 获取第i个文件的名称 getFileName(i) { // 获取第i个文件的名称
return 'chunk_0.dat'; return `chunk_${i}.dat`;
} }
} }
} }
}); });
this.model = await paddle.load();
this.model = await paddle.load();
console.log('needPreheat', options.needPreheat)
if (!options.needPreheat) {
return;
}
await this.preheat();
}
async checkModelLoaded() {
if (!this.model) {
console.info('It\'s better to preheat the model before running.');
await this.loadModel();
}
}
// 预热 用用空数据跑一遍
async preheat() {
await this.checkModelLoaded();
this.flags.isPreheating = true;
let {fh, fw} = this.modelConfig.feedShape;
let feed = this.preheatFeed = [{
data: new Float32Array(3 * fh * fw).fill(5.0),
name: 'image',
shape: [1, 3, fh, fw]
}];
let inst = this.model.execute({ const inst = this.model.execute({
input: feed input: feed
}); });
await this.runAfter(inst);
this.flags.isPreheating = false; this.flags.isPreheating = false;
return this; return this;
} }
...@@ -85,88 +102,93 @@ export default class Runner { ...@@ -85,88 +102,93 @@ export default class Runner {
// 跑一遍 // 跑一遍
async run(input, callback) { async run(input, callback) {
this.flags.isRunning = true; this.flags.isRunning = true;
let {fh, fw} = this.modelConfig.feedShape; const options = this.modelConfig;
let path = this.modelConfig.modelPath; let {fh, fw} = options.feedShape;
if (!this.model) {
console.warn('It\'s better to preheat the model before running.'); const {inputType = 'image', fill, targetSize, scale, mean, std} = options;
await this.preheat();
}
// log.start('总耗时'); // eslint-disable-line
// log.start('预处理'); // eslint-disable-line
let feed; let feed;
if (typeof input === 'string') { switch (inputType) {
const dfIO = new DataFeed(); case 'video':
feed = await dfIO.process({ feed = [
input: `/${path}/${input}`, {
shape: [1, 3, fh, fw] data: input,
}); shape: [1, 3, fh, fw],
} name: 'image'
else { }
feed = this.io.process({ ];
input: input, break;
params: { case 'image':
gapFillWith: '#000', // 缩放后用什么填充不足方形部分 feed = this.io.process({
targetSize: { input: input,
height: fw, params: {
width: fh gapFillWith: fill || '#000', // 缩放后用什么填充不足方形部分
}, targetSize: targetSize, // { height: fw, width: fh}
targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名 scale: scale, // 缩放尺寸
// shape: [3, 608, 608], // 预设tensor形状 targetShape: [1, 3, fh, fw], // 目标形状 为了兼容之前的逻辑所以改个名
mean: [117.001, 114.697, 97.404] // 预设期望 mean: mean || [0, 0, 0], // 预设期望
// std: [0.229, 0.224, 0.225] // 预设方差 std: std || [1, 1, 1] // 预设方差
} }
}); });
break;
} }
// log.end('预处理'); // eslint-disable-line
// log.start('运行耗时'); // eslint-disable-line await this.runWithFeed(feed, callback);
}
async runAfter(inst) {
let result = await inst.read();
let fetchShape = this.modelConfig.fetchShape;
let N = fetchShape[0];
let C = fetchShape[1];
let H = fetchShape[2];
let W = fetchShape[3];
let nhwcShape = [N, H, W, C];
let nchwData = Utils.nhwc2nchw(result, nhwcShape);
Utils.stridePrint(nchwData);
Utils.continuousPrint(nchwData);
// fileDownload(nchwData, `paddle.txt`);
return nchwData;
}
async runWithFeed(feed, callback) {
await this.checkModelLoaded();
let inst = this.model.execute({ let inst = this.model.execute({
input: feed input: feed
}); });
let result = await inst.read(); const nchwData = await this.runAfter(inst);
// log.end('后处理-读取数据'); // eslint-disable-line
const newData = []; await callback && callback(nchwData);
let newIndex = -1;
const [w, h, c, b] = this.modelConfig.outputShapes.from;
// c channel
for (let i = 0; i < c; i++) {
// height channel
for (let j = 0; j < h; j++) {
// width channel
for (let k = 0; k < w; k++) {
// position: (0, 0, 0, 0)
const index = j * (c * h) + k * c + i;
// const index = j * (i * k) + k * i + i;
newData[++newIndex] = result[index];
}
}
}
this.postProcess.run(newData, input, callback, feed[0].canvas);
// log.end('后处理'); // eslint-disable-line
this.flags.isRunning = false; this.flags.isRunning = false;
// log.end('总耗时'); // eslint-disable-line
} }
// 传入获取图片的function // 传入获取图片的function
async runStream(getMedia, callback) { async runStream(getMedia, callback) {
await this.run(getMedia, callback); const result = await this.run(getMedia, callback);
if (!this.flags.runVideoPaused) { if (this.modelConfig.inputType === 'video' && !this.flags.runVideoPaused) {
setTimeout(async () => { setTimeout(async () => {
await this.runStream(getMedia, callback); await this.runStream(getMedia, callback);
}, 0); }, 0);
} }
return result;
} }
stopStream() { stopStream() {
this.flags.runVideoPaused = true; this.flags.runVideoPaused = true;
} }
startStream(getMedia, callback) { async predict(getMedia, callback) {
this.flags.runVideoPaused = false; this.flags.runVideoPaused = false;
if (typeof getMedia === 'function') { if (typeof getMedia === 'function') {
this.runStream(getMedia(), callback); await this.runStream(getMedia(), callback);
} else { } else {
this.runStream(getMedia, callback); await this.runStream(getMedia, callback);
} }
} }
} }
window.Paddle = Runner;
...@@ -7,6 +7,7 @@ export default class Factory { ...@@ -7,6 +7,7 @@ export default class Factory {
constructor(opts) { constructor(opts) {
this.defaultOpts = Object.assign({}, opts); this.defaultOpts = Object.assign({}, opts);
this.webglVersion = 2; this.webglVersion = 2;
this.isFrameBufferSupportFloat = true;
this.texture2d = 'texture'; this.texture2d = 'texture';
} }
...@@ -17,6 +18,10 @@ export default class Factory { ...@@ -17,6 +18,10 @@ export default class Factory {
} }
} }
setIsFrameBufferSupportFloat(res = true) {
this.isFrameBufferSupportFloat = res;
}
buildShader(opName, data, runtime = undefined) { buildShader(opName, data, runtime = undefined) {
let result = ''; let result = '';
result = this.buildPrefix(opName); result = this.buildPrefix(opName);
...@@ -30,7 +35,7 @@ export default class Factory { ...@@ -30,7 +35,7 @@ export default class Factory {
buildPrefix(opName) { buildPrefix(opName) {
if (this.webglVersion === 1) { if (this.webglVersion === 1) {
return ops.common.prefix; return this.isFrameBufferSupportFloat ? ops.common.prefix : ops.common.prefixHalf;
} }
return ops.common.prefix2; return ops.common.prefix2;
} }
......
...@@ -3,6 +3,7 @@ import common_params from '../../shader/atom/common_params'; ...@@ -3,6 +3,7 @@ import common_params from '../../shader/atom/common_params';
import common_func from '../../shader/atom/common_func'; import common_func from '../../shader/atom/common_func';
import prefix from '../../shader/atom/prefix'; import prefix from '../../shader/atom/prefix';
import prefix2 from '../../shader/atom/prefix2'; import prefix2 from '../../shader/atom/prefix2';
import prefixHalf from '../../shader/atom/prefix_half';
import suffix from '../../shader/atom/suffix'; import suffix from '../../shader/atom/suffix';
import ivec56 from '../../shader/atom/type_ivec56'; import ivec56 from '../../shader/atom/type_ivec56';
...@@ -61,6 +62,10 @@ import concat_params from '../../shader/concat/params'; ...@@ -61,6 +62,10 @@ import concat_params from '../../shader/concat/params';
import concat_func from '../../shader/concat/main'; import concat_func from '../../shader/concat/main';
import concat_conf from '../../shader/concat/conf'; import concat_conf from '../../shader/concat/conf';
import concat_mul_params from '../../shader/concat_mul/params';
import concat_mul_func from '../../shader/concat_mul/main';
import concat_mul_conf from '../../shader/concat_mul/conf';
import split_params from '../../shader/split/params'; import split_params from '../../shader/split/params';
import split_func from '../../shader/split/main'; import split_func from '../../shader/split/main';
import split_conf from '../../shader/split/conf'; import split_conf from '../../shader/split/conf';
...@@ -91,6 +96,7 @@ export default { ...@@ -91,6 +96,7 @@ export default {
params: common_params, params: common_params,
func: common_func, func: common_func,
prefix, prefix,
prefixHalf,
prefix2, prefix2,
suffix, suffix,
ivec56 ivec56
...@@ -156,6 +162,12 @@ export default { ...@@ -156,6 +162,12 @@ export default {
func: concat_func, func: concat_func,
confs: concat_conf confs: concat_conf
}, },
concat_mul: {
params: concat_mul_params,
func: concat_mul_func,
confs: concat_mul_conf
},
split: { split: {
params: split_params, params: split_params,
func: split_func, func: split_func,
......
...@@ -81,23 +81,29 @@ export default class imageFeed { ...@@ -81,23 +81,29 @@ export default class imageFeed {
/** /**
* 全部转rgb * H * W * 全部转rgb * H * W
* @param shape * @param imageData 数据
* @param opt 参数
* @param opt.mean 均值
* @param opt.std 方差
* @param opt.targetShape 输出shape
* @param opt.normalizeType 0:将数据映射为0~1, 1:映射为-1~1之间
*/ */
allReshapeToRGB(imageData, opt, scaleSize) { allReshapeToRGB(imageData, opt) {
//const {sw, sh} = scaleSize;
const [b, c, h, w] = opt.targetShape;
let data = imageData.data || imageData;
// mean和std是介于0-1之间的 // mean和std是介于0-1之间的
let mean = opt.mean; let {mean, std, normalizeType = 0, targetShape} = opt;
let std = opt.std; const [b, c, h, w] = targetShape;
let dataLength = data.length; let data = imageData.data || imageData;
// let result = new Float32Array(dataLength * 3);
let result = this.result; let result = this.result;
// let offsetR = 0;
// let offsetG = dataLength / 4;
// let offsetB = dataLength / 2;
let offset = 0; let offset = 0;
let size = h * w;
if (!result) {
const [b, c, h, w] = targetShape;
// 计算确定targetShape所需Float32Array占用空间
result = new Float32Array(h * w * c);
}
// h w c // h w c
for (let i = 0; i < h; ++i) { for (let i = 0; i < h; ++i) {
let iw = i * w; let iw = i * w;
...@@ -105,15 +111,14 @@ export default class imageFeed { ...@@ -105,15 +111,14 @@ export default class imageFeed {
let iwj = iw + j; let iwj = iw + j;
for (let k = 0; k < c; ++k) { for (let k = 0; k < c; ++k) {
let a = iwj * 4 + k; let a = iwj * 4 + k;
result[offset] = data[a] / 255; result[offset] = normalizeType === 0 ? data[a] / 255 : (data[a] - 128 ) / 128;
result[offset] -= mean[k]; result[offset] -= mean[k];
result[offset] /= std[k]; result[offset] /= std[k];
//result[offset] = 0.5;
offset++; offset++;
} }
} }
} }
return result; return result;
}; };
...@@ -316,8 +321,8 @@ export default class imageFeed { ...@@ -316,8 +321,8 @@ export default class imageFeed {
let data2; let data2;
let scaleSize; let scaleSize;
if (pixels instanceof HTMLImageElement || pixels instanceof HTMLVideoElement) { if (pixels instanceof HTMLImageElement || pixels instanceof HTMLVideoElement) {
this.pixelWidth = pixels.naturalWidth || pixels.width; this.pixelWidth = pixels.naturalWidth || pixels.videoWidth || pixels.width;
this.pixelHeight = pixels.naturalHeight || pixels.height; this.pixelHeight = pixels.naturalHeight || pixels.videoWidth || pixels.height;
if (opt.scale && opt.targetSize){ // Moblienet的情况 if (opt.scale && opt.targetSize){ // Moblienet的情况
data = this.resizeAndFitTargetSize(pixels, opt); data = this.resizeAndFitTargetSize(pixels, opt);
data2 = this.fromPixels2DContext2.getImageData(0, 0, this.pixelWidth, this.pixelHeight); data2 = this.fromPixels2DContext2.getImageData(0, 0, this.pixelWidth, this.pixelHeight);
......
...@@ -16,40 +16,59 @@ const CONF = { ...@@ -16,40 +16,59 @@ const CONF = {
}; };
const MAX_WAIT = 100; const MAX_WAIT = 100;
export default class gpu { export default class gpu {
constructor(opts = {}) { constructor(opts = {}) {
// 版本, 默认webgl version 2.0
this.version = 2; this.version = 2; // 版本, 默认webgl version 2.0
this.opts = opts; this.opts = opts;
this.frameBufferSupportFloat = true; // 默认frame buffer支持 float精度
opts.width_raw_canvas = Number(opts.width_raw_canvas) || 512; opts.width_raw_canvas = Number(opts.width_raw_canvas) || 512;
opts.height_raw_canvas = Number(opts.height_raw_canvas) || 512; opts.height_raw_canvas = Number(opts.height_raw_canvas) || 512;
const canvas = opts.el ? opts.el : document.createElement('canvas'); let gl = null;
if (!this.opts.gl) {
canvas.addEventListener('webglcontextlost', evt => { const canvas = opts.el ? opts.el : document.createElement('canvas');
evt.preventDefault();
console.log('webgl context is lost~'); canvas.addEventListener('webglcontextlost', evt => {
}, false); evt.preventDefault();
let gl = canvas.getContext('webgl2', CONF); console.log('webgl context is lost~');
if (!!gl) { }, false);
// 开启float32 gl = canvas.getContext('webgl2', CONF);
this.version = 2; if (!!gl) {
this.textureFloat = gl.getExtension('EXT_color_buffer_float'); // 开启float32
this.internalFormat = gl.R32F; this.version = 2;
this.textureFormat = gl.RED; this.textureFloat = gl.getExtension('EXT_color_buffer_float');
this.downloadInternalFormat = gl.RGBA32F; this.internalFormat = gl.R16F;
} else { this.textureFormat = gl.RED;
gl = canvas.getContext('webgl', CONF) || canvas.getContext('experimental-webgl', CONF); this.downloadInternalFormat = gl.RGBA16F;
} else {
gl = canvas.getContext('webgl', CONF) || canvas.getContext('experimental-webgl', CONF);
this.version = 1;
this.internalFormat = gl.RGBA;
this.textureFormat = gl.RGBA;
this.downloadInternalFormat = gl.RGBA;
if (!gl) {
this.version = 0;
alert('当前环境创建webgl context失败');
} else {
// 开启扩展
this.textureFloat = gl.getExtension('OES_texture_float');
this.textureHalfFloat = gl.getExtension('OES_texture_half_float');
// 帧缓冲区是否支持float精度(IOS 不支持float精度,只支持half_float)
this.frameBufferSupportFloat = this.isDownloadFloatTextureEnabled(gl);
}
}
}
else {
gl = this.opts.gl;
this.version = 1; this.version = 1;
this.internalFormat = gl.RGBA; this.internalFormat = gl.RGBA;
this.textureFormat = gl.RGBA; this.textureFormat = gl.RGBA;
this.downloadInternalFormat = gl.RGBA; this.downloadInternalFormat = gl.RGBA;
if (!gl) { this.textureFloat = gl.getExtension('OES_texture_float');
this.version = 0; this.textureHalfFloat = gl.getExtension('OES_texture_half_float');
alert('当前环境创建webgl context失败'); // 帧缓冲区是否支持float精度(IOS 不支持float精度,只支持half_float)
} else { this.frameBufferSupportFloat = this.isDownloadFloatTextureEnabled(gl);
// 开启扩展
this.textureFloat = gl.getExtension('OES_texture_float');
console.log('float extension is started or not? ' + !!this.textureFloat);
}
} }
this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
...@@ -70,9 +89,9 @@ export default class gpu { ...@@ -70,9 +89,9 @@ export default class gpu {
// 同步查看次数 // 同步查看次数
this.waits = 0; this.waits = 0;
console.log('WebGl版本是 ' + this.version); // console.log('WebGl版本是 ' + this.version);
console.log('MAX_TEXTURE_SIZE is ' + this.maxTextureSize); // console.log('MAX_TEXTURE_SIZE is ' + this.maxTextureSize);
console.log('MAX_TEXTURE_IMAGE_UNITS is ' + this.maxTextureImageUnits); // console.log('MAX_TEXTURE_IMAGE_UNITS is ' + this.maxTextureImageUnits);
} }
getWebglVersion() { getWebglVersion() {
...@@ -87,6 +106,10 @@ export default class gpu { ...@@ -87,6 +106,10 @@ export default class gpu {
return this.maxTextureImageUnits; return this.maxTextureImageUnits;
} }
getIsFrameBufferSupportFloat() {
return this.frameBufferSupportFloat;
}
initCache() { initCache() {
// 运行次数 // 运行次数
this.times = 0; this.times = 0;
...@@ -144,12 +167,41 @@ export default class gpu { ...@@ -144,12 +167,41 @@ export default class gpu {
return (this.textureFloat !== null); return (this.textureFloat !== null);
} }
// 判断当前frameBuffer能否支持 float texture
isDownloadFloatTextureEnabled(gl) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var width = 1;
var height = 1;
gl.texImage2D(
gl.TEXTURE_2D,
0,
this.downloadInternalFormat,
width,
height,
0,
gl.RGBA,
gl.FLOAT,
null
);
const frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
const isFrameBufferComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteTexture(texture);
gl.deleteFramebuffer(frameBuffer);
return isFrameBufferComplete;
}
createProgram(fshader, out) { createProgram(fshader, out) {
const gl = this.gl; const gl = this.gl;
const program = gl.createProgram(); const program = gl.createProgram();
gl.attachShader(program, this.vertexShader); gl.attachShader(program, this.vertexShader);
gl.attachShader(program, fshader); gl.attachShader(program, fshader);
gl.linkProgram(program); gl.linkProgram(program);
// 生成output的texture缓存 // 生成output的texture缓存
const texture = gl.createTexture(); const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture); gl.bindTexture(gl.TEXTURE_2D, texture);
...@@ -164,7 +216,9 @@ export default class gpu { ...@@ -164,7 +216,9 @@ export default class gpu {
out.height_texture, out.height_texture,
0, // Always 0 in OpenGL ES. 0, // Always 0 in OpenGL ES.
gl.RGBA, // Format for each pixel. gl.RGBA, // Format for each pixel.
gl.FLOAT, // Data type for each chanel. this.frameBufferSupportFloat
? gl.FLOAT
: this.textureHalfFloat.HALF_FLOAT_OES, // Data type for each chanel.
null); null);
gl.bindTexture(gl.TEXTURE_2D, null); gl.bindTexture(gl.TEXTURE_2D, null);
this.texturesMap[out.tensorId] = texture; this.texturesMap[out.tensorId] = texture;
...@@ -311,7 +365,6 @@ export default class gpu { ...@@ -311,7 +365,6 @@ export default class gpu {
let value; let value;
status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
switch (status) switch (status)
{ {
case gl.FRAMEBUFFER_COMPLETE: case gl.FRAMEBUFFER_COMPLETE:
...@@ -411,7 +464,6 @@ export default class gpu { ...@@ -411,7 +464,6 @@ export default class gpu {
return this.uniformLocations['' + ilayer][name]; return this.uniformLocations['' + ilayer][name];
} }
let loc = this.gl.getUniformLocation(this.program, name); let loc = this.gl.getUniformLocation(this.program, name);
if (loc === null) throw `getUniformLoc ${name} err`;
// 缓存 // 缓存
this.uniformLocations['' + ilayer] = this.uniformLocations['' + ilayer] || {}; this.uniformLocations['' + ilayer] = this.uniformLocations['' + ilayer] || {};
this.uniformLocations['' + ilayer][name] = loc; this.uniformLocations['' + ilayer][name] = loc;
...@@ -448,8 +500,12 @@ export default class gpu { ...@@ -448,8 +500,12 @@ export default class gpu {
let textureIndex = 0; let textureIndex = 0;
data.forEach(item => { data.forEach(item => {
if (item.type === 'texture') { if (item.type === 'texture') {
const loc = that.getUniformLoc(item.variable + '_' + item.tensor, iLayer, isRendered);
if (!loc) {
return;
}
that.initTexture(textureIndex, item, iLayer, isRendered); that.initTexture(textureIndex, item, iLayer, isRendered);
gl.uniform1i(that.getUniformLoc(item.variable + '_' + item.tensor, iLayer, isRendered), textureIndex++); gl.uniform1i(loc, textureIndex++);
} }
else if (item.type === 'uniform') { else if (item.type === 'uniform') {
gl[item.setter](that.getUniformLoc(item.variable + '_' + item.tensor, iLayer, isRendered), item.data); gl[item.setter](that.getUniformLoc(item.variable + '_' + item.tensor, iLayer, isRendered), item.data);
...@@ -461,45 +517,45 @@ export default class gpu { ...@@ -461,45 +517,45 @@ export default class gpu {
} }
createPBO() { createPBO() {
if (this.version == 2){ if (this.version == 2) {
const gl2 = this.gl; const gl2 = this.gl;
const buffer = this.pbo; const buffer = this.pbo;
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer); gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer);
const sizeBytes = 4 * 4 * this.width_texture_out * this.height_texture_out; const sizeBytes = 4 * 4 * this.width_texture_out * this.height_texture_out;
gl2.bufferData(gl2.PIXEL_PACK_BUFFER, sizeBytes, gl2.STREAM_READ); gl2.bufferData(gl2.PIXEL_PACK_BUFFER, sizeBytes, gl2.STREAM_READ);
gl2.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl2.RGBA, gl2.FLOAT, 0); gl2.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl2.RGBA, gl2.FLOAT, 0);
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null); gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null);
return buffer; return buffer;
} }
else { else {
let buffer = new Float32Array(this.width_texture_out * this.height_texture_out * 4); let buffer = new Float32Array(this.width_texture_out * this.height_texture_out * 4);
const gl2 = this.gl; const gl2 = this.gl;
gl2.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl2.RGBA, gl2.FLOAT, buffer); gl2.readPixels(0, 0, this.width_texture_out, this.height_texture_out, gl2.RGBA, gl2.FLOAT, buffer);
return buffer; return buffer;
} }
} }
downloadFoat32TensorFromBuffer(buffer) { downloadFoat32TensorFromBuffer(buffer) {
const gl2 = this.gl; const gl2 = this.gl;
const size = 4 * this.width_texture_out * this.height_texture_out; const size = 4 * this.width_texture_out * this.height_texture_out;
if (this.version == 2){ if (this.version == 2) {
const pixels = new Float32Array(size); const pixels = new Float32Array(size);
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer); gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer);
gl2.getBufferSubData(gl2.PIXEL_PACK_BUFFER, 0, pixels); gl2.getBufferSubData(gl2.PIXEL_PACK_BUFFER, 0, pixels);
gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null); gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null);
let result = []; let result = [];
for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) { for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) {
result.push(pixels[4 * i]); result.push(pixels[4 * i]);
} }
return result; return result;
} }
else { else {
let pixels = buffer; let pixels = buffer;
let result = []; let result = [];
for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) { for (let i = 0; i < this.width_texture_out * this.height_texture_out; i++) {
result.push(pixels[4 * i]); result.push(pixels[4 * i]);
} }
return result; return result;
} }
} }
......
...@@ -31,6 +31,7 @@ export default class Graph { ...@@ -31,6 +31,7 @@ export default class Graph {
this.isExecuted = false; this.isExecuted = false;
// 网络层数 // 网络层数
this.iLayer = 0; this.iLayer = 0;
this.queryList = [];
if (this.options && this.options.options ) { if (this.options && this.options.options ) {
if (this.options.options.test === true) { if (this.options.options.test === true) {
...@@ -44,8 +45,10 @@ export default class Graph { ...@@ -44,8 +45,10 @@ export default class Graph {
if (!this.inst) { if (!this.inst) {
// op runner // op runner
this.inst = Runtime.init(); this.inst = new Runtime(this.options.options);
factory.setWebglVersion(this.inst.getWebglVersion()); factory.setWebglVersion(this.inst.getWebglVersion());
factory.setIsFrameBufferSupportFloat(this.inst.getIsFrameBufferSupportFloat());
Utils.setTextureMaxSize(this.inst.getWebglMaxTextureSize());
} }
} }
...@@ -90,8 +93,16 @@ export default class Graph { ...@@ -90,8 +93,16 @@ export default class Graph {
if (executor.type === 'fetch') { if (executor.type === 'fetch') {
return; return;
} }
const gl = this.inst.gpu.gl;
let query = Utils.beginQuery(gl);
opindex++; opindex++;
executor.execute(this.inst, this.isExecuted); executor.execute(this.inst, this.isExecuted);
this.queryList.push({name: executor.type, query, count: 1});
query = Utils.endQuery(gl, query);
if (false && executor.opData && opindex >= 184){ if (false && executor.opData && opindex >= 184){
console.log('return!'); console.log('return!');
console.dir(executor); console.dir(executor);
...@@ -123,6 +134,7 @@ export default class Graph { ...@@ -123,6 +134,7 @@ export default class Graph {
if (this.isExecuted) { if (this.isExecuted) {
this.updateFeed(); this.updateFeed();
} }
this.queryList = [];
this.execute_(executor[0]); this.execute_(executor[0]);
this.isExecuted = true; this.isExecuted = true;
return this.inst; return this.inst;
...@@ -175,10 +187,21 @@ export default class Graph { ...@@ -175,10 +187,21 @@ export default class Graph {
that.feedOp = executor; that.feedOp = executor;
} }
else { else {
input[key] = that.getTensorAttr(input[key][0]); if (key === 'X' && input[key].length > 1) {
// 兼容key为X,value是个长度大于1的数组的情况,如concat
const [x, y, z] = input[key];
input['X'] = that.getTensorAttr(x);
y && (input['Y'] = that.getTensorAttr(y));
if (z) {
input['Z'] = that.getTensorAttr(z);
executor.type += '_mul';
}
}
else {
input[key] = that.getTensorAttr(input[key][0]);
}
} }
}); });
// console.log(input);
return { return {
inputs: input, inputs: input,
outputs: output, outputs: output,
......
...@@ -7,32 +7,26 @@ import Factory from '../factory/fshader/factory'; ...@@ -7,32 +7,26 @@ import Factory from '../factory/fshader/factory';
* @author wangqun@baidu.com, yangmingming@baidu.com * @author wangqun@baidu.com, yangmingming@baidu.com
* *
*/ */
export default { export default class Runtime {
/** constructor(opts = {}) {
* 初始化, 生成gpu实例 this.gpu = new Gpu(opts);
* @param {Object} opts 运行时参数,包含el:canvas,dim: 256 }
* @return {Object} this 实例对象
*/
init(opts = {}) {
const gpu = this.gpu = new Gpu(opts);
if (gpu.isFloatingTexture()) {
return this;
} else {
return null;
}
},
getWebglVersion() { getWebglVersion() {
return this.gpu.getWebglVersion(); return this.gpu.getWebglVersion();
}, }
getWebglMaxTextureSize() { getWebglMaxTextureSize() {
return this.gpu.maxTextureSize(); return this.gpu.getWebglMaxTextureSize();
}, }
getWebglMaxTextureImageUnits() { getWebglMaxTextureImageUnits() {
return this.gpu.maxTextureImageUnits(); return this.gpu.maxTextureImageUnits();
}, }
getIsFrameBufferSupportFloat() {
return this.gpu.getIsFrameBufferSupportFloat();
}
run(opName, opData, isRendered) { run(opName, opData, isRendered) {
// console.dir(['fscode', opData.fsCode]); // console.dir(['fscode', opData.fsCode]);
...@@ -52,7 +46,7 @@ export default { ...@@ -52,7 +46,7 @@ export default {
// 生成帧缓存材质 // 生成帧缓存材质
gpu.attachFrameBuffer(opData.iLayer, outTensorId); gpu.attachFrameBuffer(opData.iLayer, outTensorId);
// let end = +Date.now(); // let end = +Date.now();
let bufferStatus = gpu.frameBufferIsComplete(); // let bufferStatus = gpu.frameBufferIsComplete();
// if (bufferStatus.isComplete) { // if (bufferStatus.isComplete) {
// start = +Date.now(); // start = +Date.now();
// timeObj['buferstatus-time'] = start - end; // timeObj['buferstatus-time'] = start - end;
...@@ -70,7 +64,7 @@ export default { ...@@ -70,7 +64,7 @@ export default {
// } // }
}); });
}, }
/** /**
* 读取op计算结果, 并返回数据 * 读取op计算结果, 并返回数据
...@@ -82,7 +76,7 @@ export default { ...@@ -82,7 +76,7 @@ export default {
return this.gpu.compute(); return this.gpu.compute();
} }
return null; return null;
}, }
async read() { async read() {
const pbo = this.gpu.createPBO(); const pbo = this.gpu.createPBO();
...@@ -94,7 +88,7 @@ export default { ...@@ -94,7 +88,7 @@ export default {
// 开始读数据 // 开始读数据
// window.log.end('执行时间'); // window.log.end('执行时间');
return this.gpu.downloadFoat32TensorFromBuffer(pbo); return this.gpu.downloadFoat32TensorFromBuffer(pbo);
}, }
createProgram(fsCode, outTensor) { createProgram(fsCode, outTensor) {
const fshader = this.gpu.initShader(fsCode, 'fragment'); const fshader = this.gpu.initShader(fsCode, 'fragment');
...@@ -104,7 +98,7 @@ export default { ...@@ -104,7 +98,7 @@ export default {
// alert(maxUniforms.maxFragmentShader); // alert(maxUniforms.maxFragmentShader);
// console.table(maxUniforms.uniforms); // console.table(maxUniforms.uniforms);
return program; return program;
}, }
// 释放资源 // 释放资源
dispose() { dispose() {
......
...@@ -7,6 +7,7 @@ export default ` ...@@ -7,6 +7,7 @@ export default `
// dynamic的input数据 // dynamic的input数据
const float multi_value = float(MULTI_VALUE); const float multi_value = float(MULTI_VALUE);
const float bias_value = float(BIAS_VALUE); const float bias_value = float(BIAS_VALUE);
const bool fuse_relu = bool(FUSE_RELU);
// 输出数据 // 输出数据
const int width_shape_out = WIDTH_SHAPE_OUT; const int width_shape_out = WIDTH_SHAPE_OUT;
......
/* eslint-disable */
/**
* @file 预设条件
* @author yangmingming
*/
export default `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
precision highp int;
#else
precision highp float;
precision highp int;
#endif
#define isnan(value) isnan_custom(value)
bool isnan_custom(float val) {
return (val > 0. || val < 1. || val == 0.) ? false : true;
}
varying vec2 vCoord;
varying vec4 outColor;
void setOutput(float result) {
if(isnan(result)) {
gl_FragColor.r = 0.0;
}else {
gl_FragColor.r = result;
}
}
`;
...@@ -11,10 +11,10 @@ void main(void) { ...@@ -11,10 +11,10 @@ void main(void) {
float o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a); float o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
// 归一化数据 // 归一化数据
vec4 scale = getPixelsFromTexturePos_texture_scale(vec2((float(oPos.g) + 0.5) / float(width_texture_scale), 0.0)); vec4 scale = getPixelsFromTexturePos_texture_scale(vec2( float(oPos.g) / float(width_texture_scale) + 0.00001, 0.0));
vec4 bias = getPixelsFromTexturePos_texture_bias(vec2((float(oPos.g) + 0.5) / float(width_texture_bias), 0.0)); vec4 bias = getPixelsFromTexturePos_texture_bias(vec2( float(oPos.g) / float(width_texture_bias) + 0.00001, 0.0));
vec4 mean = getPixelsFromTexturePos_texture_mean(vec2((float(oPos.g) + 0.5) / float(width_texture_mean), 0.0)); vec4 mean = getPixelsFromTexturePos_texture_mean(vec2((float(oPos.g)) / float(width_texture_mean) + 0.00001, 0.0));
vec4 variance = getPixelsFromTexturePos_texture_variance(vec2((float(oPos.g) + 0.5) / float(width_texture_variance), 0.0)); vec4 variance = getPixelsFromTexturePos_texture_variance(vec2((float(oPos.g)) / float(width_texture_variance) + 0.00001, 0.0));
float x = (o - mean[0]) / sqrt(variance[0] + epsilon); float x = (o - mean[0]) / sqrt(variance[0] + epsilon);
float res = scale[0] * x + bias[0]; float res = scale[0] * x + bias[0];
......
...@@ -7,11 +7,11 @@ export default ` ...@@ -7,11 +7,11 @@ export default `
// start函数 // start函数
void main(void) { void main(void) {
// 输出数据 // 输出数据
ivec4 oPos = getOutputTensorPos(); ivec4 oPos = getOutputTensorPosLIMIT_OUT();
// 输出坐标转换为输入坐标 // 输出坐标转换为输入坐标
//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; //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); //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 o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
float scale_x = float(width_shape_out - 1) / float(width_shape_origin - 1); 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 scale_y = float(height_shape_out - 1) / float(height_shape_origin - 1);
float x = float(oPos.a) / scale_x; float x = float(oPos.a) / scale_x;
...@@ -22,10 +22,10 @@ void main(void) { ...@@ -22,10 +22,10 @@ void main(void) {
int y2 = int(ceil(y)); int y2 = int(ceil(y));
float dist_x = x - float(x1); float dist_x = x - float(x1);
float dist_y = y - float(y1); float dist_y = y - float(y1);
float value11 = getValueFromTensorPos_origin(oPos.r, oPos.g, y1, x1); float value11 = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, y1, x1);
float value12 = getValueFromTensorPos_origin(oPos.r, oPos.g, y2, x1); float value12 = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, y2, x1);
float value21 = getValueFromTensorPos_origin(oPos.r, oPos.g, y1, x2); float value21 = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, y1, x2);
float value22 = getValueFromTensorPos_origin(oPos.r, oPos.g, y2, x2); float value22 = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, y2, x2);
float value = (1.0 - dist_x) * (1.0 - dist_y) * value11 + 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 + (1.0 - dist_x) * dist_y * value12 + dist_x * (1.0 - dist_y) * value21 +
dist_x * dist_y * value22; dist_x * dist_y * value22;
......
...@@ -6,17 +6,17 @@ ...@@ -6,17 +6,17 @@
export default ` export default `
// start函数 // start函数
void main(void) { void main(void) {
ivec4 oPos = getOutputTensorPos(); ivec4 oPos = getOutputTensorPosLIMIT_OUT();
// 输出坐标转换为输入坐标 // 输出坐标转换为输入坐标
// 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; // 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); // ivec4 new_oPos = transferFromNHWCtoNCHW(sumVal, channel_out, width_shape_out, height_shape_out, total_shape_out);
float o = 0.0; float o = 0.0;
if (oPos[dim] > inputs_dim - 1) { if (oPos[dim] > inputs_dim - 1) {
oPos[dim] = oPos[dim] - inputs_dim; oPos[dim] = oPos[dim] - inputs_dim;
o = getValueFromTensorPos_counter(oPos.r, oPos.g, oPos.b, oPos.a); o = getValueFromTensorPosLIMIT_COUNTER_counter(oPos.r, oPos.g, oPos.b, oPos.a);
} }
else { else {
o = getValueFromTensorPos_origin(oPos.r, oPos.g, oPos.b, oPos.a); o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
} }
setOutput(float(o)); setOutput(float(o));
} }
......
/* eslint-disable */
/**
* @file concat的配置文件
* @author zhangjingyuan02
*/
export default {
dep: [
{
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'origin'
}
},
{
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'counter'
}
},
{
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'appender'
}
},
{
func: 'transferFromNHWCtoNCHW'
}
],
conf: [
'LENGTH_SHAPE_COUNTER',
'WIDTH_SHAPE_COUNTER',
'HEIGHT_SHAPE_COUNTER',
'WIDTH_TEXTURE_COUNTER',
'HEIGHT_TEXTURE_COUNTER',
'CHANNEL_COUNTER',
'LENGTH_SHAPE_APPENDER',
'WIDTH_SHAPE_APPENDER',
'HEIGHT_SHAPE_APPENDER',
'WIDTH_TEXTURE_APPENDER',
'HEIGHT_TEXTURE_APPENDER',
'CHANNEL_APPENDER',
'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'
],
input: [
{
tensor: 'origin',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
},
{
tensor: 'counter',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
},
{
tensor: 'appender',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
}
]
};
/* eslint-disable */
/**
* @file concat主函数
* @author zhangjingyuan02
*/
export default `
// start函数
void main(void) {
ivec4 oPos = getOutputTensorPosLIMIT_OUT();
// 输出坐标转换为输入坐标
float o = 0.0;
int dim_total = inputs_dim + append_num;
if (oPos[dim] < inputs_dim - 1) {
o = getValueFromTensorPosLIMIT_ORIGIN_origin(oPos.r, oPos.g, oPos.b, oPos.a);
}
else if (oPos[dim] < dim_total - 1) {
o = getValueFromTensorPosLIMIT_COUNTER_counter(oPos.r, oPos.g, oPos.b, oPos.a);
}
else {
o = getValueFromTensorPosLIMIT_APPENDER_appender(oPos.r, oPos.g, oPos.b, oPos.a);
}
setOutput(float(o));
}
`;
/* eslint-disable */
/**
* @file concat 参数文件
* @author zhangjingyuan02
*/
export default `
// mul的input数据
const int axis = AXIS;
// 常量
// 输入数据
const int length_shape_counter = LENGTH_SHAPE_COUNTER;
const int width_shape_counter = WIDTH_SHAPE_COUNTER;
const int height_shape_counter = HEIGHT_SHAPE_COUNTER;
const int width_texture_counter = WIDTH_TEXTURE_COUNTER;
const int height_texture_counter = HEIGHT_TEXTURE_COUNTER;
const int channel_counter = CHANNEL_COUNTER;
const int total_shape_counter = TOTAL_SHAPE_COUNTER;
const int length_shape_appender = LENGTH_SHAPE_APPENDER;
const int width_shape_appender = WIDTH_SHAPE_APPENDER;
const int height_shape_appender = HEIGHT_SHAPE_APPENDER;
const int width_texture_appender = WIDTH_TEXTURE_APPENDER;
const int height_texture_appender = HEIGHT_TEXTURE_APPENDER;
const int channel_appender = CHANNEL_APPENDER;
const int total_shape_appender = TOTAL_SHAPE_APPENDER;
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;
const int dim = DIM;
const int inputs_dim = INPUTS_DIM;
const int append_num = APPEND_NUM;
// uniform变量
// 输入数据
uniform sampler2D texture_counter;
uniform sampler2D texture_appender;
uniform sampler2D texture_origin;
`;
...@@ -16,6 +16,12 @@ export default { ...@@ -16,6 +16,12 @@ export default {
conf: { conf: {
TENSOR_NAME: 'filter' TENSOR_NAME: 'filter'
} }
},
{
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'bias'
}
}, },
{ {
func: 'transferFromNHWCtoNCHW', func: 'transferFromNHWCtoNCHW',
...@@ -32,6 +38,13 @@ export default { ...@@ -32,6 +38,13 @@ export default {
'HEIGHT_TEXTURE_FILTER', 'HEIGHT_TEXTURE_FILTER',
'CHANNEL_FILTER', 'CHANNEL_FILTER',
'WIDTH_SHAPE_BIAS',
'HEIGHT_SHAPE_BIAS',
'LENGTH_SHAPE_BIAS',
'WIDTH_TEXTURE_BIAS',
'HEIGHT_TEXTURE_BIAS',
'CHANNEL_BIAS',
'WIDTH_SHAPE_ORIGIN', 'WIDTH_SHAPE_ORIGIN',
'HEIGHT_SHAPE_ORIGIN', 'HEIGHT_SHAPE_ORIGIN',
'LENGTH_SHAPE_ORIGIN', 'LENGTH_SHAPE_ORIGIN',
...@@ -55,6 +68,7 @@ export default { ...@@ -55,6 +68,7 @@ export default {
'GROUPS', 'GROUPS',
'MULTI_VALUE', 'MULTI_VALUE',
'BIAS_VALUE', 'BIAS_VALUE',
'FUSE_RELU',
'ACTIVE_FUNCTION' 'ACTIVE_FUNCTION'
], ],
input: [ input: [
...@@ -75,7 +89,13 @@ export default { ...@@ -75,7 +89,13 @@ export default {
variable: 'texture', variable: 'texture',
setter: 'initTexture', setter: 'initTexture',
type: 'texture' type: 'texture'
} },
{
tensor: 'bias',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
},
// { // {
// tensor: 'origin', // tensor: 'origin',
// variable: 'numbers_shape', // variable: 'numbers_shape',
......
...@@ -10,7 +10,7 @@ export default ` ...@@ -10,7 +10,7 @@ export default `
int x = oPos.a; int x = oPos.a;
int c = oPos.g; int c = oPos.g;
int y = oPos.b; int y = oPos.b;
int b = oPos.r; int b = oPos.r;
float res = 0.0; float res = 0.0;
// 获取output的坐标 // 获取output的坐标
...@@ -43,6 +43,12 @@ export default ` ...@@ -43,6 +43,12 @@ export default `
} }
oy += dilation_v; oy += dilation_v;
} }
float bi = getValueFromTensorPosLIMIT_BIAS_bias(0, 0, 0, c);
res += bi;
if (fuse_relu) {
res = max(0.0, res);
}
setOutput(res); setOutput(res);
} }
`; `;
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
export default ` export default `
// conv2d的input数据 // conv2d的input数据
// 常量 // 常量
// 卷积核 // 卷积核
const int length_shape_filter = LENGTH_SHAPE_FILTER; const int length_shape_filter = LENGTH_SHAPE_FILTER;
...@@ -14,7 +14,7 @@ export default ` ...@@ -14,7 +14,7 @@ export default `
const int width_texture_filter = WIDTH_TEXTURE_FILTER; const int width_texture_filter = WIDTH_TEXTURE_FILTER;
const int height_texture_filter = HEIGHT_TEXTURE_FILTER; const int height_texture_filter = HEIGHT_TEXTURE_FILTER;
const int channel_filter = CHANNEL_FILTER; const int channel_filter = CHANNEL_FILTER;
// 输入数据 // 输入数据
const int width_shape_origin = WIDTH_SHAPE_ORIGIN; const int width_shape_origin = WIDTH_SHAPE_ORIGIN;
const int height_shape_origin = HEIGHT_SHAPE_ORIGIN; const int height_shape_origin = HEIGHT_SHAPE_ORIGIN;
...@@ -23,6 +23,14 @@ export default ` ...@@ -23,6 +23,14 @@ export default `
const int height_texture_origin = HEIGHT_TEXTURE_ORIGIN; const int height_texture_origin = HEIGHT_TEXTURE_ORIGIN;
const int channel_origin = CHANNEL_ORIGIN; const int channel_origin = CHANNEL_ORIGIN;
// bias
const int width_shape_bias = WIDTH_SHAPE_BIAS;
const int height_shape_bias = HEIGHT_SHAPE_BIAS;
const int length_shape_bias = LENGTH_SHAPE_BIAS;
const int width_texture_bias = WIDTH_TEXTURE_BIAS;
const int height_texture_bias = HEIGHT_TEXTURE_BIAS;
const int channel_bias = CHANNEL_BIAS;
// 计算相关 // 计算相关
// 拆分步长 // 拆分步长
const int stride_h = STRIDES_X; const int stride_h = STRIDES_X;
...@@ -35,11 +43,15 @@ export default ` ...@@ -35,11 +43,15 @@ export default `
const int dilation_v = DILATIONS_Y; const int dilation_v = DILATIONS_Y;
// groups // groups
const int groups = GROUPS; const int groups = GROUPS;
// uniform变量 // uniform变量
// 卷积核 // 卷积核
uniform sampler2D texture_filter; uniform sampler2D texture_filter;
// 输入数据 // 输入数据
uniform sampler2D texture_origin; uniform sampler2D texture_origin;
// bias
uniform sampler2D texture_bias;
`; `;
...@@ -17,7 +17,13 @@ export default { ...@@ -17,7 +17,13 @@ export default {
TENSOR_NAME: 'filter' TENSOR_NAME: 'filter'
} }
}, },
{ {
func: 'getValueFromTensorPos',
conf: {
TENSOR_NAME: 'bias'
}
},
{
func: 'transferFromNHWCtoNCHW', func: 'transferFromNHWCtoNCHW',
conf:{ conf:{
...@@ -32,6 +38,13 @@ export default { ...@@ -32,6 +38,13 @@ export default {
'HEIGHT_TEXTURE_FILTER', 'HEIGHT_TEXTURE_FILTER',
'CHANNEL_FILTER', 'CHANNEL_FILTER',
'WIDTH_SHAPE_BIAS',
'HEIGHT_SHAPE_BIAS',
'LENGTH_SHAPE_BIAS',
'WIDTH_TEXTURE_BIAS',
'HEIGHT_TEXTURE_BIAS',
'CHANNEL_BIAS',
'WIDTH_SHAPE_ORIGIN', 'WIDTH_SHAPE_ORIGIN',
'HEIGHT_SHAPE_ORIGIN', 'HEIGHT_SHAPE_ORIGIN',
'LENGTH_SHAPE_ORIGIN', 'LENGTH_SHAPE_ORIGIN',
...@@ -68,6 +81,12 @@ export default { ...@@ -68,6 +81,12 @@ export default {
variable: 'texture', variable: 'texture',
setter: 'initTexture', setter: 'initTexture',
type: 'texture' type: 'texture'
},
{
tensor: 'bias',
variable: 'texture',
setter: 'initTexture',
type: 'texture'
} }
] ]
}; };
...@@ -10,7 +10,7 @@ export default ` ...@@ -10,7 +10,7 @@ export default `
int x = oPos.a; int x = oPos.a;
int c = oPos.g; int c = oPos.g;
int y = oPos.b; int y = oPos.b;
int b = oPos.r; int b = oPos.r;
float res = 0.0; float res = 0.0;
int top = y * stride_v - padTop; int top = y * stride_v - padTop;
int left = x * stride_h - padLeft; int left = x * stride_h - padLeft;
...@@ -36,6 +36,11 @@ export default ` ...@@ -36,6 +36,11 @@ export default `
res += f * o; res += f * o;
} }
} }
float bi = getValueFromTensorPosLIMIT_BIAS_bias(0, 0, 0, c);
res += bi;
if (fuse_relu) {
res = max(0.0, res);
}
setOutput(res); setOutput(res);
} }
`; `;
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
export default ` export default `
// conv2d的input数据 // conv2d的input数据
// 常量 // 常量
// 卷积核 // 卷积核
const int length_shape_filter = LENGTH_SHAPE_FILTER; const int length_shape_filter = LENGTH_SHAPE_FILTER;
...@@ -14,7 +14,7 @@ export default ` ...@@ -14,7 +14,7 @@ export default `
const int width_texture_filter = WIDTH_TEXTURE_FILTER; const int width_texture_filter = WIDTH_TEXTURE_FILTER;
const int height_texture_filter = HEIGHT_TEXTURE_FILTER; const int height_texture_filter = HEIGHT_TEXTURE_FILTER;
const int channel_filter = CHANNEL_FILTER; const int channel_filter = CHANNEL_FILTER;
// 输入数据 // 输入数据
const int width_shape_origin = WIDTH_SHAPE_ORIGIN; const int width_shape_origin = WIDTH_SHAPE_ORIGIN;
const int height_shape_origin = HEIGHT_SHAPE_ORIGIN; const int height_shape_origin = HEIGHT_SHAPE_ORIGIN;
...@@ -22,7 +22,15 @@ export default ` ...@@ -22,7 +22,15 @@ export default `
const int width_texture_origin = WIDTH_TEXTURE_ORIGIN; const int width_texture_origin = WIDTH_TEXTURE_ORIGIN;
const int height_texture_origin = HEIGHT_TEXTURE_ORIGIN; const int height_texture_origin = HEIGHT_TEXTURE_ORIGIN;
const int channel_origin = CHANNEL_ORIGIN; const int channel_origin = CHANNEL_ORIGIN;
// bias
const int width_shape_bias = WIDTH_SHAPE_BIAS;
const int height_shape_bias = HEIGHT_SHAPE_BIAS;
const int length_shape_bias = LENGTH_SHAPE_BIAS;
const int width_texture_bias = WIDTH_TEXTURE_BIAS;
const int height_texture_bias = HEIGHT_TEXTURE_BIAS;
const int channel_bias = CHANNEL_BIAS;
// 计算相关 // 计算相关
// 拆分步长 // 拆分步长
const int stride_h = STRIDES_X; const int stride_h = STRIDES_X;
...@@ -33,11 +41,14 @@ export default ` ...@@ -33,11 +41,14 @@ export default `
// dilation膨胀系数 // dilation膨胀系数
const int dilation_h = DILATIONS_X; const int dilation_h = DILATIONS_X;
const int dilation_v = DILATIONS_Y; const int dilation_v = DILATIONS_Y;
// uniform变量 // uniform变量
// 卷积核 // 卷积核
uniform sampler2D texture_filter; uniform sampler2D texture_filter;
// 输入数据 // 输入数据
uniform sampler2D texture_origin; uniform sampler2D texture_origin;
// bias
uniform sampler2D texture_bias;
`; `;
...@@ -19,7 +19,7 @@ export default { ...@@ -19,7 +19,7 @@ export default {
'HEIGHT_TEXTURE_OUT', 'HEIGHT_TEXTURE_OUT',
'CHANNEL_OUT', 'CHANNEL_OUT',
'OFFSET_Y_OUT', 'OFFSET_Y_OUT',
'FUSE_RELU',
'MULTI_VALUE', 'MULTI_VALUE',
'BIAS_VALUE', 'BIAS_VALUE',
'ACTIVE_FUNCTION' 'ACTIVE_FUNCTION'
......
/* eslint-disable */
/**
* @file batchnorm的配置文件
* @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 reshape主函数
* @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;
ivec4 new_oPos = transferFromNHWCtoNCHW(sumVal, channel_origin, width_shape_origin, height_shape_origin, total_shape_origin);
float o = getValueFromTensorPos_origin(new_oPos.r, new_oPos.g, new_oPos.b, new_oPos.a);
setOutput(float(o));
}
`;
/* eslint-disable */
/**
* @file batchnorm参数文件
* @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;
// 输入数据
uniform sampler2D texture_origin;
`;
/* eslint-disable */
/**
* @file batchnorm的配置文件
* @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 reshape主函数
* @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;
ivec4 new_oPos = transferFromNHWCtoNCHW(sumVal, channel_out, width_shape_out, height_shape_out, total_shape_origin);
// 转置 坐标变换
oPos = new_oPos;
float o = 0.0;
if (perm_size == 1) {
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)]);
}
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)]);
}
else if (perm_size == 4) {
o = getValueFromTensorPos_origin(oPos[perm_0], oPos[perm_1], oPos[perm_2], oPos[perm_3]);
}
setOutput(float(o));
}
`;
/* eslint-disable */
/**
* @file batchnorm参数文件
* @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 perm_size = PERM_SIZE;
const int perm_0 = PERM_0;
const int perm_1 = PERM_1;
const int perm_2 = PERM_2;
const int perm_3 = PERM_3;
// 输入数据
uniform sampler2D texture_origin;
`;
...@@ -3,7 +3,10 @@ ...@@ -3,7 +3,10 @@
* @file 顶点文件 * @file 顶点文件
* @author yangmingming * @author yangmingming
*/ */
export default ` export default `
precision highp float;
precision highp int;
attribute vec4 position; attribute vec4 position;
varying vec2 vCoord; varying vec2 vCoord;
......
export default class Enviroment {
constructor() {
this.ENV = {};
}
static setEntry(name, entry) {
this.ENV[name] = entry;
}
static env() {
if (!this.ENV) {
this.ENV = new Enviroment();
}
return this.ENV;
}
}
\ No newline at end of file
/* eslint-disable */ /* eslint-disable */
import Utils from './utils'; import Utils from './utils';
import Tensor from './tensor'; import Tensor from './tensor';
/** /**
* @file op的数据对象 * @file op的数据对象
* @author yangmingming * @author yangmingming
...@@ -44,6 +45,7 @@ const tensorName = { ...@@ -44,6 +45,7 @@ const tensorName = {
'x': 'origin', 'x': 'origin',
'filter': 'filter', 'filter': 'filter',
'y': 'counter', 'y': 'counter',
'z': 'appender',
'output': 'out', 'output': 'out',
'out': 'out', 'out': 'out',
'scale': 'scale', 'scale': 'scale',
...@@ -55,10 +57,12 @@ const tensorName = { ...@@ -55,10 +57,12 @@ const tensorName = {
const opBehavior = { const opBehavior = {
conv2d: [ conv2d: [
'needBatch', 'needBatch',
'adaptPaddings',
'isApplySeparableConv' 'isApplySeparableConv'
], ],
conv2d_transpose: [ conv2d_transpose: [
'needBatch' 'needBatch',
// 'adaptPaddings'
], ],
batchnorm: [ batchnorm: [
'needBatch', 'needBatch',
...@@ -110,6 +114,12 @@ const opBehavior = { ...@@ -110,6 +114,12 @@ const opBehavior = {
'normalizeDim', 'normalizeDim',
'needBatch' 'needBatch'
], ],
concat_mul: [
'needBatch',
'processDim',
'normalizeDim',
'normalizeDim2',
],
split: [ split: [
'normalizeDim', 'normalizeDim',
'needBatch' 'needBatch'
...@@ -140,7 +150,8 @@ export default class OpData { ...@@ -140,7 +150,8 @@ export default class OpData {
this.data = { this.data = {
'active_function': 'scale', 'active_function': 'scale',
'multi_value': '1.0', 'multi_value': '1.0',
'bias_value': '0.0' 'bias_value': '0.0',
'fuse_relu': false
}; };
// tensor数据 // tensor数据
...@@ -152,9 +163,28 @@ export default class OpData { ...@@ -152,9 +163,28 @@ export default class OpData {
} }
} }
adaptPaddings() {
for (let key in this.attrs) {
if (this.attrs.hasOwnProperty(key) && key === 'paddings') {
const item = this.attrs[key];
const [x, y] = item;
if (x === 0 && y === 1) {
// 兼容paddings为[0, 1]的情况
this.attrs[key][1] = 0;
}
return;
}
}
}
inferShape(){ inferShape(){
if (this.name == 'reshape2'){ if (this.name == 'reshape2'){
let inputShape = this.input.X[0].shape; let inputShape = this.input.X[0].shape;
// 把shape变更为new_shape
if (this.attrs.shape) {
this.attrs.new_shape = this.attrs.shape;
delete this.attrs.shape;
}
let targetShape = this.attrs.new_shape; let targetShape = this.attrs.new_shape;
for (let i = 0; i < targetShape.length; i++){ for (let i = 0; i < targetShape.length; i++){
if (targetShape[i] == 0) { if (targetShape[i] == 0) {
...@@ -360,14 +390,33 @@ export default class OpData { ...@@ -360,14 +390,33 @@ export default class OpData {
isApplySeparableConv(tensorData = []) { isApplySeparableConv(tensorData = []) {
const groups = this.attrs.groups; const groups = this.attrs.groups;
let hasBias = false;
let outC;
const filter = tensorData.filter(item => { const filter = tensorData.filter(item => {
const [b, c, h, w] = item.shape; const {shape, tensorName} = item;
if (tensorName === 'bias') {
hasBias = true;
}
const [b, c, h, w] = shape;
if (!hasBias && !outC && tensorName === 'out') {
outC = c;
}
return (b === groups) && (c === 1) && (item.tensorName === 'filter'); return (b === groups) && (c === 1) && (item.tensorName === 'filter');
}); });
if (filter && filter.length) { if (filter && filter.length) {
// 可以执行separable conv // 可以执行separable conv
this.name += '_depthwise'; this.name += '_depthwise';
} }
!hasBias && tensorData.push({
name: "conv1_scale_offset",
needBatch: true,
persistable: true,
shape: [outC],
data: Array.from(new Float32Array(outC), i => 0),
tensorName: "bias"
});
} }
setPacked(tensorData = []) { setPacked(tensorData = []) {
...@@ -454,6 +503,29 @@ export default class OpData { ...@@ -454,6 +503,29 @@ export default class OpData {
this.attrs.inputs_dim = origin_shape[axis]; this.attrs.inputs_dim = origin_shape[axis];
this.attrs.dim = 4 - origin_shape.length + axis; this.attrs.dim = 4 - origin_shape.length + axis;
} }
normalizeDim2() {
let origin_shape_temp = this.input.Y[0].shape;
if (origin_shape_temp.length < 4) {
let batch = [];
for (let i = 0; i < (4 - origin_shape_temp.length); i++) {
batch.push(1);
}
origin_shape_temp = batch.concat(origin_shape_temp);
}
const origin_shape = origin_shape_temp;
const axis = this.attrs.axis > -1 ? this.attrs.axis : origin_shape.length + this.attrs.axis;
// 保存 输入 tensor 对应dim 的长度
this.attrs.append_num = origin_shape[axis];
}
processDim() {
const axis = this.attrs.axis;
if (axis !== -1) {
let shape = this.input.X[0].shape;
this.attrs.axis += 4 - shape.length;
}
}
processAxis() { processAxis() {
let shape_x = this.input.X[0].shape; let shape_x = this.input.X[0].shape;
......
...@@ -3,7 +3,35 @@ ...@@ -3,7 +3,35 @@
* @author yangmingming * @author yangmingming
*/ */
/* eslint-disable */ /* eslint-disable */
let GPU_TEXTURE_MAX_SIZE = null;
export default { export default {
setTextureMaxSize(size) {
GPU_TEXTURE_MAX_SIZE = size;
},
getQueryTime(gl, query) {
const timeElapsedNanos = gl.getQueryParameter(query, gl.QUERY_RESULT);
// Return milliseconds.
return timeElapsedNanos;
},
beginQuery(gl) {
const ext = gl.getExtension('EXT_disjoint_timer_query_webgl2');
if (!ext) {
return;
}
const query = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
return query;
},
endQuery(gl, query) {
const ext = gl.getExtension('EXT_disjoint_timer_query_webgl2');
if (!ext) {
return;
}
gl.endQuery(ext.TIME_ELAPSED_EXT);
return query;
},
// todo: 适用2维矩阵乘法,以后实现通用版本 // todo: 适用2维矩阵乘法,以后实现通用版本
getReshapeInPaddle(inputShape = [], counterShape = [], outShape = []) { getReshapeInPaddle(inputShape = [], counterShape = [], outShape = []) {
let total = inputShape.reduce((all, num) => all * num); let total = inputShape.reduce((all, num) => all * num);
...@@ -117,14 +145,14 @@ export default { ...@@ -117,14 +145,14 @@ export default {
let width = c * w; let width = c * w;
let offsetX = 0; let offsetX = 0;
let offsetY = 0; let offsetY = 0;
// 安卓和ios的max texture size是4096, 改造存储空间(2bh, cw / 2) // 安卓和ios的max texture size是4096, 改造存储空间(4bh, cw / 4)
let exceedMax = false; let exceedMax = false;
// trick TEXTURE_SIZE 超限问题,后续升级更优解 // trick TEXTURE_SIZE 超限问题,后续升级更优解
if (height > 4096 || width > 4096) { if (height > GPU_TEXTURE_MAX_SIZE || width > GPU_TEXTURE_MAX_SIZE) {
//console.error('大小超限', shape); console.error('大小超限', shape);
//height *= 4; height *= 4;
//width = c * (Math.ceil(w / 4)); width = c * (Math.ceil(w / 4));
//exceedMax = true; exceedMax = true;
} }
if (isPacked) { if (isPacked) {
// 紧凑布局 // 紧凑布局
...@@ -325,7 +353,7 @@ export default { ...@@ -325,7 +353,7 @@ export default {
const texture_height = shape_b * shape_h; const texture_height = shape_b * shape_h;
const texture_width = shape_c * shape_w; const texture_width = shape_c * shape_w;
if (texture_height <= 4096 && texture_width <= 4096) { if (texture_height <= GPU_TEXTURE_MAX_SIZE && texture_width <= GPU_TEXTURE_MAX_SIZE) {
return nchwData; return nchwData;
} }
let pos = 0; let pos = 0;
...@@ -345,6 +373,11 @@ export default { ...@@ -345,6 +373,11 @@ export default {
} }
return formatData; return formatData;
},
// 小数转百分比
toPercent(data) {
let str = Number(data * 100).toFixed(3);
return str += '%';
} }
}; };
/* eslint-enable */ /* eslint-enable */
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -127,5 +127,6 @@ ...@@ -127,5 +127,6 @@
2 2
] ]
} }
] ]
} }
因为 它太大了无法显示 source diff 。你可以改为 查看blob
{ {
"ops": [ "ops": [
{ {
"attrs": { "attrs": {
"axis": 1, "axis": 1,
"use_mkldnn": false, "use_mkldnn": false,
"x_data_format": "", "x_data_format": "",
"y_data_format": "" "y_data_format": ""
}, },
"inputs": { "inputs": {
"X": [ "X": [
"fc_0.tmp_0" "fc_0.tmp_0"
],
"Y": [
"fc7_offset"
]
},
"outputs": {
"Out": [
"fc_0.tmp_1"
]
},
"type": "elementwise_add"
}
],
"vars": [
{
"data": [
-1.1098297834396362,
6.280017375946045,
3.1823835372924805,
1.9810107946395874,
0.03745591640472412,
2.6181418895721436,
2.867142915725708,
2.11924409866333,
-0.6121698617935181,
-4.319775581359863, 11, 12
], ],
"Y": [ "name": "fc_0.tmp_0",
"fc7_offset" "shape": [
3, 2 ,2
] ]
}, },
"outputs": { {
"Out": [ "data": [
"fc_0.tmp_1" -0.003687990130856633,
0.008941259235143661,
-0.042509354650974274,
-0.07615242153406143,
0.0016824366757646203,
0.030000973492860794,
-0.05920300632715225,
0.007062121760100126,
0.010919729247689247,
-0.005986877251416445, 1, 1
],
"name": "fc7_offset",
"shape": [
3, 2 ,2
] ]
},
"type": "elementwise_add"
}
],
"vars": [
{
"data": [
0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 2, 0, 2, 0, 2, 0, 2, 0,
0, 2, 0, 2, 0, 2, 0, 2, 0,
0, 2, 0, 2, 0, 2, 0, 2, 0,
0, 2, 0, 2, 0, 2, 0, 2, 0
],
"name": "pixel",
"persistable": 0,
"shape": [
1,
8,
3,
3
]
},
{ },
"data": [ {
-1.1098297834396362, "data": [
6.280017375946045, -0.10982978343963623,
3.1823835372924805, 7.280017375946045,
1.9810107946395874, 4.1823835372924805,
0.03745591640472412, 2.981010913848877,
2.6181418895721436, 1.0374559164047241,
2.867142915725708, 3.6181418895721436,
2.11924409866333, 3.867142915725708,3.11924409866333, 0.38783013820648193,-3.3197755813598633,12,13
-0.6121698617935181, ],
-4.319775581359863, "name": "fc_0.tmp_1",
-5.5695600509643555, "shape": [
-3.0855345726013184, 3, 2 ,2
0.2046980857849121, ]
-2.9285874366760254, }
-4.034234046936035, ]
-0.3219590187072754, }
-3.8337182998657227,
-3.458463668823242,
-1.8676337003707886,
-2.8824174404144287,
-3.224912166595459,
2.8730430603027344,
1.17366361618042,
0.7122759819030762,
-2.003032922744751,
-0.08305394649505615,
1.0322399139404297,
-0.13402244448661804,
-1.4503525495529175,
0.9064493179321289,
1.312484860420227,
-0.5213003158569336,
2.973198890686035,
2.2515311241149902,
4.331067085266113,
0.39521080255508423,
-0.024464011192321777,
-2.817532777786255,
-1.181924819946289,
-1.9536917209625244,
-1.3022257089614868,
-3.0054824352264404,
1.0263299942016602,
2.1801626682281494,
-2.5572702884674072,
-1.9350857734680176,
-1.5212739706039429,
-3.0372211933135986,
-3.9655723571777344,
-3.16747784614563,
0.9443843960762024,
-2.5688347816467285,
-3.845409631729126,
-3.5706634521484375,
0.07929372787475586,
-1.7236900329589844,
-2.5290720462799072,
-2.59753155708313,
-1.938873529434204,
0.13098883628845215,
0.8310225009918213,
-4.163984775543213,
-2.2919321060180664,
-2.2529170513153076,
-0.32626527547836304,
-1.6464781761169434,
-0.8053542971611023,
-0.43675923347473145,
-1.8472626209259033,
-1.5393996238708496,
-1.3766282796859741,
-2.5448594093322754,
-1.8978112936019897,
2.9039812088012695,
1.774146318435669,
-0.513042688369751,
1.1454157829284668,
1.4261561632156372,
1.5273460149765015,
-0.7735292911529541,
1.6160634756088257,
0.7888234853744507,
1.1879230737686157,
-0.7824995517730713,
-4.992694854736328,
-1.5696773529052734,
-0.7463071346282959,
-2.967804431915283,
-1.9331011772155762,
-4.363243579864502,
-1.9011057615280151,
-3.65684175491333,
-4.679007530212402,
-2.854567527770996,
-0.7942641377449036,
-4.447449684143066,
-1.8494857549667358,
-0.6775758266448975,
-3.124417543411255,
-1.0919077396392822,
-1.204681634902954,
2.697819471359253,
-4.28972864151001,
-1.4630482196807861,
-1.6940839290618896,
-4.467775821685791,
1.658867359161377,
5.264161109924316,
-0.23039180040359497,
-2.0056653022766113,
2.4297993183135986,
3.8325250148773193,
6.236888408660889,
1.081353783607483,
0.9114763140678406,
3.819485902786255,
-0.8213856220245361,
2.6917107105255127,
3.1594784259796143,
3.2505340576171875,
-1.599015474319458,
5.865414619445801,
3.3848185539245605,
1.0470486879348755,
1.7181504964828491,
5.232596397399902,
2.4393012523651123,
-0.6650027632713318,
-2.698718547821045,
-3.7027933597564697,
-1.0648775100708008,
-4.57002592086792,
-1.3015716075897217,
-4.141479969024658,
-3.543605327606201,
0.11356914043426514,
-4.142419815063477,
-3.0896196365356445,
-5.248664379119873,
-1.0557355880737305,
-5.700218677520752,
-3.210575819015503,
-6.002849578857422,
-1.5150558948516846,
0.7668859958648682,
2.0850210189819336,
-1.9190276861190796,
7.063694953918457,
2.1589503288269043,
-2.5693466663360596,
-0.41036903858184814,
0.27354103326797485,
-4.041271686553955,
-1.8141188621520996,
-0.9877132773399353,
-1.400024175643921,
-2.7775607109069824,
-2.2304954528808594,
-3.7750062942504883,
-2.6431808471679688,
-1.1961359977722168,
-0.8919503688812256,
-2.6909024715423584,
-0.6629705429077148,
-1.7510700225830078,
-0.8857673406600952,
-3.2500250339508057,
-2.1082746982574463,
0.2042170763015747,
-2.210299253463745,
0.7864104509353638,
-2.9751083850860596,
-2.2737724781036377,
-0.68779057264328,
-0.9036482572555542,
-0.7623353600502014,
-3.5691213607788086,
-0.9564109444618225,
-1.3931095600128174,
-2.2496964931488037,
-3.593845844268799,
-2.067422866821289,
-0.5507739782333374,
2.6511547565460205,
3.190521717071533,
-0.4711952805519104,
-0.44052132964134216,
0.020955059677362442,
2.9489078521728516,
0.2345447540283203,
-1.57606041431427,
2.722463369369507,
-1.085034966468811,
-2.1278340816497803,
-4.472021102905273,
-0.15057799220085144,
1.023224949836731,
0.1553490161895752,
-0.8380561470985413,
2.7073187828063965,
-1.1645872592926025,
-1.3870041370391846,
-0.19245240092277527,
1.5917038917541504,
-1.8875302076339722,
-2.0529909133911133,
-2.716744899749756,
0.7809892892837524,
-2.2398364543914795,
-1.214713454246521,
-3.069598913192749,
0.19325768947601318,
2.2853477001190186,
3.8020496368408203,
0.9614565968513489,
0.25733819603919983,
-2.749157667160034,
0.5181249380111694,
-0.05282244086265564,
2.6641454696655273,
0.4792838394641876,
-0.8193203806877136,
-1.7853703498840332,
1.2008960247039795,
2.9270849227905273,
-3.4362072944641113,
-0.9281041622161865,
-2.711972713470459,
-0.30203473567962646,
-1.243424892425537,
0.21164435148239136,
0.25878894329071045,
-0.3724523186683655,
1.21412193775177,
-0.8826887607574463,
-0.25927621126174927,
-1.2882156372070312,
-0.7579304575920105,
-2.3151230812072754,
-1.9493675231933594,
1.0950922966003418,
-0.9096841812133789,
-0.6080835461616516,
-4.516273021697998,
-2.077496290206909,
-0.13329768180847168,
-2.554391860961914,
-0.882907509803772,
-1.4816160202026367,
-0.8138746023178101,
0.4209463894367218,
2.1191864013671875,
-0.5152456760406494,
-1.3701984882354736,
-1.842582106590271,
-3.198296070098877,
-0.5327607989311218,
-2.23941707611084,
2.802278518676758,
1.1445939540863037,
-0.10909640789031982,
-2.1707987785339355,
-0.6605309844017029,
-1.702032208442688,
-1.3742380142211914,
0.30779576301574707,
-1.527796745300293,
2.5908055305480957,
-5.370712757110596,
3.1592442989349365,
1.8471250534057617,
1.4450740814208984,
-0.29365819692611694,
2.8080296516418457,
0.7826064229011536,
2.24487566947937,
3.8284924030303955,
2.0590174198150635,
-3.0601096153259277,
-0.38943415880203247,
-0.9199885129928589,
-2.6166539192199707,
-3.7082812786102295,
1.6603496074676514,
-1.9530476331710815,
-2.1296348571777344,
1.4963228702545166,
-1.9633915424346924,
0.9424124956130981,
-2.3196699619293213,
-0.8016772270202637,
2.1566343307495117,
-4.999898910522461,
0.11684525012969971,
6.941814422607422,
2.546445608139038,
3.173893451690674,
0.08999282121658325,
-0.12652826309204102,
0.8835113048553467,
-6.410438060760498,
1.4145431518554688,
0.6318698525428772,
-1.1987061500549316,
-0.07767903804779053,
-4.531796455383301,
-0.8173074126243591,
-1.51220703125,
0.49932414293289185,
3.565516471862793,
2.5288636684417725,
-1.4967541694641113,
-1.2811284065246582,
2.1081948280334473,
-1.1358236074447632,
0.49249017238616943,
-2.2904512882232666,
-1.4134225845336914,
0.013357375748455524,
0.6631985902786255,
0.8505830764770508,
1.5555975437164307,
-2.922717332839966,
-0.4823005199432373,
-1.6811696290969849,
-2.7099595069885254,
-4.608072280883789,
6.704110622406006,
2.128044366836548,
4.943448066711426,
-2.8732614517211914,
0.35023045539855957,
-2.2871432304382324,
-0.41411900520324707,
-3.4737284183502197,
0.8822903633117676,
2.4548470973968506,
0.2483443021774292,
-3.75382137298584,
4.36890983581543,
-1.286186933517456,
-1.3454530239105225,
-2.3936538696289062,
-2.380206823348999,
-0.6745333671569824,
1.6055960655212402,
-4.198836803436279,
5.09708309173584,
-1.8996615409851074,
-2.6783154010772705,
2.8310494422912598,
-1.8546035289764404,
-3.533179759979248,
-5.79323148727417,
4.695282459259033,
0.7224174737930298,
-1.5337331295013428,
-2.323596715927124,
-2.1259078979492188,
-1.7988808155059814,
-0.7696970701217651,
-1.3165106773376465,
-3.482513904571533,
-1.9235535860061646,
-3.8766250610351562,
2.8696720600128174,
-1.4360194206237793,
-0.8234670758247375,
-5.143311500549316,
-4.450238227844238,
-3.2954797744750977,
-2.9979262351989746,
0.6171916723251343,
-0.00595325231552124,
0.6727069616317749,
-4.503152370452881,
-2.3362483978271484,
-0.9406384229660034,
-0.6121606826782227,
-2.160066843032837,
0.6046799421310425,
0.2239534854888916,
-1.9791312217712402,
-5.341414451599121,
-0.08803188800811768,
1.6064965724945068,
0.20806407928466797,
-0.8675591945648193,
-4.5164008140563965,
3.120645046234131,
1.309441089630127,
-1.250939130783081,
-0.5207388997077942,
-0.7241864800453186,
-0.25348925590515137,
0.2392439842224121,
0.544073224067688,
-0.37482893466949463,
-1.4554963111877441,
0.3761484622955322,
1.5785998106002808,
0.834793210029602,
1.4881293773651123,
0.8964934349060059,
1.2715522050857544,
3.930844783782959,
1.4107838869094849,
2.465442180633545,
-3.588897228240967,
3.716876745223999,
-0.22951894998550415,
-4.336287021636963,
-0.7980577349662781,
-1.0871174335479736,
-2.829066276550293,
-1.2431702613830566,
-2.1182312965393066,
5.274393558502197,
2.6847620010375977,
-0.17691034078598022,
2.0382988452911377,
4.685642719268799,
-1.648077368736267,
-6.088254451751709,
-2.4805350303649902,
5.693214416503906,
2.1471195220947266,
2.6805875301361084,
-1.257446527481079,
-1.9631949663162231,
-4.690670967102051,
-0.9372278451919556,
3.6071414947509766,
1.5920652151107788,
-0.5450392365455627,
1.9293763637542725,
-3.0089166164398193,
8.61243724822998,
0.8929249048233032,
1.8419400453567505,
2.788212776184082,
3.637413263320923,
5.870749473571777,
-5.372323036193848,
-0.24803829193115234,
0.10370641946792603,
-3.5142319202423096,
4.495314121246338,
2.1045520305633545,
2.0311503410339355,
-5.7489423751831055,
0.6904568076133728,
-0.2398514747619629,
-1.1769464015960693,
-2.284090995788574,
-0.25422826409339905,
-0.18415647745132446,
1.0443592071533203,
0.6887814402580261,
-0.009091198444366455,
4.3580169677734375,
-0.14628857374191284,
-2.0272841453552246,
0.4465930759906769,
1.2870067358016968,
-2.3178417682647705,
-1.5118120908737183,
-0.33232688903808594,
1.9783192873001099,
6.8699846267700195,
6.672363758087158,
5.466246604919434,
1.4994380474090576,
-5.813544273376465,
-1.6810972690582275,
5.7172627449035645,
4.691410064697266,
-6.627619743347168,
-4.731492042541504,
-3.009411334991455,
-0.7301946878433228,
-3.7846250534057617,
-4.3645524978637695,
3.143440008163452,
-1.224428653717041,
-1.9145143032073975,
-0.1480833888053894,
-2.4886786937713623,
5.607964515686035,
3.4411098957061768,
1.11717689037323,
1.888771653175354,
-0.7449076175689697,
-2.2770392894744873,
4.673813819885254,
-3.319258689880371,
1.4409315586090088,
4.926970958709717,
5.2587361335754395,
-1.0249165296554565,
-1.9151029586791992,
3.3469390869140625,
-5.655460834503174,
-0.9310908317565918,
1.889914870262146,
1.7415921688079834,
2.792124032974243,
-2.2904415130615234,
-0.35307103395462036,
-7.687912464141846,
3.3800578117370605,
-1.0004303455352783,
-0.538013756275177,
5.968576431274414,
-1.8725266456604004,
4.414268493652344,
-1.3398373126983643,
5.847112655639648,
-0.8823839426040649,
-3.061614513397217,
-4.172097682952881,
0.5199050903320312,
-2.83974552154541,
1.7894599437713623,
-0.3212776482105255,
1.9916589260101318,
-3.59755539894104,
-0.05543780326843262,
-4.00023889541626,
-4.610026836395264,
3.1512610912323,
0.3296220302581787,
-4.829360485076904,
-3.8058745861053467,
-2.9025802612304688,
-4.724573135375977,
2.7765512466430664,
-0.8614257574081421,
4.6350016593933105,
-3.192822217941284,
8.156087875366211,
2.1967530250549316,
1.4798681735992432,
-0.2139655351638794,
2.5098695755004883,
-0.9141243100166321,
0.8962705731391907,
-5.281251430511475,
-5.2019758224487305,
0.36304938793182373,
-2.2317490577697754,
-4.200922966003418,
3.646543264389038,
-1.4773303270339966,
5.693246364593506,
6.649788856506348,
9.594747543334961,
8.084684371948242,
4.109189033508301,
-1.1514382362365723,
-3.79378342628479,
-3.480154037475586,
10.20333480834961,
2.9916653633117676,
-4.7623443603515625,
-2.815553903579712,
3.1256189346313477,
-0.17683625221252441,
1.4069968461990356,
0.15567752718925476,
4.422062397003174,
-0.13792681694030762,
-0.13611863553524017,
-4.004006862640381,
-0.7330857515335083,
0.2794785499572754,
1.2011271715164185,
1.155246376991272,
4.6407623291015625,
-1.1888951063156128,
4.365846633911133,
-0.6002482771873474,
-3.0060014724731445,
0.6116334199905396,
-0.7408015131950378,
1.695010781288147,
0.935187578201294,
0.6442794799804688,
-3.2748143672943115,
-2.0293121337890625,
-5.253023624420166,
0.3686100244522095,
-4.746075630187988,
0.7276730537414551,
-0.5353613495826721,
1.609863042831421,
0.22987711429595947,
-3.051483631134033,
-2.196925163269043,
2.5409834384918213,
2.590078115463257,
2.8073747158050537,
-0.28132355213165283,
-3.6353588104248047,
3.98014235496521,
-2.2295749187469482,
-2.7915709018707275,
8.170427322387695,
-1.0024746656417847,
2.566547393798828,
0.06248068809509277,
-0.7986176013946533,
-4.506911754608154,
-2.927586555480957,
-0.12328934669494629,
-3.035170078277588,
4.570350646972656,
-0.9428645372390747,
0.2511644959449768,
7.779752731323242,
2.5547313690185547,
-3.305330276489258,
3.045858860015869,
-0.4476429522037506,
-2.0454654693603516,
-0.903998851776123,
4.6712188720703125,
0.27812618017196655,
5.7286057472229,
0.5027726888656616,
-3.1397976875305176,
-2.410263776779175,
0.7584738731384277,
-0.09872323274612427,
-1.150364875793457,
-1.4736695289611816,
-4.299774169921875,
0.017202258110046387,
2.481471061706543,
-0.31894949078559875,
-4.897672653198242,
0.9074056148529053,
0.812396764755249,
2.7788052558898926,
6.849625587463379,
5.36129093170166,
4.017366886138916,
-3.183743953704834,
-0.5459802150726318,
3.2476983070373535,
3.6680338382720947,
1.4542344808578491,
0.735497236251831,
-1.1498156785964966,
-2.0790834426879883,
0.16575568914413452,
-0.03247302770614624,
6.315743446350098,
0.924880862236023,
-2.996906280517578,
2.4611358642578125,
-3.311616897583008,
-3.387801170349121,
0.8263566493988037,
2.1338391304016113,
0.4939492642879486,
0.8877021074295044,
1.1741135120391846,
2.520150661468506,
0.24434268474578857,
-0.21956467628479004,
1.3664960861206055,
4.209738731384277,
-2.212778329849243,
-2.8679332733154297,
-3.226949691772461,
-1.7605046033859253,
2.150820016860962,
-0.9418412446975708,
0.37490323185920715,
0.8136546611785889,
-0.11969602108001709,
5.994228839874268,
4.868772029876709,
-0.013888329267501831,
-0.030041515827178955,
-4.1262617111206055,
-1.131576657295227,
-0.29804515838623047,
1.016602873802185,
-2.378706932067871,
-0.5206512212753296,
-2.7961068153381348,
2.4040234088897705,
2.989335060119629,
-0.5807543992996216,
-0.8712574243545532,
-2.622992515563965,
2.751124858856201,
2.263490676879883,
0.004918038845062256,
4.510312557220459,
0.1265907883644104,
2.1885972023010254,
1.1275163888931274,
-1.1744939088821411,
-1.9860807657241821,
-2.6154427528381348,
2.6831283569335938,
-5.057710647583008,
-2.955465793609619,
3.8433141708374023,
0.37156692147254944,
-0.9450574517250061,
0.5926560163497925,
1.3082735538482666,
7.855043411254883,
-1.4003933668136597,
6.306633472442627,
-0.4289991855621338,
-2.9058985710144043,
-2.930300235748291,
-3.4064619541168213,
-0.6290552616119385,
2.236776828765869,
-0.5510813593864441,
-5.766793727874756,
4.212404251098633,
1.1983050107955933,
-6.177562236785889,
-0.21780884265899658,
5.1457014083862305,
-3.8856449127197266,
5.100142478942871,
-1.179671049118042,
1.9967836141586304,
-1.6635756492614746,
2.04691743850708,
1.2857341766357422,
-0.9254895448684692,
-1.8866302967071533,
-2.21700119972229,
-2.081390142440796,
-0.5563896894454956,
5.322556018829346,
3.021404266357422,
-4.315042972564697,
-0.7041801810264587,
-5.1402740478515625,
0.4352649450302124,
-1.2055838108062744,
-0.915346622467041,
-4.0407562255859375,
-0.260110467672348,
-2.177421808242798,
8.112772941589355,
-0.8848628997802734,
1.0522022247314453,
0.43089449405670166,
0.016312897205352783,
0.11614853143692017,
-0.970054030418396,
2.685154914855957,
4.828297138214111,
3.130793571472168,
-3.9669342041015625,
6.695780277252197,
-1.3808481693267822,
-0.301638126373291,
-1.1256015300750732,
-1.3600900173187256,
-2.324624538421631,
2.2629315853118896,
0.5607572793960571,
-5.157692909240723,
3.9711337089538574,
6.691866874694824,
-2.4260101318359375,
-1.418802261352539,
0.4121089577674866,
4.471992492675781,
0.9565921425819397,
2.776496410369873,
2.192915916442871,
1.3897244930267334,
2.5141682624816895,
-0.05197015404701233,
0.06691209971904755,
-5.464636325836182,
-2.1806037425994873,
-6.835583686828613,
-2.281047821044922,
0.77875816822052,
-1.253766417503357,
0.9833312034606934,
3.8752336502075195,
4.124049663543701,
-0.8178051710128784,
-3.7768311500549316,
-2.536095380783081,
-5.925909042358398,
4.3578410148620605,
4.045070648193359,
1.4647364616394043,
-3.2888472080230713,
2.4718637466430664,
-2.6735756397247314,
2.3179798126220703,
0.4816662073135376,
-1.835519790649414,
-2.349308490753174,
1.4841803312301636,
8.026285171508789,
1.0783554315567017,
0.7481228113174438,
2.799593210220337,
-3.5019006729125977,
-0.878243088722229,
5.556700706481934,
5.841644287109375,
-0.8360974788665771,
4.000271797180176,
2.1913576126098633,
-2.534567356109619,
4.1587934494018555,
-1.4160758256912231,
2.1097140312194824,
4.607666969299316,
1.5096783638000488,
-1.2303180694580078,
-4.263491153717041,
-2.718886375427246,
5.722687721252441,
-0.5992395877838135,
2.4602646827697754,
0.32089829444885254,
3.0749223232269287,
2.154711961746216,
1.0471856594085693,
6.153417587280273,
-1.0595678091049194,
-0.8727691173553467,
1.8015199899673462,
0.8221091628074646,
-1.4698102474212646,
-0.8753116130828857,
3.660459518432617,
1.7487772703170776,
-4.510850429534912,
1.0301592350006104,
1.6128931045532227,
0.6620266437530518,
1.428957462310791,
-0.8467459678649902,
2.08194637298584,
-1.0377404689788818,
-0.8258668184280396,
-1.931388020515442,
0.07245266437530518,
3.392714738845825,
-2.9453344345092773,
-1.9955157041549683,
15.100059509277344,
-0.8732953071594238,
1.9544179439544678,
-3.4860191345214844,
2.509908676147461,
3.5911426544189453,
-2.4688429832458496,
0.247595876455307,
0.7223533391952515,
0.6755980253219604,
4.797938346862793,
2.8082027435302734,
-4.613275051116943,
5.547893524169922,
3.452322244644165,
-1.9822416305541992,
-3.2672886848449707,
2.8431692123413086,
3.9009008407592773,
-2.3796653747558594,
-3.2589194774627686,
1.6440908908843994,
2.7890090942382812,
0.004936039447784424,
-3.948458433151245,
-0.13766270875930786,
2.2167553901672363,
0.6457685232162476,
-3.3130836486816406,
-4.4620842933654785,
-1.9370622634887695,
-4.617079734802246,
-6.038240909576416,
1.54433012008667,
-0.09978294372558594,
-2.07271671295166,
3.6365294456481934,
1.2165300846099854,
6.736310005187988,
-0.18252074718475342,
3.483471632003784,
2.921428918838501,
5.8854570388793945,
0.9763119220733643,
-2.0435452461242676,
1.5152926445007324,
7.39365816116333,
3.9875752925872803,
0.22976088523864746,
0.17124438285827637,
3.20837140083313,
2.285531997680664,
-2.976733684539795,
2.699382781982422,
-0.7666529417037964,
0.43301108479499817,
0.16560816764831543,
3.5898046493530273,
7.006841659545898,
-0.12547287344932556,
0.5199018120765686,
-0.11101913452148438,
-2.995083808898926,
-0.888218879699707,
-1.3327231407165527,
-3.944938898086548,
-1.4718095064163208,
2.740164041519165,
-2.3250980377197266,
-5.957701683044434,
1.1843727827072144,
-3.0477213859558105,
-1.6871494054794312,
-1.3469650745391846,
-1.4783258438110352,
-0.056777626276016235,
-0.17500090599060059,
-3.129871368408203,
0.3952667713165283,
3.8376286029815674,
2.0914740562438965,
-0.17175006866455078,
-4.356967449188232,
3.0029993057250977,
-2.175262928009033,
0.5232577323913574,
-0.9669685959815979,
0.48462820053100586,
2.615009307861328,
0.39842450618743896,
3.2784276008605957,
-0.7935425043106079,
-0.8281271457672119,
-5.32557487487793,
-3.431715488433838,
2.657937526702881,
1.8374935388565063,
-1.3508665561676025,
1.165624737739563,
-0.7844128608703613,
-3.8114514350891113,
-2.442646026611328,
-1.308203101158142,
-0.1618315577507019,
3.670588970184326,
-1.6248745918273926,
2.7459731101989746,
-0.6265474557876587,
8.495512008666992,
4.642634391784668,
4.539473056793213,
0.5902433395385742,
9.182209014892578,
5.103418827056885,
4.956284046173096,
2.566216468811035,
4.942897796630859,
3.6660542488098145,
23.049583435058594,
-2.7657229900360107,
3.5249435901641846,
1.7531436681747437,
1.537284255027771,
-0.08369851112365723,
0.965727686882019,
1.0605276823043823,
2.5457205772399902,
3.432680130004883,
4.784576416015625,
-4.050437927246094,
-2.3392884731292725,
-1.146059274673462,
1.710395336151123,
0.8851326704025269,
-4.536794662475586,
-2.2027015686035156,
2.881460428237915,
0.0770329087972641
],
"name": "fc_0.tmp_0",
"shape": [
1000
]
},
{
"data": [
-0.003687990130856633,
0.008941259235143661,
-0.042509354650974274,
-0.07615242153406143,
0.0016824366757646203,
0.030000973492860794,
-0.05920300632715225,
0.007062121760100126,
0.010919729247689247,
-0.005986877251416445,
-0.027077991515398026,
-0.03718835487961769,
-0.04542677477002144,
-0.03190528228878975,
-0.03503408282995224,
-0.02900092490017414,
-0.01618349924683571,
-0.04425717145204544,
0.022584278136491776,
-0.029175972566008568,
0.007222338113933802,
0.07700718194246292,
0.03663356229662895,
0.03943665325641632,
0.018214982002973557,
-0.006235828157514334,
0.03991832956671715,
-0.009165618568658829,
0.052990756928920746,
0.027237508445978165,
0.004488788545131683,
0.004633789882063866,
0.0016598375514149666,
-0.029173247516155243,
-0.030307913199067116,
-0.09201760590076447,
0.01796901598572731,
-0.02547488361597061,
0.037831202149391174,
-0.025843188166618347,
-0.0007046036189422011,
0.014085481874644756,
0.042991623282432556,
-0.028124360367655754,
0.0057566845789551735,
0.00628122640773654,
0.018652061000466347,
0.01148306205868721,
-0.034914530813694,
0.012302433140575886,
0.009908963926136494,
-0.03329543396830559,
0.014409501105546951,
0.06615757942199707,
0.048445116728544235,
-0.032974425703287125,
-0.012695248238742352,
0.009905386716127396,
0.029218202456831932,
0.04958366975188255,
-0.038969654589891434,
0.044527195394039154,
0.011119761504232883,
0.042752981185913086,
0.045461833477020264,
0.02014610916376114,
-0.042606718838214874,
-0.043032560497522354,
0.028376195579767227,
0.03386761248111725,
-0.036220550537109375,
0.010016041807830334,
0.009949347004294395,
0.04470713436603546,
-0.051252298057079315,
0.0767943486571312,
0.0041234842501580715,
0.036432620137929916,
0.03746800497174263,
0.049837492406368256,
-0.016233598813414574,
0.004503053147345781,
0.047307197004556656,
-0.07187791168689728,
-0.04691136255860329,
0.01753365993499756,
-0.045829590409994125,
0.03300822526216507,
0.013956207782030106,
0.05863100290298462,
-0.022346297279000282,
-0.01606469787657261,
0.023254569619894028,
-0.01878412440419197,
0.0038996823132038116,
-0.04281593859195709,
0.03302016854286194,
-0.0386907197535038,
-0.07114642858505249,
-0.041318245232105255,
-0.04032706469297409,
-0.04344240576028824,
0.014916200190782547,
0.03272692859172821,
0.07935557514429092,
-0.008555051870644093,
-0.009787137620151043,
-0.0306097399443388,
-0.08618611097335815,
-0.07458283752202988,
-0.075184166431427,
0.11888779699802399,
-0.004389737732708454,
-0.032326407730579376,
0.021167520433664322,
-0.10738597810268402,
-0.02206539548933506,
-0.012461562640964985,
-0.029862049967050552,
-0.02732396312057972,
-0.006496133748441935,
-0.06019638106226921,
0.011636381037533283,
-0.03529941290616989,
-0.024814391508698463,
-0.0558750219643116,
-0.04255114123225212,
-0.008036980405449867,
-0.0013836845755577087,
-0.008182249031960964,
-0.07602342218160629,
-0.017665550112724304,
-0.03154440596699715,
0.03391769528388977,
-0.06318379193544388,
-0.09120860695838928,
-0.009102470241487026,
-0.04334781691431999,
-0.03436822071671486,
-0.057156793773174286,
-0.026569120585918427,
-0.049035243690013885,
-0.07681417465209961,
-0.007682671770453453,
-0.06119278818368912,
-0.013299357146024704,
0.027436597272753716,
-0.10607337951660156,
-0.04855261370539665,
-0.01895856484770775,
-0.03375741094350815,
0.02278212644159794,
-0.07413793355226517,
0.044130343943834305,
-0.042438071221113205,
0.030345484614372253,
0.016346510499715805,
-0.022047536447644234,
-0.0268916767090559,
0.023788440972566605,
0.0037406908813863993,
0.07911145687103271,
0.10528411716222763,
0.028225675225257874,
0.03214694559574127,
-0.036065131425857544,
0.0065807499922811985,
-0.04256792366504669,
0.0017863328102976084,
0.04745251312851906,
0.04024731367826462,
0.07360631227493286,
0.00813769269734621,
-0.0032228557392954826,
0.09753743559122086,
-0.03156182914972305,
-0.015077676624059677,
-0.015156712383031845,
0.057017698884010315,
-0.030488548800349236,
0.01436206977814436,
0.021209977567195892,
0.050788190215826035,
-0.04890962317585945,
0.03269631788134575,
0.03792430832982063,
0.00979586411267519,
0.0075846584513783455,
-0.0013552780728787184,
0.04568997025489807,
0.014611033722758293,
0.03396603837609291,
0.036835771054029465,
-0.015292062424123287,
-0.006450719200074673,
0.09010869264602661,
0.01520546805113554,
0.05093624070286751,
-0.007369194179773331,
0.05408911034464836,
-0.07000315189361572,
-0.01344625186175108,
0.01375866774469614,
0.05445721000432968,
0.08905062079429626,
-0.00881881918758154,
-0.05341064929962158,
-0.03651686757802963,
-0.016954468563199043,
0.07111198455095291,
-0.006579005159437656,
0.043587543070316315,
0.0061905719339847565,
-0.05055670812726021,
-0.010135982185602188,
-0.029468845576047897,
-0.0005263779894448817,
0.11087743937969208,
0.056521639227867126,
0.03685186058282852,
0.003410185454413295,
-0.04220917075872421,
-0.060174569487571716,
0.11088450253009796,
-0.069431833922863,
0.04977741837501526,
0.026545176282525063,
0.011630460619926453,
-0.07659721374511719,
0.06973671168088913,
0.01941361278295517,
-0.011653874069452286,
0.03184152767062187,
0.028282474726438522,
0.028816957026720047,
-0.009142627008259296,
0.08147864043712616,
0.05270121991634369,
0.03915988653898239,
0.07278130203485489,
0.005851069465279579,
-0.019348109140992165,
0.028488166630268097,
-0.004942269530147314,
-0.00551163824275136,
0.10196322947740555,
-0.053148940205574036,
0.03904684633016586,
-0.01270862203091383,
-0.007544093765318394,
-0.007785910274833441,
0.025109879672527313,
-0.039188750088214874,
-0.02362559735774994,
0.01791459508240223,
0.012472287751734257,
-0.024860121309757233,
0.04719432815909386,
0.00444876030087471,
0.028805160894989967,
0.027503645047545433,
0.02371162176132202,
-0.01892799884080887,
0.0607261024415493,
-0.015286020003259182,
0.009634957648813725,
0.03645457327365875,
-0.0011025714920833707,
-0.05426860973238945,
-0.01658141426742077,
0.0731697604060173,
-0.05162889510393143,
0.004718414507806301,
-0.0245496928691864,
-0.028555067256093025,
-0.047821901738643646,
0.01644270494580269,
-0.03812135383486748,
-0.013669120147824287,
0.024389216676354408,
-0.012269080616533756,
0.09645938873291016,
-0.06203361600637436,
-0.026839524507522583,
0.08298112452030182,
0.03540303185582161,
0.010105741210281849,
-0.0029790534172207117,
-0.03672816976904869,
-0.026661334559321404,
-0.036529384553432465,
-0.03294587880373001,
-0.04116649180650711,
-0.03697272390127182,
-0.029658380895853043,
0.011680827476084232,
-0.04510074108839035,
-0.004310951568186283,
0.008505568839609623,
0.022901875898241997,
-0.029224766418337822,
-0.018233710899949074,
0.0029424179811030626,
-0.04292156919836998,
-0.06061087176203728,
0.029131216928362846,
0.025320354849100113,
-0.051130231469869614,
-0.036364343017339706,
-0.03604738041758537,
-0.018819935619831085,
-0.02530958689749241,
0.037919577211141586,
0.03258763253688812,
0.028257347643375397,
0.039612989872694016,
-0.041416067630052567,
-0.021830370649695396,
0.04463235288858414,
0.007241268642246723,
-0.042530711740255356,
-0.06662322580814362,
-0.06920646131038666,
-0.05042976886034012,
-0.03885788470506668,
-0.02979196049273014,
-0.05639709159731865,
-0.03180181607604027,
-0.00023263058392331004,
-0.04037349298596382,
-0.011919450014829636,
-0.04540950059890747,
0.017394384369254112,
0.05616847798228264,
-0.017490621656179428,
-0.01792430691421032,
0.038348469883203506,
-0.0448252335190773,
-0.006676798220723867,
0.01121603325009346,
-0.01954822801053524,
-0.024139299988746643,
-0.008223014883697033,
-0.06968462467193604,
-0.03202514722943306,
0.00808144174516201,
0.0738309919834137,
0.00757223553955555,
0.0350271537899971,
-0.069671630859375,
0.018206359818577766,
-0.017576169222593307,
-0.05238618329167366,
0.0021791569888591766,
0.021363601088523865,
-0.0041518486104905605,
0.02223283238708973,
-0.023093393072485924,
-0.00603022426366806,
0.08376206457614899,
-0.01123447623103857,
0.01212579570710659,
-0.0034400124568492174,
0.011145046912133694,
0.03473440185189247,
0.00573844276368618,
-0.003223319770768285,
0.030685516074299812,
-0.03471050783991814,
0.022468747571110725,
-0.00850107241421938,
-0.039500683546066284,
-0.0366390161216259,
0.009813347831368446,
-0.056138601154088974,
-0.063619464635849,
0.021581145003437996,
-0.03223695605993271,
0.05089665204286575,
0.044291429221630096,
-0.022422200068831444,
-0.03323088213801384,
0.003001729492098093,
-0.00490409042686224,
-0.07070058584213257,
-0.03231103718280792,
-0.015496424399316311,
-0.026021216064691544,
-0.04688943549990654,
-0.034998681396245956,
-0.03197839483618736,
0.02240949310362339,
-0.06649056822061539,
-0.07519687712192535,
-0.026499437168240547,
-0.034499913454055786,
-0.08717647939920425,
-0.04213351011276245,
-0.0034737081732600927,
0.027897685766220093,
0.01174659188836813,
0.05360700562596321,
0.008449586108326912,
-0.025189554318785667,
-0.08118382841348648,
0.06983719766139984,
-0.029494380578398705,
-0.0221935473382473,
-0.10271820425987244,
-0.049354854971170425,
-0.055738139897584915,
0.013217085972428322,
0.013849622569978237,
0.09116585552692413,
0.05216317996382713,
-0.00837879441678524,
0.0464133620262146,
-0.01044970378279686,
0.05477564409375191,
-0.026014428585767746,
-0.001173704513348639,
0.0022124918177723885,
0.03065471351146698,
0.07647182047367096,
0.07389799505472183,
-0.005795970559120178,
-0.07854931801557541,
-0.04907945916056633,
-0.013740096241235733,
-0.013098184019327164,
-0.026600196957588196,
0.00023228125064633787,
0.009565023705363274,
0.05302581563591957,
-0.0523621030151844,
-0.02576652728021145,
0.008274256251752377,
-0.020338213071227074,
0.015584398992359638,
-0.03614825755357742,
0.006268330384045839,
0.036880869418382645,
-0.011098813265562057,
0.004662139806896448,
0.017491009086370468,
0.06573306769132614,
0.011701547540724277,
0.036138277500867844,
0.1117096096277237,
0.04971364140510559,
0.023937132209539413,
0.010641202330589294,
-0.02406194806098938,
-0.0066932812333106995,
0.019962571561336517,
0.06228780373930931,
0.034523192793130875,
0.06635024398565292,
-0.03500073403120041,
0.07475458830595016,
-0.0378866121172905,
0.05885902792215347,
0.0123667661100626,
0.0033683942165225744,
0.06744785606861115,
-0.03752945363521576,
-0.011967504397034645,
-0.026434602215886116,
0.03977688029408455,
-0.030183641240000725,
0.08546694368124008,
-0.03120378963649273,
-0.027351297438144684,
-0.01445120107382536,
-0.05552313104271889,
-0.016734162345528603,
-0.09428578615188599,
0.036037396639585495,
-0.04630902409553528,
-0.01387853268533945,
0.001500910148024559,
-0.004781987983733416,
0.0019548535346984863,
0.0006819817936047912,
-0.05335703864693642,
0.02906760200858116,
0.0030452110804617405,
0.04172055050730705,
-0.07467839121818542,
-0.004307988099753857,
-0.08344320207834244,
0.019224606454372406,
0.07147758454084396,
-0.014791854657232761,
0.026968568563461304,
-0.039765797555446625,
-0.013828659430146217,
-0.08377131819725037,
0.041675712913274765,
0.005277384538203478,
-0.06006735935807228,
0.010793866589665413,
0.015272704884409904,
0.022149482741951942,
0.01512757409363985,
-0.004527449142187834,
-0.012935543432831764,
-0.03776730224490166,
-0.013095385394990444,
-0.048143234103918076,
-0.017418906092643738,
0.034333061426877975,
0.003142914967611432,
0.048323437571525574,
-0.03474922850728035,
-0.004325039219111204,
-0.00014415760233532637,
-0.04636875540018082,
-0.059930045157670975,
0.0034931458067148924,
-0.059927452355623245,
-0.024852020666003227,
0.01490060891956091,
0.05583285540342331,
0.026326831430196762,
-0.03696326166391373,
0.006741013377904892,
-0.0030682350043207407,
-0.06642714887857437,
0.03142065554857254,
0.0037036347202956676,
0.0017363938968628645,
-0.015277402475476265,
0.019609834998846054,
-0.02694837749004364,
-0.008354587480425835,
-0.0055337161757051945,
0.022408809512853622,
-0.006945227272808552,
0.05902312695980072,
-0.0698198601603508,
-0.04078444465994835,
0.030125360935926437,
0.010561134666204453,
-0.04395989701151848,
-0.024733366444706917,
-0.028281502425670624,
-0.058289363980293274,
-0.04675664007663727,
0.030668746680021286,
-0.002263790462166071,
0.002689843764528632,
0.015689371153712273,
-0.01950017176568508,
-0.03821331635117531,
-0.009851339273154736,
-0.08586031943559647,
0.05122917518019676,
0.02099631354212761,
0.0006388869951479137,
0.02541801519691944,
-0.0322190523147583,
-0.033301420509815216,
0.09745650738477707,
-0.012861361727118492,
-0.05405476689338684,
-0.008959059603512287,
0.07859686017036438,
0.023672476410865784,
-0.03663608431816101,
-0.045123424381017685,
0.003407943295314908,
0.036900319159030914,
-0.0012528724037110806,
0.051791124045848846,
0.015041890554130077,
0.03089899756014347,
0.008894169703125954,
0.03784835338592529,
0.04624969884753227,
-0.0602201484143734,
-0.0167662613093853,
0.04718945175409317,
0.03888638690114021,
0.040561284869909286,
-0.015315012075006962,
-0.029687007889151573,
0.075917549431324,
0.02619314193725586,
0.011586178094148636,
0.01692967861890793,
-0.05843432620167732,
-0.030753903090953827,
0.04426487162709236,
-0.002235148334875703,
0.00011897759395651519,
0.022682417184114456,
0.04427789896726608,
-0.0253220833837986,
0.016511814668774605,
0.014768368564546108,
0.06125757098197937,
0.01421970222145319,
0.005477714352309704,
0.05005384981632233,
0.0009486618218943477,
0.004594333469867706,
0.008400551043450832,
0.04632335156202316,
0.008378999307751656,
0.042716316878795624,
-0.07891610264778137,
-0.03962177783250809,
-0.030608778819441795,
0.02148515172302723,
-0.016777973622083664,
-0.03356126695871353,
0.018223969265818596,
-0.017884358763694763,
-0.046243660151958466,
0.03091009333729744,
0.04488755017518997,
0.06628728657960892,
0.14274229109287262,
0.033918581902980804,
0.005349063780158758,
0.03341435268521309,
0.05175795778632164,
-0.012876573018729687,
0.08838945627212524,
0.04307498037815094,
-0.039001114666461945,
0.05480039119720459,
0.018039382994174957,
0.023021742701530457,
-0.037194445729255676,
0.08447261899709702,
0.004635825287550688,
0.007818537764251232,
-0.0471501424908638,
-0.04337930306792259,
-0.03731657192111015,
0.029189802706241608,
-2.943669824162498e-05,
0.04206568002700806,
-0.046573907136917114,
0.049842674285173416,
-0.07550699263811111,
0.013699652627110481,
0.01364654116332531,
0.044443529099226,
-0.032991472631692886,
0.00199594022706151,
0.03455238416790962,
0.06704609841108322,
0.10915092378854752,
0.013607824221253395,
0.030938198789954185,
0.03007160872220993,
0.03932444006204605,
0.03017045184969902,
-0.045967865735292435,
0.07971260696649551,
-0.03735628351569176,
0.004719314631074667,
0.025986433029174805,
0.05499814823269844,
0.03798016905784607,
-0.03506499156355858,
-0.07836069166660309,
-0.006422300357371569,
0.08364897966384888,
0.031139858067035675,
0.0237562395632267,
0.03418833762407303,
-0.04556337743997574,
-0.054386042058467865,
0.037647366523742676,
0.07103682309389114,
0.032817550003528595,
0.017459850758314133,
0.025301214307546616,
0.012718969956040382,
0.040260981768369675,
0.053317587822675705,
-0.02250387705862522,
0.06267426162958145,
-0.041697483509778976,
-0.0776071771979332,
-0.029911287128925323,
-0.009513238444924355,
-0.011716986075043678,
0.04091794043779373,
-0.07932541519403458,
-0.05547358840703964,
0.022563990205526352,
0.056522518396377563,
-0.05715760216116905,
0.017715174704790115,
-0.027290472760796547,
0.007600400596857071,
-0.012442394159734249,
-0.07039974629878998,
-0.00028295081574469805,
0.07013864815235138,
-0.04879284277558327,
0.016179071739315987,
0.0013504876988008618,
-0.041525281965732574,
0.02081078104674816,
-0.0196123868227005,
0.032823868095874786,
0.02349238656461239,
-0.017578549683094025,
0.04525979235768318,
0.012601063586771488,
0.05026762932538986,
-0.0040748827159404755,
0.03857560455799103,
0.08672965317964554,
0.028569836169481277,
-0.012252695858478546,
0.05252901092171669,
-0.030442694202065468,
-0.047434158623218536,
0.011545209214091301,
0.004960620775818825,
-0.0417361781001091,
-0.059848688542842865,
-0.002107459818944335,
-0.05377114191651344,
0.05968847870826721,
0.053163085132837296,
-0.05112070590257645,
-0.04243450611829758,
-0.03251194208860397,
0.013431361876428127,
-0.01739482954144478,
-0.001889650709927082,
0.05608241632580757,
-0.01217451598495245,
0.016882428899407387,
0.010958705097436905,
0.000917949597351253,
0.005902082193642855,
0.01774146594107151,
0.019388500601053238,
0.031179876998066902,
0.03483326733112335,
0.08622352033853531,
-0.023635651916265488,
0.04065284878015518,
0.04532768949866295,
0.004761804360896349,
-0.012697340920567513,
-0.01930900476872921,
0.020402081310749054,
-0.054622046649456024,
0.022921158000826836,
0.029295874759554863,
-0.012813729234039783,
0.033268582075834274,
-0.02670474536716938,
0.019629303365945816,
0.03199295327067375,
0.009693413972854614,
-0.05808739364147186,
0.022128207609057426,
0.007398845162242651,
0.05463213473558426,
-0.001370777958072722,
-0.010825964622199535,
-0.004721509292721748,
0.01866617053747177,
0.06790919601917267,
0.004824503790587187,
0.030829856172204018,
0.062489259988069534,
-0.031852807849645615,
-0.039454106241464615,
-0.05762400105595589,
-0.034367915242910385,
0.026951737701892853,
-0.0058794948272407055,
-0.018224380910396576,
-0.0033117542043328285,
-0.015716953203082085,
-0.04995019733905792,
-0.02712280862033367,
-0.008370775729417801,
-0.03431384637951851,
0.0416133776307106,
0.0005534720839932561,
0.002803171519190073,
-0.046293120831251144,
-0.06276726722717285,
-0.0257625263184309,
-0.018244262784719467,
-0.025223413482308388,
-0.01072604674845934,
-0.05687200278043747,
0.003217678051441908,
-0.04279552027583122,
-0.027273062616586685,
-0.026034438982605934,
0.005079316906630993,
0.00520298769697547,
-0.018159575760364532,
0.011921577155590057,
0.003878217190504074,
-0.08502774685621262,
-0.03791035711765289,
0.04824737459421158,
-0.024019774049520493,
-0.019636359065771103,
-0.03588871285319328,
0.08719196915626526,
0.028716744855046272,
-0.04219309985637665,
0.024259814992547035,
-0.027386216446757317,
-0.0009738823282532394,
0.016394784674048424,
0.102895587682724,
0.03388987109065056,
0.00011744347284547985,
-0.020539140328764915,
-0.06474660336971283,
0.06117396429181099,
-0.02797951176762581,
0.006057301070541143,
0.0028115161694586277,
0.0039796908386051655,
-0.015010246075689793,
0.10862033069133759,
-0.03992471843957901,
0.08181249350309372,
0.07777091860771179,
0.06840945780277252,
0.025010455399751663,
0.007091366220265627,
-0.01059243455529213,
0.0447077713906765,
0.0604066327214241,
0.022920845076441765,
0.08226370066404343,
0.013317991979420185,
0.0011763354996219277,
0.03883127123117447,
0.0745445266366005,
0.05125625804066658,
-0.03705110028386116,
0.011146004311740398,
-0.027503741905093193,
-0.027643678709864616,
0.020032767206430435,
-0.057130493223667145,
0.0054396879859268665,
0.04384961724281311,
0.07611638307571411,
-0.03160066157579422,
0.011447485536336899,
-0.05587098002433777,
0.016214223578572273,
-0.004277338273823261,
-0.012149898335337639,
0.0005352659500204027,
-0.0011923728743568063,
0.09622707962989807,
-0.013957038521766663,
0.02614167146384716,
-0.04715534672141075,
0.07046947628259659,
-0.030087245628237724,
-0.07538038492202759,
0.005601473618298769,
0.020381541922688484,
0.0007213251665234566,
-0.03494713827967644,
0.09191235899925232,
0.0776251032948494,
0.01217822078615427,
0.03080901876091957,
-0.009339629672467709,
0.008593853563070297,
0.09997996687889099,
-0.04608052223920822,
-0.046993814408779144,
-0.0025786906480789185,
0.04704232141375542,
-0.03138108551502228,
-0.03445694223046303,
0.01121643465012312,
0.06339779496192932,
-0.027784790843725204,
0.035187043249607086,
0.03848481550812721,
0.04067709669470787,
0.02477540634572506,
-0.017407990992069244,
-0.02562996745109558,
-0.017839206382632256,
-0.013904049061238766,
0.07074828445911407,
-0.01998770982027054,
0.04176481068134308,
0.025349991396069527,
0.03619129955768585,
-0.028926564380526543,
0.023561900481581688,
0.06832046806812286,
-0.0022936644963920116,
-0.037927981466054916,
-0.011110823601484299,
0.003997039515525103,
-0.018610212951898575,
-0.0777856633067131,
-0.06572680920362473,
0.015108302235603333,
0.07599352300167084,
0.06262318789958954,
0.016255853697657585,
-0.020373031497001648,
0.010496476665139198,
-0.06893618404865265,
-0.0399383120238781,
-0.04000330716371536,
-0.013301906175911427,
-0.006480810232460499,
0.11576880514621735,
0.03634243085980415,
-0.005271580535918474,
-0.014077144674956799,
-0.026059696450829506,
0.013743389397859573,
-0.013923931866884232,
-0.010056555271148682,
-0.046551626175642014,
-0.07423108071088791,
-0.03545554727315903,
0.030452528968453407,
-0.0164776723831892,
-0.03782391920685768,
-0.030053239315748215,
-0.0450371690094471,
-0.017368139699101448,
-0.03565021976828575,
-0.03353315219283104,
0.008026614785194397,
-0.023412618786096573,
-0.025333400815725327,
-0.03468359634280205,
0.011942660436034203,
-0.04171815142035484,
-0.015292288735508919,
-0.016381343826651573,
-0.011084257625043392,
-0.008780824951827526,
-0.022404469549655914,
-0.09128870815038681,
-0.029446301981806755,
0.005666058510541916,
-0.04409130662679672,
-0.02468474768102169,
-0.08587147295475006,
0.01264773029834032,
0.0693143829703331,
0.04210692644119263,
-0.008101150393486023,
0.04196253791451454,
-0.057191651314496994,
0.03887677565217018,
0.0007247937028296292,
-0.07097858190536499,
-0.028197672218084335,
0.01593373529613018,
0.027537429705262184,
0.04274371266365051,
0.026650140061974525,
-0.06849484145641327,
0.033079057931900024,
0.016998326405882835,
0.0614488385617733,
-0.03208369016647339,
-0.0011799107305705547,
-0.008556938730180264,
-0.04253137484192848,
0.006528179626911879,
-0.008368730545043945,
0.006762103643268347,
0.032385826110839844,
-0.0629633367061615,
-0.020283207297325134,
-0.10449697077274323,
-0.03983088955283165,
-0.0652599185705185,
-0.011780574917793274,
-0.00901532918214798,
-0.017431063577532768,
8.897688530851156e-05
],
"name": "fc7_offset",
"shape": [
1000
]
},
{
"data": [
-1.1135177612304688,
6.288958549499512,
3.139874219894409,
1.9048583507537842,
0.03913835436105728,
2.6481428146362305,
2.8079400062561035,
2.1263062953948975,
-0.6012501120567322,
-4.3257622718811035,
-5.596638202667236,
-3.122722864151001,
0.15927131474018097,
-2.9604926109313965,
-4.069268226623535,
-0.3509599566459656,
-3.8499019145965576,
-3.502720832824707,
-1.8450493812561035,
-2.911593437194824,
-3.2176897525787354,
2.9500503540039062,
1.2102972269058228,
0.7517126202583313,
-1.9848179817199707,
-0.08928977698087692,
1.0721582174301147,
-0.14318805932998657,
-1.3973617553710938,
0.9336868524551392,
1.3169736862182617,
-0.5166665315628052,
2.9748587608337402,
2.222357988357544,
4.300759315490723,
0.30319321155548096,
-0.006494995206594467,
-2.8430075645446777,
-1.144093632698059,
-1.9795348644256592,
-1.3029303550720215,
-2.991396903991699,
1.069321632385254,
2.152038335800171,
-2.551513671875,
-1.9288045167922974,
-1.5026218891143799,
-3.02573823928833,
-4.000486850738525,
-3.1551754474639893,
0.9542933702468872,
-2.602130174636841,
-3.8310000896453857,
-3.5045058727264404,
0.1277388483285904,
-1.756664514541626,
-2.5417673587799072,
-2.5876262187957764,
-1.9096553325653076,
0.180572509765625,
0.7920528650283813,
-4.119457721710205,
-2.2808122634887695,
-2.2101640701293945,
-0.2808034420013428,
-1.6263320446014404,
-0.8479610085487366,
-0.4797917902469635,
-1.818886399269104,
-1.5055320262908936,
-1.4128488302230835,
-2.5348434448242188,
-1.887861967086792,
2.948688268661499,
1.7228940725326538,
-0.4362483322620392,
1.1495392322540283,
1.4625887870788574,
1.5648139715194702,
-0.7236918210983276,
1.599829912185669,
0.7933265566825867,
1.2352303266525269,
-0.8543774485588074,
-5.039606094360352,
-1.5521436929702759,
-0.7921367287635803,
-2.934796094894409,
-1.9191449880599976,
-4.304612636566162,
-1.9234520196914673,
-3.6729063987731934,
-4.655753135681152,
-2.873351573944092,
-0.7903644442558289,
-4.490265846252441,
-1.8164656162261963,
-0.7162665724754333,
-3.195564031600952,
-1.1332260370254517,
-1.2450087070465088,
2.654376983642578,
-4.2748122215271,
-1.4303213357925415,
-1.614728331565857,
-4.476330757141113,
1.6490802764892578,
5.233551502227783,
-0.3165779113769531,
-2.0802481174468994,
2.3546152114868164,
3.9514129161834717,
6.232498645782471,
1.0490273237228394,
0.9326438307762146,
3.712100028991699,
-0.8434510231018066,
2.6792490482330322,
3.1296162605285645,
3.223210096359253,
-1.6055116653442383,
5.80521821975708,
3.3964550495147705,
1.011749267578125,
1.6933361291885376,
5.176721572875977,
2.3967502117156982,
-0.6730397343635559,
-2.7001023292541504,
-3.7109756469726562,
-1.14090096950531,
-4.587691307067871,
-1.333116054534912,
-4.107562065124512,
-3.6067891120910645,
0.022360533475875854,
-4.151522159576416,
-3.132967472076416,
-5.283032417297363,
-1.1128923892974854,
-5.726787567138672,
-3.259611129760742,
-6.0796637535095215,
-1.5227385759353638,
0.7056931853294373,
2.0717215538024902,
-1.8915910720825195,
6.9576215744018555,
2.1103978157043457,
-2.5883052349090576,
-0.4441264569759369,
0.29632315039634705,
-4.115409851074219,
-1.7699885368347168,
-1.0301513671875,
-1.3696787357330322,
-2.761214256286621,
-2.2525429725646973,
-3.8018980026245117,
-2.6193923950195312,
-1.1923953294754028,
-0.8128389120101929,
-2.585618257522583,
-0.6347448825836182,
-1.7189230918884277,
-0.9218324422836304,
-3.2434442043304443,
-2.1508426666259766,
0.20600341260433197,
-2.162846803665161,
0.826657772064209,
-2.9015021324157715,
-2.265634775161743,
-0.6910134553909302,
-0.8061107993125916,
-0.7938972115516663,
-3.5841989517211914,
-0.9715676307678223,
-1.3360918760299683,
-2.2801849842071533,
-3.5794837474823,
-2.046212911605835,
-0.49998578429222107,
2.6022450923919678,
3.2232179641723633,
-0.43327096104621887,
-0.43072545528411865,
0.028539717197418213,
2.9475526809692383,
0.2802347242832184,
-1.561449408531189,
2.756429433822632,
-1.04819917678833,
-2.1431262493133545,
-4.478471755981445,
-0.06046929955482483,
1.0384304523468018,
0.2062852531671524,
-0.8454253673553467,
2.7614078521728516,
-1.2345904111862183,
-1.400450348854065,
-0.1786937266588211,
1.6461610794067383,
-1.7984795570373535,
-2.061809778213501,
-2.770155429840088,
0.7444724440574646,
-2.25679087638855,
-1.143601417541504,
-3.0761778354644775,
0.2368452250957489,
2.2915382385253906,
3.751492977142334,
0.9513205885887146,
0.22786934673786163,
-2.7496840953826904,
0.6290023922920227,
0.003699198365211487,
2.7009973526000977,
0.48269402980804443,
-0.861529529094696,
-1.8455449342727661,
1.311780571937561,
2.8576531410217285,
-3.386429786682129,
-0.9015589952468872,
-2.7003421783447266,
-0.37863194942474365,
-1.1736881732940674,
0.23105797171592712,
0.24713507294654846,
-0.3406108021736145,
1.2424044609069824,
-0.8538718223571777,
-0.2684188485145569,
-1.2067370414733887,
-0.7052292227745056,
-2.275963306427002,
-1.8765861988067627,
1.1009433269500732,
-0.9290322661399841,
-0.5795953869819641,
-4.521215438842773,
-2.0830078125,
-0.03133445233106613,
-2.6075408458709717,
-0.8438606858253479,
-1.4943246841430664,
-0.8214187026023865,
0.4131604731082916,
2.144296169281006,
-0.5544344186782837,
-1.3938241004943848,
-1.8246674537658691,
-3.185823678970337,
-0.5576209425926208,
-2.192222833633423,
2.806727170944214,
1.1733990907669067,
-0.08159276098012924,
-2.1470870971679688,
-0.6794589757919312,
-1.6413061618804932,
-1.389523983001709,
0.3174307346343994,
-1.4913421869277954,
2.589702844619751,
-5.424981594085693,
3.14266300201416,
1.9202947616577148,
1.3934451341629028,
-0.28893977403640747,
2.783479928970337,
0.7540513277053833,
2.1970536708831787,
3.844935178756714,
2.0208959579467773,
-3.0737786293029785,
-0.3650449514389038,
-0.9322575926780701,
-2.5201945304870605,
-3.770314931869507,
1.6335101127624512,
-1.870066523551941,
-2.0942318439483643,
1.506428599357605,
-1.9663705825805664,
0.9056843519210815,
-2.3463313579559326,
-0.8382065892219543,
2.1236884593963623,
-5.041065216064453,
0.07987252622842789,
6.912156105041504,
2.558126449584961,
3.1287927627563477,
0.08568187057971954,
-0.11802269518375397,
0.906413197517395,
-6.439662933349609,
1.396309494972229,
0.6348122954368591,
-1.2416276931762695,
-0.1382899135351181,
-4.502665042877197,
-0.7919870615005493,
-1.5633372068405151,
0.46295979619026184,
3.5294690132141113,
2.5100436210632324,
-1.5220637321472168,
-1.243208885192871,
2.140782356262207,
-1.107566237449646,
0.5321031808853149,
-2.3318674564361572,
-1.4352529048919678,
0.05798972770571709,
0.6704398393630981,
0.8080523610115051,
1.4889743328094482,
-2.9919238090515137,
-0.5327302813529968,
-1.7200275659561157,
-2.7397515773773193,
-4.664469242095947,
6.672308921813965,
2.1278116703033447,
4.903074741363525,
-2.885180950164795,
0.3048209547996521,
-2.2697489261627197,
-0.3579505383968353,
-3.4912190437316895,
0.8643660545349121,
2.4931955337524414,
0.2035190761089325,
-3.760498285293579,
4.380125999450684,
-1.3057351112365723,
-1.369592308998108,
-2.401876926422119,
-2.4498915672302246,
-0.7065585255622864,
1.6136775016784668,
-4.125005722045898,
5.1046552658081055,
-1.864634394645691,
-2.7479870319366455,
2.8492558002471924,
-1.8721797466278076,
-3.5855660438537598,
-5.791052341461182,
4.716646194458008,
0.7182656526565552,
-1.5115002393722534,
-2.3466901779174805,
-2.1319382190704346,
-1.7151187658309937,
-0.7809315323829651,
-1.3043848276138306,
-3.4859538078308105,
-1.9124085903167725,
-3.841890573501587,
2.875410556793213,
-1.4392427206039429,
-0.7927815318107605,
-5.1780219078063965,
-4.427769660949707,
-3.303980827331543,
-3.0374269485473633,
0.5805526375770569,
0.003860095515847206,
0.616568386554718,
-4.566771984100342,
-2.314667224884033,
-0.9728753566741943,
-0.5612640380859375,
-2.1157753467559814,
0.5822577476501465,
0.19072259962558746,
-1.9761295318603516,
-5.34631872177124,
-0.15873247385025024,
1.5741854906082153,
0.19256766140460968,
-0.893580436706543,
-4.563290119171143,
3.085646390914917,
1.2774627208709717,
-1.228529691696167,
-0.5872294902801514,
-0.7993833422660828,
-0.27998870611190796,
0.20474407076835632,
0.45689675211906433,
-0.4169624447822571,
-1.458970069885254,
0.4040461480617523,
1.5903464555740356,
0.8884001970291138,
1.4965789318084717,
0.8713038563728333,
1.190368413925171,
4.0006818771362305,
1.3812894821166992,
2.443248748779297,
-3.691615343093872,
3.6675219535827637,
-0.28525710105895996,
-4.323070049285889,
-0.7842081189155579,
-0.9959515929222107,
-2.7769031524658203,
-1.2515490055084229,
-2.0718178749084473,
5.263943672180176,
2.7395377159118652,
-0.20292477309703827,
2.0371251106262207,
4.687855243682861,
-1.6174226999282837,
-6.011782646179199,
-2.406636953353882,
5.687418460845947,
2.068570137023926,
2.6315081119537354,
-1.2711865901947021,
-1.9762932062149048,
-4.717271327972412,
-0.9369955658912659,
3.616706609725952,
1.6450910568237305,
-0.5974013209342957,
1.9036098718643188,
-3.0006422996520996,
8.5920991897583,
0.9085093140602112,
1.8057917356491089,
2.794481039047241,
3.6742942333221436,
5.859650611877441,
-5.367660999298096,
-0.23054727911949158,
0.16943949460983276,
-3.502530336380005,
4.531452178955078,
2.216261625289917,
2.0808639526367188,
-5.725005149841309,
0.7010980248451233,
-0.26391342282295227,
-1.183639645576477,
-2.2641284465789795,
-0.19194045662879944,
-0.1496332883834839,
1.1107094287872314,
0.6537806987762451,
0.06566338986158371,
4.320130348205566,
-0.08742954581975937,
-2.0149173736572266,
0.44996148347854614,
1.3544546365737915,
-2.3553712368011475,
-1.5237796306610107,
-0.3587614893913269,
2.0180962085723877,
6.839800834655762,
6.757830619812012,
5.435042858123779,
1.472086787223816,
-5.827995300292969,
-1.7366204261779785,
5.700528621673584,
4.597124099731445,
-6.591582298278809,
-4.777801036834717,
-3.023289918899536,
-0.7286937832832336,
-3.7894070148468018,
-4.362597465515137,
3.1441218852996826,
-1.2777856588363647,
-1.8854466676712036,
-0.1450381726026535,
-2.446958065032959,
5.533286094665527,
3.4368019104003906,
1.0337337255477905,
1.9079962968826294,
-0.6734300255775452,
-2.2918312549591064,
4.700782299041748,
-3.3590245246887207,
1.4271029233932495,
4.843199729919434,
5.300411701202393,
-1.0196391344070435,
-1.975170373916626,
3.3577330112457275,
-5.640188217163086,
-0.9089413285255432,
1.9050424098968506,
1.7370647192001343,
2.779188394546509,
-2.3282089233398438,
-0.3661664128303528,
-7.736055850982666,
3.3626389503479004,
-0.9660972952842712,
-0.5348708629608154,
6.016900062561035,
-1.907275915145874,
4.409943580627441,
-1.3399814367294312,
5.80074405670166,
-0.9423139691352844,
-3.0581214427948,
-4.232025146484375,
0.49505308270454407,
-2.8248448371887207,
1.8452928066253662,
-0.29495081305503845,
1.954695701599121,
-3.5908143520355225,
-0.058506038039922714,
-4.066666126251221,
-4.578606128692627,
3.1549646854400635,
0.3313584327697754,
-4.844637870788574,
-3.786264657974243,
-2.9295287132263184,
-4.7329277992248535,
2.771017551422119,
-0.8390169739723206,
4.628056526184082,
-3.1337990760803223,
8.086268424987793,
2.15596866607666,
1.509993553161621,
-0.20340439677238464,
2.465909719467163,
-0.9388576745986938,
0.8679890632629395,
-5.339540958404541,
-5.248732566833496,
0.3937181234359741,
-2.2340128421783447,
-4.198233127593994,
3.6622326374053955,
-1.4968304634094238,
5.655033111572266,
6.639937400817871,
9.50888729095459,
8.135913848876953,
4.130185127258301,
-1.1507993936538696,
-3.7683653831481934,
-3.5123729705810547,
10.17003345489502,
3.0891218185424805,
-4.775205612182617,
-2.8696086406707764,
3.1166598796844482,
-0.09823939204216003,
1.4306693077087402,
0.11904144287109375,
4.376938819885254,
-0.13451887667179108,
-0.09921831637620926,
-4.0052595138549805,
-0.6812946200370789,
0.29452043771743774,
1.232026219367981,
1.1641405820846558,
4.678610801696777,
-1.1426453590393066,
4.305626392364502,
-0.6170145273208618,
-2.9588119983673096,
0.6505197882652283,
-0.7002402544021606,
1.679695725440979,
0.905500590801239,
0.7201970219612122,
-3.2486212253570557,
-2.017725944519043,
-5.236093997955322,
0.31017568707466125,
-4.776829719543457,
0.771937906742096,
-0.5375965237617493,
1.6099820137023926,
0.2525595426559448,
-3.0072057247161865,
-2.222247362136841,
2.557495355606079,
2.604846477508545,
2.8686323165893555,
-0.2671038508415222,
-3.6298811435699463,
4.030196189880371,
-2.228626251220703,
-2.7869765758514404,
8.178828239440918,
-0.9561513066291809,
2.5749263763427734,
0.1051970049738884,
-0.8775336742401123,
-4.546533584594727,
-2.958195447921753,
-0.10180419683456421,
-3.051948070526123,
4.536789417266846,
-0.9246405959129333,
0.23328013718128204,
7.733509063720703,
2.585641384124756,
-3.2604427337646484,
3.1121461391448975,
-0.3049006462097168,
-2.0115468502044678,
-0.8986498117446899,
4.7046332359313965,
0.3298841416835785,
5.715729236602783,
0.5911621451377869,
-3.0967226028442383,
-2.4492650032043457,
0.8132742643356323,
-0.08068384975194931,
-1.1273431777954102,
-1.510864019393921,
-4.215301513671875,
0.021838083863258362,
2.4892895221710205,
-0.36609962582588196,
-4.941051959991455,
0.870089054107666,
0.8415865898132324,
2.778775930404663,
6.891691207885742,
5.314716815948486,
4.067209720611572,
-3.2592508792877197,
-0.5322805643081665,
3.2613449096679688,
3.712477445602417,
1.4212429523468018,
0.7374931573867798,
-1.1152633428573608,
-2.0120372772216797,
0.27490660548210144,
-0.018865203484892845,
6.346681594848633,
0.9549524784088135,
-2.9575817584991455,
2.4913063049316406,
-3.3575847148895264,
-3.308088541030884,
0.789000391960144,
2.1385583877563477,
0.5199357271194458,
0.9427002668380737,
1.212093710899353,
2.4850857257843018,
0.16598199307918549,
-0.22598697245121002,
1.4501450061798096,
4.240878582000732,
-2.1890220642089844,
-2.833745002746582,
-3.2725131511688232,
-1.8148906230926514,
2.188467502593994,
-0.8708044290542603,
0.40772077441215515,
0.8311145305633545,
-0.09439480304718018,
6.006947994232178,
4.909032821655273,
0.039429258555173874,
-0.05254539102315903,
-4.063587665557861,
-1.1732741594314575,
-0.37565234303474426,
0.9866915941238403,
-2.3882200717926025,
-0.5323681831359863,
-2.7551889419555664,
2.324697971343994,
2.933861494064331,
-0.5581904053688049,
-0.814734935760498,
-2.680150032043457,
2.7688400745391846,
2.2362000942230225,
0.012518439441919327,
4.497869968414307,
0.05619104206562042,
2.188314199447632,
1.1976550817489624,
-1.223286747932434,
-1.96990168094635,
-2.6140923500061035,
2.6416029930114746,
-5.036900043487549,
-2.9750781059265137,
3.8761379718780518,
0.3950593173503876,
-0.9626359939575195,
0.6379157900810242,
1.320874571800232,
7.905311107635498,
-1.404468297958374,
6.345209121704102,
-0.34226953983306885,
-2.877328634262085,
-2.9425530433654785,
-3.3539328575134277,
-0.6594979763031006,
2.189342737197876,
-0.53953617811203,
-5.761833190917969,
4.170668125152588,
1.1384563446044922,
-6.1796698570251465,
-0.2715799808502197,
5.205389976501465,
-3.832481861114502,
5.0490217208862305,
-1.2221055030822754,
1.9642716646194458,
-1.650144338607788,
2.029522657394409,
1.2838444709777832,
-0.8694071173667908,
-1.898804783821106,
-2.2001187801361084,
-2.0704314708709717,
-0.5554717183113098,
5.328458309173584,
3.0391457080841064,
-4.295654296875,
-0.6730002760887146,
-5.105440616607666,
0.5214884877204895,
-1.2292194366455078,
-0.874693751335144,
-3.9954285621643066,
-0.25534865260124207,
-2.1901192665100098,
8.093463897705078,
-0.864460825920105,
0.9975801706314087,
0.45381563901901245,
0.045608773827552795,
0.10333479940891266,
-0.9367854595184326,
2.658450126647949,
4.847926616668701,
3.1627864837646484,
-3.9572408199310303,
6.637692928314209,
-1.3587199449539185,
-0.2942392826080322,
-1.0709693431854248,
-1.36146080493927,
-2.3354504108428955,
2.2582101821899414,
0.5794234275817871,
-5.089783668518066,
3.9759581089019775,
6.722696781158447,
-2.363520860671997,
-1.4506551027297974,
0.37265485525131226,
4.414368629455566,
0.922224223613739,
2.80344820022583,
2.1870365142822266,
1.3715001344680786,
2.5108563899993896,
-0.06768710911273956,
0.016961902379989624,
-5.491759300231934,
-2.188974618911743,
-6.869897365570068,
-2.2394344806671143,
0.7793116569519043,
-1.2509632110595703,
0.9370380640029907,
3.8124663829803467,
4.098287105560303,
-0.8360494375228882,
-3.8020546436309814,
-2.546821355819702,
-5.982780933380127,
4.361058712005615,
4.002274990081787,
1.437463402748108,
-3.3148815631866455,
2.476943016052246,
-2.668372631072998,
2.2998201847076416,
0.49358779191970825,
-1.8316415548324585,
-2.4343361854553223,
1.4462699890136719,
8.074532508850098,
1.0543357133865356,
0.7284864783287048,
2.763704538345337,
-3.4147086143493652,
-0.8495263457298279,
5.51450777053833,
5.865904331207275,
-0.8634836673736572,
3.999297857284546,
2.2077524662017822,
-2.4316718578338623,
4.192683219909668,
-1.4159584045410156,
2.08917498588562,
4.5429205894470215,
1.570852279663086,
-1.2582975625991821,
-4.257433891296387,
-2.7160749435424805,
5.726667404174805,
-0.6142498254776001,
2.568885087966919,
0.2809735834598541,
3.1567347049713135,
2.23248291015625,
1.1155951023101807,
6.1784281730651855,
-1.052476406097412,
-0.8833615779876709,
1.846227765083313,
0.8825157880783081,
-1.4468894004821777,
-0.7930479049682617,
3.6737775802612305,
1.7499536275863647,
-4.472019195556641,
1.1047037839889526,
1.6641494035720825,
0.6249755620956421,
1.4401034116744995,
-0.8742496967315674,
2.05430269241333,
-1.0177077054977417,
-0.8829973340034485,
-1.9259483814239502,
0.11630228161811829,
3.4688310623168945,
-2.9769351482391357,
-1.9840682744979858,
15.044188499450684,
-0.8570810556411743,
1.9501405954360962,
-3.4981689453125,
2.510443925857544,
3.5899503231048584,
-2.3726158142089844,
0.23363883793354034,
0.7484949827194214,
0.6284427046775818,
4.868407726287842,
2.7781155109405518,
-4.688655376434326,
5.553494930267334,
3.472703695297241,
-1.9815202951431274,
-3.3022358417510986,
2.9350814819335938,
3.9785258769989014,
-2.3674871921539307,
-3.2281105518341064,
1.634751319885254,
2.797602891921997,
0.10491600632667542,
-3.9945390224456787,
-0.1846565306186676,
2.214176654815674,
0.6928108334541321,
-3.3444647789001465,
-4.4965410232543945,
-1.9258458614349365,
-4.55368185043335,
-6.066025733947754,
1.579517126083374,
-0.061298128217458725,
-2.0320396423339844,
3.6613049507141113,
1.1991220712661743,
6.71068000793457,
-0.20035995543003082,
3.4695675373077393,
2.9921772480010986,
5.865469455718994,
1.018076777458191,
-2.018195152282715,
1.5514839887619019,
7.364731788635254,
4.011137008666992,
0.29808133840560913,
0.16895072162151337,
3.170443534851074,
2.274421215057373,
-2.9727365970611572,
2.680772542953491,
-0.8444386124610901,
0.36728426814079285,
0.18071646988391876,
3.6657981872558594,
7.069464683532715,
-0.10921701788902283,
0.49952876567840576,
-0.10052265971899033,
-3.0640199184417725,
-0.9281572103500366,
-1.3727264404296875,
-3.9582407474517822,
-1.478290319442749,
2.8559329509735107,
-2.2887556552886963,
-5.962973117828369,
1.1702955961227417,
-3.0737810134887695,
-1.6734060049057007,
-1.360888957977295,
-1.488382339477539,
-0.10332925617694855,
-0.2492319941520691,
-3.1653268337249756,
0.425719290971756,
3.8211510181427,
2.053650140762329,
-0.2018033117055893,
-4.402004718780518,
2.985631227493286,
-2.2109131813049316,
0.4897245764732361,
-0.9589419960975647,
0.4612155854701996,
2.5896759033203125,
0.3637409210205078,
3.290370225906372,
-0.8352606296539307,
-0.8434194326400757,
-5.34195613861084,
-3.4427998065948486,
2.6491568088531494,
1.8150891065597534,
-1.4421552419662476,
1.1361784934997559,
-0.7787467837333679,
-3.8555426597595215,
-2.4673306941986084,
-1.394074559211731,
-0.14918382465839386,
3.739903450012207,
-1.5827677249908447,
2.7378718852996826,
-0.5845848917961121,
8.43832015991211,
4.681511402130127,
4.540197849273682,
0.5192647576332092,
9.154011726379395,
5.119352340698242,
4.983821392059326,
2.6089601516723633,
4.969547748565674,
3.5975594520568848,
23.08266258239746,
-2.7487246990203857,
3.586392402648926,
1.721060037612915,
1.5361043214797974,
-0.09225545078516006,
0.9231963157653809,
1.0670558214187622,
2.5373518466949463,
3.4394421577453613,
4.816962242126465,
-4.113401412963867,
-2.359571695327759,
-1.250556230545044,
1.6705644130706787,
0.8198727369308472,
-4.548575401306152,
-2.211716890335083,
2.8640294075012207,
0.07712188363075256
],
"name": "fc_0.tmp_1",
"shape": [
1000
]
},
]
}
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
{
"ops": [
{
"attrs": {
"is_test": 1,
"use_mkldnn": false,
"threshold": 6.0
},
"inputs": {
"X": [
"relu6.tmp_2"
]
},
"outputs": {
"Out": [
"relu6.tmp_2-1"
]
},
"type": "relu6"
}
],
"vars": [
{
"data": [
-0.4105755090713501,
7.7698103189468384,
0.7541497945785522,
0.35911399126052856,
0.0,
0.0,
0.0,
0.5168685913085938,
0.9540461301803589,
0.9214242696762085
],
"name": "relu6.tmp_2",
"persistable": 0,
"shape": [
10
]
},
{
"data": [
0.0,
6.0,
0.7541497945785522,
0.35911399126052856,
0.0,
0.0,
0.0,
0.5168685913085938,
0.9540461301803589,
0.9214242696762085
],
"name": "relu6.tmp_2-1",
"persistable": 0,
"shape": [
10
]
}
]
}
{
"ops": [
{
"attrs": {
"is_test": 1,
"use_mkldnn": false,
"new_shape": [
-1,
0,
3,
2
]
},
"inputs": {
"X": [
"reshape_input"
]
},
"outputs": {
"Out": [
"reshape_output"
]
},
"type": "reshape2"
}
],
"vars": [
{
"data": [
0.0,
1.0,
2.0,
3.0,
4.0,
5.0,
6.0,
7.0,
8.0,
9.0,
10.0,
11.0,
12.0,
13.0,
14.0,
15.0,
16.0,
17.0,
18.0,
19.0,
20.0,
21.0,
22.0,
23.0
],
"name": "reshape_input",
"persistable": 0,
"shape": [
2,
4,
3
]
},
{
"data": [
0.0,
1.0,
2.0,
3.0,
4.0,
5.0,
6.0,
7.0,
8.0,
9.0,
10.0,
11.0,
12.0,
13.0,
14.0,
15.0,
16.0,
17.0,
18.0,
19.0,
20.0,
21.0,
22.0,
23.0
],
"name": "reshape_output",
"persistable": 0,
"shape": [
1,
4,
3,
2
]
}
]
}
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
"ops": [ "ops": [
{ {
"attrs": { "attrs": {
"bias": 0.0,
"bias_after_scale": true, "bias_after_scale": true,
"scale": 1.0 "scale": 2.0
}, },
"inputs": { "inputs": {
"X": [ "X": [
...@@ -43,16 +42,7 @@ ...@@ -43,16 +42,7 @@
{ {
"data": [ "data": [
1.6038109389511792e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 2, 3.3008389557533373e-16
1.6038109389511792e-28,
1.6038109389511792e-28,
1.6038109389511792e-28,
1.6038109389511792e-28,
1.6038109389511792e-28,
1.6038109389511792e-28,
1.6038109389511792e-28,
1.0,
1.6504194778766687e-16
], ],
"name": "scale_0.tmp_0", "name": "scale_0.tmp_0",
"persistable": 0, "persistable": 0,
......
[
"aberfeldy",
"ardbea",
"arran",
"balvenie",
"beefeater",
"ben_nevis",
"benriach",
"brewdog",
"bruichladdich",
"bunnahabhain",
"chimay",
"dalmore",
"edradour",
"erdinger",
"glendronach",
"glenfarclas",
"glenlivet",
"glenmorangie",
"glenscotia",
"gordon_macphail",
"g_vine",
"hakushu",
"hibiki",
"hoegaarden",
"jack_daniels",
"jiangxiaobai",
"jiaopianji",
"jim_beam",
"lazy_guys",
"lemonade",
"luxardo",
"macallan",
"maredsous",
"mastons",
"mortlach",
"paoshangou",
"paulaner",
"pearl_necklace",
"rollercoaster",
"shiqimen"
]
\ No newline at end of file
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.batchnorm.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'batchnorm';
const output = deepCopy(opInfo);
const expected = output.vars.find(item => item.name === 'batch_norm_12.tmp_2').data;
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expected));
}
test('test op batchnorm ==============>', async () => {
await run();
});
const WEBGL_CONF = {
alpha: false,
antialias: false,
premultipliedAlpha: false,
preserveDrawingBuffer: false,
depth: false,
stencil: false,
failIfMajorPerformanceCaveat: true
};
const WEBGL_WIDTH = 64;
const WEBGL_HEIGHT = 64;
const gl = require('gl')(WEBGL_WIDTH, WEBGL_HEIGHT, WEBGL_CONF);
export const webgl = gl;
export function deepCopy (data) {
return JSON.parse(JSON.stringify(data));
}
const getResult = function (id) {
const data = output.ops.filter(item => id === item.type);
return getoutputs(data[0]);
};
const getValue = function(name, datas) {
return datas.vars.find(item => name === item.name);
};
const OUTPUT_KEYS = ['out', 'y', 'output'];
const getoutputs = function (data) {
const outputkey = Object.keys(data.outputs).find(key => OUTPUT_KEYS.includes(key.toLowerCase()));
const outputTensorId = data.outputs[outputkey].slice(-1)[0];
const outputTensor = getValue(outputTensorId, output);
return outputTensor;
};
// get output tensor shape
let output = null;
export function getOutputShape (outputData, modelType) {
output = outputData;
var outputTensor = getResult(modelType);
return outputTensor.shape;
}
// NCHW shape 2 NHWC shape
export function nchwShape2nhwcShape(nchw) {
let batchNCHW = nchw;
if (nchw.length < 4) {
let batch = [];
for (let i = 0; i < (4 - nchw.length); i++) {
batch.push(1);
}
batchNCHW = batch.concat(nchw);
}
const N = batchNCHW[0];
const C = batchNCHW[1];
const H = batchNCHW[2];
const W = batchNCHW[3];
return [N, H, W, C];
}
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.concat.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'concat';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expected = [1, 2, 11, 3, 4, 12, 5, 6, 13, 7, 8, 14];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expected));
}
test('test op concat ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.conv2d.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'conv2d';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expectd = [
4, 4, 4, 4,
8, 8, 8, 8,
16, 16, 16, 16,
16, 16, 16, 16
];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expectd));
}
test('test op conv2d ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.depthwise_conv2d.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'depthwise_conv2d';
const output = deepCopy(opInfo);
const expected = output.vars.find(item => item.name === 'depthwise_conv2d_0.tmp_0').data;
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expected));
}
test('test op concat ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.elementwise_add.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'elementwise_add';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expectd = [-1.1135177612304688, 6.288958549499512, 3.139874219894409, 1.9048583507537842, 0.03913835436105728, 2.6481428146362305, 2.8079400062561035, 2.1263062953948975, -0.6012501120567322, -4.3257622718811035, 12, 13];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expectd));
}
test('test op elementwise_add ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.mul.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType= 'mul';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expectd = [9, -2, -1, 9, 9, 11];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expectd));
}
test('test op mul ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.relu.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'relu';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expectd = [
0,
0.7698103189468384,
0.7541497945785522,
0.35911399126052856,
0.0,
0.0,
0.0,
0.5168685913085938,
0.9540461301803589,
0.9214242696762085
];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expectd));
}
test('test op relu ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.relu6.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'relu6';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expectd = [
0.0,
6.0,
0.7541497945785522,
0.35911399126052856,
0.0,
0.0,
0.0,
0.5168685913085938,
0.9540461301803589,
0.9214242696762085
];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expectd));
}
test('test op relu6 ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.reshape.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'reshape2';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expeected = [
0.0,
1.0,
2.0,
3.0,
4.0,
5.0,
6.0,
7.0,
8.0,
9.0,
10.0,
11.0,
12.0,
13.0,
14.0,
15.0,
16.0,
17.0,
18.0,
19.0,
20.0,
21.0,
22.0,
23.0
];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expeected));
}
test('test op reshape2 ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.scale.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'scale';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
const expected = [3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 3.2076218779023584e-28, 2, 3.3008389557533373e-16];
expect(JSON.stringify(formatData)).toBe(JSON.stringify(expected));
}
test('test op scale ==============>', async () => {
await run();
});
import Graph from '../../src/graph/graph';
import GraphExecutor from '../../src/executor/executor';
import opInfo from '../../test/data/model.test.split.json';
import Utils from '../../src/utils/utils';
import {webgl} from './common';
import {nchwShape2nhwcShape, getOutputShape, deepCopy} from './common/utils';
const modelType = 'split';
const output = deepCopy(opInfo);
const op = opInfo.ops[0];
const graphExecutor = new GraphExecutor(op);
const graph = new Graph({
options: {
test: true,
gl: webgl
}
});
graph.data = opInfo;
graph.buildOpData(graphExecutor);
async function run() {
graph.execute_(graphExecutor);
let result = await graph.inst.read();
// 获取 NHWC -> NCHW 的 输出
const outputNCHWShape = getOutputShape(output, modelType);
const outputNHWCShape = nchwShape2nhwcShape(outputNCHWShape);
let nchwResult = Utils.nhwc2nchw(result, outputNHWCShape);
const formatData = Utils.formatReadData(nchwResult, outputNCHWShape);
expect(JSON.stringify(formatData)).toBe(JSON.stringify([ 4, 5, 6, 10, 11, 12, 16, 17, 18, 22, 23, 24 ]));
}
test('test op split ==============>', async () => {
await run();
});
...@@ -37,7 +37,7 @@ python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple ...@@ -37,7 +37,7 @@ python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
``` ```
- 如果`需要`使用优化模型的能力,执行命令: - 如果`需要`使用优化模型的能力,执行命令:
``` bash ``` bash
python -m pip install paddlepaddle paddlelite -i https://mirror.baidu.com/pypi/simple python -m pip install paddlepaddle paddlelite==2.6.0 -i https://mirror.baidu.com/pypi/simple
``` ```
### 1.2. 快速上手 ### 1.2. 快速上手
......
...@@ -23,7 +23,7 @@ def grantWritePermission(func, path, execinfo): ...@@ -23,7 +23,7 @@ def grantWritePermission(func, path, execinfo):
if __name__ == "__main__": if __name__ == "__main__":
""" """
Example: Example:
'python convertToPaddleJSModel.py --modelPath=../infer_model/MobileNetV2/__model__ --paramPath=../infer_model/MobileNetV2/params --outputDir=../jsmodel --optimize=1' 'python convertToPaddleJSModel.py --modelPath=../infer_model/MobileNetV2/model --paramPath=../infer_model/MobileNetV2/params --outputDir=../jsmodel --optimize=1'
""" """
try: try:
p = argparse.ArgumentParser(description='转化为PaddleJS模型参数解析') p = argparse.ArgumentParser(description='转化为PaddleJS模型参数解析')
......
...@@ -16,11 +16,11 @@ module.exports = { ...@@ -16,11 +16,11 @@ module.exports = {
minimize: true minimize: true
}, },
entry: { entry: {
index: ['./src/executor/runner'] index: ['./src/index']
}, },
output: { output: {
filename: '../graphfe/dep/paddleweb/index.min.js', filename: 'index.js',
path: path.resolve(__dirname, './'), path: path.resolve(__dirname, './pub/dist'),
library: 'panorama', library: 'panorama',
libraryTarget: 'umd', libraryTarget: 'umd',
libraryExport: 'default' libraryExport: 'default'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册