🎼 Compositor de IA en Python: Crear música desde cero
¡Cómo enseñamos a una red neuronal a entender música, generarla y guardarla en un archivo para escucharla!
Pones música y escuchas la melodía. Ahora imagina: ¡la red neuronal también «escucha» música, la memoriza y luego compone la suya propia! 🤯
💡 Crearemos una red neuronal de este tipo desde cero. Y comenzaremos con el primer paso: ¡prepararemos la música en un formato cómodo para el aprendizaje, entrenaremos el modelo y, finalmente, generaremos la primera composición!
🔧 Parte 1: Preparación de datos y conceptos básicos
1. Instalamos la herramienta para trabajar con música
Abre la terminal (o línea de comandos) y escribe:
pip install music21📦 Esta es la biblioteca music21. Es como un traductor musical:
lee archivos
.mid(contienen música),saca notas y acordes,
permite guardar y crear nuevas melodías.
Este es nuestro asistente para convertir la música en datos que Python y las redes neuronales puedan entender.
2. Prepara la música
Para que la IA aprenda a componer, necesita ejemplos. Como un niño: primero escucha cómo cantan los adultos y solo entonces empieza a tararear él mismo 🎵
🎼 Nos vendrán bien MIDI-файлы: son como «borradores musicales» donde se registra qué notas se tocan, en qué orden y durante cuánto tiempo.
🔍 ¿Dónde conseguirlo?
Visita el sitio web https://bitmidi.com
Descarga algunas melodías (por ejemplo, Bach o Beethoven)
Crea una carpeta llamada
midi_songsjunto al códigoColoca allí los archivos con la extensión
.mid
3. Leer música en Python
Ahora, el código. Este código leerá todos los archivos MIDI, extraerá las notas y las añadirá a la lista. Aquí tienes un ejemplo completo:
from music21 import converter, note, chord
import glob
notes = []
# Pasamos por todos los archivos de la carpeta midi_songs
for file in glob.glob("midi_songs/*.mid"):
# Cargando el archivo como una obra musical
midi = converter.parse(file)
# Sacamos todas las notas y acordes, ignorando los instrumentos
elements = midi.flat.notes
for element in elements:
if isinstance(element, note.Note):
# Esta es una nota única, por ejemplo, «C4» (do en la cuarta octava)
notes.append(str(element.pitch))
elif isinstance(element, chord.Chord):
# Este acorde, por ejemplo, «60.64.67»
# Tomamos los números de todas las notas del acorde y los conectamos en una línea
notes.append('.'.join(str(n) for n in element.normalOrder))📌 Explicación:
glob.glob("midi_songs/*.mid")— busca todos los archivos MIDI en la carpeta.converter.parse(file)— lee el archivo y lo convierte en un objeto con el que se puede trabajar.midi.flat.notes— solo obtiene notas (todavía no tocamos el ritmo, el tempo y los instrumentos).note.Note— notas individuales (do, re, mi, etc.)chord.Chord— acordes (varias notas al mismo tiempo, como en un acorde de guitarra).
🎵 ¿Por qué guardamos las notas en forma de líneas?
Porque así es más fácil transferirlos a la red neuronal. Por ejemplo:
"C4"— nota normal."60.64.67"— un acorde de tres notas, donde cada dígito es el número de la nota en altura.
Lo que hemos conseguido
👉 La variable notes ahora contiene toda la música de los archivos MIDI, nota por nota, acorde por acorde.
Por ejemplo:
notes[:10]
# ['E4', 'D4', 'C4', 'C4', 'D4', 'E4', 'E4', 'E4', 'D4', 'D4']Es como si escribieras una melodía de oído, pero no con los oídos, sino con el código 🎧
✅ RESULTADO DE LA PRIMERA PARTE:
Hemos instalado la biblioteca necesaria
Descargaron música
La convirtieron en una lista de notas
Este es el «material de aprendizaje» para la IA.
🔁 Parte 2: Entrenamiento de la red neuronal
La última vez convertimos la música de los archivos .mid en una lista de notas. Ahora viene lo más interesante: enseñaremos a la IA a entender cómo se construye una melodía y a generar la suya propia 🎶
Aunque acabes de empezar a aprender Python, ¡lo entenderás! ¡Vamos! 🚀
1. Dividimos la música en trozos
Para que la IA aprenda a componer, necesita ejemplos: «Aquí tienes un fragmento de notas, adivina cuál será la siguiente». Como si estuvieras escuchando una canción conocida y adivinaras lo que vendrá después 🎧
# Obtenemos una lista de notas únicas
pitchnames = sorted(set(notes))
# Creamos un diccionario: nota -> número
note_to_int = {note: number for number, note in enumerate(pitchnames)}
sequence_length = 50 # longitud de la pieza (50 notas)
network_input = []
network_output = []
for i in range(len(notes) - sequence_length):
# Tomamos 50 notas consecutivas
sequence_in = notes[i:i + sequence_length]
# La siguiente nota es la «respuesta»se"
sequence_out = notes[i + sequence_length]
# Traducimos las notas en números
network_input.append([note_to_int[n] for n in sequence_in])
network_output.append(note_to_int[sequence_out])📌 Aquí estamos:
Encontramos todas las notas únicas (por ejemplo, C4, D4, 60.64.67).
Convertimos cada nota en un número, porque la red neuronal no entiende el texto, solo los números.
🧠 En pocas palabras:
Tomamos un fragmento de 50 notas como contexto.
Y le pedimos a la red neuronal que adivine la nota 51.
Tendremos miles de ejemplos de este tipo y la red neuronal aprenderá de cada uno de ellos.
2. Prepararemos los datos para la red neuronal
La red neuronal funciona con números del 0 al 1, no solo con números de notas. Por lo tanto, normalizamos los datos de entrada:
import numpy as np
from tensorflow.keras.utils import to_categorical
n_patterns = len(network_input)
n_vocab = len(pitchnames)
# Convertimos al formato deseado y dividimos por el número total de notas
network_input = np.reshape(network_input, (n_patterns, sequence_length, 1))
network_input = network_input / float(n_vocab)
# Convertimos las salidas en categorías (one-hot)
network_output = to_categorical(network_output)🔍 ¿Qué está pasando aquí?
Cambiamos la forma de entrada de la lista habitual al formato 3D (necesario para el funcionamiento de la red neuronal).
Dividimos cada número por el número total de notas para obtener valores de 0 a 1.
Las salidas (respuestas correctas) se convierten en una vista especial, donde cada nota es una «salida» separada de la red.
3. Construimos una red neuronal simple
Ahora la magia:
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dropout, Dense model = Sequential() model.add(LSTM(256, input_shape=(sequence_length, 1))) model.add(Dropout(0.3)) model.add(Dense(n_vocab, activation='softmax'))📌 Explicación:
LSTMes un tipo especial de red neuronal que recuerda bien las secuencias (por ejemplo, música).Dropout— para que el modelo no «memorice», sino que aprenda de verdad.Dense(n_vocab, activation='softmax')— a la salida, la red dirá: «Creo que con una probabilidad del 80 % la siguiente nota es C4, 10 % — D4...»
4. Entrenamos la red neuronal
model.compile(loss='categorical_crossentropy', optimizer='adam') model.fit(network_input, network_output, epochs=50, batch_size=64)💡 El aprendizaje llevará un poco de tiempo. La esencia es la siguiente:
La red mira 50 notas.
Intenta adivinar la 51ª.
Descubre si te has equivocado o no.
Y ajusta su «lógica» para adivinar con mayor precisión la próxima vez.
Así, miles de veces seguidas. Y cada vez lo hace mejor y mejor. Como un niño que aprende a componer melodías de oído 🎶
🔥 ¡Listo! Ahora tenemos un modelo entrenado que puede predecir la siguiente nota de la melodía.
🎼 Parte 3: Generación y almacenamiento de música
Ya has recopilado los datos, entrenado la red neuronal y ahora llega el momento mágico: 👉 ¡la IA compondrá música por sí misma! Y podrás escuchar el resultado.
1. Empezamos con una pequeña melodía
Hemos enseñado a la red: «Aquí tienes 50 notas, adivina la 51». Ahora hacemos lo contrario: Le damos 50 notas, ella predice la siguiente, luego otra y otra...
import random import numpy as np # Diccionario: de entre - en la nota int_to_note = {number: note for number, note in enumerate(pitchnames)} # Elegimos una secuencia de inicio aleatoria (50 notas) start = random.randint(0, len(network_input) - 1) pattern = network_input[start]💡 Tomamos una pieza al azar (el mismo formato que se usó durante el entrenamiento): será la «semilla», el comienzo de una nueva melodía.
2. Generamos la continuación de la melodía
A continuación, le preguntaremos al modelo 300 veces seguidas: «¿Qué nota quieres poner a continuación?»
prediction_output = [] for i in range(300): # queremos 300 notas nuevas # Preparando la entrada: reshape + normalización (de 0 a 1) prediction_input = pattern.reshape(1, len(pattern), 1) prediction_input = prediction_input / float(n_vocab) # Predice la siguiente nota prediction = model.predict(prediction_input, verbose=0) # Tomamos el índice de la nota más probable index = np.argmax(prediction) # Convertimos el número de nuevo en el nombre de la nota result = int_to_note[index] prediction_output.append(result) # Actualizamos la secuencia: eliminamos la primera, añadimos una nueva pattern = np.append(pattern[1:], [[index]], axis=0)🔍 Lo que es importante aquí:
.reshape(...)— convertimos los datos al formato requerido (1 melodía, 50 notas, 1 valor por nota)./ float(n_vocab)— normalizamos los valores para que la red pueda funcionar correctamente.model.predict(...)— la red predice las probabilidades para todas las notas.np.argmax(...)— elegimos la que recibió la mayor probabilidad.append(..., [[index]], ...)— desplazamos la melodía un paso.
📌 Así, paso a paso, la IA compone una nueva melodía: primero la nota 51, luego la 52, y así hasta la 300.
3. Convertimos las notas en música
Ahora tenemos una lista de notas en forma de cadenas:
['E4', 'F4', 'G4', '60.64.67', ...]Esta es la melodía futura, pero para escucharla, debes recopilar un archivo
.midde ella: es como un borrador para un programa de música.from music21 import stream, note, chord, instrument output_notes = [] for pattern in prediction_output: if '.' in pattern or pattern.isdigit(): # Esto es un acorde notes_in_chord = pattern.split('.') chord_notes = [note.Note(int(n)) for n in notes_in_chord] new_chord = chord.Chord(chord_notes) output_notes.append(new_chord) else: # Esta es una nota única, como «C4» new_note = note.Note(pattern) new_note.storedInstrument = instrument.Piano() output_notes.append(new_note)📌 Explicación:
Si la línea contiene puntos o solo números, es un acorde (varias notas).
Si es una nota normal, hacemos
note.Note(...)y la añadimos como un sonido separado.Todas las notas/acordes se suman en
output_notes.
4. Guardar música en un archivo
Ahora creamos un flujo de música y lo guardamos en un archivo:
midi_stream = stream.Stream(output_notes) midi_stream.write('midi', fp='generated_music.mid')🎉 ¡Listo! Ahora tienes el archivo
generated_music.mid— ábrelo en:🎼 https://musescore.org/ — editor de partituras y reproductor gratuito
🧠 Incluso en el navegador: https://onlinesequencer.net/
Pulsa Play y escucha lo que ha compuesto tu compositor de IA 🤖🎵
✅ Lo que has hecho:
Convirtió la música en datos
Enseñó a una red neuronal a continuar melodías
Recibí mi primera composición generada
🧑🎼 Esto ya no es solo código Python. ¡Es tu coautor de IA!
🎁 ¿Quieres añadir:
¿Un ensayo con un estilo específico?
¿Mantenimiento del ritmo y la duración?
¿Generar música pulsando un botón en la aplicación web?
Si te ha salido bien, compártelo en Telegram o súbelo a TikTok: los músicos de IA están de moda 😎
Código fuente
Puedes encontrar el código fuente completo del proyecto en GitHub:
