"\u001b[0;32m<ipython-input-19-7371839df3e6>\u001b[0m in \u001b[0;36mprocess_corpus\u001b[0;34m(corpus_URL)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\"\"\"Read a list of files to process from the text file at corpusURL. Return a list of URLs\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;31m# Open and read each line\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0murl_list_text_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0murllib2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcorpus_URL\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# it's a file like object and works just like a file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfile_URL\u001b[0m \u001b[0;32min\u001b[0m \u001b[0murl_list_text_data\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# files are iterable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mfile_URL\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-19-7371839df3e6>\u001b[0m in \u001b[0;36mprocess_corpus\u001b[0;34m(corpus_URL)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\"\"\"Read a list of files to process from the text file at corpusURL. Return a list of URLs\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;31m# Open and read each line\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0murl_list_text_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0murllib2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcorpus_URL\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# it's a file like object and works just like a file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfile_URL\u001b[0m \u001b[0;32min\u001b[0m \u001b[0murl_list_text_data\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# files are iterable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mfile_URL\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/sw/lib/python2.7/httplib.pyc\u001b[0m in \u001b[0;36m_send_output\u001b[0;34m(self, message_body)\u001b[0m\n\u001b[1;32m 842\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mmessage_body\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 843\u001b[0m \u001b[0mmessage_body\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 844\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 845\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmessage_body\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 846\u001b[0m \u001b[0;31m#message_body was not a string (i.e. it is a file) and\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'sample_rate' is not defined"
]
}
],
"prompt_number": 18
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "markdown",
...
...
@@ -246,120 +189,180 @@
"\n",
"2. Since the features are different scales, we will want to normalize each feature vector to a common range - storing the scaling coefficients for later use. Many techniques exist for scaling your features. We'll use linear scaling, which forces the features into the range -1 to 1.\n",
"\n",
" For this, we'll use a custom-created function called scale. Scale returns an array of scaled values, as well as the multiplication and subtraction values which were used to conform each column into -1 to 1. Use this function in your code. \n",
" For this, we'll use a scikit.learn class called [MinMaxScaler](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html). MinMaxScaler fits and transforms, returning an array of scaled values, and retains coefficients which were used to scale each column into -1 to 1. Use these functions in your code. "
" This k-NN model uses 5 features, 2 classes for output (the label), uses k-NN = 1, and takes in the feature data via a feature array called trainingFeatures.\n",
"\u001b[0;31mNameError\u001b[0m: name 'featuresSnare' is not defined"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Build a k-NN model for the snare drums using scikit.learn's [KNeighborsClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html) class."
" These labels indicate which sample in our feature data is a snare, vs. a non-snare. The k-NN model uses this information to build a means of comparison and classification. It is really important that you get these labels correct - because they are the crux of all future classifications that are made later on. (Trust me, I've made many mistakes in this area - training models with incorrect label data.)\n",
"The labels describe which \"class\" (snare or non-snare, i.e kick, in this case), the features identify. This is formed as an array of ones and twos (class labels) to correspond to the 10 snares and 10 kicks in our training sample set. For example..."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"labels = np.empty(20, np.int32)\n",
"labels[0:9] = 1 # First 10 are the first sample type, e.g. snare\n",
"labels[10:20] = 2 # Second 10 are the second sample type, e.g kick\n",
"This k-NN model uses 5 features, 2 classes for output (the label), uses k-NN = 1, and takes in the feature data via a feature array called trainingFeatures."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"model_snare.fit(trainingFeatures, labels)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These labels indicate which sample in our feature data is a snare, vs. a non-snare. The k-NN model uses this information to build a means of comparison and classification. It is really important that you get these labels correct - because they are the crux of all future classifications that are made later on. (Trust me, I've made many mistakes in this area - training models with incorrect label data.)\n",
"\n",
"4. Create a script which extracts features for a single file, re-scales its feature values, and evaluates them with your kNN classifier. \n",
"\n",
"Evaluating samples with your k-NN\n",
"Now that the hard part is done, it's time to throw some feature data through the trained k-NN and see what it outputs. \n",
" \n",
"RESCALING.\n",
"In evaluating a new audio file, we need to extract it's features, re-scale them to the same range as the trained feature values, and then send them through the knn.\n",
"\n",
"Some helpful commands:\n",
"featuresScaled = rescale(features,mf,sf) ; % This uses the previous calculated linear scaling parameters to adjust the incoming features to the same range. \n",
"The output voting gives you a breakdown of how many nearest neighbors were closest to the test feature vector. \n",
" \n",
"The `model_output` provides a list of whether output is Class 1 or Class 2.\n",
"\n",
" output = zeros(size(model_output),2)\n",
" output(find(model_output==1),1)=1\n",
" output(find(model_output==2),2)=1\n",
"\n",
"Now you can visually compare the output to trainlabels\n",
" \n",
"Once you have completed function, first, test it with your training examples. Since a k-NN model has exact representations of the training data, it will have 100% training accuracy - meaning that every training example should be predicted correctly, when fed back into the trained model. \n",
"\n",
"Now, test out with the examples in the folder \"test kicks\" and \"test snares\", located in the drum samples folder. These are real-world testing samples\u2026\n",
"\n",
"If the output labels \"1\" or \"0\" aren't insightful for you, you can add an if statement to display them as strings \"snare\" and \"kick\".\n",
"### Evaluating samples with your k-NN\n",
"\n",
"Now that the hard part is done, it's time to throw some feature data through the trained k-NN and see what it outputs. \n",
" \n",
"NEED HELP?\n",
"Tricks of the trade\n",
"Select code in Matlab editor and then press F9. This will execute the currently selected code.\n",
"To run a Matlab \"cell\" (multiline block of code), press Control-Enter with the text cursor in the current cell.\n",
"\n",
"The clear command re-initializes a variable. To avoid confusion, you mind find it helpful to clear arrays and structures at the beginning of your scripts.\n",
"\n",
"Common Errors\n",
"### Rescaling\n",
"\n",
" >??? Index exceeds matrix dimensions.\n",
"\n",
"Are you trying to access, display, plot, or play past the end of the file / frame? \n",
"For example, if an audio file is 10,000 samples long, make sure that the index is not greater than this maximum value. If the value is > than the length of your file, use an if statement to catch the problem.\n",
"\n",
" "
"In evaluating a new audio file, we need to extract it's features, re-scale them to the same range as the trained feature values, and then send them through the knn."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"input": [
"# This uses the previous calculated linear scaling parameters to adjust the incoming features to the same range. \n",
"\u001b[0;32m<ipython-input-12-3e535d776ccc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# This uses the previous calculated linear scaling parameters to adjust the incoming features to the same range.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mfeaturesScaled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mscaler\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfeatures\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'features' is not defined"
"\u001b[0;32m<ipython-input-13-5265c345102e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmodel_output\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel_snare\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfeaturesScaled\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'model_snare' is not defined"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `model_output` provides a list of whether output is Class 1 or Class 2. If the output labels \"1\" or \"2\" aren't insightful for you, you can add an if statement to display them as strings \"snare\" and \"kick\". Now you can visually compare the output to the training labels.\n",
" \n",
"Once you have completed writing the function, first, test it with your training examples. Since a k-NN model has exact representations of the training data, it will have 100% training accuracy - meaning that every training example should be predicted correctly, when fed back into the trained model. \n",
"\n",
"Now, test out with the examples using https://ccrma.stanford.edu/workshops/mir2014/TestKicksCorpus.txt and https://ccrma.stanford.edu/workshops/mir2014/TestSnaresCorpus.txt. These are real-world testing samples\u2026"