Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Learn site typos #427

Merged
merged 19 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/routes/(content)/learn/batch-processing/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ There is also [this](https://discourse.flucoma.org/t/supernova-supercollider-una
</TabPanel>
</Tabs>

In this example a single audio file is sliced into a collection of segments. Each segment will be analysed with an audio descriptor and the result for that segment will be stored in a [DataSet](/reference/dataset).The example illustrates how one can iterate through several portions of the source buffer and use the segmentation result to control a process that only analyses specific portions of time in the source file.
In this example a single audio file is sliced into a collection of segments. Each segment will be analysed with an audio descriptor and the result for that segment will be stored in a [DataSet](/reference/dataset). The example illustrates how one can iterate through several portions of the source buffer and use the segmentation result to control a process that only analyses specific portions of time in the source file.

The step-by-step workflow is as follows:

Expand Down Expand Up @@ -181,7 +181,7 @@ src='/examples/batch/add-list.png'
alt='Using vexpr to add two lists together'
/>

The complexity of the patching hasn't increased greatly, and by replacing `+` with `vexpr` (vector expression), we can process entire lists of values. The patch will also still work with single value inputs (scalars) making it much more flexible than what we had originally. While the patching itself is not too complicated, knowing about the existence of these objects and how they work is not greatly emphasised in the way visual programming is taught wich is often concerned entirely with _streams_ of scalar values. Furthermore, while this is just a toy example, it demonstrates that the notion of processing groups of things together is not the **first** and **most obvious** way to patch. Conversely, SuperCollider has the language (sclang) which offers built-in methods for dealing with arrays of data. Most operators are also _overloaded_, meaning the interface for adding two integers is roughly the same as adding two arrays of integers. For example:
The complexity of the patching hasn't increased greatly, and by replacing `+` with `vexpr` (vector expression), we can process entire lists of values. The patch will also still work with single value inputs (scalars) making it much more flexible than what we had originally. While the patching itself is not too complicated, knowing about the existence of these objects and how they work is not greatly emphasised in the way visual programming is taught, which is often concerned entirely with _streams_ of scalar values. Furthermore, while this is just a toy example, it demonstrates that the notion of processing groups of things together is not the **first** and **most obvious** way to patch. Conversely, SuperCollider has the language (sclang) which offers built-in methods for dealing with arrays of data. Most operators are also _overloaded_, meaning the interface for adding two integers is roughly the same as adding two arrays of integers. For example:

<CodeBlock title='Operator overloading'>

Expand Down
2 changes: 1 addition & 1 deletion src/routes/(content)/learn/bufnmf/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ As you can see (and hear in the playback), these different drum hits overlap qui

This is where non-negative matrix factorisation can be quite useful.

We can use BufNMF to analyze the drum loop’s spectrogram and determine which parts of the spectrum always (or often) occur together in time. For example, in the snare hits (the green boxes) you can see the different partials of the drum head’s resonant tone (the horizontal bands from ~300 Hz to ~2000 Hz) always occurring together. Sometimes there is also some cymbal sound happening (above that in a red box), but because the cymbal sound is often not there, NMF will try to decompose the spectrogram in such a way that these can be considered separate components. In general, the more that different sound objects are separated out in time and the more repetitions of each sound object, the better BufNMF will be at identifying and separating them.
We can use BufNMF to analyze the drum loop’s spectrogram and determine which parts of the spectrum always (or often) occur together in time. For example, in the snare hits (the blue boxes) you can see the different partials of the drum head’s resonant tone (the horizontal bands from ~300 Hz to ~2000 Hz) always occurring together. Sometimes there is also some cymbal sound happening (above that in a yellow box), but because the cymbal sound is often not there, NMF will try to decompose the spectrogram in such a way that these can be considered separate components. In general, the more that different sound objects are separated out in time and the more repetitions of each sound object, the better BufNMF will be at identifying and separating them.

Processing this mono drum loop with BufNMF (specifying that we want it to try to decompose the sound into three components) returns these three buffers, one with each component it was able to separate:

Expand Down
4 changes: 2 additions & 2 deletions src/routes/(content)/learn/decomposition-overview/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ featuredimage: /img/flucoma-magical.jpg

## Introduction

One of the strongest arms of the toolkit is its *decomposition* capabilities. If you’re not familiar with the term, the basic idea is that any mixed sound is likely to be made up of many other sounds. Unfortunately it can be really hard to find and listen to those “hidden” sounds so decomposition offers some strategies, algorithms and manoeuvres that help you discover and explore the internal structure of a sound.
One of the strongest arms of the toolkit is its *decomposition* capabilities. If you’re not familiar with the term, the basic idea is that any mixed sound is likely to be made up of many other sounds. Unfortunately it can be really hard to find and listen to those “hidden” sounds, so decomposition offers some strategies, algorithms and manoeuvres that help you discover and explore the internal structure of a sound.

Here on the team, we tend to think of there being two types of objects that deal with this process distinctly.

Expand All @@ -38,4 +38,4 @@ These objects take sounds and *deconstruct* them, returning to you a set of new

Separation techniques often open the musical question: “What are you hoping to find?”. Sometimes these objects can serve a direct and clear purpose such as wanting to extract a specific sound from a mixed source. On the other hand, they can also function as speculative tools, and can be used to listen to what might be lurking in the mixture. In this vein, there is a wonderful object called [BufNMF](/reference/bufnmf). Perhaps one of, if not THE most powerful tool in the toolkit on its own it can be used for “blind source separation”, classification, feature learning amongst many other things. We have a great set of articles talking about how you can use [BufNMF](/reference/bufnmf), such as [Seeding BufNMF with Bases and Activations](/learn/seeding-nmf), and [Audio Decomposition Using BufNMF](/learn/bufnmf).

Lastly is the world of hybridisation through separation. Imagine you want to cross the bright timbre of a hi-hat with the envelope of a synthesiser. This is where objects like [AudioTransport](/reference/audiotransport) and [BufNMFCross](/reference/bufnmfcross) come into play. These are definitely not easy points of entry though so try out the other objects first!
Lastly is the world of hybridisation through separation. Imagine you want to cross the bright timbre of a hi-hat with the envelope of a synthesiser. This is where objects like [AudioTransport](/reference/audiotransport) and [BufNMFCross](/reference/bufnmfcross) come into play. These are definitely not easy points of entry though so try out the other objects first!
4 changes: 2 additions & 2 deletions src/routes/(content)/learn/mlp-parameters/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Because changing `hiddenLayers` changes the internal structure of the neural net

Generally speaking, the larger the internal structure of a neural network is, the more data points it needs to train. A general-principle is to have about ten times as many data points as there are the total number of internal parameters. The number of internal parameters in a neural network is total number of weights + the total number of biases. The total number of weights equals the sum of the products of each pair of adjacent layers. The total number of biases is equal to the number of hidden neurons + the number of output neurons.

For example, consider a neural network with 13 input neurons, two hidden layers of 5 and 4 neurons, and an output layer of 3 neurons. The total number of weights is `( 13 * 5 ) + ( 5 * 4 ) + ( 4 * 3 ) = 97`. The total number of biases is `5 + 4 + 3 = 12`. Which makes the total number of parameters `97 + 12 = 109`. The general-principle suggests that it would be good to have around 1,000 data points (about ten times as many) to successfully train this neural network. In practice, a neural network of this size may be able to learn from many fewer points. It completely depends on how clearly patterns in the data are represented. This general-principle may become important if your training is not going well--consider how many point you have and how that compares to how may internal parameters are in your neural nentwork. Based on these numbers consider changing the size of your neural network or using a different number of data points and see if your neural network improves.
For example, consider a neural network with 13 input neurons, two hidden layers of 5 and 4 neurons, and an output layer of 3 neurons. The total number of weights is `( 13 * 5 ) + ( 5 * 4 ) + ( 4 * 3 ) = 97`. The total number of biases is `5 + 4 + 3 = 12`. Which makes the total number of parameters `97 + 12 = 109`. The general-principle suggests that it would be good to have around 1,000 data points (about ten times as many) to successfully train this neural network. In practice, a neural network of this size may be able to learn from many fewer points. It completely depends on how clearly patterns in the data are represented. This general-principle may become important if your training is not going well--consider how many point you have and how that compares to how many internal parameters are in your neural network. Based on these numbers consider changing the size of your neural network or using a different number of data points and see if your neural network improves.

<Image
src="/learn/mlp/13-5-4-3.txt.png"
Expand Down Expand Up @@ -75,7 +75,7 @@ The `learnRate` is a scalar for indicating how much the neural network should ad

## `maxIter`

`maxIter` indicates how many epochs to train for when `fit` is called on the object. An epoch is consists of training on all the data points one time. For example, if `maxIter` is set to 100, when `fit` is called the neural network will use each input-output example pair 100 times before returning the "error" to report how it is performing. The reason it represents a _maximum_ number of epochs is related to the [`validation`](#validation) (below).
`maxIter` indicates how many epochs to train for when `fit` is called on the object. An epoch consists of training on all the data points one time. For example, if `maxIter` is set to 100, when `fit` is called the neural network will use each input-output example pair 100 times before returning the "error" to report how it is performing. The reason it represents a _maximum_ number of epochs is related to the [`validation`](#validation) (below).

## `validation`

Expand Down
2 changes: 1 addition & 1 deletion src/routes/(content)/learn/mlp-training/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ A useful metaphor for understanding how the feedforward algorithm works is to th

### Training

The message that tells an MLP to train is `fit`. `fit` is synonymous with "train". Its terminology is similar to "finding a line of best fit" or "fitting a curve to data". `fit` takes two arguments: 1. the inputs the neural network (a [DataSet](/reference/dataset)) and 2. the outputs we want the neural network to learn to predict (a [LabelSet](/reference/labelset) for the MLPClassifer, a [DataSet](/reference/dataset) for the MLPRegressor). In order for the the neural network will know which inputs to associate with which outputs, the input-output example pairs must have the same identifier in their respective (Label- or Data-) Set.
The message that tells an MLP to train is `fit`. `fit` is synonymous with "train". Its terminology is similar to "finding a line of best fit" or "fitting a curve to data". `fit` takes two arguments: 1. the inputs to the neural network (a [DataSet](/reference/dataset)) and 2. the outputs we want the neural network to learn to predict (a [LabelSet](/reference/labelset) for the MLPClassifer, a [DataSet](/reference/dataset) for the MLPRegressor). In order for the the neural network will know which inputs to associate with which outputs, the input-output example pairs must have the same identifier in their respective (Label- or Data-) Set.

During the training process, an MLP neural network uses all the data points from the input [DataSet](/reference/dataset) and predicts output guesses (either a label for MLPClassifier or a data point for MLPRegressor). At first these guesses will be quite wrong because the MLP begins in a randomised state. After each of these output guesses it checks what the _desired_ output is for the given input and measures how wrong the guess was. Based on how wrong it was, the neural network will then slightly adjust its internal weights and biases (using a process called [backpropagation](https://en.wikipedia.org/wiki/Backpropagation)) so that it can be more accurate the next time it makes a prediction on this input. After training on each data point thousands of times, these small adjustments enable the neural network to (hopefully!) make accurate predictions on the data points in the DataSet, as well as on data points it has never seen before.

Expand Down
2 changes: 1 addition & 1 deletion src/routes/(content)/learn/outliers/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ The scalers [Normalize](/reference/normalize) and [Standardize](/reference/stand

### Removing Outliers With BufStats

Another strategy for managing outliers is to use the `outliersCutoff` feature of BufStats, which can find and remove outliers by using an analysis of the data to set boundaries for each channel in the buffer. Any frames that have a value outside the its channel's boundaries will not be used to compute the statistics. See the page on [removing outliers](/learn/removing-outliers) to learn more.
Another strategy for managing outliers is to use the `outliersCutoff` feature of BufStats, which can find and remove outliers by using an analysis of the data to set boundaries for each channel in the buffer. Any frames that have a value outside its channel's boundaries will not be used to compute the statistics. See the page on [removing outliers](/learn/removing-outliers) to learn more.

### Weighting BufStats

Expand Down
2 changes: 1 addition & 1 deletion src/routes/(content)/learn/time/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ These simple models of sound are simple, but are valid representations of how di

This question emerges in several different places, especially in our own tutorials and ultimately we think it is important to recognise that machine listening is context specific. For example, the [classification with a neural network](/learn/classification-neural-network) tutorial deals with time in a straightforward and effective way. A representation of different timbres is constructed by capturing and storing several examples of very brief moments in time using the [MFCC descriptor](/reference/mfcc). This analysis procedure is designed with somewhat static sounds in mind, where the variation of those MFCC values will be relatively stable and won't evolve too rapidly. The neural network that learns from this data is also quite clever. In theory, with enough examples and sufficient training the network can be good at differentiating timbres with just these instantaneous snapshots of sound data provided to it. For example though, if you wanted to explicitly have the same neural network classify sounds based on the evolution of timbre, you would probably want to explore a different method of capturing the _temporal_ features of those sounds, rather than just looking at singular spectral frames of analysis.

As another example, the [2D Corpus Explorer tutorial](/learn/2d-corpus-explorer) operates on a set of basic assumptions about how time might be encoded into data. Like the classification tutorial, it uses MFCC data alongside [statistical derivatives](/reference/bufstats#derivatives) to try and encode the evolving spectral structures of short sound samples. This approach is actually quite prone to producing noisy and nonsensical data so we slap another algorithm on after that called [UMAP](/reference/umap), and hope that it can unfurl some structure from that mess of data its given. The idea is that after UMAP has analysed and compressed the data it was given, a new set of fewer numbers will emerge that have some kind of statistical relevance and were able to introspect on the time varying aspects of the sounds encoded in those statistical derivatives. This approach, and the classification tutorial's approach are of course entirely validated by their success in musical practice. They are by no means _perfect_ approaches to encoding time and we are not looking for exact answers here, rather, they are functional patches based on a context-specific musical application.
As another example, the [2D Corpus Explorer tutorial](/learn/2d-corpus-explorer) operates on a set of basic assumptions about how time might be encoded into data. Like the classification tutorial, it uses MFCC data alongside [statistical derivatives](/reference/bufstats#derivatives) to try and encode the evolving spectral structures of short sound samples. This approach is actually quite prone to producing noisy and nonsensical data so we slap another algorithm on after that called [UMAP](/reference/umap), and hope that it can unfurl some structure from that mess of data it's given. The idea is that after UMAP has analysed and compressed the data it was given, a new set of fewer numbers will emerge that have some kind of statistical relevance and were able to introspect on the time varying aspects of the sounds encoded in those statistical derivatives. This approach, and the classification tutorial's approach are of course entirely validated by their success in musical practice. They are by no means _perfect_ approaches to encoding time and we are not looking for exact answers here, rather, they are functional patches based on a context-specific musical application.

This is really just the start of thinking about _time_ and we hope that you delve into it more through a series of [Learn Articles](/learn) that we think might provoke you to consider how you represent time through data, and how the evolution of sound can be captured and encoded into workflows with the FluCoMa toolkit.

Expand Down
2 changes: 1 addition & 1 deletion src/routes/(content)/reference/bufnmfseed/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ For an example of what to do with the results of BufNMFSeed, see [Seeding NMF](/

</Admonition>

During the NNDSVD process, any zeros in the ``soruce`` buffer won't be able to be updated because the process multiplies these values by a scalar (and ``0 * anything = 0``). Therefore, it may be useful to change any zeros to something else before this process. BufNMFSeed has four options for managing values in the ``source`` buffer before processing:
During the NNDSVD process, any zeros in the ``source`` buffer won't be able to be updated because the process multiplies these values by a scalar (and ``0 * anything = 0``). Therefore, it may be useful to change any zeros to something else before this process. BufNMFSeed has four options for managing values in the ``source`` buffer before processing:

* **NMF-SVD** Nonnegative Double Singular Value Decomposition where any negative values are first converted to their absolute value. This is likely to be quicker than the other options, but less rigorous. (This is the default.)
* **NNDSVDar** Nonnegative Double Singular Value Decomposition where any elements that are zero are first filled with a random value between 0 and the ``average * 0.01`` (essentially small random values). This may be slightly faster but slightly less accurate than other options.
Expand Down
Loading