-
Notifications
You must be signed in to change notification settings - Fork 1
/
learn.py
150 lines (116 loc) · 4.67 KB
/
learn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from pybrain.tools.shortcuts import buildNetwork
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.datasets import SupervisedDataSet
from songfactory import SongFactory
from model import SongModel
from pybrain.structure import FeedForwardNetwork
from pybrain.structure import LinearLayer, SigmoidLayer
from pybrain.structure import FullConnection
from pybrain.structure.modules import BiasUnit
from pybrain.tools.shortcuts import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.xml.networkwriter import NetworkWriter
from pybrain.tools.xml.networkreader import NetworkReader
import random
import pdb
import static
TRAINED_DATA_FILEPATH_MAJOR = 'trained-major.data'
TRAINED_DATA_FILEPATH_MINOR = 'trained-minor.data'
class Learn:
def __init__(self, mode):
self.net = None
self.major = True
if mode == "minor":
self.major = False
def train(self):
n = FeedForwardNetwork()
dataModel = SongFactory(self.major).getModels()
ds = SupervisedDataSet(static.NUM_OF_INPUTS, 1)
#adds samples from the data received from songfactory and the k
for data in dataModel:
for input, target in data.model:
print input, target
ds.addSample(input, target)
#instantiate the network
self.net = FeedForwardNetwork()
bias = BiasUnit()
self.net.addModule(bias)
#create the layers of the network
inLayer = LinearLayer(static.NUM_OF_INPUTS)
outLayer = LinearLayer(1)
hidden1 = SigmoidLayer(25)
hidden2 = SigmoidLayer(5)
#add the layers
self.net.addInputModule(inLayer)
self.net.addOutputModule(outLayer)
self.net.addModule(hidden1)
self.net.addModule(hidden2)
#create the connection
in_h1 = FullConnection(inLayer,hidden1)
h1_h2 = FullConnection(hidden1, hidden2)
h2_out = FullConnection(hidden2, outLayer)
b_h1 = FullConnection(bias, hidden1)
b_h2 = FullConnection(bias, hidden2)
#add the connection
self.net.addConnection(in_h1)
self.net.addConnection(h1_h2)
self.net.addConnection(h2_out)
self.net.addConnection(b_h1)
self.net.addConnection(b_h2)
self.net.sortModules()
#trainer to edit the network
trainer = BackpropTrainer(self.net, ds, learningrate = 0.003)
trainer.trainEpochs(25)
#generate a song given an input sequence
def getSong(self, inputSequence, songLength = 128):
if self.net is None:
print "Cannot create from nothing"
return
inputSequence = [x for x in inputSequence]
song = [inputSequence[x] for x in range(0, static.NUM_OF_INPUTS)]
nextout = 0
for x in range(0, songLength):
nextout = int(self.net.activate(tuple(inputSequence)))
# just to shake it up a little if we get 4 of the same chord in a row
if nextout == inputSequence[-1] and nextout == inputSequence[-2] and nextout == inputSequence[-3]:
recurring = dict()
for i in song:
if i in recurring:
recurring[i] += 1
else:
recurring[i] = 1
nextout = int(min(recurring, key = recurring.get))
song.append(nextout)
inputSequence = inputSequence[1:]
inputSequence.append(nextout)
'''print song[4:]
f = open('output.txt', 'w')
f.write(' '.join(song[4:]))
f.close()'''
return song[4:]
# Save trained data to file for later usage
def saveToFile(self):
if self.net is not None:
if self.major:
NetworkWriter.writeToFile(self.net, TRAINED_DATA_FILEPATH_MAJOR)
else:
NetworkWriter.writeToFile(self.net, TRAINED_DATA_FILEPATH_MINOR)
else:
print "Cannot save nothing"
# Load trained data from file
def loadFromFile(self):
try:
if self.major:
self.net = NetworkReader.readFrom(TRAINED_DATA_FILEPATH_MAJOR)
else:
self.net = NetworkReader.readFrom(TRAINED_DATA_FILEPATH_MINOR)
except:
print "Could not find or open file"
def run(mode):
learner = Learn(mode)
learner.loadFromFile()
learner.getSong([0, 2 ,4 ,0], 128)
if __name__ == "__main__":
run("major")
run("minor")