简单音乐推荐系统的设计与实现
本文提供两种简单的传统音乐推荐系统(next-songs 方向)的思路与实现。(数学原理和机器学习方法从略)
下文仅给出思路以及关键代码,完整代码实现见: https://github.com/cdfmlr/murecom-intro
1. 基于音频特征
分析音频特征,做基于内容的推荐(Content-Based Filtering,CBF)。
1.1 设计思路
一个喜欢巴赫的人可能也喜欢肖邦,所以一种自然的想法是,我们可以把音频送给机器进行学习,试图让它分别不同种类、风格的音乐。给定一首歌,送入训练好的模型,推荐出风格上最相近的其他歌曲。
song-classification.ipynb
实现了这种模型的训练。
加拿大维多利亚大学的 genres 数据集(http://opihi.cs.uvic.ca/sound/genres.tar.gz),提供了良好标注的不同种类音乐片段。
$ ls genres
blues country hiphop metal reggae
classical disco jazz pop rock
我们把这些片段利用 librosa 库转化为梅尔频谱图(mel-spectrogram)。
(上图为数据集中 Hip-Hop 风格片段的平均频谱图)
把频谱送入一个一维卷积池化堆叠 + 全连接分类头的神经网络,训练,得到的模型即一个音乐风格检测器。
def cnn_model(input_shape):
inputs = Input(input_shape)
x = inputs
# 一维卷积池化
levels = 64
for level in range(3):
x = Conv1D(levels, 3, activation='relu')(x)
x = BatchNormalization()(x)
x = MaxPooling1D(pool_size=2, strides=2)(x)
levels *= 2
# x -> shape(128)
x = GlobalMaxPooling1D()(x)
# 计算类型标签的全连接网络
for fc in range(2):
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
labels = Dense(10, activation='softmax')(x)
model = Model(inputs=[inputs], outputs=[labels])
# optimizer and compile model
sgd = SGD(learning_rate=0.0003, momentum=0.9, decay=1e-5, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])
return model