Update 20 Apr 2016: Check out the paper on arXiv (PDF)

LSTM Realbook

Summary

Char-RNN and Word-RNN with Keras (LSTM text generation example) and Theano for automatic composition of jazz score. 2,846 Realbook jazz songs from a website were used for training after a conversion into a text file. Band-in-a-box format files were converted into a text file using java code written by Simon Dixon and Matthias Mauch, then learned as usual. The result is fun – you can listen to 5 LSTM Realbook songs!

A Quick look at things

LSTM

LSTM (Long Short-Term Memory) is a type of RNN. It is known to be able to learn a sequence effectively.

RNN

RNN (Recurrent Neural Network) is a type of deep learning neural network. See this post by WildML for further understanding.

Char-RNN

Character-based RNN introduced by Andrej Karpathy is literally an RNN that predicts a character. Character space can be significantly smaller than word space, resulting in efficient learning in terms of both memory and computation. Please enjoy enormous examples in the original post – Shakespeare, Wikipedia, Linux source code, baby names, etc.

Keras

Keras is a deep learning framework based on Theano and Tensorflow. I used Theano as backend but this shouldn’t affect the output.

Realbook

Realbook is a collection of jazz standard songs with title, composer, chord, theme melody, and rhythm. As far as I know there are Realbook 1, 2, 3, and New Realbook 1,2,3, the Fakebook, the real Latin book, etc.

Band-in-a-box

Band-in-a-box is a software of PGMusic and has quite a long history – since 1990! Literally it’s a band-in-a-box for you. It accompanies, improvises solos, play the theme, just as your band except it doesn’t hear what you play (or make mistakes).

The procedure

Conversion to some known formats.

I don’t know how the band-in-a-box score file (.mgu) is structured. I used a java code written by Simon Dixon and Matthias Mauch. As a result, I got files like this – a .xlab format:

1:1 0.0 8 2.8235294117647056 C:maj C C 3:1 2.8235294117647056 8 5.647058823529411 G:9 G9 C 5:1 5.647058823529411 4 7.0588235294117645 C:9 C9 C 6:1 7.0588235294117645 4 8.470588235294118 C:7 C7 C 7:1 8.470588235294118 4 9.88235294117647 F:maj F C 8:1 9.88235294117647 4 11.294117647058822 F:min7 Fm7 C 9:1 11.294117647058822 4 12.705882352941176 C:maj C C 10:1 12.705882352941176 4 14.117647058823529 G:min7 Gm7 C 11:1 14.117647058823529 4 15.529411764705882 A:7 A7 C

.lab format is explained here, and .xlab is an extension of .lab. The format is (seems):

bar:measure start_time beat end_time chord chord key

Preprocess

To decreases number of cases, I kind of normalised the score – so that every score is in C key. I used <key> information in .xlab format and transposed every chord.

Between the two chord, I chose the first one – e.g. C:maj, G:7, C:sus4(b7).

There are more than one chords for a bar (e.g. see bar 22 in the band-in-a-box screenshot above). I decided to fill every blank beat with the corresponding chord. For example

| A:7 . . . | A:7 . C:maj . |

is converted into…

| A:7 A:7 A:7 A:7 | A:7 A:7 C:maj C:maj |

but without bars. (Perhaps I should have put the bar in the training file..?)

Every score is converted into a sentence with a start flag and end flag. A two-bar score would be represented as below:

_START_ A:7 A:7 A:7 A:7 A:7 A:7 C:maj C:maj _END_

See some numbers of the data

2,486 scores

1,259 unique chords

39 characters (including C,D,E,F,G,A,B,#,b,:,m,a,j,(m,)i,n,s,u(,s), …)

1,239.78 characters per score on average

Maximum 10,151 characters in a score

3,531,261 characters in total

545,300 words in total

# The text file is included in the repo.

Char-RNN and Word-RNN

Char-RNN : predicting a character given N characters. Character space is 39 dimensions.

Word-RNN : predicting a word given N words. Word == Chord name here, and word space is 1,259 dimensions.

Word space is bigger but a word (chord) has more meaning. Also, a sentence (score) requires less number of words than characters. It means the LSTM doesn’t need to recall old things when it’s dealing with words. However, I just used the same structure and hyperparameters. Which is as below:

model = Sequential() model.add(LSTM(512, return_sequences=True, input_shape=(maxlen, num_chars))) model.add(Dropout(0.2)) model.add(LSTM(512, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(512, return_sequences=False)) model.add(Dropout(0.2)) model.add(Dense(num_chars)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam')

which is super arbitrary.

Result 1 – Char-rnn

So I could get some chord progressions. I did something tedious to make posting more interesting – sequencing midi, copy&paste apple loop, and add some bass note for a more pleasing experience. Chords with red are what you listen.

Char-rnn, diversity 0.5, iteration: 1 (LSTM Realbook 1)

Seed: maj C:maj C:maj C:ma Result: maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj

With a low diversity it is so boring. II – V – I progression is not fun! My take away from this result is that I and V chords are the most common in music.

Char-rnn, diversity 1.2, iteration: 1 (LSTM Realbook 2)

Seed: maj C:maj C:maj C:ma Result: maj C:maj C:maj C:maj G#:min6 G#:min D#:7 D#:7 D:min7 C:maj/5 C:maj/5 C:maj/5 C:maj/5 C:maj/5 C:maj/5 C:maj/5 C:maj6/5 E:min7/4 E:min7/4 C:#ds(s11) C:sus4 D#:maj6 A#:maj A#:maj A#:maj A#:maj A:7 A:7 A:7 A:7 A:7 D:min7 D:min7 D:min7 D:hdim D:hdim C:hdim C:hdim C:hdim C:hdim C:hdim C:hdim C:hdim G:9 G:9 D:min7 D:min7 D#:dim G#:di9 G#:min7 G#:min7 G#:min7 G:sus4(b7) G:sus4(b7) G:sus4(b7) G:sus4(b7) G:sus4(b7) G:sus4(b7) G:sus4(b7) G#:9(s51) D:min D:min G:7/5 G:7/5 C:maj C:maj C:maj C:maj G:7(b9) G:7(b9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) D:maj7 D:maj7 G:maj(b7,b9,11,13) E:maj(b7,b9,11,13) E:9 E:9 E:9 E:9 E:9(s5,*5) E:9(b5,*5) E:min(b7,9,11) E:min(b7,9,11) E:min(b7,9,11) E:min7 E:min7 D:min6 D:min6 D:min6 A:min(b6,9,11) A:maj(b7,9,11,13) D:min7 D:min7 D:min7 A:9 A:min6 A:min A#:maj C#:min C#:min G#:maj G#:maj G#:maj G:9 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:sus4(b7,9) F:maj6 F:maj6 F:maj6 F:maj F:maj A:maj A#:maj A:hdim A:dim :mdn7 D:min7 D:min7 G:maj(b7,b9,11,13) C:6 C:9 F:9 A#s5us4(b7) A#:sus4(b7) B:sus4(b9) B:sus4(b7,9) B:sus4(b7,b5,49) B:sus4(b7) B:sus4(b7) B:sus4(b7) F:maj7 F:maj7 F:maj7 F:maj7 F:maj7 F:maj7 F:maj7 F:maj7 F:maj7 D#:maj7 D:dim D:dim F:maj7 F:maj6 D:min7 D:min7 C:maj C:maj F:maj F:maj F:maj F:aug F:7 F:7 F:7 C:7 G:min D:hdim G:sus4(b7,9) G:sus4(b7,9) C:maj7 C:maj7 C:maj7 C:maj7 C:maj7 F:maj9 F:maj7 F:maj7 F:maj7 F#:hdim F#:hdim F:min7 E:7(s5,*5) A:7(s9) A:7(s9) A:7(b9) A:7(b9) A:7(b9) D:min7 D:min7 E:min(7) E:min(7) E:min7 A:min7 A:min7 A:min7 A:min7 F:

One iteration results in kind of okay progression.

As each chord represent one beat, usually one chord should continue for 4 times. It is not obvious in this example.

Not II-V-I progression yet.

Char-rnn, diversity 0.5, iteration: 22

Seed: aj C:7/5 C:7/5 C:7 C Result: aj C:7/5 C:7/5 C:7 C:7 F:maj F:maj F:min F:min F:min F:min C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj

With enough iteration, the diversity of 0.5 looks still the same – So many C major, few G7, then comes back to C major.

Char-rnn, diversity 1.2, iteration 22 (LSTM Realbook 3)

Seed: aj C:7/5 C:7/5 C:7 C Result: aj C:7/5 C:7/5 C:7 C:7 F:maj6 F:maj6 F#:dim F#:dim C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:6(9) C:maj E:7(b9) E:7(b9) E:7(b9) E:7(b9) A:min(6,9) A:min(6,9) A#:min(6,9) A#:min(6,9) A#:min(6,9) A#:min(6,9) A#:min(6,9) A#:min(6,9) A:(1,b3,b5) A:(1,b3,b5) G#:(1,b3,b5) G#:(1,b3,b5) G:min(b7,9,11) G:min(b7,9,11) G:min(b7,9,11) G:min(b7,9,11) G#:min(b7,9,11) F#:min(b7,9,11) F#:min(b7,9,11) C:min9 C:min9 B:7(s5,*5,s9) B:7(s5,*5,s9) B:7(s5,*5,s9) C:6(9) C:6(9) C:6(9) A:7 A:7 D:min7 D:min7 D:min7/9 D:min(b7,9,11)/b5 E:min(b7,9,11)/b3 E:min7(s5,*5)/b7 E:min(b7,9,11)/b7 E:min(b7,9,11)/b7 E:min(b7,9,11)/b7 E:min7 E:min7 E:min7 E:min7 A:7(b9) A:7(b9) D:min D:min D:min D:min G:9 G:9 C:maj C:maj F:9 F:9 F:9 F:9 C:maj6 C:maj6 C:maj6 C:min6 C:min6 F:9 F:9 F:9 F:9 D:min7 D:min7 D:min7 D:min7 D:min7 C#:maj(b7,9,11,13)/b7 G#:maj(b7,9,11,13) G#:maj(b7,9,11,13) C:maj7 C:maj7 E:min7 E:min7 D#:min7 D#:min7 D#:min7 E:min7 A:7(b9) A:7(b9) D:min D:min D:min D:min D:min D:min D:min D:min _END_ _START_ A:min A:min F:maj F:maj B:7 B:7 E:maj E:maj E:maj B:9 B:9 B:maj B:maj D:min(b7,9,11) D:min(b7,9,11) D:min(b7,9,11) D:min(b7,9,11) D:min(b7,9,11) G:aug(b7,9) G:aug(b7,9) G:min7 G:min7 E:aug(b7) A:7 A:7 A:7 A:7 A:7 D:min7 D:min7 D:min7 D:min7 C#:maj/2 C#:maj/2 C#:maj/2 D:aug(b7) D:7 F:maj F:maj G:maj G:maj C:maj C:maj A#:maj A:7 A:7 A:7 A:7 D:min7 E:dim F:min6 D:hdim D:hdim D:hdim D:hdim D:hdim D:hdim D:hdim D:hdim G:7(b9) G:7(b9) G:7(b9) G:7(b9) G#:7 G#:7 E:hdim E:hdim E:hdim E:hdim E:hdim A:7 A:

It learned _START_ is always with _END_

After _START_, it doesn’t start with C but with A! Although I ‘normalised’ the scores there were many excerpts that don’t begin with C.

Do you think it learned 4-times repetition thing to have one chord for one bar? I’m not sure.

Now I see II-V-I! Dm-G9-CM.

Result 2 – Word-rnn

Word-rnn, diversity 0.5, iteration 1

C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj

C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj6

Word-rnn, diversity 1.2, iteration 1

C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj

C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj _END_ F:min G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj C:maj C:7 C:7 F#:dim C:maj6 _START_ _START_ C#:maj A#:min A:sus4/5 C:maj/3 F:min7 A:min7 D:min7 D:min7 G:sus4(b7,9) D:aug(b7) G:9 F:maj/2 G:7(s5,*5) G:9 G:7 G:sus4(b7,s5,*5)/b5 C:6(9) C:maj7 C:maj7 G:7 G:7 C:maj7 D:min7 C:maj6 E:min7 G:sus4(b7) G:9 C:maj6 C:maj6 E:hdim C:maj6 _START_ D:min7/b7 G:9/2 D:min7/b7 D:min7 D:min7 G:7 A:dim F:min6/5 G:7 G:7 G:7 G:7 G:7 D:min7 D:min7 G:7 G:7 G:dim G:7 G:7 F:min6 G:maj6 D:min7 D:min7 C:dim F#:hdim B:7 E:min7 B:7(b9) D:maj6 D:9 D:9 C:7(b9) G:maj/2 D:min D:min7 D:min7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj G:7 D:min7 D:min7 D:min7 G:7 G:9 D:min7 D:min7 G:7 G:7 D:min7 G:7 A:7(b9) A:7 A:min7 A:9 D:min D:min7 D:min7 D:min7 D:min7 C:maj C:maj C:7 C:7 F:maj6 G:7 G:7 G:7 D:min7/4 F:aug F:min6 D:sus4 D#:aug(b7) G:min6 C:maj/3 D:min F:min6 G:9 G:9 _START_ G:9 D:min7 D:min7 D:min7 D:min7 D:min7

Obviously it doesn’t know the meaning of _START_ and _END_.

Word-rnn, diversity 0.5, iteration 8 (LSTM Realbook 4)

G:7(b9) C:maj C:maj A:min A:min D:min7 D:min7 G:7(b9) G:7(b9) C:maj C:maj C:maj C:maj A:min7 A:min7 A:min7 A:min7 D:9 D:9 D:9

G:7(b9) C:maj C:maj A:min A:min D:min7 D:min7 G:7(b9) G:7(b9) C:maj C:maj C:maj C:maj A:min7 A:min7 A:min7 A:min7 D:9 D:9 D:9 D:9 D:9 D:9 D:9 D:9 D:7 D:7 D:7 D:7 D:min7 D:min7 D:min7 D:min7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:7 C:7 C:7 C:7 F:maj F:maj F:maj F:maj F:min F:min F:min F:min C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj D:7 D:7 D:7 D:7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj G:7 G:7 G:7 G:7 G:7 G:7 G:7 G:7 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj

Looks like it learned it’s good to fill a bar with the same chord.

Word-rnn, diversity 1.2, iteration 8 (LSTM Realbook 5)

G:7(b9) C:maj C:maj A:min A:min D:min7 D:min7 G:7(b9) G:7(b9) C:maj C:maj C:maj C:maj A:min7 A:min7 A:min7 A:min7 D:9 D:9 D:9

G:7(b9) C:maj C:maj A:min A:min D:min7 D:min7 G:7(b9) G:7(b9) C:maj C:maj C:maj C:maj A:min7 A:min7 A:min7 A:min7 D:9 D:9 D:9 E:hdim/b5 D:9 D:9 D:9 D:9 D:min7 D:min7 D:min7 D:min7 G:7 G:7 G:7 G:7 C:maj6/6 F#:dim C:9 C:9 F:maj6 F:maj6 C:7 C:7 F:maj6 F:maj6 F:maj6 F:maj6 A#:maj6 A#:maj6 A#:maj6 A#:maj6 C:maj/3 C:maj/3 C:maj/3 C:maj/3 C:maj C:maj C:maj C:maj C:maj C:maj C:maj C:maj A#:9 F:maj7 A#:7 A#:7 C:maj C:maj C:maj/3 C:maj/3 F:maj6 F:maj6 C:maj C:maj C:maj C:maj C:maj C:maj G:min7 G:min7 G:min7 G:min7 F:maj F:maj F:maj F:maj D:min7 D:min7 D:min7/4 G:sus4(b7) G:min9 G:min9 G:min9 F#:(1,3,b5,b7,9,13) C:6(9) G:sus4(b7,9) E:7(s5,*5,s9) E:7(s5,*5,s9) A:min9 A:min9 A:min9 A:min9 D:min7 D:min7 D:7(b9) D:9 G#:9(s11) G:(1,4,5,b7,9,11,13) G:aug(b7,9) G:9(s5,*5) C:maj6 C:maj6 E:min7(s5,*5)/b7 A:7(s9,s11,b13) D#:min9 D:min9 F:maj(b7,9,11,13) F:maj(b7,9,11,13) B:min9 D#:min9 D:min9 D:min9 C:6(9) C:6(9) B:hdim B:hdim A:min7 A:min7 G#:7(s9) A:min7/4 B:hdim E:7(s5,*5,b9) E:aug(b7) E:aug(b7) A:min7 A:min7 D:maj(b7,9,11,13) D:maj(b7,9,11,13) D:min D:min D:min(7) D:9(b5,*5) A#:7 A#:7 A#:7 A#:7 B:min7 B:min7 E:7 E:7 D:7 D:7 D:7 D:7 D:7 D:7 D:7 D:7 G#:9 G#:9 C#:maj7 C#:maj7 B:maj B:maj D#:sus4 F#:maj6 B:maj7 B:maj7 A#:maj7 A#:maj7 A#:maj7

Code

The Code and the training text file are provided in my repo. Enjoy!