| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <template>
- <v-card width="50%" flat>
- <v-row>
- <v-col md="6" cols="12">
- <v-menu
- v-for="(layer, i) in layers"
- :key="i"
- offset-x
- :close-on-content-click="false"
- >
- <template v-slot:activator="{ on }">
- <v-card height="50" width="100%" class="ml-2" tile v-on="on">
- <v-row>
- <v-col cols="2" class="text-center">
- {{ i + 1 }}
- </v-col>
- <v-col cols="10" class="text-center">
- {{ layer.layerName }}
- </v-col>
- </v-row>
- </v-card>
- </template>
- <!-- Conv2d Setting Board -->
- <layer-setting-board
- v-if="layer.layerType === 'conv2d'"
- :layer="layer"
- >
- <v-row>
- <v-col cols="12" md="4">
- <v-select
- v-model="layer.kernelSize"
- :items="[1, 2, 3, 4, 5, 6]"
- label="Kernel Size"
- />
- </v-col>
- <v-col cols="12" md="4">
- <v-select
- v-model="layer.filters"
- :items="[16, 32, 48, 64]"
- label="Filters"
- />
- </v-col>
- <v-col cols="12" md="4">
- <v-select
- v-model="layer.activation"
- :items="activations"
- label="Activation"
- />
- </v-col>
- </v-row>
- </layer-setting-board>
- <!-- Pooling Layer Setting Board -->
- <layer-setting-board
- v-else-if="isPoolingLayer(layer.layerType)"
- :layer="layer"
- >
- <v-row>
- <v-col cols="12" md="6">
- <v-select
- v-model="layer.poolsize"
- label="Pool Size"
- :items="[2, 3, 4, 5, 6]"
- />
- </v-col>
- <v-col cols="12" md="6">
- <v-select
- v-model="layer.strides"
- label="Strides"
- :items="[2, 3, 4, 5, 6]"
- />
- </v-col>
- </v-row>
- </layer-setting-board>
- <!-- Dense Layer Setting Board -->
- <layer-setting-board
- v-else-if="layer.layerType === 'dense'"
- :layer="layer"
- >
- <v-row>
- <v-col cols="12" md="4">
- <v-select
- v-model="layer.activation"
- :items="activations"
- label="Activation"
- />
- </v-col>
- <v-col cols="12" md="4">
- <v-text-field
- v-model="layer.units"
- type="number"
- label="Units"
- />
- </v-col>
- </v-row>
- </layer-setting-board>
- <!-- Dense Layer Setting Board -->
- </v-menu>
- <v-row>
- <v-col cols="12" class="text-right mx-2">
- <!-- buttons for adding new layer -->
- <v-menu :close-on-content-click="false" offset-x>
- <template v-slot:activator="{ on }">
- <v-btn block large outlined color="primary" v-on="on">
- Add Layer
- </v-btn>
- </template>
- <v-card max-width="450" class="pa-2">
- <v-row>
- <v-btn
- v-for="(item, i) in addLayerBtns"
- :key="i"
- color="primary"
- class="ma-2"
- @click="item.clickCallback"
- >
- {{ item.layerType }}
- </v-btn>
- </v-row>
- </v-card>
- </v-menu>
- </v-col>
- <v-col cols="12">
- <v-btn block outlined color="success" @click="compileModel">
- Compile
- </v-btn>
- </v-col>
- </v-row>
- </v-col>
- </v-row>
- </v-card>
- </template>
- <script lang="ts">
- import Vue from 'vue'
- import * as tf from '@tensorflow/tfjs'
- import { Layer, LayerType, activations } from './layer'
- import LayerSettingBoard from './LayerSetttingBoard.vue'
- import { IMAGE_H, IMAGE_W } from './data'
- const headers = [
- { text: 'Layer Name', value: 'layerName' },
- { text: 'Output Shape', value: 'outputShape' },
- { text: 'Number of Params', value: 'paramsNum' },
- { text: 'Trainable', value: 'trainable' }
- ]
- interface AddLayerButton {
- layerType: LayerType
- clickCallback: () => void
- }
- export default Vue.extend({
- components: {
- LayerSettingBoard
- },
- data() {
- return {
- headers,
- addLayerBtns: [] as AddLayerButton[],
- layers: [] as Layer[],
- settingBoardWidth: 500,
- settingBoardHeight: 300,
- activations
- }
- },
- created() {
- this.addLayerBtns = [
- {
- layerType: 'conv2d',
- clickCallback: () => this.layers.push(Layer.conv2dLayer())
- },
- {
- layerType: 'maxPooling2d',
- clickCallback: () => this.layers.push(Layer.maxPooling2dLayer())
- },
- {
- layerType: 'averagePooling2d',
- clickCallback: () => this.layers.push(Layer.averagePooling2dLayer())
- },
- {
- layerType: 'flatten',
- clickCallback: () => this.layers.push(Layer.flattenLayer())
- },
- {
- layerType: 'dense',
- clickCallback: () => this.layers.push(Layer.denseLayer())
- }
- ]
- },
- methods: {
- isPoolingLayer(layerType: string) {
- return layerType === 'maxPooling2d' || layerType === 'averagePooling2d'
- },
- compileModel() {
- const model = tf.sequential()
- for (let i = 0; i < this.layers.length; i++) {
- const layer = this.layers[i]
- if (i === 0) {
- model.add(layer.toTfLayer([IMAGE_W, IMAGE_H, 1]))
- } else {
- model.add(layer.toTfLayer())
- }
- }
- model.summary()
- }
- }
- })
- </script>
- <style scoped></style>
|