In [1]:
%pylab inline
import numpy as np
import pandas as pd
import keras
import arrow
In [21]:
labels_file = 'data/beatles/chord-pcs/4096_2048/The_Beatles/01_-_Please_Please_Me/08_-_Love_Me_Do.pcs'
features_file = 'data/beatles/chromagram/block=4096_hop=2048_bins=-48,67_div=1/The_Beatles/01_-_Please_Please_Me/08_-_Love_Me_Do.npz'
In [331]:
df_labels = pd.read_csv(labels_file, sep='\t')
df_labels.head(15)
Out[331]:
In [485]:
labels_pcs = df_labels[df_labels.columns[1:]].as_matrix()
labels_pcs[:10]
Out[485]:
In [24]:
data = np.load(features_file)
In [28]:
features = data['X']
times = data['times']
In [29]:
features.shape
Out[29]:
In [31]:
times.shape
Out[31]:
In [41]:
imshow(features[:100].T, cmap='gray');
In [43]:
hist(features.flatten(), 100);
In [988]:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X = scaler.fit_transform(features).astype('float32')
In [990]:
plt.hist(X.flatten(), 100);
In [52]:
# non-zero values
hist(X[X > 0].flatten(), 20);
In [530]:
import scipy.signal
def plot_labels(l, fifths=False, resample=True):
figure(figsize=(20,5))
if fifths:
l = l[:,np.arange(12)*7 % 12]
l = l.T
if resample:
l = scipy.signal.resample(l, 200, axis=1)
imshow(l, cmap='gray', interpolation='none')
plot_labels(labels_pcs)
In [496]:
plot_labels(labels_pcs, fifths=True)
In [241]:
plot(X[500]);
In [240]:
imshow(X[100,:108].reshape(-1,12), cmap='gray', interpolation='nearest');
In [243]:
plot(X.mean(axis=0));
In [249]:
imshow(X.mean(axis=0)[:108].reshape(-1,12), cmap='gray', interpolation='nearest');
In [248]:
plot(X.mean(axis=0)[:108].reshape(-1,12).max(axis=0), 'o:');
In [656]:
from sklearn.feature_extraction import DictVectorizer
from sklearn.preprocessing import OneHotEncoder
label_dict = dict((c,i) for (i, c) in enumerate(sorted(df_labels['label'].drop_duplicates())))
label_classes = df_labels['label'].apply(lambda l: label_dict[l]).as_matrix().reshape(-1, 1)
n_classes = len(label_dict)
label_ohe = OneHotEncoder(n_values=n_classes)
labels_ohe = label_ohe.fit_transform(label_classes).toarray().astype(np.int32)
labels_ohe
Out[656]:
In [991]:
from sklearn.cross_validation import train_test_split
ix_train, ix_test = train_test_split(np.arange(len(X)), test_size=0.2, random_state=42)
ix_train, ix_valid = train_test_split(ix_train, test_size=0.2/(1-0.2), random_state=42)
X_train, X_valid, X_test = X[ix_train], X[ix_valid], X[ix_test]
y_train, y_valid, y_test = labels_pcs[ix_train], labels_pcs[ix_valid], labels_pcs[ix_test]
y_ohe_train, y_ohe_valid, y_ohe_test = labels_ohe[ix_train], labels_ohe[ix_valid], labels_ohe[ix_test]
y_cls_train, y_cls_valid, y_cls_test = label_classes[ix_train], label_classes[ix_valid], label_classes[ix_test]
In [992]:
for d in [X_train, X_valid, X_test, y_train, y_valid, y_test]:
print(d.shape)
In [471]:
y_ohe_train[:10]
Out[471]:
In [470]:
y_train[:10]
Out[470]:
In [473]:
from sklearn.dummy import DummyClassifier
dummy_classifier = DummyClassifier()
dummy_classifier.fit(X_train, y_train)
print('training score:', dummy_classifier.score(X_train, y_train))
print('validation score:', dummy_classifier.score(X_valid, y_valid))
plot_labels(dummy_classifier.predict(features))
In [474]:
from sklearn.dummy import DummyClassifier
dummy_classifier_ohe = DummyClassifier()
dummy_classifier_ohe.fit(X_train, y_one_train)
print('training score:', dummy_classifier_ohe.score(X_train, y_ohe_train))
print('validation score:', dummy_classifier_ohe.score(X_valid, y_ohe_valid))
plot_labels(dummy_classifier_ohe.predict(features))
In [1176]:
from sklearn.metrics import hamming_loss, accuracy_score
def model_report_multilabel(model_predict, X_train, y_train, X_valid, y_valid):
def report_dataset(X, y_true, title):
y_pred = model_predict(X)
print(title + ' accuracy (exatch match):', accuracy_score(y_true, y_pred))
print(title + ' hamming score (non-exatch match):', 1 - hamming_loss(y_true, y_pred))
report_dataset(X_train, y_train, 'training')
report_dataset(X_valid, y_valid, 'validation')
In [1177]:
from sklearn.linear_model import LogisticRegression
from sklearn.multiclass import OneVsRestClassifier
log_reg = OneVsRestClassifier(LogisticRegression())
log_reg.fit(X_train, y_train)
print('training score:', log_reg.score(X_train, y_train))
print('validation score:', log_reg.score(X_valid, y_valid))
model_report_multilabel(log_reg.predict, X_train, y_train, X_valid, y_valid)
It seems that score for OneVsRestClassifier + LogisticRegression is the same as accuracy score.
In [478]:
plot_labels(log_reg.predict(features))
In [499]:
plot_labels(labels_pcs - log_reg.predict(features))
In [149]:
import scipy
scipy.misc.imsave('log_reg.png', log_reg.predict(features).T)
In [536]:
plot_labels(labels_pcs[:100] - log_reg.predict(features[:100]), resample=False)
In [533]:
plot_labels(labels_pcs[:100], resample=False)
In [555]:
log_reg_ohe = OneVsRestClassifier(LogisticRegression(multi_class='multinomial', solver='lbfgs'))
log_reg_ohe.fit(X_train, y_ohe_train)
print('training score:', log_reg_ohe.score(X_train, y_ohe_train))
print('validation score:', log_reg_ohe.score(X_valid, y_ohe_valid))
# model_report_multilabel(log_reg_ohe.predict)
In [559]:
plot_labels(log_reg_ohe.predict(features[:100]), resample=False)
In [560]:
log_reg_ohe.predict(features[:10])
Out[560]:
In [276]:
from sklearn.svm import SVC
svc = OneVsRestClassifier(SVC())
svc.fit(X_train, y_train)
print('training score:', svc.score(X_train, y_train))
print('validation score:', svc.score(X_valid, y_valid))
In [277]:
plot_labels(svc.predict(features))
In [1178]:
def conv_reshape(X):
return X.reshape(X.shape[0], X.shape[1], 1)
X_conv_train = conv_reshape(X_train)
X_conv_valid = conv_reshape(X_valid)
In [1397]:
def save_model(model_id, model):
arch_file = '%s_arch.yaml' % model_id
weights_file = '%s_weights.h5' % model_id
print('architecture:', arch_file)
print('weights:', weights_file)
open(arch_file, 'w').write(model.to_yaml())
model.save_weights(weights_file)
def new_model_id():
return 'model_%s' % arrow.get().format('YYYY-MM-DD-HH-mm-ss')
In [1065]:
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Flatten, Dropout
from keras.layers.convolutional import Convolution1D, MaxPooling1D
from keras.layers.normalization import BatchNormalization
In [ ]:
# working model
# results after 150 epochs:
# - validation accuracy (exatch match): 0.79837398374
# - validation hamming score (non-exatch match): 0.9456639566395664
model = Sequential()
model.add(Dense(50, input_dim=features.shape[1]))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(12))
model.add(Activation('sigmoid'))
print('number of parameters:', model.count_params())
print('weights', [w.shape for w in model.get_weights()])
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adadelta')
In [ ]:
# working example with convolutional layers:
# results after 100 epochs:
# training accuracy (exatch match): 0.810298102981
# training hamming score (non-exatch match): 0.9575880758807588
# validation accuracy (exatch match): 0.767479674797
# validation hamming score (non-exatch match): 0.9387533875338754
# number of parameters: 8552
# weights [(5, 1, 5, 1), (5,), (111, 5), (111, 5), (111, 5), (111, 5), (10, 5, 5, 1), (10,), (51, 10), (51, 10), (51, 10), (51, 10), (510, 12), (12,)]
model = Sequential()
model.add(Convolution1D(5, 5, input_shape=(features.shape[1], 1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(2, 2))
model.add(Convolution1D(10, 5))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(12))
model.add(Activation('sigmoid'))
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adam')
In [ ]:
# one more dense layer:
# 100 epochs
# training accuracy (exatch match): 0.931707317073
# training hamming score (non-exatch match): 0.984914182475158
# validation accuracy (exatch match): 0.827642276423
# validation hamming score (non-exatch match): 0.9470189701897019
# number of parameters: 54732
# weights [(5, 1, 5, 1), (5,), (111, 5), (111, 5), (111, 5), (111, 5), (10, 5, 5, 1), (10,), (51, 10), (51, 10), (51, 10), (51, 10), (510, 100), (100,), (100, 12), (12,)]
model = Sequential()
model.add(Convolution1D(5, 5, input_shape=(features.shape[1], 1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(2, 2))
model.add(Convolution1D(10, 5))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(100))
model.add(Activation('relu'))
model.add(Dense(12))
model.add(Activation('sigmoid'))
print('number of parameters:', model.count_params())
print('weights', [w.shape for w in model.get_weights()])
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adam')
In [ ]:
# more convolution filters, more smaller dense layers at the end
# number of parameters: 14702
# weights [(10, 1, 5, 1), (10,), (111, 10), (111, 10), (111, 10), (111, 10), (10, 10, 5, 1), (10,), (51, 10), (51, 10), (51, 10), (51, 10), (510, 20), (20,), (20, 20), (20,), (20, 12), (12,)]
# 100 epochs
# last lost: 0.0493504540061
# training accuracy (exatch match): 0.918699186992
# training hamming score (non-exatch match): 0.9811201445347787
# validation accuracy (exatch match): 0.827642276423
# validation hamming score (non-exatch match): 0.9518970189701897
model = Sequential()
model.add(Convolution1D(10, 5, input_shape=(features.shape[1], 1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(2, 2))
model.add(Convolution1D(10, 5))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(12))
model.add(Activation('sigmoid'))
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adam')
In [ ]:
# max-pooling after the two convolutions
# number of parameters: 16522
# weights [(10, 1, 3, 1), (10,), (113, 10), (113, 10), (113, 10), (113, 10), (10, 10, 3, 1), (10,), (111, 10), (111, 10), (111, 10), (111, 10), (550, 20), (20,), (20, 20), (20,), (20, 12), (12,)]
# 100 epochs
# last loss: 0.0579237073095
# training accuracy (exatch match): 0.919241192412
# training hamming score (non-exatch match): 0.9795392953929539
# validation accuracy (exatch match): 0.834146341463
# validation hamming score (non-exatch match): 0.9521680216802169
model = Sequential()
model.add(Convolution1D(10, 3, input_shape=(features.shape[1], 1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Convolution1D(10, 3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(2, 2))
model.add(Flatten())
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(12))
model.add(Activation('sigmoid'))
print('number of parameters:', model.count_params())
print('weights', [w.shape for w in model.get_weights()])
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adam')
In [1385]:
model_id = new_model_id()
In [1363]:
model = Sequential()
model.add(Convolution1D(10, 3, input_shape=(features.shape[1], 1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Convolution1D(10, 3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(2, 2))
model.add(Flatten())
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(20))
model.add(Activation('relu'))
model.add(Dense(12))
model.add(Activation('sigmoid'))
print('number of parameters:', model.count_params())
print('weights', [w.shape for w in model.get_weights()])
model.compile(class_mode='binary', loss='binary_crossentropy', optimizer='adam')
In [1364]:
hist = model.fit(X_conv_train, y_train, nb_epoch=100)
# hist = model.fit(X_train, y_train, nb_epoch=100)
In [1398]:
save_model(model_id, model)
In [1365]:
losses = hist.history['loss']
print('last loss:', losses[-1])
plot(losses);
In [1366]:
model_report_multilabel(model.predict_classes, X_conv_train, y_train, X_conv_valid, y_valid)
In [1368]:
# true labels
plot_labels(labels_pcs)
In [1367]:
# predicted labels
labels_pred_full = model.predict_classes(conv_reshape(X))
plot_labels(labels_pred_full)
In [1370]:
# difference
plot_labels(labels_pcs - labels_pred_full)
In [1371]:
plot_labels(labels_pred_full[:100], resample=False)
In [1372]:
plot_labels(labels_pcs[:100] - labels_pred_full[:100], resample=False)