Edge Impulse API Create Impulse MFCC Block

I was trying to use the Edge Impulse API & CLI to fully develop a model (from uploading data to deploying as an Arduino library).

I used https://docs.edgeimpulse.com/reference/createimpulse to create the impulse in my project. I wanted the DSP block to be MFCC. However, when I use https://docs.edgeimpulse.com/reference/generatefeaturesjob to generate the features, I get an error. The error is: “at least one row of the mel filterbank contains all zeros”

But, when I use the regular UI in the Edge Impulse Studio, I don’t get this error. I used the same data. The only difference is how I created the Impulse. Is the MFCC block created in the API different than the one in the studio?

Additionally, in the UI, you can choose “Classifier” as your learning block. Of the options in the API, which one functions in the most similar way? I am using audio .wav files, so I assumed keras-transfer-kws would work best.

Below I have the code for how I uploaded my data and created the impulse. As in the code, my Project ID is 336512. Please let me know if you have any questions!

#set basic ei proj settings
project_id = 336512 # YOUR PROJECT ID
api_key = "ei_9b98922c498895589e062ea4d5afa3022b03af67c67d21a52d4225d06b275568" # YOUR API KEY
deploy_type = "arduino" # CAN CHANGE TO DIFFERENT TYPE

headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "x-api-key": api_key
}

#------------------------------------------------------#

#import all dataset(s)
os.system(f"edge-impulse-uploader --directory dataset --api-key {api_key} --silent")

#------------------------------------------------------#

#create impulse
url = f"https://studio.edgeimpulse.com/v1/api/{project_id}/impulse"

payload = {
    "inputBlocks": [
        {
            "type": "time-series",
            "id": 1,
            "name": "Time series data",
            "title": "Time series data",
            "windowSizeMs": 1000,
            "windowIncreaseMs": 500,
            "frequencyHz": 16000,
            "padZeros": True
        }
    ],
    "dspBlocks": [
        {
            "id": 2,
            "type": "mfcc",
            "name": "MFCC",
            "title": "MFCC",
            "axes": ["audio"],
            "implementationVersion": 1
        }
    ],
    "learnBlocks": [
        {
            "type": "keras-transfer-kws",
            "primaryVersion": True,
            "id": 3,
            "name": "Classifier",
            "dsp": [2],
            "title": "Classifier"
        }
    ]
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

Hi @jeanelled,

It’s probably linked to the implementationVersion (current one is 4).

The keras-transfer-kws will be a good choice for keyword spotting. The regular classifier’s type is “keras” otherwise.

If you want to reproduce exactly the impulse from the UI, a good tip is using your browser’s dev tools and check the impulse request payload. Below is an example.

Alterntively, use the following endpoint with the API: https://docs.edgeimpulse.com/reference/getimpulse

Aurelien

Hello @jeanelled,

You can also load the template for your impulse in the EON Tuner Search Spaces:

It’s usually a good starting point to know what fields are available.

Best,

Louis

One more thing. Using https://docs.edgeimpulse.com/reference/trainkerasjob, when I try to train the Keras model, I get the error, “Number of new classes and neurons should be a positive number!”

I matched all the API settings to the payloads from the Chrome browser. However, it’s still not working. I’ll paste the code I used to train the model below. I’ve also tried adding a dense layer at the end to serve as an output layer, but that didn’t work. I’ve checked and the impulse blocks are also matched.

I switched to a different project, so the new Project ID is 337137.

As a side question, if I run the create impulse API script twice, will the blocks be overwritten? Because I am not allowed to delete the learning blocks. So if they do not overwrite, then I have to create a new project every time I test the API (because the API creates another learning block with the same ID and all that).

Here’s my code:

import requests

url = "https://studio.edgeimpulse.com/v1/api/337137/jobs/train/keras/5"

payload = {
    "augmentationPolicySpectrogram": {
        "enabled": False,
        "gaussianNoise": "high",
        "freqMasking": "none",
        "timeMasking": "low",
        "warping": False
    },
    "akidaEdgeLearningConfig": { "enabled": False },
    "mode": "visual",
    "visualLayers": [{
            "type": "reshape",
            "columns": 13
        }, {
            "type": "conv1d",
            "neurons": 8,
            "kernelSize": 3,
            "stack": 1
        }, {
            "type": "dropout",
            "dropoutRate": 0.25
        }, {
            "type": "conv1d",
            "neurons": 16,
            "kernelSize": 3,
            "stack": 1
        }, {
            "type": "dropout",
            "dropoutRate": 0.25
        }, { "type": "flatten" }],
    "trainingCycles": 5,
    "learningRate": 0.005,
    "profileInt8": False,
    "augmentationPolicyImage": "none",
    "autoClassWeights": False,
    "trainTestSplit": 0.2
}
headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "x-api-key": "ei_128ba30ff7c8b8879d5e2b7e1ba07b0c6b02a8d60c227cf25c6a65645550643a"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

Once again, thank you so much!