See More

from nltk.util import ngrams from nltk.corpus import gutenberg import nltk import glob import argparse import random from random import shuffle from mido import Message, MidiFile, MidiTrack def load_split_file(filename): tokens = open(filename).read().strip().replace("\n"," ").split(" ") return [token for token in tokens if token != ""] def get_corpus(): filenames = glob.glob('./corpus.txt/*.txt') songs = [load_split_file(filename) for filename in filenames] return songs n_for_ngrams = 3 right_pad_symbol = 'EOS' left_pad_symbol = 'BOS' def our_ngrams(sentence, our_n=None): if our_n is None: our_n = n_for_ngrams return ngrams(sentence, our_n, pad_left = True, pad_right = True, right_pad_symbol=right_pad_symbol, left_pad_symbol=left_pad_symbol) # Natural Language Toolkit: Language Models # # Copyright (C) 2001-2014 NLTK Project # Authors: Steven Bird # Daniel Blanchard # Ilia Kurenkov # URL: # For license information, see LICENSE.TXT # http://www.nltk.org/_modules/nltk/model/ngram.html # Copyright (C) 2001-2018 NLTK Project # # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # def cross_entropy(estimator,text,n=n_for_ngrams,lpad=left_pad_symbol,rpad=right_pad_symbol): """ Calculate the approximate cross-entropy of the n-gram model for a given evaluation text. This is the average log probability of each word in the text. :param text: words to use for evaluation :type text: list(str) """ e = 0.0 text = [lpad] + text + [rpad] for i in range(n - 1, len(text)): #context = tuple(text[i - n + 1:i]) context = tuple(text[i - n + 1:i+1]) #token = text[i] estimate = estimator.logprob(context) #print((context,estimate)) e += estimate return -1 * e / float(len(text) - (n - 1)) def probability_sum(our_grams, estimator): for gram in our_grams: prob_sum += estimator.prob(gram) return prob_sum def apply_vocab(from_vocab=None,to_vocab=None,text=None): assert(to_vocab is not None) assert(from_vocab is not None) assert(text is not None) assert(len(to_vocab) == len(from_vocab)) vmap = dict(zip(from_vocab,to_vocab)) #print(vmap) return ([vmap[x] for x in text], vmap) def render_midifile( tokens, midi_name="midi",note_length=256 ): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) track.append(Message('program_change', program=12, time=0)) for token in tokens: note = int(token[1:]) track.append(Message('note_on', note=note, velocity=64, time=0)) track.append(Message('note_off', note=note, velocity=127, time=note_length)) mid.save('outputs/' + midi_name + '.mid') def render_textfile(notes, notes_name): fd = file('outputs/' + notes_name + '.txt','w') fd.write(" ".join(notes)) fd.close() def render_notesfile(notes, notes_name): fd = file('outputs/' + notes_name + '.notes','w') fd.write(tokens_to_notes_full(notes)) fd.close() midi_to_note_dict = { "127":"G9", "126":"Gb9", "125":"F9", "124":"E9", "123":"Eb9", "122":"D9", "121":"Db9", "120":"C9", "119":"B8", "118":"Bb8", "117":"A8", "116":"Ab8", "115":"G8", "114":"Gb8", "113":"F8", "112":"E8", "111":"Eb8", "110":"D8", "109":"Db8", "108":"C8", "107":"B7", "106":"Bb7", "105":"A7", "104":"Ab7", "103":"G7", "102":"Gb7", "101":"F7", "100":"E7", "99":"Eb7", "98":"D7", "97":"Db7", "96":"C7", "95":"B6", "94":"Bb6", "93":"A6", "92":"Ab6", "91":"G6", "90":"Gb6", "89":"F6", "88":"E6", "87":"Eb6", "86":"D6", "85":"Db6", "84":"C6", "83":"B5", "82":"Bb5", "81":"A5", "80":"Ab5", "79":"G5", "78":"Gb5", "77":"F5", "76":"E5", "75":"Eb5", "74":"D5", "73":"Db5", "72":"C5", "71":"B4", "70":"Bb4", "69":"A4", "68":"Ab4", "67":"G4", "66":"Gb4", "65":"F4", "64":"E4", "63":"Eb4", "62":"D4", "61":"Db4", "60":"C4", "59":"B3", "58":"Bb3", "57":"A3", "56":"Ab3", "55":"G3", "54":"Gb3", "53":"F3", "52":"E3", "51":"Eb3", "50":"D3", "49":"Db3", "48":"C3", "47":"B2", "46":"Bb2", "45":"A2", "44":"Ab2", "43":"G2", "42":"Gb2", "41":"F2", "40":"E2", "39":"Eb2", "38":"D2", "37":"Db2", "36":"C2", "35":"B1", "34":"Bb1", "33":"A1", "32":"Ab1", "31":"G1", "30":"Gb1", "29":"F1", "28":"E1", "27":"Eb1", "26":"D1", "25":"Db1", "24":"C1", "23":"B0", "22":"Bb0", "21":"A0" } def midi_to_note(note_number): return midi_to_note_dict[str(note_number)] def tokens_to_notes(tokens): return "".join([midi_to_note(int(token[1:]))[0] for token in tokens]) def tokens_to_notes_full(tokens): return " ".join([midi_to_note(int(token[1:])) for token in tokens]) def mutation_swap(original_perm, all_tokens=None): new_perm = list(original_perm) x = range(0,len(new_perm)) shuffle(x) i = x[0] # random.randint(0,len(new_perm) - 1) j = x[1] # random.randint(0,len(new_perm) - 1) new_perm[i], new_perm[j] = new_perm[j], new_perm[i] return new_perm def mutation_replace(original_perm, all_tokens): remaining = set(all_tokens).difference(original_perm) new_token = random.choice(list(remaining)) new_perm = list(original_perm) i = random.randint(0,len(new_perm) - 1) new_perm[i] = new_token return new_perm def test_mutation_replace(): orig = [chr(x) for x in range(ord('a'),ord('z')+1)] n = 10 partial = orig[0:n] for i in range(0,100000): new_perm = mutation_replace(partial, orig) assert partial != new_perm assert len(set(partial).difference(set(new_perm))) == 1 def test_mutation_swap(): orig = [chr(x) for x in range(ord('a'),ord('z')+1)] n = 10 partial = orig[0:n] for i in range(0,100000): new_perm = mutation_swap(partial, orig) assert partial != new_perm assert len(set(partial).difference(set(new_perm))) == 0 assert set(partial) == set(new_perm) def mutate_perm(original_perm, all_tokens, n_mutations=10): n_mutations = random.randint(1,n_mutations) mutaters = [mutation_swap, mutation_replace] new_perm = list(original_perm) for i in range(0, n_mutations): mutant_f = random.choice(mutaters) new_perm = mutant_f(new_perm, all_tokens) return new_perm