!7 cmodule PerceptronVAD1 > DynImageSurface { switchable int w = 5; switchable int h = 10; switchable int nMaxExamples = 2000; switchable S teacherModule; // an accurate VAD that we learn from switchable bool learn; switchable bool train; switchable double c = 1; transient S status; new Perceptron perceptron; transient double[] parameters; transient ReliableSingleThread rstTrain = dm_rst(this, r train); transient double lastError; visualize { JComponent c = super.visualize(); imageSurface_pixelated(imageSurface); setZoom(20); ret centerAndSouth(c, withMargin(vstackWithSpacing( centerAndEastWithMargin(dm_textFieldWithLabel teacherModule(), dm_checkBox learn()), centerAndEastWithMargin(dm_label status(), dm_checkBox train())))); } start { updateStatus(); dm_requireLiveAudioFFT(); dm_audioInput_enableSendOutClonedData(); dm_vmBus_onMessage_q newAudioFrequencyImageFromData(voidfunc(virtual BWImage _img, short[] fromData) { BWImage img = cast quickImport(_img); BWIntegralImage ii = new(img); BWImage bw = scaleDownUsingIntegralImageBW(ii, w, h); setImage(bw); parameters = concatDoubleArrays( bwImage_averageBrightnessPerRow(bw), bwImage_standardDeviationPerRow(bw)); if (teacherModule != null && learn) { Bool va = cast dm_call(teacherModule, 'hasVoiceActivity, fromData); // TODO: wait a bit while va == null print("va: " + va); if (va != null && l(perceptron.examples) < nMaxExamples) { perceptron.addExample(parameters, va); change(); updateStatus(); rstTrain.trigger(); } } }); dm_watchFieldAndNow c(r {perceptron.c = c }); dm_watchFieldAndNow train(rstTrain); } void train enter { if (!train) ret; print("Training"); long n = 0; for ping (Double error : perceptron.trainingIterator()) { if (deleted || !train) ret; ++n; if (error != null) lastError = error; if (error != null || (perceptron.trainingRound % 10000) == 0) { //perceptron.printWithWeights(); updateStatus(); change(); } } print("Trained (" + nRounds(n) + ")"); } void updateStatus { setField(status := "Error: " + firstNonNegativeDouble_orMinus1(perceptron.error, lastError) + " for " + nExamples(perceptron.examples) + ", " + nRounds(perceptron.trainingRound)); } }