teticio / Deej-AI

Create automatic playlists by using Deep Learning to *listen* to the music.
GNU General Public License v3.0
334 stars 52 forks source link

Adding creativity factor #119

Closed AlfredJKwack closed 12 hours ago

AlfredJKwack commented 4 weeks ago

Looking through the Deej-AI.online-app project I noticed there is a creativity factor that one can use to influence the playlist. Reading the text it speaks of:

In the settings screen, you can control the number of tracks that are added to the playlists as well as a couple of aspects of how they are generated. If creativity is set to 100%, then tracks are chosen with similar sound, energy, mood and instrumentation. It does this by simply "listening" and not using any information about the tracks themselves. If creativity is set to 0%, then tracks are selected based on similar artists ("Spotify users also included in their playlists..."). It can be interesting to use a value of 99%, which is enough to keep the playlist grounded. You can use the noise setting to add a bit of randomness.

That sounds like a very attractive feature indeed. I wonder, would there be appetite to have this same feature implemented in this project?

Looking through the codebase of Deej-AI.online-app you find that the creativity factor is ultimately implemented at deejai.py#L131-L134 as a set of positive and negative weights for the most_similar function. Higher level functions don't seem to do much with the values other than to pass it down to this one place.

Specifically the weights that creativity represents has been implemented in Deej-AI.online-app as follows:

    async def most_similar(  # pylint: disable=too-many-arguments
            self,
            mp3tovecs,
            weights,
            positive=iter(()),
            negative=iter(()),
            noise=0,
            vecs=None):
        """Most similar IDs.
        """
        mp3_vecs_i = np.array([
            weights[j] *
            np.sum([mp3tovecs[i, j]
                    for i in positive] + [-mp3tovecs[i, j] for i in negative],
                   axis=0) for j in range(len(weights))
        ])

That same function exists in this Deej-AI project (no surprise really). That makes me wonder how hard it would be to implement that same feature here? What would it take beyond modifying the signatures of a few functions and implementing the weights?

Implementation proposal for most_similar

def most_similar(positive=[], negative=[], topn=5, noise=0, weights=[0.5, 0.5]):
    ...
   #mp3_vec_i = np.sum([mp3tovec[i] for i in positive] + [-mp3tovec[i] for i in negative], axis=0)
    mp3_vec_i = np.sum([weights[0] * mp3tovec[i] for i in positive] + [-weights[1] * mp3tovec[i] for i in negative], axis=0)

Other functions to consider

@teticio, what do you think? Does the approach, and most importantly the actual proposal for the implementation make sense? I don't really have the means to coherently test the results so I'm going purely on the codebase. Maybe I'm missing something quite big.

Looking forward to the feeback.

teticio commented 13 hours ago

Hi. The problem is that for "creativity" to work we would need to different embeddings (ways to measure similarity between songs). With the tracklists I got from Spotify I was able to do this because I had (a) information on what songs tended to appear together in playlists and (b) the vector encodings using my "Speccy model", which captured similar genres, moods, energy and instrumentation. If there were a way to map your personal mp3 library to a spotify track ID, then this would be possible.

AlfredJKwack commented 12 hours ago

Aha, yep, I figured there was something quite big that I was missing. Finding a Spotify track ID from a random file on someone's HDD is a whole different scope. Thanks for the consideration.