Voice-Gestuurde Web-Visualisaties, met Vue.js en Machine Learning

0
15

In deze tutorial paar Vue.js, three.js en LUIS (Cognitieve Diensten) te maken van een voice-gestuurde web-visualisatie.

Maar eerst een beetje context

Waarom zouden we moeten gebruik maken van spraakherkenning? Wat het probleem zou zoiets als dit op te lossen?

Een tijdje geleden was ik op een bus in Chicago. De buschauffeur had mij niet zien en sloot de deur op mijn pols. Als hij begon te gaan, en ik hoorde een knisperend geluid in mijn pols en hij deed uiteindelijk stoppen als de andere passagiers begonnen te schreeuwen, maar niet voordat hij scheurde een paar pezen in mijn arm.

Moest ik neem vrij van je werk, maar, typisch voor museum de medewerkers op dat moment was ik op contract en had geen echte gezondheid verzekering. Ik heb het niet zo op om te beginnen met het nemen van de tijd was gewoon geen optie voor mij. Ik werkte via de pijn. En, uiteindelijk, de gezondheid van mijn pols begon te verslechteren. Het werd echt pijnlijk zijn, zelfs mijn tanden poetsen. Voice-to-text was niet de alomtegenwoordige technologie die het nu is, en de beste tool dan beschikbaar was Draak. Het werkte goed, maar was behoorlijk frustrerend zijn om te leren en ik had nog steeds mijn handen vrij vaak voor omdat het vaak fout. Dat was 10 jaar geleden, dus ik ben er zeker van dat het bijzonder tech is duidelijk verbeterd sinds die tijd. Mijn pols is ook significant verbeterd in die tijd.

De hele ervaring heeft mij achtergelaten met een grote interesse in het spraakgestuurde technologieën. Wat kunnen we doen als we de controle van het gedrag van de web in ons voordeel, alleen maar door te spreken? Voor een experiment, heb ik besloten om gebruik LUIS, dat is een machine learning-service voor het bouwen van natuurlijke taal door het gebruik van aangepaste modellen die continu kan verbeteren. We kunnen deze gebruiken voor apps, bots, en IoT apparaten. Op deze manier kunnen we een visualisatie maken die reageert op elke stem — en het kan zelf verbeteren door te leren langs de weg.

GitHub Repo

Live Demo

Hier is een bird ‘ s eye view van wat we aan het bouwen bent:

Het opzetten van LUIS

We krijgen een gratis trial account voor Azure en ga vervolgens naar het portaal. We selecteren de Cognitieve Diensten.

Na het oppakken van Nieuw → AI/Machine Learning, we selecteer “Taal Begrijpen” (of LUIS).

Dan halen we uit onze naam en groep.

We verzamelen onze sleutels in het volgende scherm en ga dan naar de LUIS dashboard

Het is eigenlijk erg leuk om te trainen deze machines! We stellen een nieuwe toepassing en maken sommige opzichten, welke resultaten we willen triggeren op basis van een bepaalde aandoening. Hier is de voorbeeld van deze demo:

Je kan merken dat we een naamgevingsschema hier. We doen dit zodat het makkelijker is om te categoriseren, intents. We gaan eerst uitzoeken van de emotie en dan luisteren naar de intensiteit, zodat de oorspronkelijke bedoelingen worden voorafgegaan door ofwel App (deze worden voornamelijk gebruikt in de App.vue component) of Intensiteit.

Als we een duik in elk bijzonder opzet, zien we hoe het model is opgeleid. We hebben een aantal soortgelijke uitdrukkingen betekenen ongeveer hetzelfde:

U kunt zien hebben we een heleboel synoniemen voor training, maar we hebben ook de “Trein” knop bovenaan voor als we klaar om te beginnen met trainen van het model. We klikken op die knop, krijgen een succes kennisgeving, en dan zijn we klaar om te publiceren. 😀

Het opzetten van Vue

We maken een mooie standaard Vue.js toepassing via de Vue CLI. Ten eerste, wij draaien:

vue maak drie-vue-patroon
# selecteer vervolgens Handmatig…

Vue CLI v3.0.0

? Kies een voorinstelling:
standaard (babel, eslint)
“Het handmatig selecteren van functies

# Selecteer vervolgens de PWA-functie en de andere met de spatiebalk
? Kies een voorinstelling: het Handmatig selecteren van functies
? Controleer de functies die nodig zijn voor uw project:
◉ Babel
◯ TypeScript
◯ Progressieve Web App (PWA) Ondersteuning
◯ Router
◉ Vuex
◉ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testen
◯ E2E-Testen

? Kies een linter / formatter config:
ESLint met fout preventie alleen
ESLint + Airbnb config
“ESLint + Standaard config
ESLint + Mooier

? Kies extra lint eigenschappen: (Druk op <spatie> om te selecteren, een om te wisselen, ik omkeren selectie)
“◉ Lint op opslaan
◯ Lint en correctie op het plegen

Voor het succesvol project drie-vue-patroon.
Aan de slag met de volgende opdrachten:

$ cd drie-vue-patroon
$ garen dienen

Deze zal draaien tot een server voor ons en bieden een typisch Vue welkom scherm. We zullen ook toevoegen sommige afhankelijkheden onze applicatie: three.js sinus-golven, en axios. three.js zal helpen ons bij het creëren van de WebGL-visualisatie. sinus-golven geeft ons een mooi canvas abstractie voor de lader. axios zal ons toelaten een heel mooi HTTP-client, zodat we kunnen bellen LUIS voor analyse.

garen toevoegen drie sinus-golven axios

Het opzetten van onze Vuex winkel

Nu hebben we een werkend model, laten we gaan krijgen met de axios en brengen het in onze Vuex store. Dan kunnen we het verspreiden van de informatie naar alle van de verschillende componenten.

In staat, we slaan wat we nodig hebben:

staat: {
opzet: ‘Geen’,
intensiteit: ‘Geen’,
score: 0,
uiState: ‘stilstand’,
zoom: 3,
teller: 0,
},

de intentie en de intensiteit zal store de App, de intensiteit en de overleggingen, respectievelijk. De score zal slaan ons vertrouwen (dat is een score van 0 tot 100 te meten hoe goed het model denkt het te kunnen rangschikken van de ingang).

Voor uiState, we hebben drie verschillende staten:

  • idle – wachten voor de invoer van de gebruiker
  • luisteren – het horen van de input van de gebruiker
  • ophalen – het verkrijgen van gegevens van de gebruiker van de API

Zowel de zoom en de teller zijn wat we zullen gebruiken voor het bijwerken van de data-visualisatie.

Nu, in acties, we zetten de uiState (een mutatie) te halen, en maken we een oproep aan de API met axios met behulp van de gegenereerde sleutels kregen we bij het opzetten van LUIS.

getUnderstanding({ plegen }, uitspraak) {
commit(‘setUiState’, ‘ophalen’)
const url = `https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/4aba2274-c5df-4b0d-8ff7-57658254d042`

https: axios({
methode: ‘voor’,
url
params: {
uitgebreid: true,
timezoneOffset: 0,
q: uitspraak
},
headers: {
‘Content-Type’: ‘application/json’,
‘Ocp-Apim-Abonnement-Toets’: ‘XXXXXXXXXXXXXXXXXXX’
}
})

Dan, zodra we dat gedaan hebt, kunnen we voor de top-ranked scoren opzet en bewaar het in onze staat.

We moeten ook maken sommige mutaties, die we kunnen gebruiken om de status aan te passen. We gebruiken deze in onze acties. In de komende Vue 3.0, dit zal worden gestroomlijnd, omdat mutaties zullen worden verwijderd.

newIntent: (staat, { opzet, score }) => {
als lid van opzet.bevat(‘Intensiteit’)) {
staat.intensiteit = intentie
als lid van opzet.bevat(‘Meer’)) {
staat.teller++
} else if (opzet.bevat(‘Less’)) {
staat.teller–
}
} else {
staat.intent = intentie
}
staat.score = score
},
setUiState: (staat, status) => {
staat.uiState = status
},
setIntent: (staat, status) => {
staat.intent = status
},

Dit is allemaal vrij eenvoudig. We passeren in de staat, zodat wij u kunnen bijwerken voor elke gebeurtenis, met uitzondering van de Intensiteit, die zal de teller verhogen omhoog en omlaag, en dienovereenkomstig. We gaan gebruik maken van die teller in de volgende sectie voor het bijwerken van de visualisatie.

.dan(({ gegevens }) => {
console.log(‘axios resultaat’, gegevens)
als (altMaps.hasOwnProperty(gegevens.query)) {
commit(‘newIntent’, {
opzet: altMaps[data.query],
score: 1
})
} else {
commit(‘newIntent’ gegevens.topScoringIntent)
}
commit(‘setUiState’, ‘idle’)
commit(‘setZoom’)
})
.catch(err => {
console.fout(‘axios fout’, err)
})

In deze actie, zullen wij vastleggen van de mutaties gingen we gewoon naar boven of zich een fout als er iets mis gaat.

De manier waarop de logica van de werken, de gebruiker zal de eerste opname te zeggen hoe ze zich voelt. Ze zullen op een knop te schoppen. De visualisatie zal verschijnen en op dat punt zal de app continu te luisteren naar de gebruiker te zeggen in minder of meer om de controle van de geretourneerde visualisatie. Laten we de rest van de app.

De app instellen

In De App.vue, tonen we twee verschillende componenten voor het midden van de pagina, afhankelijk van het feit of we al hebben opgegeven op onze stemming.

<app-recordintent v-als=”intent === ‘None'” />
<app-recordintensity v-als=”doel !== ‘None'” :emotie=”opzet” />

Beide van deze informatie te zien voor de kijker als een SineWaves component, terwijl de UI in een luisterend staat.

De basis van de applicatie is waar de visualisatie weergegeven. Het zal laten zien met verschillende rekwisieten afhankelijk van de stemming. Hier zijn twee voorbeelden:

<app-base
v-als=”intent === ‘Blij'”
:t-config.a=”1″
:t-config.b=”200″
/>
<app-base
v-als=”intent === ‘Nerveus'”
:t-config.a=”1″
:color=”0xff0000″
:wireframe=”true”
:rainbow=”false”
:emissive=”true”
/>

Het instellen van een data visualisatie

Ik wilde aan het werk met kaleidoscope-achtige beelden voor de visualisatie en, na wat zoeken, vond deze repo. De manier waarop het werkt is dat een vorm verandert in de ruimte en dit zal breken de afbeelding uiteen en tonen stukken van het net als een kaleidoscope. Nu, dat klinkt misschien geweldig, omdat (yay!) het werk is gedaan, toch?

Helaas niet.

Er werden een aantal belangrijke wijzigingen die gedaan moest worden om dit werk te maken, en eindigde als een enorme onderneming, zelfs als de uiteindelijke visuele expressie lijkt op het origineel.

  • Vanwege het feit dat we nodig zouden hebben om te breken met de visualisatie als we besloten om het te veranderen, moest ik zetten de bestaande code te gebruiken bufferArrays, die meer performant voor dit doel.
  • De oorspronkelijke code was het één grote brok beschikbaar te hebben, zodat ik brak een aantal van de functies in kleinere methoden op het onderdeel om het makkelijker te maken om te lezen en te onderhouden.
  • Want we willen bijwerken dingen op de vlieg, ik had om op te slaan sommige van de items als de gegevens in het onderdeel, en uiteindelijk als rekwisieten die het wil ontvangen van de ouder. Ik heb ook een aantal leuke standaard (opgewonden is wat alle standaard uitzien).
  • We gebruiken de teller van de Vuex staat voor het bijwerken van de afstand van de camera ‘ s de plaatsing ten opzichte van het object, zodat we kunnen zien dat minder of meer van het en zo wordt het meer en minder complex.

Om verandering te brengen In de manier dat het lijkt volgens de configuraties maken we enkele rekwisieten:

rekwisieten: {
numAxes: {
type: Number,
standaard: 12,
nodig: false
},

tConfig: {
standaard() {
terug {
a: 2,
b: 3,
c: 100,
d: 3
}
},
nodig: false
}
},

We gebruiken deze wanneer we maken de vormen:

createShapes() {
deze.bufferCamera.positie.z = dit.shapeZoom

als dit.torusKnot !== null) {
deze.torusKnot.materiaal.dispose()
deze.torusKnot.geometrie.dispose()
deze.bufferScene.verwijder dit.torusKnot)
}

var shape = nieuwe DRIE.TorusKnotGeometry(
deze.tConfig.een,
deze.tConfig.b,
deze.tConfig.c,
deze.tConfig.d
),
materiaal

deze.torusKnot = nieuwe DRIE.Mesh(vorm, materiaal)
deze.torusKnot.materiaal.needsUpdate = true

deze.bufferScene.toevoegen(deze.torusKnot)
},

Zoals we eerder vermeld, dit is nu gesplitst in haar eigen methode. We maken er ook een andere methode die de aftrap voor de animatie, die zal ook opnieuw starten wanneer updates. De animatie maakt gebruik van requestAnimationFrame:

animate() {
deze.storeRAF = requestAnimationFrame(deze.animatie)

deze.bufferScene.rotatie.x += 0.01
deze.bufferScene.rotatie.y += 0.02

deze.renderer.render(
deze.bufferScene,
deze.bufferCamera,
deze.bufferTexture
)
deze.renderer.render(deze.scene, deze.de camera)
},

We maken een berekend eigenschap genoemd shapeZoom dat zal de terugkeer van de zoom van de winkel. Als je te herinneren, dit zal worden bijgewerkt als de stem van de gebruiker wijzigt de intensiteit.

berekend: {
shapeZoom() {
retourneren.$store.staat.zoom
}
},

We kunnen dan gebruik maken van een watcher om te zien of het zoom-niveau wijzigingen annuleren en de animatie, het herscheppen van de vormen, en opnieuw starten van de animatie.

bekijk: {
shapeZoom() {
deze.createShapes()
cancelAnimationFrame(deze.storeRAF)
deze.animate()
}
},

In gegevens, we zijn ook het opslaan van een paar dingen die we nodig hebben voor het instantiëren van de three.js scène — met name het maken van ervoor dat de camera precies gecentreerd is.

gegevens() {
terug {
bufferScene: DRIE nieuwe.Scène (de),
bufferCamera: DRIE nieuwe.PerspectiveCamera(75, 800 / 800, 0.1, 1000),
bufferTexture: DRIE nieuwe.WebGLRenderTarget(800, 800, {
minFilter: DRIE.LinearMipMapLinearFilter,
magFilter: DRIE.LinearFilter,
anti-alias: true
}),
camera: met de nieuwe DRIE.OrthographicCamera(
venster.innerWidth / -2,
venster.innerWidth / 2,
venster.innerHeight / 2,
venster.innerHeight / -2,
0.1,
1000
),

Er is meer aan deze demo, als u wilt verken de repo of stel het zelf met uw eigen parameters. De methode init doet wat je denkt dat het zou kunnen: het initialiseren van de hele visualisatie. Ik heb het commentaar van veel van de belangrijkste onderdelen als je gluren bij de bron code. Er is ook een andere methode waarmee de geometrie dat heet — u uessed — updateGeometry. U ziet veel van vars daar zo goed. Dat komt omdat het gebruikelijk om hergebruik variabelen in deze vorm van visualisatie. We schoppen alles uit door te bellen.init() in de gemonteerde() levenscyclus van de haak.

  • Nogmaals, hier is de repo als je wilt spelen met de code
  • U kunt uw eigen model door het verkrijgen van een gratis Azure account
  • U zult ook willen om te controleren LUIS (Cognitieve Diensten)

Het is best leuk om te zien hoe ver je kunt krijgen het maken van dingen voor het web dat hoeft niet per se een hand beweging te controleren. Het opent veel mogelijkheden!