Now, it's time to do some deep learning. Recall that a RBM (Restricted Boltzmann Machine) takes in a binary vector, and you can use it in the SKLearn Pipeline with a classifier. You'll want to read in Oscar's original data as an array of bitwise note vectors, and from there build the RBM to predict chords (the y's, perhaps build the chord bank and assign a unique number to each). After that, given a note vector (maybe plural?), you should be able to predict the chords for a note (notes?).
This is for Oscar's musical data. The next step is to do the classification for your n-gram model.
from collections import defaultdict
from sklearn.neural_network import BernoulliRBM
import pandas as pd
import numpy as np
# Extract chords into unique ids, e.g. 1, 2, 3, 4, 5
allchords = defaultdict()
with open("oscar2chords_extract.txt", 'rb') as f:
assert len(allchords) == len(set(allchords)) # ensure no duplicate chords
for ix, line in enumerate(f):
allchords[ix] = line.rstrip()
print len(allchords) # oscar uses this number of unique chords
40
# Read in Oscar's data.
vectors = []
notedata = pd.read_csv(open("oscar2notes.txt", 'rb'), skiprows=2)
allnotes = []
for note, octave in zip(notedata["Note/Rest"], notedata["Octave"]):
allnotes.append("%s%s" % (note, octave))
print "Number of notes (# of samples for RBM): ", len(notedata)
notedata.head()
Number of notes (# of samples for RBM): 1344
Note/Rest | Octave | Len | Offset | |
---|---|---|---|---|
0 | B | 3 | 0.500000 | 12.625 |
1 | A | 5 | 0.250000 | 15.000 |
2 | F | 4 | 3.125000 | 16.000 |
3 | G | 4 | 0.666667 | 20.625 |
4 | F | 4 | 1.250000 | 23.875 |
5 rows × 4 columns
# Given a MUSIC21 note, such as C5 or D#7, convert it
# into a note on the keyboard between 0 and 87 inclusive.
# Don't convert it for mingus; try to use music21 note style
# as much as possible for all this stuff.
def quantify(note):
notevals = {
'C' : 0,
'D' : 2,
'E' : 4,
'F' : 5,
'G' : 7,
'A' : 9,
'B' : 11
}
quantized = 0
octave = int(note[-1]) - 1
for i in note[:-1]:
if i in notevals: quantized += notevals[i]
if i == '-': quantized -= 1
if i == '#': quantized += 1
quantized += 12 * octave
return quantized
# Create bitwise note vectors for use with Restricted Boltzmann Machine.
vectors = np.zeros((1, 88))
for ix, note in enumerate(allnotes):
vect = np.zeros((1, 88))
vect[0, quantify(note)] = 1
if ix == 0:
vectors = vect
else:
vectors = np.vstack((vectors, vect))
print vectors.shape
(1344, 88)
See notes on what you should actually do.