/* * MIT License * * Copyright (c) 2019 Alexey Edelev * * This file is part of NeuralNetwork project https://git.semlanik.org/semlanik/NeuralNetwork * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 1.4 import NeuralNetworkUi 0.1 import remotecontrol 1.0 ApplicationWindow { id: root visible: true width: 1024 height: 768 Rectangle { id: bottomLayer anchors.fill: parent color: "#000000" } Row { id: rowww anchors.left: parent.left anchors.top: parent.top anchors.margins: 10 Repeater { id: layerRepeater model: visualizerModel.sizes.length delegate: Item { id: layerDelegate property alias neurons: neuronRepeater anchors.verticalCenter: parent.verticalCenter property int layerIndex: model.index property int layerSize: visualizerModel.sizes[layerIndex] width: 120 height: activationsColumn.height Column { id: activationsColumn width: 50 spacing: 10 Repeater { id: neuronRepeater model: layerSize delegate:Rectangle { width: 20 height: 20 radius: 10 color: "#00ffffff" Rectangle { id: neuron property ValueIndicator activation: visualizerModel.activation(layerIndex, model.index) anchors.fill: parent radius: 15 color: "#00ff00" ColorAnimation { id: anim target: neuron property: "color" to: "#000000" duration: 100 } function updateColor() { var alpha = activation.value; neuron.color = anim.to anim.stop() anim.from = anim.to anim.to = Qt.rgba(0, 1, 0, Math.max(0.08, alpha)) anim.start() } Component.onCompleted: { visualizerModel.activationTrigger(layerIndex).updateLayer.connect(neuron.updateColor); } } } } } } } onWidthChanged: { console.log("width: " + width) if (width !== visualizerModel.sizes.length*120) { return } for (var i = 1; i < layerRepeater.count; i++) { var neurons = layerRepeater.itemAt(i).neurons var neuronsPrev = layerRepeater.itemAt(i - 1).neurons for (var j = 0; j < neurons.count; j++) { var neuron = neurons.itemAt(j) var coord = layerRepeater.itemAt(i).mapToItem(root.contentItem, neuron.x + neuron.width/2, neuron.y + neuron.height/2) for(var k = 0; k < neuronsPrev.count; k++) { var neuronPrev = neuronsPrev.itemAt(k) var coordPrev = layerRepeater.itemAt(i - 1).mapToItem(root.contentItem, neuronPrev.x + neuronPrev.width/2, neuronPrev.y + neuronPrev.height/2) var angle = Math.atan2(coordPrev.y - coord.y, coordPrev.x - coord.x) * 180 / Math.PI var length = Math.sqrt(Math.pow(coordPrev.x - coord.x, 2) + Math.pow(coordPrev.y - coord.y, 2)) var obj = connectionComponent.createObject(bottomLayer, { x: coord.x, y: coord.y, width: length, angle: angle, weight: visualizerModel.weight(i, j, k), }) visualizerModel.weightTrigger(i).updateLayer.connect(obj.updateColor); } } } } } Component { id: connectionComponent Rectangle { id: connection property alias angle: trans.angle property ValueIndicator weight: null transformOrigin: Item.Left transform: Rotation { id: trans } color: "transparent" height: 1 function updateColor() { var newColor = weight.value; connection.color = Qt.rgba(newColor, 0, 1.0 - newColor, newColor > 0 ? 0.5 : 0.0) } } } Row { anchors.right: parent.right anchors.top: parent.top anchors.margins: 20 spacing: 10 Text { color: "#ffffff" text: "Active state: " + visualizerModel.networkState.state } Button { id: start text: "Start" enabled: visualizerModel.networkState.state === NetworkState.Idle onClicked: { visualizerModel.start(); } } } }