mirror of
https://github.com/wassname/keras-js.git
synced 2026-09-17 12:20:32 +08:00
update ResNet50 demo
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
:checked.sync="useGpu"
|
||||
:disabled="modelLoading || !hasWebgl"
|
||||
@click="toggleGpu"
|
||||
>Use GPU</mdl-switch>
|
||||
>use GPU</mdl-switch>
|
||||
</div>
|
||||
<div class="column output-column">
|
||||
<div class="output">
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
:checked.sync="useGpu"
|
||||
:disabled="modelLoading || !hasWebgl"
|
||||
@click="toggleGpu"
|
||||
>Use GPU</mdl-switch>
|
||||
>use GPU</mdl-switch>
|
||||
<div class="coordinates">
|
||||
<div class="coordinates-x">x: {{ inputCoordinates[0] < 0 ? inputCoordinates[0].toFixed(2) : inputCoordinates[0].toFixed(3) }}</div>
|
||||
<div class="coordinates-y">y: {{ inputCoordinates[1] < 0 ? inputCoordinates[1].toFixed(2) : inputCoordinates[1].toFixed(3) }}</div>
|
||||
|
||||
+158
-125
@@ -1,167 +1,200 @@
|
||||
@import './_variables.css';
|
||||
|
||||
.demo.resnet50 {
|
||||
.input-container {
|
||||
margin: 20px;
|
||||
.top-container {
|
||||
margin: 10px;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
|
||||
.input-label {
|
||||
font-family: $font-3;
|
||||
font-size: 16px;
|
||||
color: $color-2;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.image-url {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
margin: 0 10px;
|
||||
.input-container {
|
||||
.input-label {
|
||||
font-family: $font-3;
|
||||
font-size: 16px;
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.column.input-column {
|
||||
justify-content: flex-end;
|
||||
|
||||
.loading-indicator {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
|
||||
.mdl-spinner {
|
||||
margin: 20px;
|
||||
align-self: center;
|
||||
text-align: left;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: $color-err;
|
||||
font-size: 14px;
|
||||
font-family: $font-1;
|
||||
margin: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.canvas-container {
|
||||
display: inline-flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
canvas {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column.controls-column {
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.column.output-column {
|
||||
justify-content: flex-start;
|
||||
|
||||
.output {
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
|
||||
.output-class {
|
||||
.image-url {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 6px 0;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
|
||||
.output-label {
|
||||
text-align: right;
|
||||
width: 200px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: $font-2;
|
||||
font-size: 18px;
|
||||
color: $color-2;
|
||||
padding: 0 6px;
|
||||
border-right: 2px solid $color-1-lighter;
|
||||
}
|
||||
|
||||
.output-bar {
|
||||
height: 8px;
|
||||
transition: width 0.2s ease-out;
|
||||
}
|
||||
|
||||
.output-value {
|
||||
text-align: left;
|
||||
margin-left: 5px;
|
||||
font-family: $font-2;
|
||||
font-size: 14px;
|
||||
span {
|
||||
margin: 0 10px;
|
||||
font-family: $font-3;
|
||||
font-size: 16px;
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.output-class.predicted {
|
||||
.output-label {
|
||||
color: $color-1;
|
||||
border-left-color: $color-1;
|
||||
.controls {
|
||||
width: 250px;
|
||||
margin-left: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
& > .mdl-switch {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.mdl-switch__label {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.columns.input-output {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.column.input-column {
|
||||
position: relative;
|
||||
|
||||
.loading-indicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
|
||||
.mdl-spinner {
|
||||
margin: 20px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.output-value {
|
||||
color: $color-1;
|
||||
.error {
|
||||
color: $color-err;
|
||||
font-size: 14px;
|
||||
font-family: $font-1;
|
||||
margin: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.canvas-container {
|
||||
display: inline-flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
canvas {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column.output-column {
|
||||
.output {
|
||||
width: 370px;
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
|
||||
.output-class {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 6px 0;
|
||||
|
||||
.output-label {
|
||||
text-align: right;
|
||||
width: 200px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: $font-2;
|
||||
font-size: 18px;
|
||||
color: $color-2;
|
||||
padding: 0 6px;
|
||||
border-right: 2px solid $color-1-lighter;
|
||||
}
|
||||
|
||||
.output-bar {
|
||||
height: 8px;
|
||||
transition: width 0.2s ease-out;
|
||||
}
|
||||
|
||||
.output-value {
|
||||
text-align: left;
|
||||
margin-left: 5px;
|
||||
font-family: $font-2;
|
||||
font-size: 14px;
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
|
||||
.output-class.predicted {
|
||||
.output-label {
|
||||
color: $color-1;
|
||||
border-left-color: $color-1;
|
||||
}
|
||||
|
||||
.output-value {
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.architecture-container {
|
||||
max-width: 800px;
|
||||
width: 800px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
|
||||
.layers-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 5px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.layer {
|
||||
display: inline-block;
|
||||
background: white;
|
||||
border: 2px solid white;
|
||||
border-radius: 5px;
|
||||
padding: 2px 10px 0px;
|
||||
.layer-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.layer-class-name {
|
||||
color: $color-1;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
.layer {
|
||||
display: inline-block;
|
||||
background: white;
|
||||
border: 2px solid white;
|
||||
border-radius: 5px;
|
||||
padding: 2px 10px 0px;
|
||||
|
||||
.layer-class-name {
|
||||
color: $color-1;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.layer-details {
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-details {
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
.layer.has-result {
|
||||
border-color: $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
.layer.has-result {
|
||||
border-color: $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
.architecture-connections {
|
||||
|
||||
@@ -34,7 +34,7 @@ export const ResNet50 = Vue.extend({
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
model: new KerasJS.Model(Object.assign({ gpu: this.hasWebgl }, MODEL_CONFIG)),
|
||||
model: new KerasJS.Model(Object.assign({ gpu: this.hasWebgl, layerCallPauses: true }, MODEL_CONFIG)),
|
||||
modelLoading: true,
|
||||
modelRunning: false,
|
||||
imageURLInput: null,
|
||||
@@ -46,7 +46,8 @@ export const ResNet50 = Vue.extend({
|
||||
architectureDiagram: ARCHITECTURE_DIAGRAM,
|
||||
architectureConnections: ARCHITECTURE_CONNECTIONS,
|
||||
architectureDiagramPaths: [],
|
||||
useGpu: this.hasWebgl
|
||||
useGpu: this.hasWebgl,
|
||||
showComputationFlow: true
|
||||
}
|
||||
},
|
||||
|
||||
@@ -73,7 +74,7 @@ export const ResNet50 = Vue.extend({
|
||||
if (!this.output) {
|
||||
let empty = []
|
||||
for (let i = 0; i < 5; i++) {
|
||||
empty.push({ name: '.', probability: 0 })
|
||||
empty.push({ name: '-', probability: 0 })
|
||||
}
|
||||
return empty
|
||||
}
|
||||
@@ -122,6 +123,10 @@ export const ResNet50 = Vue.extend({
|
||||
this.model.toggleGpu(!this.useGpu)
|
||||
},
|
||||
|
||||
toggleComputationFlow: function () {
|
||||
this.model.layerCallPauses = !this.showComputationFlow
|
||||
},
|
||||
|
||||
imageURLInputChanged: function (e) {
|
||||
this.imageURLSelect = null
|
||||
this.loadImageToCanvas(this.imageURLInput)
|
||||
|
||||
@@ -6,24 +6,38 @@
|
||||
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
|
||||
Loading...{{ loadingProgress }}%
|
||||
</div>
|
||||
<div class="input-container" v-if="!modelLoading">
|
||||
<div class="input-label">Enter a valid image URL or select an image from the dropdown:</div>
|
||||
<div class="image-url">
|
||||
<mdl-textfield
|
||||
floating-label="enter image url"
|
||||
:value.sync="imageURLInput"
|
||||
spellcheck="false"
|
||||
@change="imageURLInputChanged"
|
||||
></mdl-textfield>
|
||||
<span>or</span>
|
||||
<mdl-select
|
||||
label="select image"
|
||||
id="image-url-select"
|
||||
:value.sync="imageURLSelect"
|
||||
:options="imageURLSelectList"
|
||||
style="width:200px;"
|
||||
@change="imageURLSelectChanged"
|
||||
></mdl-select>
|
||||
<div class="top-container" v-if="!modelLoading">
|
||||
<div class="input-container">
|
||||
<div class="input-label">Enter a valid image URL or select an image from the dropdown:</div>
|
||||
<div class="image-url">
|
||||
<mdl-textfield
|
||||
floating-label="enter image url"
|
||||
:value.sync="imageURLInput"
|
||||
spellcheck="false"
|
||||
@change="imageURLInputChanged"
|
||||
></mdl-textfield>
|
||||
<span>or</span>
|
||||
<mdl-select
|
||||
label="select image"
|
||||
id="image-url-select"
|
||||
:value.sync="imageURLSelect"
|
||||
:options="imageURLSelectList"
|
||||
style="width:200px;"
|
||||
@change="imageURLSelectChanged"
|
||||
></mdl-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<mdl-switch
|
||||
:checked.sync="useGpu"
|
||||
:disabled="modelLoading || modelRunning || !hasWebgl"
|
||||
@click="toggleGpu"
|
||||
>Use GPU</mdl-switch>
|
||||
<mdl-switch
|
||||
:checked.sync="showComputationFlow"
|
||||
:disabled="modelLoading || modelRunning"
|
||||
@click="toggleComputationFlow"
|
||||
>Show computation flow</mdl-switch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns input-output" v-if="!modelLoading">
|
||||
@@ -36,13 +50,6 @@
|
||||
<canvas id="input-canvas" width="224" height="224"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-2 controls-column">
|
||||
<mdl-switch
|
||||
:checked.sync="useGpu"
|
||||
:disabled="modelLoading || modelRunning || !hasWebgl"
|
||||
@click="toggleGpu"
|
||||
>Use GPU</mdl-switch>
|
||||
</div>
|
||||
<div class="column output-column">
|
||||
<div class="output">
|
||||
<div class="output-class"
|
||||
@@ -59,8 +66,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="architecture-container" v-if="!modelLoading">
|
||||
<div v-for="row in architectureDiagramRows" class="layers-row columns">
|
||||
<div v-for="layer in row" class="column">
|
||||
<div v-for="row in architectureDiagramRows" class="layers-row">
|
||||
<div v-for="layer in row" class="layer-column">
|
||||
<div
|
||||
v-if="layer.className"
|
||||
class="layer"
|
||||
|
||||
Reference in New Issue
Block a user