使用Keras将音乐分类为不同类型

使用Keras将音乐分类为不同类型

在本文中,我们将使用机器学习把音乐片段分类为不同类型。

我们将使用GTZAN genre collection数据集。此机器学习数据集可以从此处获取(http://opihi.cs.uvic.ca/sound/genres.tar.gz)。该机器学习数据集由10种类型组成,每种类型由100个音乐片段组成,每个音乐片段长30秒。

我们将使用Keras,采用tensorflow作为后端。

导入Python库

import librosa
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import os
import csv
# Preprocessing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
#Keras
import keras

使用Keras将音乐分类为不同类型

重要的提示:

检查tensorflow的版本应该大于1.1否则各种keras功能将失败。

Pip可能无法获得最新的tensorflow版本,因此请使用以下命令安装tensorflow:

pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.6.0-py3-none-any.whl

创建数据集

我们将根据我们的要求处理机器学习数据集。我们将创建一个包含我们所需数据的CSV文件。

header = 'filename chroma_stft rmse spectral_centroid spectral_bandwidth rolloff zero_crossing_rate'
for i in range(1, 21):
 header += f' mfcc{i}'
header += ' label'
header = header.split()

使用Keras将音乐分类为不同类型

这里我们为CSV文件生成标题。

我们将获得20 mfcc的给定采样率,因为它是针对每个帧计算的,因此mfcc有20列。

现在,我们将计算所有特征。

file = open('data.csv', 'w', newline='')
with file:
 writer = csv.writer(file)
 writer.writerow(header)
genres = 'blues classical country disco hiphop jazz metal pop reggae rock'.split()
for g in genres:
 for filename in os.listdir(f'./genres/{g}'):
 songname = f'./genres/{g}/{filename}'
 y, sr = librosa.load(songname, mono=True, duration=30)
 chroma_stft = librosa.feature.chroma_stft(y=y, sr=sr)
 rmse = librosa.feature.rmse(y=y)
 spec_cent = librosa.feature.spectral_centroid(y=y, sr=sr)
 spec_bw = librosa.feature.spectral_bandwidth(y=y, sr=sr)
 rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr)
 zcr = librosa.feature.zero_crossing_rate(y)
 mfcc = librosa.feature.mfcc(y=y, sr=sr)
 to_append = f'{filename} {np.mean(chroma_stft)} {np.mean(rmse)} {np.mean(spec_cent)} {np.mean(spec_bw)} {np.mean(rolloff)} {np.mean(zcr)}' 
 for e in mfcc:
 to_append += f' {np.mean(e)}'
 to_append += f' {g}'
 file = open('data.csv', 'a', newline='')
 with file:
 writer = csv.writer(file)
 writer.writerow(to_append.split())

使用Keras将音乐分类为不同类型

我们使用librosa包计算了所有功能,并创建了一个带有data.csv文件名的数据集,并在给定的标题中插入了给定音乐的所有特征值。

预处理机器学习数据集

读取数据集

data = pd.read_csv('data.csv')
data.head()

使用Keras将音乐分类为不同类型

删除不必要的列

# Dropping unneccesary columns
data = data.drop(['filename'],axis=1)
data.head()

使用Keras将音乐分类为不同类型

“文件名”列不是必需的。

现在,我们将把类型编码为整数

genre_list = data.iloc[:, -1]
encoder = LabelEncoder()
y = encoder.fit_transform(genre_list)
print(y)

使用Keras将音乐分类为不同类型

在这里,我们创建了一个流派和整数之间的映射。每个整数代表特定的类型。

归一化数据集

scaler = StandardScaler()
X = scaler.fit_transform(np.array(data.iloc[:, :-1], dtype = float))

使用Keras将音乐分类为不同类型

x的计算方法是取均值除以方差。

将机器学习数据集拆分为训练和测试数据集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

我们将数据集分成80:20比例的训练和测试数据集。

机器学习模型创建,训练和测试

创建模型

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_shape=(X_train.shape[1],)))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

使用Keras将音乐分类为不同类型

我们使用keras序列模型。

我们的网络有4层。首先是输入层,因此必须给出输入大小。然后有2个隐藏层,最后一层是输出层。dense内的值表示输出空间的维度。所以第一层有256个神经元,因此它的输出空间的维数是256。输出层有10个神经元,因为我们分为10个类型。

编译模型

model.compile(optimizer='adam',
 loss='sparse_categorical_crossentropy',
 metrics=['accuracy'])

使用Keras将音乐分类为不同类型

在开始训练之前,我们需要先进行配置。Optimizer代表了一种优化算法,我们将使用adam算法,它在深度学习中被广泛使用。loss是评价网络效率的一个函数。模型的目标是减少这个损失函数。Metric是要评估的度量,我们将评估准确性。损失函数sparse_categorical_crossentropy与categorical_crossentropy类似,后者仅在有多个分类字段时使用。

训练模型

history = model.fit(X_train,
 y_train,
 epochs=20,
 batch_size=128)

使用Keras将音乐分类为不同类型

利用fit函数对给定训练输入和输出的模型进行训练。

评估模型

test_loss, test_acc = model.evaluate(X_test,y_test)
print('test_acc: ',test_acc)

使用Keras将音乐分类为不同类型

我们将获得模型的准确性,可以根据提取的特征预测给定音乐的类型。

预测

predictions = model.predict(X_test)
np.argmax(predictions[0])

使用Keras将音乐分类为不同类型

predict函数给出了每种音乐类型匹配程度的百分比。给定类型的最高百分比是由argmax计算的最终结果。

相关推荐