In[]:=
SetDirectory[NotebookDirectory[]];​​<<"../Howl/HowlMidiTools.wl"
In[]:=
encToNetInput[encSong_]:=<|​​"NoteData"->encSong[[All,1;;3]],​​"Notes"->encSong[[All,4]]​​|>
In[]:=
trained=Import["checkpoints_2021-07-21T12-31-21\\2021-07-21T12-31-33_0_4971_54680_2.62e+1_2.39e+1.wlnet"]
Out[]=
NetGraph
Number of inputs:
2
Lossport:
real

In[]:=
predictor=NetGraph[<|​​"rnn"->NetExtract[trained,"rnn"],​​"lastPred"->SequenceLastLayer[],​​"lastDataPred"->SequenceLastLayer[]​​|>,​​{​​NetPort["rnn","NotePred"]->"lastPred"->NetPort["NotesPred"],​​NetPort["rnn","NoteDataPred"]->"lastDataPred"->NetPort["NoteDataPred"]​​},​​"Notes"->{"Varying",NetEncoder[{"Class",validNotes}]},​​"NotesPred"->NetDecoder[{"Class",validNotes}]​​]
Out[]=
NetGraph
Number of inputs:
2
Number of outputs:
2

predictor=Import["checkpoints_2021-07-22T05-13-24\\predictor_2021-07-22T05-13-24.wlnet"]
Out[]=
NetGraph
Number of inputs:
2
Number of outputs:
2

In[]:=
predictor=Import["checkpoints_2021-07-22T06-02-58\\predictor_2021-07-22T06-02-58.wlnet"]
Out[]=
NetGraph
Number of inputs:
2
Number of outputs:
2

In[]:=
fromPred[pred_]:=Transpose@Join[Transpose[pred["NoteDataPred"]],{pred["NotesPred"]}]
In[]:=
ClearAll[firstNote]​​firstNote[]:={{RandomReal[],RandomReal[],RandomReal[{0.3,1.0}],RandomInteger[{-12,24}]}}​​{fromPred[predictor[encToNetInput[firstNote[]]]]}//HowlDecodeNotesV1//Sound
Join
:Heads Transpose and List at positions 1 and 2 are expected to be the same.
Out[]=
Sound[{Transpose[Join[Transpose[predictor[NoteData{{0.247839,0.520196,0.469823}},Notes{7}][NoteDataPred]],{predictor[NoteData{{0.247839,0.520196,0.469823}},Notes{7}][NotesPred]}]]}]
In[]:=
makeMusic[predictor_,firstNote_,len_]:=Nest[​​Join[#,{fromPred[predictor[encToNetInput[#[[-Min[Length@#,500];;]]],TargetDevice->{"GPU",2}]]}]&,​​firstNote,len]//HowlDecodeNotesV1//Sound
In[]:=
makeMusic[predictor,firstNote[],500]
Out[]=

512 node GRU

In[]:=
results=Import["checkpoints_2021-07-22T20-36-58\\results_2021-07-22T20-36-58.wxf"]​​predictor=Import["checkpoints_2021-07-22T20-36-58\\predictor_2021-07-22T20-36-58.wlnet"]
Out[]=
NetTrainResultsObject
NetTrain Results
summary
batches:
73557,
rounds:
1988,
time:
12h
,
examples/s:
109
data
training examples:
2368,
validation examples:
290,
processed examples:
4707648,
skipped examples:
0
method
ADAM
optimizer
,
batch size
64,
GPU
1
round
loss:
1.48,
error:
36.4%
validation
loss:
1.43,
error:
35.7%
‹
error rate
›
​
rounds
error rate
training set
validation set

Out[]=
NetGraph
Number of inputs:
2
Number of outputs:
2

In[]:=
makeMusic[predictor,firstNote[],500]
Out[]=
In[]:=
dateTimeStr=StringReplace[DateString["ISODateTime"],":"->"-"];​​Export["rnn_gru_512_"<>dateTimeStr<>".mid",%23]
Out[]=
rnn_gru_512_2021-07-23T09-01-01.mid

1024 Node LSTM

In[]:=
results=Import["checkpoints_2021-07-22T21-40-55\\results_2021-07-22T21-40-55.wxf"]​​predictor=Import["checkpoints_2021-07-22T21-40-55\\predictor_2021-07-22T21-40-55.wlnet"]
Out[]=
NetTrainResultsObject
NetTrain Results
summary
batches:
130336,
rounds:
1343,
time:
12h
,
examples/s:
72.
data
training examples:
2328,
validation examples:
290,
processed examples:
3128064,
skipped examples:
0
method
ADAM
optimizer
,
batch size
24,
GPU
2
round
loss:
5.18×
-1
10
,
error:
7.74%
validation
loss:
4.06×
-1
10
,
error:
7.00%
‹
loss
›
​
rounds
loss
training set
validation set

Out[]=
NetGraph
Number of inputs:
2
Number of outputs:
2

In[]:=
makeMusic[predictor,firstNote[],500]
Out[]=

416 node LSTM

Note, I lost the first 6 hours of training this one. So this is several hours in.