From 13c90da84939ceae8fa46619f01244dc330910c3 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Sat, 26 Aug 2017 12:58:48 -0400 Subject: [PATCH 01/12] added DNN training --- scripts/DNN_training/NNTrain.py | 521 ++++++++++++++++++ scripts/DNN_training/NNTrain.pyc | Bin 0 -> 16362 bytes scripts/DNN_training/README.md | 134 +++++ scripts/DNN_training/ctc.py | 137 +++++ scripts/DNN_training/ctc.pyc | Bin 0 -> 4534 bytes scripts/DNN_training/genLabels.py | 339 ++++++++++++ scripts/DNN_training/genLabels.pyc | Bin 0 -> 14192 bytes scripts/DNN_training/makeFileListFromTrans.py | 19 + scripts/DNN_training/readSen.py | 96 ++++ scripts/DNN_training/requirements.txt | 67 +++ scripts/DNN_training/runDatasetGen.py | 41 ++ scripts/DNN_training/runNNPredict.py | 48 ++ scripts/DNN_training/runNNTrain.py | 168 ++++++ scripts/DNN_training/sample_nn.cfg | 22 + scripts/DNN_training/test.csv | 0 scripts/DNN_training/utils.py | 333 +++++++++++ scripts/DNN_training/utils.pyc | Bin 0 -> 11188 bytes 17 files changed, 1925 insertions(+) create mode 100644 scripts/DNN_training/NNTrain.py create mode 100644 scripts/DNN_training/NNTrain.pyc create mode 100644 scripts/DNN_training/README.md create mode 100644 scripts/DNN_training/ctc.py create mode 100644 scripts/DNN_training/ctc.pyc create mode 100644 scripts/DNN_training/genLabels.py create mode 100644 scripts/DNN_training/genLabels.pyc create mode 100644 scripts/DNN_training/makeFileListFromTrans.py create mode 100644 scripts/DNN_training/readSen.py create mode 100644 scripts/DNN_training/requirements.txt create mode 100644 scripts/DNN_training/runDatasetGen.py create mode 100644 scripts/DNN_training/runNNPredict.py create mode 100644 scripts/DNN_training/runNNTrain.py create mode 100644 scripts/DNN_training/sample_nn.cfg create mode 100644 scripts/DNN_training/test.csv create mode 100644 scripts/DNN_training/utils.py create mode 100644 scripts/DNN_training/utils.pyc diff --git a/scripts/DNN_training/NNTrain.py b/scripts/DNN_training/NNTrain.py new file mode 100644 index 00000000..9bddc8aa --- /dev/null +++ b/scripts/DNN_training/NNTrain.py @@ -0,0 +1,521 @@ +from keras.models import Sequential, Model +from keras.optimizers import SGD,Adagrad, Adam +from keras.layers.normalization import BatchNormalization +from keras.layers import ( + Input, + Dense, + Activation, + Dropout, + Conv1D, + Conv2D, + LocallyConnected2D, + MaxPooling2D, + AveragePooling2D, + Reshape, + Flatten, + Masking) +from keras.layers.core import Lambda +from keras.layers.merge import add, concatenate +from keras.utils import to_categorical, plot_model +from keras.models import load_model, Model +from keras.callbacks import History,ModelCheckpoint,CSVLogger,ReduceLROnPlateau +from keras import regularizers +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +import numpy as np +import matplotlib.pyplot as plt +import tensorflow as tf +from tensorflow.python.ops import math_ops +from tensorflow.python.ops import array_ops +from tfrbm import GBRBM,BBRBM +from sys import stdout +import time +import gc +from sklearn.preprocessing import StandardScaler +from guppy import hpy +import threading +import struct +from utils import * +import ctc + +""" + This module provides functions for training different neural network architectures + Below is a bried summary of the different functions and their purpose, more detail + can be found below: + - mlp1: creates a MLP consisting of a number dense layers + - mlp_wCTC: creates a MLP that calculates the ctc loss during training + - mlp4: create convolutional neural networks and residual networks + - DBN_DNN: performs DBN pretraining on simple MLPs + - preTrain: performs layer-wise pretraining on simple MLPs + - trainAndTest: runs training on a provided model using the given dataset +""" + +def mlp1(input_dim,output_dim,depth,width,dropout=False, + BN=False, regularize=False, lin_boost=False, activation='sigmoid'): + print locals() + model = Sequential() + model.add(Dense(width, activation=activation, input_shape=(input_dim,), + kernel_regularizer=regularizers.l2(0.05) if regularize else None)) + if BN: + model.add(BatchNormalization()) + if dropout: + model.add(Dropout(dropout)) + for i in range(depth - 1): + model.add(Dense(width, activation=activation, + kernel_regularizer=regularizers.l2(0.05) if regularize else None)) + if dropout: + model.add(Dropout(dropout)) + if BN: + model.add(BatchNormalization()) + if lin_boost: + model.add(Dense(output_dim)) + model.add(Lambda(lambda x: K.exp(x))) + else: + model.add(Dense(output_dim, name='out')) + model.add(Activation('softmax', name='softmax')) + opt = Adam(lr=10/(np.sqrt(input_dim * width * output_dim))) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model + +def ctc_lambda_func(args): + import tensorflow as tf + y_pred, labels, input_length, label_length = args + label_length = K.cast(tf.squeeze(label_length), 'int32') + input_length = K.cast(tf.squeeze(input_length), 'int32') + # return K.ctc_batch_cost(labels, y_pred, input_length, label_length) + labels = K.ctc_label_dense_to_sparse(labels,label_length) + return tf.nn.ctc_loss(labels,y_pred,input_length, + preprocess_collapse_repeated=True, + ctc_merge_repeated=False, + time_major=False, + ignore_longer_outputs_than_inputs=True) + +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def decode_output_shape(inputs_shape): + y_pred_shape, seq_len_shape = inputs_shape + return (y_pred_shape[:1], None) + +def decode(args): + import tensorflow as tf + y_pred, label_len = args + label_len = K.cast(tf.squeeze(label_len), 'int32') + # ctc_labels = tf.nn.ctc_greedy_decoder(y_pred, label_len)[0][0] + # return ctc_labels + ctc_labels = K.ctc_decode(y_pred,label_len,greedy=False)[0][0] + return K.ctc_label_dense_to_sparse(ctc_labels, label_len) + +# def ler(args): +# y_pred, y_true, input_length, label_length = args +# label_length = K.cast(tf.squeeze(label_length), 'int32') +# input_length = K.cast(tf.squeeze(input_length), 'int32') + +# y_pred = K.ctc_decode(y_pred,input_length)[0][0] +# # y_pred = tf.nn.ctc_greedy_decoder(y_pred,input_length)[0][0] +# y_pred = K.cast(y_pred,'int32') +# # y_pred = math_ops.to_int32(y_pred) +# # y_true = math.ops.to_int64(y_true) +# y_true = K.ctc_label_dense_to_sparse(y_true,label_length) +# y_pred = K.ctc_label_dense_to_sparse(y_pred,input_length) +# return tf.reduce_mean(tf.edit_distance(y_pred, y_true)) +# def ler(y_true, y_pred, **kwargs): +# """ +# Label Error Rate. For more information see 'tf.edit_distance' +# """ +# return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def mlp_wCTC(input_dim,output_dim,depth,width,BN=False): + print locals() + x = Input(name='x', shape=(1000,input_dim)) + h = x + h = Masking()(h) + for i in range(depth): + h = Dense(width)(h) + if BN: + h = BatchNormalization()(h) + h = Activation('sigmoid')(h) + out = Dense(output_dim,name='out')(h) + softmax = Activation('softmax', name='softmax')(out) + # a = 1.0507 * 1.67326 + # b = -1 + # # out = Lambda(lambda x : a * K.pow(x,3) + b)(h) + # out = Lambda(lambda x: a * K.exp(x) + b, name='out')(h) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def ctc_model(model): + x = model.get_layer(name='x').input + + out = model.get_layer(name='out').output + softmax = Activation('softmax', name='softmax')(out) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def _bn_act(input,activation='relu'): + """Helper to build a BN -> relu block + """ + norm = BatchNormalization()(input) + return Activation(activation)(norm) + +def make_dense_res_block(inp, size, width, drop=False,BN=False,regularize=False): + x = inp + for i in range(size): + x = Dense(width, + kernel_regularizer=regularizers.l2(0.05) if regularize else None)(x) + if i < size - 1: + if drop: + x = Dropout(0.15)(x) + if BN: + x = _bn_relu(x) + return x + +def mlp4(input_dim,output_dim,nBlocks,width, n_frames, block_depth=1, + n_filts=[84], filt_dims=[(11,8)], pooling=[['max',(6,6),(2,2)]], + block_width=None, dropout=False, BN=False, activation='relu', + parallelize=False, conv=False, regularize=False, + exp_boost=False, quad_boost=False, shortcut=False, + opt='adam', lr=0.001): + + print locals() + if block_width == None: + block_width = width + inp = Input(shape=input_dim, name='x') + x = inp + if conv: + x = Reshape((n_frames,input_dim/n_frames,1))(x) + for i in range(len(n_filts)): + print i + + x = LocallyConnected2D(n_filts[i],filt_dims[i], + padding='valid')(x) + x = _bn_act(x,activation=activation) + if pooling[i] != None: + pooling_type, win_size, stride = pooling[i] + if pooling_type == 'max': + x = MaxPooling2D(win_size,strides=stride,padding='same')(x) + if pooling_type == 'avg': + x = AveragePooling2D(win_size,strides=stride,padding='same')(x) + x = Flatten()(x) + if block_width != width: + x = Dense(block_width)(x) + for i in range(nBlocks): + y = make_dense_res_block(x,block_depth,block_width,BN=BN,drop=dropout,regularize=regularize) + if shortcut: + x = add([x,y]) + else: + x = y + if dropout: + x = Dropout(dropout)(x) + if BN: + x = _bn_act(x,activation=activation) + else: + x = Activation(activation)(x) + + if exp_boost: + x = Dense(output_dim)(x) + z = Lambda(lambda x : K.exp(x))(x) + if quad_boost: + x = Dense(output_dim)(x) + a = 0.001 + b = 0.4 + z = Lambda(lambda x : a * K.pow(x,3) + b)(x) + else: + z = Dense(output_dim, name='out')(x) + z = Activation('softmax', name='softmax')(z) + model = Model(inputs=inp, outputs=z) + if parallelize: + model = make_parallel(model, len(CUDA_VISIBLE_DEVICES.split(','))) + # opt = Adam(lr=25/(np.sqrt(width * output_dim))) + if opt == 'sgd': + opt = SGD + if opt == 'adam': + opt = Adam + if opt == 'adagrad': + opt = Adagrad + opt = opt(lr=lr) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model + +def resnet_wrapper(input_dim,output_dim,depth,width,reshape_layer): + builder = resnet.ResnetBuilder() + model = builder.build_resnet_18(input_dim, output_dim,reshape_layer) + x = model.get_layer(name='flatten_1').get_output_at(-1) + for i in range(depth): + x = Dense(width,activation='relu')(x) + softmax = Dense(output_dim,activation='softmax')(x) + model = Model(inputs=model.inputs, outputs=softmax) + opt = Adam(lr=10/np.sqrt(input_dim * output_dim)) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model +def DBN_DNN(inp,nClasses,depth,width,batch_size=2048): + RBMs = [] + weights = [] + bias = [] + # batch_size = inp.shape + nEpoches = 5 + if len(inp.shape) == 3: + inp = inp.reshape((inp.shape[0] * inp.shape[1],inp.shape[2])) + sigma = np.std(inp) + # sigma = 1 + rbm = GBRBM(n_visible=inp.shape[-1],n_hidden=width,learning_rate=0.002, momentum=0.90, use_tqdm=True,sample_visible=True,sigma=sigma) + rbm.fit(inp,n_epoches=15,batch_size=batch_size,shuffle=True) + RBMs.append(rbm) + for i in range(depth - 1): + print 'training DBN layer', i + rbm = BBRBM(n_visible=width,n_hidden=width,learning_rate=0.02, momentum=0.90, use_tqdm=True) + for e in range(nEpoches): + batch_size *= 1 + (e*0.5) + n_batches = (inp.shape[-2] / batch_size) + (1 if inp.shape[-2]%batch_size != 0 else 0) + for j in range(n_batches): + stdout.write("\r%d batch no %d/%d epoch no %d/%d" % (int(time.time()),j+1,n_batches,e,nEpoches)) + stdout.flush() + b = np.array(inp[j*batch_size:min((j+1)*batch_size, inp.shape[0])]) + for r in RBMs: + b = r.transform(b) + rbm.partial_fit(b) + RBMs.append(rbm) + for r in RBMs: + (W,_,Bh) = r.get_weights() + weights.append(W) + bias.append(Bh) + model = mlp1(x_train.shape[1],nClasses,depth-1,width) + print len(weights), len(model.layers) + assert len(weights) == len(model.layers) - 1 + for i in range(len(weights)): + W = [weights[i],bias[i]] + model.layers[i].set_weights(W) + return model +# def gen_data(active): + + +def preTrain(model,modelName,x_train,y_train,meta,skip_layers=[],outEqIn=False,fit_generator=None): + print model.summary() + layers = model.layers + output = layers[-1] + outdim = output.output_shape[-1] + for i in range(len(layers) - 1): + if i in skip_layers: + print 'skipping layer ',i + continue + if len(model.layers[i].get_weights()) == 0: + print 'skipping layer ',i + continue + last = model.layers[i].get_output_at(-1) + if outEqIn: + preds = Dense(outdim)(last) + else: + preds = Dense(outdim,activation='softmax')(last) + model_new = Model(model.input,preds) + for j in range(len(model_new.layers) - 2): + print "untrainable layer ",j + model_new.layers[j].trainable=False + model_new.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + print model_new.summary() + batch_size = 2048 + if fit_generator == None: + model_new.fit(x_train,y_train,epochs=1,batch_size=2048) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=3) + # model.fit_generator(gen_bracketed_data(x_train,y_train,meta['framePos_Train'],4), + # steps_per_epoch=len(meta['framePos_Train']), epochs=3, + # callbacks=[ModelCheckpoint('%s_CP.h5' % modelName,monitor='loss',mode='min')]) + # model.fit_generator(gen_data(x_train,y_train,batch_size), + # steps_per_epoch = x_train.shape[0] / batch_size, + # epochs = 1) + model.layers[i].set_weights(model_new.layers[-2].get_weights()) + for l in model.layers: + l.trainable = True + return model + +def trainNtest(model,x_train,y_train,x_test,y_test,meta, + modelName,testOnly=False,pretrain=False, batch_size=512, + init_epoch=0, fit_generator=None, ctc_train=False): + print 'TRAINING MODEL:',modelName + if not testOnly: + if pretrain: + print 'pretraining model...' + model = preTrain(model,modelName,x_train,y_train,meta,fit_generator=fit_generator) + if ctc_train: + model = ctc_model(model) + print model.summary() + print 'starting fit...' + callback_arr = [ModelCheckpoint('%s_CP.h5' % modelName,save_best_only=True,verbose=1), + ReduceLROnPlateau(patience=5,factor=0.5,min_lr=10**(-6), verbose=1), + CSVLogger(modelName+'.csv',append=True)] + + if fit_generator == None: + history = model.fit(x_train,y_train,epochs=100,batch_size=batch_size, + initial_epoch=init_epoch, + validation_data=(x_test,y_test), + callbacks=callback_arr) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=75, + validation_data=fit_generator(x_test,y_test,batch_size), + validation_steps = (meta['nFrames_Dev']) / batch_size, + callbacks=callback_arr) + model = Model(inputs=[model.get_layer(name='x').input], + outputs=[model.get_layer(name='softmax').output]) + print model.summary() + model.compile(loss='sparse_categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + print 'saving model...' + model.save(modelName+'.h5') + # model.save_weights(modelName+'_W.h5') + print(history.history.keys()) + print history.history['lr'] + print 'plotting graphs...' + # summarize history for accuracy + fig, ax1 = plt.subplots() + ax1.plot(history.history['acc']) + ax1.plot(history.history['val_acc']) + ax2 = ax1.twinx() + ax2.plot(history.history['loss'],color='r') + ax2.plot(history.history['val_loss'],color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + else: + model = load_model(modelName) + print 'scoring...' + score = model.evaluate_generator(gen_bracketed_data(x_test,y_test,meta['framePos_Dev'],4), + len(meta['framePos_Dev'])) + print score + +if __name__ == '__main__': + print 'PROCESS-ID =', os.getpid() + print 'loading data...' + meta = np.load('../GSOC/wsj0_phonelabels_cqt_meta.npz') + x_train = np.load('../GSOC/wsj0_phonelabels_cqt_train.npy') + y_train = np.load('../GSOC/wsj0_phonelabels_cqt_train_labels.npy') + print x_train.shape + print y_train.shape + nClasses = int(np.max(map(np.max,y_train)))+1 + print nClasses + + print 'loading test data...' + x_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev.npy') + y_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev_labels.npy') + + print 'initializing model...' + # model = load_model('dbn-3x2048-sig-adagrad_CP.h5') + # model = resnet_wrapper((x_train.shape[1:]),nClasses,1,1024,Reshape(x_train.shape[1:] + (1,))) + # model = mlp4(x_train[0].shape[-1] * 21, nClasses,1,1,2048, + # shortcut=False,BN=True,conv=True,dropout=False, + # regularize=False) + # model = mlp1(x_train.shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) + # # model = mlp_wCTC(x_train.shape[-1],nClasses,3,2048,BN=True) + # # model = DBN_DNN(x_train, nClasses,5,3072,batch_size=128) + # # print 'wrapping ctc...' + # # model = ctc_model(model) + # # model = DBN_DNN(x_train, nClasses,5,2560,batch_size=128) + # # model = load_model('mlp4-2x2560-cd-adam-bn-drop-conv-noshort_CP.h5') + # fg = gen_bracketed_data(context_len=5) + # trainNtest(model,x_train,y_train,x_test,y_test,meta,'mlp4-1x2048-conv-cqt-BN',ctc_train=False,fit_generator=fg) + + meta = np.load('../GSOC/wsj0_phonelabels_ci_meta.npz') + model = load_model('bestModels/best_CI.h5',custom_objects={'dummy_loss':dummy_loss, + 'decoder_dummy_loss':decoder_dummy_loss, + 'ler':ler}) + # model = Model(inputs=[model.get_layer(name='x').input], + # outputs=[model.get_layer(name='softmax').output]) + print model.summary() + # # # getPredsFromFilelist(model,'../wsj/wsj0/single_dev.txt','/home/mshah1/wsj/wsj0/feat_cd_mls/','.mls','/home/mshah1/wsj/wsj0/single_dev_NN/','.sen',meta['state_freq_Train'],context_len=5,weight=0.00035457) + # # # getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev2/','.sen',meta['state_freq_Train']) + getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_dev_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev_ci/','.sen',meta['state_freq_Train'], + context_len=4, + # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), + # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), + weight=0.1,n_feat=25) + # *0.00311573 + # 00269236 + # # getPredsFromArray(model,np.load('DEV_PRED.npy'),meta['framePos_Dev'],meta['filenames_Dev'],'/home/mshah1/wsj/wsj0/senscores_dev_ci_hammad/','.sen',meta['state_freq_Train'],preds_in=True,weight=-0.00075526,offset=234.90414376) + # f = filter(lambda x : '22go0208.wv1.flac' in x, meta['filenames_Dev'])[0] + # file_idx = list(meta['filenames_Dev']).index(f) + # print file_idx + # # split = lambda x: x[sum(meta['framePos_Dev'][:file_idx]):sum(meta['framePos_Dev'][:file_idx+1])] + # pred = model.predict(x_test[file_idx:file_idx+1],verbose=1) + # pred = np.array(map(lambda x: np.argmax(x,axis=-1),pred)) + # print pred + # print y_test[file_idx] + # data = split(x_test) + # context_len = 5 + # pad_top = np.zeros((context_len,data.shape[1])) + # pad_bot = np.zeros((context_len,data.shape[1])) + # padded_data = np.concatenate((pad_top,data),axis=0) + # padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + # data = [] + # for j in range(context_len,len(padded_data) - context_len): + # new_row = padded_data[j - context_len: j + context_len + 1] + # new_row = new_row.flatten() + # data.append(new_row) + # data = np.array(data) + # pred = model.predict(data,verbose=1) + # pred = pred.reshape(1,pred.shape[0],pred.shape[1]) + # print pred.shape + # [bp],out = K.ctc_decode(pred,[pred.shape[1]]) + # print K.eval(bp), len(K.eval(bp)[0]) + # print K.eval(out) + + # print pred + # # writeSenScores('senScores',pred) + # np.save('pred.npy',np.log(pred)/np.log(1.001)) + + # plotFromCSV('mlp4-1x2048-conv-cqt-BN') \ No newline at end of file diff --git a/scripts/DNN_training/NNTrain.pyc b/scripts/DNN_training/NNTrain.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ae37de6c3b110642b8f7d4c3350ac02e9b1bc9b GIT binary patch literal 16362 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 literal 0 HcmV?d00001 diff --git a/scripts/DNN_training/README.md b/scripts/DNN_training/README.md new file mode 100644 index 00000000..6996623c --- /dev/null +++ b/scripts/DNN_training/README.md @@ -0,0 +1,134 @@ +# DNNs For ASR +The work is part of a Google Summer of Code project, the goal of which was to integrate DNNs with CMUSphinx. This particular repository contains some convenient scripts that wrap Keras code and allow for easy training of DNNs. +## Getting Started +Start by cloning the repository. +### Prerequisites +The required python libraries available from pypi are in the requirements.txt file. Install them by running: +``` +pip install -r requirements.txt +``` +Additional libraries not available from pypi: +- tfrbm- for DBN-DNN pretraining. + - available at https://github.com/meownoid/tensorfow-rbm +## Getting Started +Since the project is primarily intended to be used with PocketSphinx the file formats for feature files, state-segmentation output files and the prediction files are in sphinx format. +### Feature File Format +``` +N: number of frames +M: dimensions of the feature vector +N*M (4 bytes) +Frame 1: f_1...f_M (4*M bytes) +. +. +. +Frame N: f_1,...,f_M (4*M bytes) +``` +Look at readMFC in utils.py +### state-segmentation files +format for each frame: +``` + 2 2 2 1 4 bytes +st1 [st2 st3] pos scr +``` +### Prediction output +format for each frame: +``` +N: number of states +N (2 bytes) +scr_1...scr_N (2*N bytes) +``` +### Wrapper Scripts +``` +runDatasetGen.py -train_fileids -val_fileids [-test_fileids] -n_filts -feat_dir -feat_ext -stseg_dir -stseg_ext -mdef [-outfile_prefix] [-keep_utts] +``` +runDatasetGen takes feature files and state-segmentation files stored in sphinx format along with the definition file of the GMM-HMM model to generate a set of numpy arrays that form a python readable dataset. +runDatasetGen writes the following files in the directory it was called in: +- Data Files + - _train.npy + - _dev.npy + - _test.npy +- label files + - _train_label.npy + - _dev_label.npy + - _test_label.npy +- metadata file + - _meta.npz + +The metadata file is a zipped collection of arrays with the follwing keys: +- File names for utterances + - filenames_Train + - filenames_Dev + - filenames_Test +- Number of frames per utterance (useful if -keep_utts is not set) + - framePos_Train + - framePos_Dev + - framePos_Test +- State Frequencies (useful for scaling in some cases) + - state_freq_Train + - state_freq_Dev + - state_freq_Test +``` +runNNTrain.py -train_data -train_labels -val_data -val_labels -nn_config [-context_win] [-cuda_device_id] [-pretrain] [-keras_model] -model_name +``` +runNNTrain takes the training and validation data files (as generated by runDatasetGen) and trains a neural network on them. +The architecture and parameters of the neural network is defined in a text file. Currently this script supports 4 network types: +- MLP (mlp) +- Convolutional Neural Network (conv) +- MLP with short cut connections (resnet) +- Convolutional Network with residual connections in the fully connected layers (conv + resnet) +See sample_nn.cfg for an example. +The format for the configuration file consists of ```param``` and ```value``` pairs +if value has multiple elemets (represented by ... below) they should be separated by spaces. +Params and possible values: +- **type** mlp, conv, resnet, conv+resnet +- **width** any integer value +- **depth** any integer value +- **dropout** float in (0,1) +- **batch_norm** - +- **activation** sigmoid, hard_sigmoid, elu, relu, selu, tanh, softplus, softsign, softmax, linear +- **optimizer** sgd, adam, adagrad +- **lr** float in (0,1) +- **batch_size** any integer value +- **ctc_loss** - +- for type = conv and type = conv+resnet + - **conv** [n_filters, filter_window]... + - **pooling** None, [max/avg, window_size, stride_size] +- for type = resnet and type = conv+resnet + - **block_depth** any integer value + - **n_blocks** any integer value +``` +runNNPredict -keras_model -ctldir -inext -outdir -outext -nfilts [-acoustic_weight] [-context_win] [-cuda_device_id] +``` +runNNPredict takes a keras model and a list of feature files to generate predictions. The predictions are stored as binary files in sphinx readable format (defined above). +Please ensure that the dimensionality of the feature vectors matches nfilts and the context window is the same as that for which the model was trained. +The acoustic_weight is used to scale the output scores. This is required because if the scores are passed through a GMM-GMM decoder like PocketSphinx are too small or too large then the decoding performance suffers. One way of estimating this weight is to generate scores from the GMM-HMM decoder being used, fit a linear regression between the GMM-HMM scores and the NN-scores and use the coefficient as the weight. +``` +readSen.py -gmm_score_dir -gmm_ctllist -nn_score_dir -nn_ctllist [-gmm_ext] [-nn_ext] +``` +readSen takes scores (stored in sphinx readable binary files) obtained from a GMM-HMM decoder and a NN, and fit a regression to them. + +## Example workflow with CMUSphinx +- Feature extraction using sphinx_fe: + ``` + sphinx_fe -argfile ../../en_us.ci_cont/feat.params -c etc/wsj0_train.fileids -di wav/ -do feat_ci_mls -mswav yes -eo mls -ei wav -ofmt sphinx -logspec yes + ``` +- State-segmentation using sphinx3_align + ``` + sphinx3_align -hmm ../../en_us.ci_cont/ -dict etc/cmudict.0.6d.wsj0 -ctl etc/wsj0_train.fileids -cepdir feat_ci_mls/ -cepext .mfc -insent etc/wsj0.transcription -outsent wsj0.out -stsegdir stateseg_ci_dir/ -cmn batch + ``` +- Generate dataset using runDatasetGen.py +- Train NN using runNNtrain.py +- Generate predictions from the NN using runNNPredct.py +- Generate predictions from PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir feat_ci_mfc/ -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -senlogdir sendump_ci/ -compallsen yes -bestpath no -fwdflat no -remove_noise no -remove_silence no -logbase 1.0001 -pl_window 0 +``` +- Compute the acoustic weight using readSen.py +- Decode the scaled NN predictions with PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir senscores/ -cepext .sen -hyp NN2.hyp -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -compallsen yes -logbase 1.0001 -pl_window 0 -senin yes +``` + + + + diff --git a/scripts/DNN_training/ctc.py b/scripts/DNN_training/ctc.py new file mode 100644 index 00000000..87363173 --- /dev/null +++ b/scripts/DNN_training/ctc.py @@ -0,0 +1,137 @@ +import sys +import fst +import random +import math +import numpy as np +from scipy.sparse import bsr_matrix +reload(sys) +sys.setdefaultencoding('utf8') + +def ran_lab_prob(n_samps): + r = [random.random() for i in range(138)] + s = sum(r) + return [[i/s for i in r]]*n_samps + +def genBigGraph(label_prob, symbols, seq_len, label='x'): + t = fst.Transducer() + sym=fst.SymbolTable() + + symbols = map(str,symbols) + x=0 + for j in range(seq_len): + for i in range(len(symbols)): + prob = label_prob[j][i] #"%.4f" % + t.add_arc(0+x, 1+x,str(label+str(j)),symbols[i],-math.log(prob)) + x+=1 + t[j+1].final = -1 + return t + +def gen_utt_graph(labels,symdict): + t2=fst.Transducer() + sym=fst.SymbolTable() + #3x3 states for this example + count = 0 + x = 0 + # print labels + for l in labels: + symbols = symdict[l] + symbols = map(str,symbols) + for i in range(len(symbols)): + if i == 0: + t2.add_arc(0+x,1+x,symbols[i],str(l+"/"+"("+symbols[i]+")")) + else: + t2.add_arc(0+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) + t2.add_arc(1+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) + + x+=1 + + t2[x].final=True + return t2 + +def gen_parents_dict(graph): + parents={} + for state in graph.states: + for arc in state.arcs: + if arc.nextstate in parents: + parents[arc.nextstate].append(state.stateid) + else: + parents[arc.nextstate]=[state.stateid] + return parents + +def make_prob_dict(graph,n_samps,n_labels): + y_t_s = np.zeros((n_samps + 1,n_labels)) # dictionary to store probabilities indexed by time and label + F = [0] + for t in range(n_samps + 1): + # y_t_s[t] = {} + for s in F: + arcs = graph[s].arcs + for a in arcs: + osym = graph.osyms.find(a.olabel) + osym = osym[osym.find("(")+1:osym.find(")")] + y_t_s[t][int(osym)] = np.exp(-1 * float(a.weight)) + F = map(lambda x: map(lambda y: y.nextstate,graph[x].arcs),F) + F = set([s for ss in F for s in ss]) + y_t_s = bsr_matrix(y_t_s,dtype='float32') + return y_t_s + +def calc_alpha(n_samps, symbols, y_t_s): + alpha = {} + # symbols = map(str,symbols) + for t in range(n_samps + 1): + alpha[t] = {} + for i in range(len(symbols)): + # print alpha + # print t,i, + if t == 0: + if i == 0: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) + else: + alpha[t][symbols[i]] = 0.0 + else: + if i == 0: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * alpha[t-1][symbols[i]] + else: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * (alpha[t-1][symbols[i]] + alpha[t-1][symbols[i-1]]) + # print alpha[t][symbols[i]] + return alpha + +def calc_beta(n_samps,symbols,y_t_s): + beta = {} + # symbols = map(str,symbols) + for t in range(n_samps,0,-1): + beta[t] = {} + for i in range(len(symbols)): + if t == n_samps: + if i == len(symbols) - 1: + beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) + else: + beta[t][symbols[i]] = 0.0 + else: + if i < len(symbols) - 1: + score = beta[t+1][symbols[i]] + beta[t+1][symbols[i+1]] + else: + score = beta[t+1][symbols[i]] + beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * score + return beta + +def print_graph(t): + for state in t.states: + for arc in state.arcs: + print('{} -> {} / {}:{} / {}'.format(state.stateid, + arc.nextstate, + t.isyms.find(arc.ilabel), + t.osyms.find(arc.olabel), + arc.weight)) +# symbols = ['G1','G2','G3','UH1','UH2','UH3','D1','D2','D3'] +# t = genBigGraph(ran_lab_prob,symbols,11) +# labels = ['G','UH','D'] + +# symdict={'G': ['G1','G2','G3'], +# 'UH': ['UH1','UH2','UH3'], +# 'D': ['D1','D2','D3']} +# t2 = gen_utt_graph(labels, symdict) +# t3 = t>>t2 +# parents = gen_parents_dict(t3) +# y_t_s = make_prob_dict(t3) +# print calc_alpha(10,symbols,y_t_s) +# print calc_beta(10,symbols,y_t_s) \ No newline at end of file diff --git a/scripts/DNN_training/ctc.pyc b/scripts/DNN_training/ctc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed7ba087c11729143c498c3ecc49eb7694ce1f2d GIT binary patch literal 4534 zcma)9U2hx56}_{hNRgr}S(Zf8K~o1s0lGmff3!$y&~6kHwu?3juyiX_1w*WMR}^J_ z?-C_b@u85B1_j#3qR;&Sedzxv(Dx$fbAjfe2#`Lu=iFIRia!)d+~MqdWQ)-+%U}U-**zIrx4bPxMzb0X|0BB75_`kv%h$JF@4@`YG8<&H8ECThP8E?TmD? zvX>PTE=nkJV$c&g%1MyYmmn?Ap+7GHmSp5P^e;(}RbfGbMeQt0kkig33G&)mkzh$X zs}dBnbD2l2m6vhs*8lLgQ#R2s%GqxA>Ix$D0QK!t)#91`mM&xz+5q8IQv>j?2l_3yqq7r&rhrLd? z)rk(h!`oYre!R2&(=9*tZ}ul~0i)Qb(f0Nm{b6sPhKRVOnD3f`QEg+N8*(IvN6qjz zbYKH}=V@B|xUI-^L2yhM5Z63$cwg9invwBmypy#^wf>1rvodZ{g!^%-eya7FOc!a9 zg~5fo!0UC)=BZurAPIp9d^}OUJx|Ap|9Wq&JOKhuc^L1Xm!1InKssa;Eu4Z4$-BN z?i1O5IA~BM5u(%7N3q>^(s5M>uW;njkGdT_dtpfMV$HDoL96+A==Bd*@EUER5#XWV zteA|sVoK(cd5Gt-@p(_;g8M2qYS{b~8;ArP#bN`Y4=|*)U6An`2A;0guNXLn?#sa6 z*%^G`SilD;`Ogd`>T0;PTK`;8vPeD892x$FxJodxU@?L(I9LGzSHt}&$kTIS5i~;3 zoTSBcx4&t5N{)0dEO?EMWPgD3mHS^n0cec~U64Utb_Z|EZVVKwK1HYlgwmU55UOt9 z(zdMa4TY;q_qhyfmn7$2VnZJ)Al+5=E~8Og0Cj=_-@riKK63?Nq>!O4B1>=l8Qpgdp^>b43_(SzDk@ErR7}Nnk0&&kWGWrmetBEBOvv0Y0Fg31e9m0qS*6HN_z?=Ckb8Uzu%ivJaJ z&3VK4)J@FrQ0zy%mW^Lr5+PQEO%7(M3@C*?5X0jyG{xB&uvfMI50d}*52Vv-{Zo?u zXCQI}HO$ID?vrz?^+N_PMquV6WCZYahV~}Y>jy$aDe+I9ih5g1@0IBcI|tPz7E=#wuu9=2=TJ#j-ql1)ds5 z{x~IruVnCVJy==>ccEvQd!Xb%v2kLIg;7nzWyfX=*iPJUv$>8&s|%k9nIZKG`cV-L zE`hr}7qySTKAI|%8eqPJ%W7Og$5=ei5XT|+Z8Wxc;p^nW*jU8uO55w~2i}7x=tp=& z>krEn-{Y(9Kt{K{o9y9{^Q#H>`mlJq?pu5%>-B7&BRa#eU8UM|@K<50d1%vL3v8t76~|%hVu4sz{~Y|@AuwuE}*vRHCC!_~9U44wuwPo$@glG;iwM6KtWB<6WK-m_4Xxd!5WE+U5t zI4x(2U^D)2nD3Z7=Bl}6)@)Gn<~+(nJkfpZM|Mle_?7{H00_nhkYBC8X@F-8G6vF8 z882}HQUbyk<2vQPj7!-$Y4qOze!3}jFRRMLTF?Y{bfbAVt&mrzP8w|JtNX?srU+|yMrRgIyEow=r))N^vH&PT5q38 zjupyidxeWlY1?>JV0!KTp=VLTDP=qt2@I|2e6Q^{RKbT>6^VxxjC(%n{~w(CzkKR{xbP$e1gyV+0P`{ezDN)N;1B_Srr+imfn%>y`up=e zIP+d*aKnI;Uvy#RWu5qO@vmeaOR$-OQsTi=k&c#%px^H1s}^A3b@<50OMb6_`%8)6 z8T3in#F}2Y`h4fp=r1~-rN(|3pYgroA@X~}@WLoyL7*t0rhU95G>~yh1OXthsUX-i zx1CLpflsuO%jPuD!OQqyUf%pt%N>`2izHI5KW4duV6f%Qyqsb7SYV#Dbt+>U63x7n z=#M3K@`7JXkDm;#!F+lAP(lK-KTM+y?ECBK^>-dzN4tgQUh-|(^#+D5V=^iZdPDra zao?ekSxPO{`Z}ezl+xWFa?U+AWJMc_%E7lNyGBc1Zbm4iqEOR`=A2=OWER9+6oqjR z9(bd69CrO)(CRi_y4htN>+> t2 + parents = ctc.gen_parents_dict(t3) + y_t_s = ctc.make_prob_dict(t3,data.shape[0],n_states) + active_state.append(y_t_s) + # print active_state + nFrames = data.shape[0] + else: + labels = frame2state(stseg_path + f, phone2state,onlyPhone=False) + nFrames = min(len(labels), data.shape[0]) + sys.stdout.write('(%d,%d) (%d,)' % (data.shape + np.array(labels).shape)) + data = data[:nFrames] + labels = labels[:nFrames] + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if n_deltas > 0: + pad_top = np.zeros((n_deltas,data.shape[1])) + pad_bot = np.zeros((n_deltas,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + data = [] + for j in range(n_deltas,len(padded_data) - n_deltas): + delta_top = padded_data - padded_data[j - n_deltas:j] + delta_bot = padded_data - padded_data[j:j + n_deltas] + new_row = delta_top + padded_data + delta_bot + data.append(new_row) + for l in labels: + state_freq[l] += 1 + filenames.append(data_file) + frames.append(nFrames) + if keep_utts: + allData.append(data) + allLabels.append(np.array(labels)) + else: + allData += list(data) + allLabels += list(labels) + pos += nFrames + if not ctc_labels: + assert(len(allLabels) == len(allData)) + # print allData + print len(allData), len(allLabels) + if max_len == None: + max_len = 100 * ((max(map(len,X_Train)) + 99)/ 100) + print 'max_len', max_len + if keep_utts and pad: + X_Train = pad_sequences(X_Train,maxlen=max_len,dtype='float32',padding='post') + Y_Train = pad_sequences(Y_Train,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Train = Y_Train.reshape(Y_Train.shape[0],Y_Train.shape[1],1) + X_Dev = pad_sequences(X_Dev,maxlen=max_len,dtype='float32',padding='post') + Y_Dev = pad_sequences(Y_Dev,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Dev = Y_Dev.reshape(Y_Dev.shape[0],Y_Dev.shape[1],1) + X_Test = pad_sequences(X_Test,maxlen=max_len,dtype='float32',padding='post') + Y_Test = pad_sequences(Y_Test,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Test = Y_Test.reshape(Y_Test.shape[0],Y_Test.shape[1],1) + # np.savez('wsj0_phonelabels_NFrames',NFrames_Train=NFrames_Train,NFrames_Test=NFrames_Test) + # t = threading.Thread(target=ping) + # t.start() + if context_len != None: + np.save('wsj0_phonelabels_bracketed_train.npy',X_Train) + np.save('wsj0_phonelabels_bracketed_test.npy',X_Test) + np.save('wsj0_phonelabels_bracketed_dev.npy',X_Dev) + np.save('wsj0_phonelabels_bracketed_train_labels.npy',Y_Train) + np.save('wsj0_phonelabels_bracketed_test_labels.npy',Y_Test) + np.save('wsj0_phonelabels_bracketed_dev_labels.npy',Y_Dev) + if make_graph: + np.save('wsj0_phonelabels_bracketed_train_active.npy',active_states_Train) + np.save('wsj0_phonelabels_bracketed_test_active.npy',active_states_Test) + np.save('wsj0_phonelabels_bracketed_dev_active.npy',active_states_Dev) + np.savez('wsj0_phonelabels_bracketed_meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + else: + np.save(outfile_prefix + 'train.npy',X_Train) + np.save(outfile_prefix + 'dev.npy',X_Dev) + np.save(outfile_prefix + 'train_labels.npy',Y_Train) + np.save(outfile_prefix + 'dev_labels.npy',Y_Dev) + if len(X_Test) != 0: + np.save(outfile_prefix + 'test.npy',X_Test) + np.save(outfile_prefix + 'test_labels.npy',Y_Test) + if make_graph: + np.save(outfile_prefix + 'active.npy',active_states_Train) + np.save(outfile_prefix + 'active.npy',active_states_Test) + np.save(outfile_prefix + 'active.npy',active_states_Dev) + np.savez(outfile_prefix + 'meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + # done = 1 + +def normalizeByUtterance(): + data = np.load('wsj0_phonelabels_bracketed_data.npy') + nFrames = np.load('wsj0_phonelabels_bracketed_meta.npz')['framePos_Train'] + # print 'calculating frame indices...' + # nFrames = map(lambda i: sum(nFrames[:i]),xrange(len(nFrames))) + print 'normalizing...' + scaler = StandardScaler(copy=False) + print data + pos = 0 + for i in xrange(len(nFrames)): + sys.stdout.write("\rnormalizing utterance no %d " % i) + sys.stdout.flush() + data[pos:nFrames[i]] = scaler.fit_transform(data[pos:nFrames[i]]) + pos = nFrames[i] + print data +if __name__ == '__main__': + #print(read_sen_labels_from_mdef('../wsj_all_cd30.mllt_cd_cont_4000/mdef')) + # frame2state('../wsj/wsj0/statesegdir/40po031e.wv2.flac.stseg.txt', '../wsj_all_cd30.mllt_cd_cont_4000/mdef') + genDataset('../wsj/wsj0/etc/wsj0_train.fileids','../wsj/wsj0/etc/wsj0_dev.fileids','../wsj/wsj0/etc/wsj0_test.fileids',40,'../wsj/wsj0/feat_cd_mls/','../wsj/wsj0/stateseg_ci_dir/','../en_us.ci_cont/mdef', + keep_utts=True, context_len=None, cqt=True, + trans_file='../wsj/wsj0/etc/wsj0.transcription', + pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') + # normalizeByUtterance() + # ../wsj/wsj0/feat_mls/11_6_1/wsj0/sd_dt_20/00b/00bo0t0e.wv1.flac.mls 00bo0t0e.wv1.flac.stseg.txt \ No newline at end of file diff --git a/scripts/DNN_training/genLabels.pyc b/scripts/DNN_training/genLabels.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df7651c5d43c705f81acbec6f4440e59505d820d GIT binary patch literal 14192 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 hE-Jw#x3+e4bab_L= 0: + if os.path.exists(ndx_list[i]): + print i,ndx_list[i], file_list[i] + _y = list(readSen(ndx_list[i])) + _x = list(readSen(file_list[i])) + if len(_x) != len(_y): + continue + y += _y + x += _x + frame_len = min(len(x),len(y)) + # x = x[:frame_len] + # y = y[:frame_len] + print len(x),len(y), len(x)/138, len(y)/138 + assert len(x) == len(y) + else: + continue + else: + print i,ndx_list[i+1], file_list[i] + y += list(readSen(ndx_list[i+1])) + x += list(readSen(file_list[i])) + x = np.array(x).reshape(-1,1) + y = np.array(y).reshape(-1,1) + # print x.shape, y.shape + data = np.concatenate((x,y),axis=1) + # np.save('data4regression.npy',data) + + # data = np.load('data4regression.npy') + lreg = LinearRegression(normalize=True,n_jobs=-1) + lreg.fit(data[:,[1]],data[:,[0]]) + print "coefficient: %f\t\tintercept: %f" % (lreg.coef_, lreg.intercept_) + + # vs = np.std(data[:,[1]]) + # va = np.std(data[:,[0]]) + # print va/vs diff --git a/scripts/DNN_training/requirements.txt b/scripts/DNN_training/requirements.txt new file mode 100644 index 00000000..c2d0f232 --- /dev/null +++ b/scripts/DNN_training/requirements.txt @@ -0,0 +1,67 @@ +appdirs==1.4.3 +audioread==2.1.5 +backports.weakref==1.0rc1 +bleach==1.5.0 +cycler==0.10.0 +Cython==0.25.2 +daemonize==2.4.7 +decorator==4.0.6 +editdistance==0.3.1 +funcsigs==1.0.2 +functools32==3.2.3.post2 +graphviz==0.7.1 +guppy==0.1.10 +h5py==2.7.0 +htk-io==0.5 +html5lib==0.9999999 +ipython==2.4.1 +joblib==0.11 +Keras==2.0.6 +Lasagne==0.2.dev1 +librosa==0.5.1 +Mako==1.0.6 +Markdown==2.2.0 +MarkupSafe==1.0 +matplotlib==2.0.2 +memory-profiler==0.47 +mock==2.0.0 +nose==1.3.7 +numpy==1.13.1 +packaging==16.8 +pbr==3.1.1 +pexpect==4.0.1 +posix-ipc==1.0.0 +protobuf==3.3.0 +ptyprocess==0.5 +py==1.4.33 +pycurl==7.43.0 +pydot==1.2.3 +pydot-ng==1.0.0 +pyfst==0.2.3 +pygpu==0.6.5 +pyliblzma==0.5.3 +pyparsing==2.2.0 +pysqlite==1.0.1 +pytest==3.0.7 +python-apt==1.1.0b1 +python-dateutil==2.6.0 +python-speech-features==0.5 +pytools==2016.2.6 +pytz==2017.2 +PyYAML==3.12 +resampy==0.1.5 +rpm-python==4.12.0.1 +scikit-learn==0.18.1 +scipy==0.19.1 +simplegeneric==0.8.1 +six==1.10.0 +subprocess32==3.2.7 +tensorflow-gpu==1.2.0 +tfrbm==0.0.2 +Theano==0.9.0 +tkinter==0.2.0 +tqdm==4.14.0 +urlgrabber==3.9.1 +virtualenv==15.0.1 +Werkzeug==0.12.2 +yum-metadata-parser==1.1.4 diff --git a/scripts/DNN_training/runDatasetGen.py b/scripts/DNN_training/runDatasetGen.py new file mode 100644 index 00000000..d44d47b6 --- /dev/null +++ b/scripts/DNN_training/runDatasetGen.py @@ -0,0 +1,41 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate numpy array from features and alignments produced by Sphinx", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_fileids', type=str, required=True, + help="list of training files") +parser.add_argument('-val_fileids',type=str,required=True, + help='list of validation files') +parser.add_argument('-test_fileids',type=str,required=False, + help='list of test files') +parser.add_argument('-nfilts',type=int,required=True, + help='number of filters used for extracting features. (The dimensionality of the feature vector)') +parser.add_argument('-feat_dir', type=str, required=True, + help='the directory where feature files are stored (prepended to filepaths in the train, val and test filelists when looking for features)') +parser.add_argument('-feat_ext',type=str,required=True, + help='extension to be appended to each file path when looking for feature files') +parser.add_argument('-stseg_dir',type=str,required=True, + help='directory where the state-segmentation for each feature file is stored (prepended to filepaths in the train, val and test filelists when looking for labels)') +parser.add_argument('-stseg_ext',type=str,required=True, + help='extension to be appended to each file path when looking for state-segmentation files') +parser.add_argument('-mdef',type=str,required=True, + help='path to the mdef file for the Sphinx model. Needed to map phones/triphones in segmentation to state labels') +parser.add_argument('-outfile_prefix',type=str,default="", required=False, + help='prepended to the names of the output files') +parser.add_argument('-keep_utts',nargs='?',required=False, default=False, const=True, + help='store features and labels in a 3D array in which each index points to the list of features/labels for one utterance') +args = vars(parser.parse_args()) + +from genLabels import genDataset +genDataset(args['train_fileids'], + args['val_fileids'], + args['test_fileids'], + args['nfilts'], + args['feat_dir'], + args['feat_ext'], + args['stseg_dir'], + args['stseg_ext'], + args['mdef'], + args['outfile_prefix'], + keep_utts=args['keep_utts']) + diff --git a/scripts/DNN_training/runNNPredict.py b/scripts/DNN_training/runNNPredict.py new file mode 100644 index 00000000..c2dfa281 --- /dev/null +++ b/scripts/DNN_training/runNNPredict.py @@ -0,0 +1,48 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate Predictions from a Keras Model and save them in PockeSphinx readable .sen files.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-keras_model', type=str, required=True, + help="Keras model to be used for prediction in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-ctldir',type=str, required=True, + help="the directory for the control files, prepended to each file path in ctllist") +parser.add_argument('-ctllist', type=str,required=True, + help='list of input files, each representing an utterance') +parser.add_argument('-inext', type=str, required=True, + help='the extension of the control files, appended to each file path in ctllist') +parser.add_argument('-outdir', type=str,required=True, + help='Directory where the predictions are stored. The structure of this directory will be identical to ctldir') +parser.add_argument('-outext', type=str, required=True, + help='the extension of the output files') +parser.add_argument('-nfilts', type=int, required=True, + help='dimensionality of the feature vectors') +parser.add_argument('-acoustic_weight',type=float,required=False, + help='The weight to scale the predictions by. Sometimes needed to get meaningful predictions from PocketSphinx') +parser.add_argument('-context_win',type=int, required=False, default=0, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from keras.models import load_model +from utils import * + +model = load_model(keras_model,custom_objects={'dummy_loss':dummy_loss, + 'decoder_dummy_loss':decoder_dummy_loss, + 'ler':ler}) +# model = Model(inputs=[model.get_layer(name='x').input], +# outputs=[model.get_layer(name='softmax').output]) +print model.summary() +getPredsFromFilelist(model,args['ctllist'], + args['ctldir'], + args['inext'], + args['outdir'], + args['outext'], + context_len=args['context_win'], + # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), + # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), + weight=args['acoustic_weight'] if args['acoustic_weight'] != None else 0.1, + n_feat=args['nfilts']) \ No newline at end of file diff --git a/scripts/DNN_training/runNNTrain.py b/scripts/DNN_training/runNNTrain.py new file mode 100644 index 00000000..82049fce --- /dev/null +++ b/scripts/DNN_training/runNNTrain.py @@ -0,0 +1,168 @@ +from argparse import ArgumentParser +import numpy as np + +parser = ArgumentParser(description="Train a Keras neural network model.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_data',type=str, required=True, + help="the training data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-train_labels',type=str, required=True, + help="the training labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-val_data',type=str, required=True, + help="the validation data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-val_labels',type=str, required=True, + help="the validation labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-nn_config',type=str, required=True, + help='file containing the neural network configuration information (look at sample_mlp.cfg)') +parser.add_argument('-context_win',type=int, required=False, default=5, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +parser.add_argument('-pretrain', nargs='?', required=False, default=False, const=True, + help='Perform layer-wise pretraining of the MLP before starting training. (Use only with dense MLPs)') +parser.add_argument('-keras_model', type=str, required=False, + help="Keras model to be trained in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-model_name', type=str, required=True, + help='Name to be assigned to the output files') +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from NNTrain import * +from utils import * +from keras.models import load_model + +def read_config(filename): + with open(filename) as f: + lines = f.readlines() + lines = filter(lambda x: x[0] != '#' and len(x) > 2, lines) + args = {} + for l in lines: + split = l.split() + if split[0] in args: + args[split[0]].append(split[1:]) + else: + args[split[0]] = split[1:] if len(split) > 1 else [] + if len(args[split[0]]) == 1: + args[split[0]] = args[split[0]][0] + return args + +def init_model(args,input_dim,output_dim, nframes): + print args + nn_type = args['type'] + + if nn_type == 'mlp': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + BN = 'batch_norm' in args, + dropout = float(args.setdefault('dropout',False)), + activation = args.setdefault('activation','sigmoid')) + if nn_type == 'resnet': + model = mlp4(input_dim, + output_dim, + int(args['n_blocks']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + dropout=float(args.setdefault('dropout',False)), + BN='batch_norm' in args, + shortcut=True) + if nn_type == 'conv' or nn_type == 'conv+resnet': + print args + assert(len(args['conv']) == len(args['pooling']) or + (type(args['conv']) == str and + type(args['pooling'] == str))) + filts = [] + filt_dims = [] + pooling = [] + max='max' + avg='avg' + if type(args['conv']) == str: + conv = [args['conv']] + pool = [args['pooling']] + else: + conv = args['conv'] + pool = args['pooling'] + for i in range(len(conv)): + filt, dims = eval(conv[i]) + filts.append(int(filt)) + filt_dims.append(dims) + + pooling.append(eval(pool[i])) + if nn_type == 'conv': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True) + else: + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True, + shortcut=True) + + if 'ctc_loss' in args: + model = ctc_model(model) + return model + +x_train = np.load(args['train_data']) +y_train = np.load(args['train_labels']) + +x_test = np.load(args['val_data']) +y_test = np.load(args['val_labels']) + +nClasses = max(map(np.max,y_train)) + 1 + +meta = {} +meta['nFrames_Train'] = sum(map(lambda x: x.shape[0], x_train)) +meta['nFrames_Dev'] = sum(map(lambda x: x.shape[0], x_test)) +meta['state_freq_train'] = np.zeros(nClasses) +for u in y_train: + for r in u: + meta['state_freq_train'][r] += 1 + +# model = mlp1(x_train[0].shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) +conf = read_config(args['nn_config']) +context_len = args['context_win'] +if args['keras_model'] != None: + model = load_model(args['keras_model']) +else: + if 'ctc_loss' in conf: + model = init_model(conf, (None,x_train[0].shape[-1],), + nClasses + 1, 2 * context_len + 1) + fg = gen_bracketed_data(for_CTC=True, n_states=nClasses) + # trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=2,ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) + else: + model = init_model(conf, (x_train[0].shape[-1] * (2 * context_len + 1),), + nClasses, 2 * context_len + 1) + fg = gen_bracketed_data(context_len=context_len) +trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=int(conf['batch_size']),ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) + +# parser.add_argument('ctldir', metavar='-ctldir',type=str, nargs=1, +# help="the directory for the control files, prepended to each file path in ctllist") +# parser.add_argument('ctllist', metavar='-ctllist',type=str,nargs=1, +# help='list of input files, each representing an utterance') +# parser.add_argument('inext', metavar='-inext', type=str, nargs=1, +# help='the extension of the control files, appended to each file path in ctllist') +# parser.add_argument('infmt', metavar='-infmt', type=str, nargs=1, +# default='yes', choices=['mswav','mfc'], +# help='format of the files in the ctllist') +# parser.add_argument('nfilts', metavar='-nfilts',type=int, nargs=1, +# required=False, help="number of features in the input files. Only used if infmt is mfc") +# parser.add_argument('stsegdir', metavar='-stsegdir',type=str,nargs=1, +# help='the directory in which forced alignments are stored') +# parser.add \ No newline at end of file diff --git a/scripts/DNN_training/sample_nn.cfg b/scripts/DNN_training/sample_nn.cfg new file mode 100644 index 00000000..851e9aba --- /dev/null +++ b/scripts/DNN_training/sample_nn.cfg @@ -0,0 +1,22 @@ +#type resnet +#width 2048 +#block_depth 3 +#n_blocks 5 + +type mlp +width 2048 +depth 3 +#dropout 0.25 +batch_norm +activation sigmoid +#ctc_loss +batch_size 512 +optimizer SGD +lr 0.001 + + +#type conv +#conv [84,(6,8)] [168,(3,4)] +#pooling None [max,(3,3),(1,1)] +#width 2048 +#depth 3 \ No newline at end of file diff --git a/scripts/DNN_training/test.csv b/scripts/DNN_training/test.csv new file mode 100644 index 00000000..e69de29b diff --git a/scripts/DNN_training/utils.py b/scripts/DNN_training/utils.py new file mode 100644 index 00000000..c9398b89 --- /dev/null +++ b/scripts/DNN_training/utils.py @@ -0,0 +1,333 @@ +import numpy as np +import struct +import matplotlib.pyplot as plt +import pylab as pl +from sys import stdout +import os +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +from scipy.sparse import coo_matrix +from sklearn.preprocessing import StandardScaler + +def dummy_loss(y_true,y_pred): + return y_pred +def decoder_dummy_loss(y_true,y_pred): + return K.zeros((1,)) +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def dense2sparse(a): + # rows,cols = a.nonzero() + # data = map(lambda i: a[rows[i],cols[i]], range(rows.shape[0])) + # return coo_matrix((data,(rows,cols)), shape=a.shape,dtype='int32') + return coo_matrix(a,shape=a.shape,dtype='int32') + +def readMFC(fname,nFeats): + data = [] + with open(fname,'rb') as f: + v = f.read(4) + head = struct.unpack('I',v)[0] + v = f.read(nFeats * 4) + while v: + frame = list(struct.unpack('%sf' % nFeats, v)) + data .append(frame) + v = f.read(nFeats * 4) + data = np.array(data) + # print data.shape, head + assert(data.shape[0] * data.shape[1] == head) + return data + +def ctc_labels(labels, blank_labels = []): + new_labels = [] + for i in range(len(labels)): + l_curr = labels[i] + if l_curr not in blank_labels: + if i == 0: + new_labels.append(l_curr) + else: + if l_curr != labels[i-1]: + new_labels.append(l_curr) + return np.array(new_labels) +def _gen_bracketed_data_2D(x,y,nFrames, + context_len,fix_length, + for_CTC): + max_len = ((np.max(nFrames) + 50)/100) * 100 #rounding off to the nearest 100 + batch_size = 2 + while 1: + pos = 0 + nClasses = np.max(y) + 1 + if for_CTC: + alldata = [] + alllabels = [] + for i in xrange(len(nFrames)): + data = x[pos:pos + nFrames[i]] + labels = y[pos:pos + nFrames[i]] + # if for_CTC: + # labels = ctc_labels(labels,blank_labels=range(18) + [108,109,110]) + # if len(labels.shape) == 1: + # labels = to_categorical(labels,num_classes=nClasses) + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if for_CTC: + if batch_size != None: + alldata.append(data) + alllabels.append(labels) + + if len(alldata) == batch_size: + alldata = np.array(alldata) + alllabels = np.array(alllabels) + if fix_length: + alldata = pad_sequences(alldata,maxlen=1000,dtype='float32',truncating='post') + alllabels = pad_sequences(alllabels,maxlen=1000,dtype='float32',value=138,truncating='post') + inputs = {'x': alldata, + 'y': alllabels, + 'x_len': np.array(map(lambda x: len(x), alldata)), + 'y_len': np.array(map(lambda x: len(x), alllabels))} + outputs = {'ctc': np.ones([batch_size])} + yield (inputs,outputs) + alldata = [] + alllabels = [] + else: + data = np.array([data]) + labels = np.array([labels]) + inputs = {'x': data, + 'y': labels, + 'x_len': [data.shape[0]], + 'y_len': [labels.shape[0]]} + outputs = {'ctc': labels} + yield (inputs,outputs) + else: + yield (data,labels) + pos += nFrames[i] + +def _gen_bracketed_data_3D(x,y,batch_size,context_len): + epoch_no = 1 + while 1: + print epoch_no + batch_data = [] + batch_labels = [] + for i in range(len(x)): + data = x[i] + labels = y[i] + if context_len != 0: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + seq_len = 0 + while seq_len < len(data) and data[seq_len].any(): + seq_len += 1 + idxs = range(seq_len) + np.random.shuffle(idxs) + for j in idxs: + if len(batch_data) < batch_size: + batch_data.append(data[j]) + batch_labels.append(labels[j]) + else: + batch_data = np.array(batch_data) + batch_labels = np.array(batch_labels) + yield(batch_data,batch_labels) + batch_data = [] + batch_labels = [] + epoch_no += 1 +def gen_ctc_data(alldata,alllabels,batch_size, n_states): + while 1: + for i in range(batch_size,alldata.shape[0]+1,batch_size): + x = alldata[i-batch_size:i] + y = alllabels[i-batch_size:i] + # .reshape(batch_size,alllabels.shape[1]) + max_len = max(map(len,x)) + x = pad_sequences(x,maxlen=max_len,dtype='float32',padding='post') + y = pad_sequences(y,maxlen=max_len,dtype='float32',padding='post',value=n_states) + x = np.array(x) + y = np.array(y) + # print x.shape, y.shape + y_len = [] + # print y + for b in y: + # # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and int(b[pad_len]) != 138: + pad_len += 1 + y_len.append(pad_len) + y_len = np.array(y_len) + x_len = [] + for b in x: + # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and b[pad_len].any(): + pad_len += 1 + x_len.append(pad_len) + x_len = np.array(x_len) + # x_len = np.array(map(lambda x: len(x), x)) + # y_len = np.array(map(lambda x: len(x), y)) + # print x.shape,y.shape,x_len,y_len + # print y.shape + # y = dense2sparse(y) + inputs = {'x': x, + 'y': y, + 'x_len': x_len, + 'y_len': y_len} + outputs = {'ctc': np.ones([batch_size]), + 'decoder': dense2sparse(y), + 'softmax': y.reshape(y.shape[0],y.shape[1],1)} + yield(inputs,outputs) + +def gen_bracketed_data(context_len=None,fix_length=False, + for_CTC=False, n_states=None): + if for_CTC: + assert(n_states != None) + return lambda x,y,batch_size: gen_ctc_data(x,y,batch_size,n_states) + else: + return lambda x,y,batch_size: _gen_bracketed_data_3D(x,y,batch_size,context_len) + # return lambda x,y,nf: _gen_bracketed_data(x,y,nf,context_len,fix_length, + # for_CTC) + +def plotFromCSV(modelName, loss_cols=[2,5], acc_cols=[1,4]): + data = np.loadtxt(modelName+'.csv',skiprows=1,delimiter=',') + epoch = data[:,[0]] + acc = data[:,[acc_cols[0]]] + loss = data[:,[loss_cols[0]]] + val_acc = data[:,[acc_cols[1]]] + val_loss = data[:,[loss_cols[1]]] + + fig, ax1 = plt.subplots() + ax1.plot(acc) + ax1.plot(val_acc) + ax2 = ax1.twinx() + ax2.plot(loss,color='r') + ax2.plot(val_loss,color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + +def writeSenScores(filename,scores,weight,offset): + n_active = scores.shape[1] + s = '' + s = """s3 +version 0.1 +mdef_file ../../en_us.cd_cont_4000/mdef +n_sen 138 +logbase 1.000100 +endhdr +""" + s += struct.pack('I',0x11223344) + + scores = np.log(scores)/np.log(1.0001) + scores *= -1 + scores -= np.min(scores,axis=1).reshape(-1,1) + # scores = scores.astype(int) + scores *= weight + scores += offset + truncateToShort = lambda x: 32676 if x > 32767 else (-32768 if x < -32768 else x) + vf = np.vectorize(truncateToShort) + scores = vf(scores) + # scores /= np.sum(scores,axis=0) + for r in scores: + # print np.argmin(r) + s += struct.pack('h',n_active) + r_str = struct.pack('%sh' % len(r), *r) + # r_str = reduce(lambda x,y: x+y,r_str) + s += r_str + with open(filename,'w') as f: + f.write(s) + +def getPredsFromArray(model,data,nFrames,filenames,res_dir,res_ext,freqs,preds_in=False,weight=0.1,offset=0): + if preds_in: + preds = data + else: + preds = model.predict(data,verbose=1,batch_size=2048) + pos = 0 + for i in range(len(nFrames)): + fname = filenames[i][:-4] + fname = reduce(lambda x,y: x+'/'+y,fname.split('/')[4:]) + stdout.write("\r%d/%d " % (i,len(filenames))) + stdout.flush() + res_file_path = res_dir+fname+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + # preds = model.predict(data[pos:pos+nFrames[i]],batch_size=nFrames[i]) + writeSenScores(res_file_path,preds[pos:pos+nFrames[i]],freqs,weight,offset) + pos += nFrames[i] + +def getPredsFromFilelist(model,filelist,file_dir,file_ext, + res_dir,res_ext,n_feat=40,context_len=None, + weight=1,offset=0, data_preproc_fn=None, + data_postproc_fn=None): + with open(filelist) as f: + files = f.readlines() + files = map(lambda x: x.strip(),files) + filepaths = map(lambda x: file_dir+x+file_ext,files) + scaler = StandardScaler(copy=False,with_std=False) + for i in range(len(filepaths)): + stdout.write("\r%d/%d " % (i,len(filepaths))) + stdout.flush() + + f = filepaths[i] + if not os.path.exists(f): + print ("\n",f) + continue + data = readMFC(f,n_feat) + data = scaler.fit_transform(data) + + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + data[0] + pad_bot = np.zeros((context_len,data.shape[1])) + data[-1] + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if data_preproc_fn != None: + _data = data_preproc_fn(data) + preds = model.predict(_data) + preds = np.squeeze(preds) + else: + preds = model.predict(data) + + if data_postproc_fn != None: + preds = data_postproc_fn(preds) + if preds.shape[0] != data.shape[0]: + preds = preds[:data.shape[0]] + # print np.sum(preds) + # print preds.shape + res_file_path = res_dir+files[i]+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + writeSenScores(res_file_path,preds,weight,offset) + +# a = dense2sparse(np.array([[1,2,3],[4,0,6]])) +# print a.shape +# print np.asarray(a,dtype=long) \ No newline at end of file diff --git a/scripts/DNN_training/utils.pyc b/scripts/DNN_training/utils.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02407a630a248ca6fe81f2da0f595b0e10799345 GIT binary patch literal 11188 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 UgHQJbV}mE>2TxB<>vr?M0n1+JH~;_u literal 0 HcmV?d00001 From eadf21c4305d96833e7894429f4f2407b0ca3a00 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Sun, 27 Aug 2017 07:22:58 -0400 Subject: [PATCH 02/12] added DNN training scripts --- scripts/DNN_training/NNTrain.py | 521 ++++++++++++++++++ scripts/DNN_training/README.md | 134 +++++ scripts/DNN_training/ctc.py | 137 +++++ scripts/DNN_training/genLabels.py | 339 ++++++++++++ scripts/DNN_training/makeFileListFromTrans.py | 19 + scripts/DNN_training/readSen.py | 96 ++++ scripts/DNN_training/requirements.txt | 67 +++ scripts/DNN_training/runDatasetGen.py | 41 ++ scripts/DNN_training/runNNPredict.py | 48 ++ scripts/DNN_training/runNNTrain.py | 168 ++++++ scripts/DNN_training/sample_nn.cfg | 22 + scripts/DNN_training/test.csv | 0 scripts/DNN_training/utils.py | 333 +++++++++++ 13 files changed, 1925 insertions(+) create mode 100644 scripts/DNN_training/NNTrain.py create mode 100644 scripts/DNN_training/README.md create mode 100644 scripts/DNN_training/ctc.py create mode 100644 scripts/DNN_training/genLabels.py create mode 100644 scripts/DNN_training/makeFileListFromTrans.py create mode 100644 scripts/DNN_training/readSen.py create mode 100644 scripts/DNN_training/requirements.txt create mode 100644 scripts/DNN_training/runDatasetGen.py create mode 100644 scripts/DNN_training/runNNPredict.py create mode 100644 scripts/DNN_training/runNNTrain.py create mode 100644 scripts/DNN_training/sample_nn.cfg create mode 100644 scripts/DNN_training/test.csv create mode 100644 scripts/DNN_training/utils.py diff --git a/scripts/DNN_training/NNTrain.py b/scripts/DNN_training/NNTrain.py new file mode 100644 index 00000000..9bddc8aa --- /dev/null +++ b/scripts/DNN_training/NNTrain.py @@ -0,0 +1,521 @@ +from keras.models import Sequential, Model +from keras.optimizers import SGD,Adagrad, Adam +from keras.layers.normalization import BatchNormalization +from keras.layers import ( + Input, + Dense, + Activation, + Dropout, + Conv1D, + Conv2D, + LocallyConnected2D, + MaxPooling2D, + AveragePooling2D, + Reshape, + Flatten, + Masking) +from keras.layers.core import Lambda +from keras.layers.merge import add, concatenate +from keras.utils import to_categorical, plot_model +from keras.models import load_model, Model +from keras.callbacks import History,ModelCheckpoint,CSVLogger,ReduceLROnPlateau +from keras import regularizers +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +import numpy as np +import matplotlib.pyplot as plt +import tensorflow as tf +from tensorflow.python.ops import math_ops +from tensorflow.python.ops import array_ops +from tfrbm import GBRBM,BBRBM +from sys import stdout +import time +import gc +from sklearn.preprocessing import StandardScaler +from guppy import hpy +import threading +import struct +from utils import * +import ctc + +""" + This module provides functions for training different neural network architectures + Below is a bried summary of the different functions and their purpose, more detail + can be found below: + - mlp1: creates a MLP consisting of a number dense layers + - mlp_wCTC: creates a MLP that calculates the ctc loss during training + - mlp4: create convolutional neural networks and residual networks + - DBN_DNN: performs DBN pretraining on simple MLPs + - preTrain: performs layer-wise pretraining on simple MLPs + - trainAndTest: runs training on a provided model using the given dataset +""" + +def mlp1(input_dim,output_dim,depth,width,dropout=False, + BN=False, regularize=False, lin_boost=False, activation='sigmoid'): + print locals() + model = Sequential() + model.add(Dense(width, activation=activation, input_shape=(input_dim,), + kernel_regularizer=regularizers.l2(0.05) if regularize else None)) + if BN: + model.add(BatchNormalization()) + if dropout: + model.add(Dropout(dropout)) + for i in range(depth - 1): + model.add(Dense(width, activation=activation, + kernel_regularizer=regularizers.l2(0.05) if regularize else None)) + if dropout: + model.add(Dropout(dropout)) + if BN: + model.add(BatchNormalization()) + if lin_boost: + model.add(Dense(output_dim)) + model.add(Lambda(lambda x: K.exp(x))) + else: + model.add(Dense(output_dim, name='out')) + model.add(Activation('softmax', name='softmax')) + opt = Adam(lr=10/(np.sqrt(input_dim * width * output_dim))) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model + +def ctc_lambda_func(args): + import tensorflow as tf + y_pred, labels, input_length, label_length = args + label_length = K.cast(tf.squeeze(label_length), 'int32') + input_length = K.cast(tf.squeeze(input_length), 'int32') + # return K.ctc_batch_cost(labels, y_pred, input_length, label_length) + labels = K.ctc_label_dense_to_sparse(labels,label_length) + return tf.nn.ctc_loss(labels,y_pred,input_length, + preprocess_collapse_repeated=True, + ctc_merge_repeated=False, + time_major=False, + ignore_longer_outputs_than_inputs=True) + +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def decode_output_shape(inputs_shape): + y_pred_shape, seq_len_shape = inputs_shape + return (y_pred_shape[:1], None) + +def decode(args): + import tensorflow as tf + y_pred, label_len = args + label_len = K.cast(tf.squeeze(label_len), 'int32') + # ctc_labels = tf.nn.ctc_greedy_decoder(y_pred, label_len)[0][0] + # return ctc_labels + ctc_labels = K.ctc_decode(y_pred,label_len,greedy=False)[0][0] + return K.ctc_label_dense_to_sparse(ctc_labels, label_len) + +# def ler(args): +# y_pred, y_true, input_length, label_length = args +# label_length = K.cast(tf.squeeze(label_length), 'int32') +# input_length = K.cast(tf.squeeze(input_length), 'int32') + +# y_pred = K.ctc_decode(y_pred,input_length)[0][0] +# # y_pred = tf.nn.ctc_greedy_decoder(y_pred,input_length)[0][0] +# y_pred = K.cast(y_pred,'int32') +# # y_pred = math_ops.to_int32(y_pred) +# # y_true = math.ops.to_int64(y_true) +# y_true = K.ctc_label_dense_to_sparse(y_true,label_length) +# y_pred = K.ctc_label_dense_to_sparse(y_pred,input_length) +# return tf.reduce_mean(tf.edit_distance(y_pred, y_true)) +# def ler(y_true, y_pred, **kwargs): +# """ +# Label Error Rate. For more information see 'tf.edit_distance' +# """ +# return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def mlp_wCTC(input_dim,output_dim,depth,width,BN=False): + print locals() + x = Input(name='x', shape=(1000,input_dim)) + h = x + h = Masking()(h) + for i in range(depth): + h = Dense(width)(h) + if BN: + h = BatchNormalization()(h) + h = Activation('sigmoid')(h) + out = Dense(output_dim,name='out')(h) + softmax = Activation('softmax', name='softmax')(out) + # a = 1.0507 * 1.67326 + # b = -1 + # # out = Lambda(lambda x : a * K.pow(x,3) + b)(h) + # out = Lambda(lambda x: a * K.exp(x) + b, name='out')(h) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def ctc_model(model): + x = model.get_layer(name='x').input + + out = model.get_layer(name='out').output + softmax = Activation('softmax', name='softmax')(out) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def _bn_act(input,activation='relu'): + """Helper to build a BN -> relu block + """ + norm = BatchNormalization()(input) + return Activation(activation)(norm) + +def make_dense_res_block(inp, size, width, drop=False,BN=False,regularize=False): + x = inp + for i in range(size): + x = Dense(width, + kernel_regularizer=regularizers.l2(0.05) if regularize else None)(x) + if i < size - 1: + if drop: + x = Dropout(0.15)(x) + if BN: + x = _bn_relu(x) + return x + +def mlp4(input_dim,output_dim,nBlocks,width, n_frames, block_depth=1, + n_filts=[84], filt_dims=[(11,8)], pooling=[['max',(6,6),(2,2)]], + block_width=None, dropout=False, BN=False, activation='relu', + parallelize=False, conv=False, regularize=False, + exp_boost=False, quad_boost=False, shortcut=False, + opt='adam', lr=0.001): + + print locals() + if block_width == None: + block_width = width + inp = Input(shape=input_dim, name='x') + x = inp + if conv: + x = Reshape((n_frames,input_dim/n_frames,1))(x) + for i in range(len(n_filts)): + print i + + x = LocallyConnected2D(n_filts[i],filt_dims[i], + padding='valid')(x) + x = _bn_act(x,activation=activation) + if pooling[i] != None: + pooling_type, win_size, stride = pooling[i] + if pooling_type == 'max': + x = MaxPooling2D(win_size,strides=stride,padding='same')(x) + if pooling_type == 'avg': + x = AveragePooling2D(win_size,strides=stride,padding='same')(x) + x = Flatten()(x) + if block_width != width: + x = Dense(block_width)(x) + for i in range(nBlocks): + y = make_dense_res_block(x,block_depth,block_width,BN=BN,drop=dropout,regularize=regularize) + if shortcut: + x = add([x,y]) + else: + x = y + if dropout: + x = Dropout(dropout)(x) + if BN: + x = _bn_act(x,activation=activation) + else: + x = Activation(activation)(x) + + if exp_boost: + x = Dense(output_dim)(x) + z = Lambda(lambda x : K.exp(x))(x) + if quad_boost: + x = Dense(output_dim)(x) + a = 0.001 + b = 0.4 + z = Lambda(lambda x : a * K.pow(x,3) + b)(x) + else: + z = Dense(output_dim, name='out')(x) + z = Activation('softmax', name='softmax')(z) + model = Model(inputs=inp, outputs=z) + if parallelize: + model = make_parallel(model, len(CUDA_VISIBLE_DEVICES.split(','))) + # opt = Adam(lr=25/(np.sqrt(width * output_dim))) + if opt == 'sgd': + opt = SGD + if opt == 'adam': + opt = Adam + if opt == 'adagrad': + opt = Adagrad + opt = opt(lr=lr) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model + +def resnet_wrapper(input_dim,output_dim,depth,width,reshape_layer): + builder = resnet.ResnetBuilder() + model = builder.build_resnet_18(input_dim, output_dim,reshape_layer) + x = model.get_layer(name='flatten_1').get_output_at(-1) + for i in range(depth): + x = Dense(width,activation='relu')(x) + softmax = Dense(output_dim,activation='softmax')(x) + model = Model(inputs=model.inputs, outputs=softmax) + opt = Adam(lr=10/np.sqrt(input_dim * output_dim)) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model +def DBN_DNN(inp,nClasses,depth,width,batch_size=2048): + RBMs = [] + weights = [] + bias = [] + # batch_size = inp.shape + nEpoches = 5 + if len(inp.shape) == 3: + inp = inp.reshape((inp.shape[0] * inp.shape[1],inp.shape[2])) + sigma = np.std(inp) + # sigma = 1 + rbm = GBRBM(n_visible=inp.shape[-1],n_hidden=width,learning_rate=0.002, momentum=0.90, use_tqdm=True,sample_visible=True,sigma=sigma) + rbm.fit(inp,n_epoches=15,batch_size=batch_size,shuffle=True) + RBMs.append(rbm) + for i in range(depth - 1): + print 'training DBN layer', i + rbm = BBRBM(n_visible=width,n_hidden=width,learning_rate=0.02, momentum=0.90, use_tqdm=True) + for e in range(nEpoches): + batch_size *= 1 + (e*0.5) + n_batches = (inp.shape[-2] / batch_size) + (1 if inp.shape[-2]%batch_size != 0 else 0) + for j in range(n_batches): + stdout.write("\r%d batch no %d/%d epoch no %d/%d" % (int(time.time()),j+1,n_batches,e,nEpoches)) + stdout.flush() + b = np.array(inp[j*batch_size:min((j+1)*batch_size, inp.shape[0])]) + for r in RBMs: + b = r.transform(b) + rbm.partial_fit(b) + RBMs.append(rbm) + for r in RBMs: + (W,_,Bh) = r.get_weights() + weights.append(W) + bias.append(Bh) + model = mlp1(x_train.shape[1],nClasses,depth-1,width) + print len(weights), len(model.layers) + assert len(weights) == len(model.layers) - 1 + for i in range(len(weights)): + W = [weights[i],bias[i]] + model.layers[i].set_weights(W) + return model +# def gen_data(active): + + +def preTrain(model,modelName,x_train,y_train,meta,skip_layers=[],outEqIn=False,fit_generator=None): + print model.summary() + layers = model.layers + output = layers[-1] + outdim = output.output_shape[-1] + for i in range(len(layers) - 1): + if i in skip_layers: + print 'skipping layer ',i + continue + if len(model.layers[i].get_weights()) == 0: + print 'skipping layer ',i + continue + last = model.layers[i].get_output_at(-1) + if outEqIn: + preds = Dense(outdim)(last) + else: + preds = Dense(outdim,activation='softmax')(last) + model_new = Model(model.input,preds) + for j in range(len(model_new.layers) - 2): + print "untrainable layer ",j + model_new.layers[j].trainable=False + model_new.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + print model_new.summary() + batch_size = 2048 + if fit_generator == None: + model_new.fit(x_train,y_train,epochs=1,batch_size=2048) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=3) + # model.fit_generator(gen_bracketed_data(x_train,y_train,meta['framePos_Train'],4), + # steps_per_epoch=len(meta['framePos_Train']), epochs=3, + # callbacks=[ModelCheckpoint('%s_CP.h5' % modelName,monitor='loss',mode='min')]) + # model.fit_generator(gen_data(x_train,y_train,batch_size), + # steps_per_epoch = x_train.shape[0] / batch_size, + # epochs = 1) + model.layers[i].set_weights(model_new.layers[-2].get_weights()) + for l in model.layers: + l.trainable = True + return model + +def trainNtest(model,x_train,y_train,x_test,y_test,meta, + modelName,testOnly=False,pretrain=False, batch_size=512, + init_epoch=0, fit_generator=None, ctc_train=False): + print 'TRAINING MODEL:',modelName + if not testOnly: + if pretrain: + print 'pretraining model...' + model = preTrain(model,modelName,x_train,y_train,meta,fit_generator=fit_generator) + if ctc_train: + model = ctc_model(model) + print model.summary() + print 'starting fit...' + callback_arr = [ModelCheckpoint('%s_CP.h5' % modelName,save_best_only=True,verbose=1), + ReduceLROnPlateau(patience=5,factor=0.5,min_lr=10**(-6), verbose=1), + CSVLogger(modelName+'.csv',append=True)] + + if fit_generator == None: + history = model.fit(x_train,y_train,epochs=100,batch_size=batch_size, + initial_epoch=init_epoch, + validation_data=(x_test,y_test), + callbacks=callback_arr) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=75, + validation_data=fit_generator(x_test,y_test,batch_size), + validation_steps = (meta['nFrames_Dev']) / batch_size, + callbacks=callback_arr) + model = Model(inputs=[model.get_layer(name='x').input], + outputs=[model.get_layer(name='softmax').output]) + print model.summary() + model.compile(loss='sparse_categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + print 'saving model...' + model.save(modelName+'.h5') + # model.save_weights(modelName+'_W.h5') + print(history.history.keys()) + print history.history['lr'] + print 'plotting graphs...' + # summarize history for accuracy + fig, ax1 = plt.subplots() + ax1.plot(history.history['acc']) + ax1.plot(history.history['val_acc']) + ax2 = ax1.twinx() + ax2.plot(history.history['loss'],color='r') + ax2.plot(history.history['val_loss'],color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + else: + model = load_model(modelName) + print 'scoring...' + score = model.evaluate_generator(gen_bracketed_data(x_test,y_test,meta['framePos_Dev'],4), + len(meta['framePos_Dev'])) + print score + +if __name__ == '__main__': + print 'PROCESS-ID =', os.getpid() + print 'loading data...' + meta = np.load('../GSOC/wsj0_phonelabels_cqt_meta.npz') + x_train = np.load('../GSOC/wsj0_phonelabels_cqt_train.npy') + y_train = np.load('../GSOC/wsj0_phonelabels_cqt_train_labels.npy') + print x_train.shape + print y_train.shape + nClasses = int(np.max(map(np.max,y_train)))+1 + print nClasses + + print 'loading test data...' + x_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev.npy') + y_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev_labels.npy') + + print 'initializing model...' + # model = load_model('dbn-3x2048-sig-adagrad_CP.h5') + # model = resnet_wrapper((x_train.shape[1:]),nClasses,1,1024,Reshape(x_train.shape[1:] + (1,))) + # model = mlp4(x_train[0].shape[-1] * 21, nClasses,1,1,2048, + # shortcut=False,BN=True,conv=True,dropout=False, + # regularize=False) + # model = mlp1(x_train.shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) + # # model = mlp_wCTC(x_train.shape[-1],nClasses,3,2048,BN=True) + # # model = DBN_DNN(x_train, nClasses,5,3072,batch_size=128) + # # print 'wrapping ctc...' + # # model = ctc_model(model) + # # model = DBN_DNN(x_train, nClasses,5,2560,batch_size=128) + # # model = load_model('mlp4-2x2560-cd-adam-bn-drop-conv-noshort_CP.h5') + # fg = gen_bracketed_data(context_len=5) + # trainNtest(model,x_train,y_train,x_test,y_test,meta,'mlp4-1x2048-conv-cqt-BN',ctc_train=False,fit_generator=fg) + + meta = np.load('../GSOC/wsj0_phonelabels_ci_meta.npz') + model = load_model('bestModels/best_CI.h5',custom_objects={'dummy_loss':dummy_loss, + 'decoder_dummy_loss':decoder_dummy_loss, + 'ler':ler}) + # model = Model(inputs=[model.get_layer(name='x').input], + # outputs=[model.get_layer(name='softmax').output]) + print model.summary() + # # # getPredsFromFilelist(model,'../wsj/wsj0/single_dev.txt','/home/mshah1/wsj/wsj0/feat_cd_mls/','.mls','/home/mshah1/wsj/wsj0/single_dev_NN/','.sen',meta['state_freq_Train'],context_len=5,weight=0.00035457) + # # # getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev2/','.sen',meta['state_freq_Train']) + getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_dev_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev_ci/','.sen',meta['state_freq_Train'], + context_len=4, + # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), + # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), + weight=0.1,n_feat=25) + # *0.00311573 + # 00269236 + # # getPredsFromArray(model,np.load('DEV_PRED.npy'),meta['framePos_Dev'],meta['filenames_Dev'],'/home/mshah1/wsj/wsj0/senscores_dev_ci_hammad/','.sen',meta['state_freq_Train'],preds_in=True,weight=-0.00075526,offset=234.90414376) + # f = filter(lambda x : '22go0208.wv1.flac' in x, meta['filenames_Dev'])[0] + # file_idx = list(meta['filenames_Dev']).index(f) + # print file_idx + # # split = lambda x: x[sum(meta['framePos_Dev'][:file_idx]):sum(meta['framePos_Dev'][:file_idx+1])] + # pred = model.predict(x_test[file_idx:file_idx+1],verbose=1) + # pred = np.array(map(lambda x: np.argmax(x,axis=-1),pred)) + # print pred + # print y_test[file_idx] + # data = split(x_test) + # context_len = 5 + # pad_top = np.zeros((context_len,data.shape[1])) + # pad_bot = np.zeros((context_len,data.shape[1])) + # padded_data = np.concatenate((pad_top,data),axis=0) + # padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + # data = [] + # for j in range(context_len,len(padded_data) - context_len): + # new_row = padded_data[j - context_len: j + context_len + 1] + # new_row = new_row.flatten() + # data.append(new_row) + # data = np.array(data) + # pred = model.predict(data,verbose=1) + # pred = pred.reshape(1,pred.shape[0],pred.shape[1]) + # print pred.shape + # [bp],out = K.ctc_decode(pred,[pred.shape[1]]) + # print K.eval(bp), len(K.eval(bp)[0]) + # print K.eval(out) + + # print pred + # # writeSenScores('senScores',pred) + # np.save('pred.npy',np.log(pred)/np.log(1.001)) + + # plotFromCSV('mlp4-1x2048-conv-cqt-BN') \ No newline at end of file diff --git a/scripts/DNN_training/README.md b/scripts/DNN_training/README.md new file mode 100644 index 00000000..6996623c --- /dev/null +++ b/scripts/DNN_training/README.md @@ -0,0 +1,134 @@ +# DNNs For ASR +The work is part of a Google Summer of Code project, the goal of which was to integrate DNNs with CMUSphinx. This particular repository contains some convenient scripts that wrap Keras code and allow for easy training of DNNs. +## Getting Started +Start by cloning the repository. +### Prerequisites +The required python libraries available from pypi are in the requirements.txt file. Install them by running: +``` +pip install -r requirements.txt +``` +Additional libraries not available from pypi: +- tfrbm- for DBN-DNN pretraining. + - available at https://github.com/meownoid/tensorfow-rbm +## Getting Started +Since the project is primarily intended to be used with PocketSphinx the file formats for feature files, state-segmentation output files and the prediction files are in sphinx format. +### Feature File Format +``` +N: number of frames +M: dimensions of the feature vector +N*M (4 bytes) +Frame 1: f_1...f_M (4*M bytes) +. +. +. +Frame N: f_1,...,f_M (4*M bytes) +``` +Look at readMFC in utils.py +### state-segmentation files +format for each frame: +``` + 2 2 2 1 4 bytes +st1 [st2 st3] pos scr +``` +### Prediction output +format for each frame: +``` +N: number of states +N (2 bytes) +scr_1...scr_N (2*N bytes) +``` +### Wrapper Scripts +``` +runDatasetGen.py -train_fileids -val_fileids [-test_fileids] -n_filts -feat_dir -feat_ext -stseg_dir -stseg_ext -mdef [-outfile_prefix] [-keep_utts] +``` +runDatasetGen takes feature files and state-segmentation files stored in sphinx format along with the definition file of the GMM-HMM model to generate a set of numpy arrays that form a python readable dataset. +runDatasetGen writes the following files in the directory it was called in: +- Data Files + - _train.npy + - _dev.npy + - _test.npy +- label files + - _train_label.npy + - _dev_label.npy + - _test_label.npy +- metadata file + - _meta.npz + +The metadata file is a zipped collection of arrays with the follwing keys: +- File names for utterances + - filenames_Train + - filenames_Dev + - filenames_Test +- Number of frames per utterance (useful if -keep_utts is not set) + - framePos_Train + - framePos_Dev + - framePos_Test +- State Frequencies (useful for scaling in some cases) + - state_freq_Train + - state_freq_Dev + - state_freq_Test +``` +runNNTrain.py -train_data -train_labels -val_data -val_labels -nn_config [-context_win] [-cuda_device_id] [-pretrain] [-keras_model] -model_name +``` +runNNTrain takes the training and validation data files (as generated by runDatasetGen) and trains a neural network on them. +The architecture and parameters of the neural network is defined in a text file. Currently this script supports 4 network types: +- MLP (mlp) +- Convolutional Neural Network (conv) +- MLP with short cut connections (resnet) +- Convolutional Network with residual connections in the fully connected layers (conv + resnet) +See sample_nn.cfg for an example. +The format for the configuration file consists of ```param``` and ```value``` pairs +if value has multiple elemets (represented by ... below) they should be separated by spaces. +Params and possible values: +- **type** mlp, conv, resnet, conv+resnet +- **width** any integer value +- **depth** any integer value +- **dropout** float in (0,1) +- **batch_norm** - +- **activation** sigmoid, hard_sigmoid, elu, relu, selu, tanh, softplus, softsign, softmax, linear +- **optimizer** sgd, adam, adagrad +- **lr** float in (0,1) +- **batch_size** any integer value +- **ctc_loss** - +- for type = conv and type = conv+resnet + - **conv** [n_filters, filter_window]... + - **pooling** None, [max/avg, window_size, stride_size] +- for type = resnet and type = conv+resnet + - **block_depth** any integer value + - **n_blocks** any integer value +``` +runNNPredict -keras_model -ctldir -inext -outdir -outext -nfilts [-acoustic_weight] [-context_win] [-cuda_device_id] +``` +runNNPredict takes a keras model and a list of feature files to generate predictions. The predictions are stored as binary files in sphinx readable format (defined above). +Please ensure that the dimensionality of the feature vectors matches nfilts and the context window is the same as that for which the model was trained. +The acoustic_weight is used to scale the output scores. This is required because if the scores are passed through a GMM-GMM decoder like PocketSphinx are too small or too large then the decoding performance suffers. One way of estimating this weight is to generate scores from the GMM-HMM decoder being used, fit a linear regression between the GMM-HMM scores and the NN-scores and use the coefficient as the weight. +``` +readSen.py -gmm_score_dir -gmm_ctllist -nn_score_dir -nn_ctllist [-gmm_ext] [-nn_ext] +``` +readSen takes scores (stored in sphinx readable binary files) obtained from a GMM-HMM decoder and a NN, and fit a regression to them. + +## Example workflow with CMUSphinx +- Feature extraction using sphinx_fe: + ``` + sphinx_fe -argfile ../../en_us.ci_cont/feat.params -c etc/wsj0_train.fileids -di wav/ -do feat_ci_mls -mswav yes -eo mls -ei wav -ofmt sphinx -logspec yes + ``` +- State-segmentation using sphinx3_align + ``` + sphinx3_align -hmm ../../en_us.ci_cont/ -dict etc/cmudict.0.6d.wsj0 -ctl etc/wsj0_train.fileids -cepdir feat_ci_mls/ -cepext .mfc -insent etc/wsj0.transcription -outsent wsj0.out -stsegdir stateseg_ci_dir/ -cmn batch + ``` +- Generate dataset using runDatasetGen.py +- Train NN using runNNtrain.py +- Generate predictions from the NN using runNNPredct.py +- Generate predictions from PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir feat_ci_mfc/ -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -senlogdir sendump_ci/ -compallsen yes -bestpath no -fwdflat no -remove_noise no -remove_silence no -logbase 1.0001 -pl_window 0 +``` +- Compute the acoustic weight using readSen.py +- Decode the scaled NN predictions with PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir senscores/ -cepext .sen -hyp NN2.hyp -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -compallsen yes -logbase 1.0001 -pl_window 0 -senin yes +``` + + + + diff --git a/scripts/DNN_training/ctc.py b/scripts/DNN_training/ctc.py new file mode 100644 index 00000000..87363173 --- /dev/null +++ b/scripts/DNN_training/ctc.py @@ -0,0 +1,137 @@ +import sys +import fst +import random +import math +import numpy as np +from scipy.sparse import bsr_matrix +reload(sys) +sys.setdefaultencoding('utf8') + +def ran_lab_prob(n_samps): + r = [random.random() for i in range(138)] + s = sum(r) + return [[i/s for i in r]]*n_samps + +def genBigGraph(label_prob, symbols, seq_len, label='x'): + t = fst.Transducer() + sym=fst.SymbolTable() + + symbols = map(str,symbols) + x=0 + for j in range(seq_len): + for i in range(len(symbols)): + prob = label_prob[j][i] #"%.4f" % + t.add_arc(0+x, 1+x,str(label+str(j)),symbols[i],-math.log(prob)) + x+=1 + t[j+1].final = -1 + return t + +def gen_utt_graph(labels,symdict): + t2=fst.Transducer() + sym=fst.SymbolTable() + #3x3 states for this example + count = 0 + x = 0 + # print labels + for l in labels: + symbols = symdict[l] + symbols = map(str,symbols) + for i in range(len(symbols)): + if i == 0: + t2.add_arc(0+x,1+x,symbols[i],str(l+"/"+"("+symbols[i]+")")) + else: + t2.add_arc(0+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) + t2.add_arc(1+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) + + x+=1 + + t2[x].final=True + return t2 + +def gen_parents_dict(graph): + parents={} + for state in graph.states: + for arc in state.arcs: + if arc.nextstate in parents: + parents[arc.nextstate].append(state.stateid) + else: + parents[arc.nextstate]=[state.stateid] + return parents + +def make_prob_dict(graph,n_samps,n_labels): + y_t_s = np.zeros((n_samps + 1,n_labels)) # dictionary to store probabilities indexed by time and label + F = [0] + for t in range(n_samps + 1): + # y_t_s[t] = {} + for s in F: + arcs = graph[s].arcs + for a in arcs: + osym = graph.osyms.find(a.olabel) + osym = osym[osym.find("(")+1:osym.find(")")] + y_t_s[t][int(osym)] = np.exp(-1 * float(a.weight)) + F = map(lambda x: map(lambda y: y.nextstate,graph[x].arcs),F) + F = set([s for ss in F for s in ss]) + y_t_s = bsr_matrix(y_t_s,dtype='float32') + return y_t_s + +def calc_alpha(n_samps, symbols, y_t_s): + alpha = {} + # symbols = map(str,symbols) + for t in range(n_samps + 1): + alpha[t] = {} + for i in range(len(symbols)): + # print alpha + # print t,i, + if t == 0: + if i == 0: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) + else: + alpha[t][symbols[i]] = 0.0 + else: + if i == 0: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * alpha[t-1][symbols[i]] + else: + alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * (alpha[t-1][symbols[i]] + alpha[t-1][symbols[i-1]]) + # print alpha[t][symbols[i]] + return alpha + +def calc_beta(n_samps,symbols,y_t_s): + beta = {} + # symbols = map(str,symbols) + for t in range(n_samps,0,-1): + beta[t] = {} + for i in range(len(symbols)): + if t == n_samps: + if i == len(symbols) - 1: + beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) + else: + beta[t][symbols[i]] = 0.0 + else: + if i < len(symbols) - 1: + score = beta[t+1][symbols[i]] + beta[t+1][symbols[i+1]] + else: + score = beta[t+1][symbols[i]] + beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * score + return beta + +def print_graph(t): + for state in t.states: + for arc in state.arcs: + print('{} -> {} / {}:{} / {}'.format(state.stateid, + arc.nextstate, + t.isyms.find(arc.ilabel), + t.osyms.find(arc.olabel), + arc.weight)) +# symbols = ['G1','G2','G3','UH1','UH2','UH3','D1','D2','D3'] +# t = genBigGraph(ran_lab_prob,symbols,11) +# labels = ['G','UH','D'] + +# symdict={'G': ['G1','G2','G3'], +# 'UH': ['UH1','UH2','UH3'], +# 'D': ['D1','D2','D3']} +# t2 = gen_utt_graph(labels, symdict) +# t3 = t>>t2 +# parents = gen_parents_dict(t3) +# y_t_s = make_prob_dict(t3) +# print calc_alpha(10,symbols,y_t_s) +# print calc_beta(10,symbols,y_t_s) \ No newline at end of file diff --git a/scripts/DNN_training/genLabels.py b/scripts/DNN_training/genLabels.py new file mode 100644 index 00000000..cb38ca88 --- /dev/null +++ b/scripts/DNN_training/genLabels.py @@ -0,0 +1,339 @@ +import numpy as np +from functools import reduce +import os +import threading +import time +import sys +from sklearn.preprocessing import StandardScaler +import utils +from keras.preprocessing.sequence import pad_sequences +import ctc +import fst +import librosa + +done = 0 +def ping(): + curr_time = int(time.time()) + while done == 0: + if (int(time.time()) != curr_time): + curr_time = int(time.time()) + sys.stdout.write('.') + sys.stdout.flush() + + +def read_sen_labels_from_mdef(fname, onlyPhone=True): + labels = np.loadtxt(fname,dtype=str,skiprows=10,usecols=(0,1,2,3,6,7,8)) + labels = map(lambda x: + [reduce(lambda a,b: a+' '+b, + filter(lambda y: y != '-', x[:4]))] + list(x[4:]), labels) + if onlyPhone: + labels = labels[:44] + phone2state = {} + for r in labels: + phone2state[r[0]] = map(int, r[1:]) + return phone2state + +def frame2state(fname, phone2state, onlyPhone=True): + with open(fname,'r') as f: + lines = f.readlines()[2:] + lines = map(lambda x: x.split()[2:], lines) + if onlyPhone: + lines = map(lambda x: x[:2],lines) + else: + lines = map(lambda x: [x[0], reduce(lambda a,b: a+' '+b,x[1:])],lines) + for l in lines: + if l[1] not in phone2state: + l[1] = l[1].split()[0] + states = map(lambda x: phone2state[x[1]][int(x[0])], lines) + return (list(states)) + +def loadDict(filename): + def mySplit(line): + line = line.split() + for i in range(1,len(line)): + line[i] = "{0}1 {0}2 {0}3".format(line[i]) + line = [line[0], reduce(lambda x,y: x+ ' ' +y, line[1:])] + return line + with open(filename) as f: + d = f.readlines() + d = map(lambda x: x.split(),d) + myDict = {} + for r in d: + myDict[r[0]] = r[1:] + return myDict + +def loadTrans(trans_file,pDict): + trans = {} + with open(trans_file) as f: + lines = f.readlines() + for line in lines: + line = line.split() + fname = line[-1][1:-1] + labels = map(lambda x: pDict.setdefault(x,-1), line[:-1]) + labels = filter(lambda x: x!=-1, labels) + if labels == []: + continue + labels = reduce(lambda x,y: x + y, labels) + trans[fname] = labels + return trans + +def trans2labels(trans,phone2state): + d = {} + for u in trans: + labels = trans[u] + labels = map(lambda x: phone2state[x], labels) + labels = reduce(lambda x,y: x + y, labels) + d[u] = labels + return d + +def genDataset(train_flist, dev_flist, test_flist, n_feats, + feat_path, feat_ext, stseg_path, stseg_ext, mdef_fname, + outfile_prefix, context_len=None, + keep_utts=False, ctc_labels=False, pDict_file=None, + trans_file=None, make_graph=False,cqt=False, + max_len=None,n_deltas=0,pad=False): + assert(os.path.exists(stseg_path)) + train_files = np.loadtxt(train_flist,dtype=str) + dev_files = np.loadtxt(dev_flist,dtype=str) + if test_flist != None: + test_files = np.loadtxt(test_flist,dtype=str) + else: + test_files = [] + phone2state = read_sen_labels_from_mdef(mdef_fname,onlyPhone=False) + + if ctc_labels: + pDict = loadDict(pDict_file) + trans = loadTrans(trans_file,pDict) + label_dict = trans2labels(trans, phone2state) + stseg_files_train = filter(lambda x: x.split('/')[-1] in label_dict, train_files) + stseg_files_test = filter(lambda x: x.split('/')[-1] in label_dict, test_files) + stseg_files_dev = filter(lambda x: x.split('/')[-1] in label_dict, dev_files) + stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test + print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) + else: + stseg_files_train = map(lambda x: x.split('/')[-1]+stseg_ext,train_files) + stseg_files_test = map(lambda x: x.split('/')[-1]+stseg_ext,test_files) + stseg_files_dev = map(lambda x: x.split('/')[-1]+stseg_ext,dev_files) + stseg_files_train = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_train) + stseg_files_test = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_test) + stseg_files_dev = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_dev) + + stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test + print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) + + train_files = map(lambda x: feat_path+x+feat_ext,train_files) + dev_files = map(lambda x: feat_path+x+feat_ext,dev_files) + test_files = map(lambda x: feat_path+x+feat_ext,test_files) + + X_Train = [] + Y_Train = [] + X_Test = [] + Y_Test = [] + X_Dev = [] + Y_Dev = [] + framePos_Train = [] + framePos_Test = [] + framePos_Dev = [] + filenames_Train = [] + filenames_Test = [] + filenames_Dev = [] + active_states_Train = [] + active_states_Test = [] + active_states_Dev = [] + # allData = [] + # allLabels = [] + pos = 0 + scaler = StandardScaler(copy=False,with_std=False) + n_states = np.max(phone2state.values())+1 + print n_states + state_freq_Train = [0]*n_states + state_freq_Dev = [0]*n_states + state_freq_Test = [0]*n_states + + + + for i in range(len(stseg_files)): + if i < len(stseg_files_train): + # print '\n train' + frames = framePos_Train + allData = X_Train + allLabels = Y_Train + filenames = filenames_Train + state_freq = state_freq_Train + files = train_files + active_state = active_states_Train + elif i < len(stseg_files_train) + len(stseg_files_dev): + # print '\n dev' + frames = framePos_Dev + allData = X_Dev + allLabels = Y_Dev + filenames = filenames_Dev + state_freq = state_freq_Dev + files = dev_files + active_state = active_states_Dev + else: + # print '\n test' + frames = framePos_Test + allData = X_Test + allLabels = Y_Test + filenames = filenames_Test + state_freq = state_freq_Test + files = test_files + active_state = active_states_Test + + sys.stdout.write("\r%d/%d " % (i,len(stseg_files))) + sys.stdout.flush() + f = stseg_files[i] + + [data_file] = filter(lambda x: f[:-9] in x, files) + if cqt: + y,fs=librosa.load(data_file,sr=None) + data = np.absolute(librosa.cqt(y,sr=fs,window=np.hamming, + hop_length=160, n_bins=64, bins_per_octave=32).T) + # print data.shape + else: + data = utils.readMFC(data_file,n_feats).astype('float32') + data = scaler.fit_transform(data) + + if ctc_labels: + labels = label_dict[data_file.split('/')[-1][:-4]] + if make_graph: + t = ctc.genBigGraph(ctc.ran_lab_prob(data.shape[0]), + set(labels), + data.shape[0]) + t2 = ctc.gen_utt_graph(trans[data_file.split('/')[-1][:-4]],phone2state) + assert set([e for (e,_) in t.osyms.items()]) == set([e for (e,_) in t2.isyms.items()]) + t.osyms = t2.isyms + t3 = t >> t2 + parents = ctc.gen_parents_dict(t3) + y_t_s = ctc.make_prob_dict(t3,data.shape[0],n_states) + active_state.append(y_t_s) + # print active_state + nFrames = data.shape[0] + else: + labels = frame2state(stseg_path + f, phone2state,onlyPhone=False) + nFrames = min(len(labels), data.shape[0]) + sys.stdout.write('(%d,%d) (%d,)' % (data.shape + np.array(labels).shape)) + data = data[:nFrames] + labels = labels[:nFrames] + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if n_deltas > 0: + pad_top = np.zeros((n_deltas,data.shape[1])) + pad_bot = np.zeros((n_deltas,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + data = [] + for j in range(n_deltas,len(padded_data) - n_deltas): + delta_top = padded_data - padded_data[j - n_deltas:j] + delta_bot = padded_data - padded_data[j:j + n_deltas] + new_row = delta_top + padded_data + delta_bot + data.append(new_row) + for l in labels: + state_freq[l] += 1 + filenames.append(data_file) + frames.append(nFrames) + if keep_utts: + allData.append(data) + allLabels.append(np.array(labels)) + else: + allData += list(data) + allLabels += list(labels) + pos += nFrames + if not ctc_labels: + assert(len(allLabels) == len(allData)) + # print allData + print len(allData), len(allLabels) + if max_len == None: + max_len = 100 * ((max(map(len,X_Train)) + 99)/ 100) + print 'max_len', max_len + if keep_utts and pad: + X_Train = pad_sequences(X_Train,maxlen=max_len,dtype='float32',padding='post') + Y_Train = pad_sequences(Y_Train,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Train = Y_Train.reshape(Y_Train.shape[0],Y_Train.shape[1],1) + X_Dev = pad_sequences(X_Dev,maxlen=max_len,dtype='float32',padding='post') + Y_Dev = pad_sequences(Y_Dev,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Dev = Y_Dev.reshape(Y_Dev.shape[0],Y_Dev.shape[1],1) + X_Test = pad_sequences(X_Test,maxlen=max_len,dtype='float32',padding='post') + Y_Test = pad_sequences(Y_Test,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Test = Y_Test.reshape(Y_Test.shape[0],Y_Test.shape[1],1) + # np.savez('wsj0_phonelabels_NFrames',NFrames_Train=NFrames_Train,NFrames_Test=NFrames_Test) + # t = threading.Thread(target=ping) + # t.start() + if context_len != None: + np.save('wsj0_phonelabels_bracketed_train.npy',X_Train) + np.save('wsj0_phonelabels_bracketed_test.npy',X_Test) + np.save('wsj0_phonelabels_bracketed_dev.npy',X_Dev) + np.save('wsj0_phonelabels_bracketed_train_labels.npy',Y_Train) + np.save('wsj0_phonelabels_bracketed_test_labels.npy',Y_Test) + np.save('wsj0_phonelabels_bracketed_dev_labels.npy',Y_Dev) + if make_graph: + np.save('wsj0_phonelabels_bracketed_train_active.npy',active_states_Train) + np.save('wsj0_phonelabels_bracketed_test_active.npy',active_states_Test) + np.save('wsj0_phonelabels_bracketed_dev_active.npy',active_states_Dev) + np.savez('wsj0_phonelabels_bracketed_meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + else: + np.save(outfile_prefix + 'train.npy',X_Train) + np.save(outfile_prefix + 'dev.npy',X_Dev) + np.save(outfile_prefix + 'train_labels.npy',Y_Train) + np.save(outfile_prefix + 'dev_labels.npy',Y_Dev) + if len(X_Test) != 0: + np.save(outfile_prefix + 'test.npy',X_Test) + np.save(outfile_prefix + 'test_labels.npy',Y_Test) + if make_graph: + np.save(outfile_prefix + 'active.npy',active_states_Train) + np.save(outfile_prefix + 'active.npy',active_states_Test) + np.save(outfile_prefix + 'active.npy',active_states_Dev) + np.savez(outfile_prefix + 'meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + # done = 1 + +def normalizeByUtterance(): + data = np.load('wsj0_phonelabels_bracketed_data.npy') + nFrames = np.load('wsj0_phonelabels_bracketed_meta.npz')['framePos_Train'] + # print 'calculating frame indices...' + # nFrames = map(lambda i: sum(nFrames[:i]),xrange(len(nFrames))) + print 'normalizing...' + scaler = StandardScaler(copy=False) + print data + pos = 0 + for i in xrange(len(nFrames)): + sys.stdout.write("\rnormalizing utterance no %d " % i) + sys.stdout.flush() + data[pos:nFrames[i]] = scaler.fit_transform(data[pos:nFrames[i]]) + pos = nFrames[i] + print data +if __name__ == '__main__': + #print(read_sen_labels_from_mdef('../wsj_all_cd30.mllt_cd_cont_4000/mdef')) + # frame2state('../wsj/wsj0/statesegdir/40po031e.wv2.flac.stseg.txt', '../wsj_all_cd30.mllt_cd_cont_4000/mdef') + genDataset('../wsj/wsj0/etc/wsj0_train.fileids','../wsj/wsj0/etc/wsj0_dev.fileids','../wsj/wsj0/etc/wsj0_test.fileids',40,'../wsj/wsj0/feat_cd_mls/','../wsj/wsj0/stateseg_ci_dir/','../en_us.ci_cont/mdef', + keep_utts=True, context_len=None, cqt=True, + trans_file='../wsj/wsj0/etc/wsj0.transcription', + pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') + # normalizeByUtterance() + # ../wsj/wsj0/feat_mls/11_6_1/wsj0/sd_dt_20/00b/00bo0t0e.wv1.flac.mls 00bo0t0e.wv1.flac.stseg.txt \ No newline at end of file diff --git a/scripts/DNN_training/makeFileListFromTrans.py b/scripts/DNN_training/makeFileListFromTrans.py new file mode 100644 index 00000000..5de9ac1c --- /dev/null +++ b/scripts/DNN_training/makeFileListFromTrans.py @@ -0,0 +1,19 @@ +import numpy as np +def getFileListFromTran(trans,outFile): + with open(trans,'r') as f: + lines = f.readlines() + lines = map(lambda x: x.strip(), lines) + files = map(lambda x: x.split('(')[-1][:-1], lines) + np.savetxt(outFile,files,fmt='%s') + +def fixTran(trans): + with open(trans,'r') as f: + lines = f.readlines() + lines = map(lambda x: x.strip(), lines) + lines = map(lambda x: x.split('('), lines) + for l in lines: + l[-1] = l[-1].split('/')[-1] + lines = map(lambda x: reduce(lambda a,b: a+'('+b,x),lines) + np.savetxt(trans+'2',lines,fmt='%s') +# getFileListFromTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans", "../wsj/wsj0/wsj0.filelist") +fixTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans") \ No newline at end of file diff --git a/scripts/DNN_training/readSen.py b/scripts/DNN_training/readSen.py new file mode 100644 index 00000000..b47b38a8 --- /dev/null +++ b/scripts/DNN_training/readSen.py @@ -0,0 +1,96 @@ +import os +import struct +import numpy as np +from sklearn.linear_model import LinearRegression +from argparse import ArgumentParser + +def readSen(fname, print_most_prob_sen=False): + print fname + f = open(fname,'rb') + s = '' + while 'endhdr\n' not in s: + v = f.read(1) + s += struct.unpack('s',v)[0] + magic_num = struct.unpack('I',f.read(4))[0] + assert magic_num == 0x11223344 + count = 0 + data = [] + while v: + v = f.read(2) + if not v: + continue + n_active = struct.unpack('h',v)[0] + # print n_active + assert n_active == 138 + + v = f.read(2*n_active) + scores = list(struct.unpack('%sh' % n_active, v)) + # print np.argmax(scores) + count += 1 + data += scores + print count + return np.array(data) + +if __name__=='__main__': + parser = ArgumentParser(description="""Given two sets of sen files fits a regression to them and returns the coefficient and the intercept. + Useful in determining the appropriate acoustic weight to scale the outputs of the NN by. Improperly + scaled output perform much worse than appropriatly scaled outputs""", + usage='%(prog)s [options] \nUse --help for option list') + parser.add_argument('-gmm_score_dir',type=str, required=True, + help="The directory where the sen files generated by GMM-HMM decoder are stored. Preppended to file paths in gmm_ctllist") + parser.add_argument('-gmm_ctllist', type=str, required=True, + help='List of all the sen files generated by the GMM-HMM decoder') + parser.add_argument('-nn_score_dir',type=str, required=True, + help="The directory where the sen files generated by a ANN are stored. Preppended to file paths in gmm_ctllist") + parser.add_argument('-nn_ctllist', type=str, required=True, + help='List of all the sen files generated by the ANN') + parser.add_argument('-gmm_ext', type=str, required=False, default='', + help='the file extension applied to all the files in gmm_ctllist') + parser.add_argument('-nn_ext', type=str, required=False, default='', + help='the file extension applied to all the files in nn_ctllist') + args = vars(parser.parse_args()) + # readSen('../wsj/wsj0/senscores/11_14_1/wsj0/si_et_20/440/440c0401.wv1.flac.sen') + ndx_list = map(lambda x: args['nn_score_dir']+x+args['nn_ext'], np.loadtxt(args['nn_ctllist'],dtype=str)) + file_list = map(lambda x: args['gmm_score_dir']+x+args['gmm_ext'], np.loadtxt(args['gmm_ctllist'],dtype=str)) + # file_list = map(lambda x: '../wsj/wsj0/sendump_dev_ci/' + x, os.listdir('../wsj/wsj0/sendump_dev_ci/')) + # file_list.sort() + # file_list = file_list[:-1] + # ndx_list = ['../wsj/wsj0/single_dev_NN/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] + # file_list = ['../wsj/wsj0/single_dev/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] + x = [] + y = [] + for i in range(len(file_list)): + if i >= 0: + if os.path.exists(ndx_list[i]): + print i,ndx_list[i], file_list[i] + _y = list(readSen(ndx_list[i])) + _x = list(readSen(file_list[i])) + if len(_x) != len(_y): + continue + y += _y + x += _x + frame_len = min(len(x),len(y)) + # x = x[:frame_len] + # y = y[:frame_len] + print len(x),len(y), len(x)/138, len(y)/138 + assert len(x) == len(y) + else: + continue + else: + print i,ndx_list[i+1], file_list[i] + y += list(readSen(ndx_list[i+1])) + x += list(readSen(file_list[i])) + x = np.array(x).reshape(-1,1) + y = np.array(y).reshape(-1,1) + # print x.shape, y.shape + data = np.concatenate((x,y),axis=1) + # np.save('data4regression.npy',data) + + # data = np.load('data4regression.npy') + lreg = LinearRegression(normalize=True,n_jobs=-1) + lreg.fit(data[:,[1]],data[:,[0]]) + print "coefficient: %f\t\tintercept: %f" % (lreg.coef_, lreg.intercept_) + + # vs = np.std(data[:,[1]]) + # va = np.std(data[:,[0]]) + # print va/vs diff --git a/scripts/DNN_training/requirements.txt b/scripts/DNN_training/requirements.txt new file mode 100644 index 00000000..c2d0f232 --- /dev/null +++ b/scripts/DNN_training/requirements.txt @@ -0,0 +1,67 @@ +appdirs==1.4.3 +audioread==2.1.5 +backports.weakref==1.0rc1 +bleach==1.5.0 +cycler==0.10.0 +Cython==0.25.2 +daemonize==2.4.7 +decorator==4.0.6 +editdistance==0.3.1 +funcsigs==1.0.2 +functools32==3.2.3.post2 +graphviz==0.7.1 +guppy==0.1.10 +h5py==2.7.0 +htk-io==0.5 +html5lib==0.9999999 +ipython==2.4.1 +joblib==0.11 +Keras==2.0.6 +Lasagne==0.2.dev1 +librosa==0.5.1 +Mako==1.0.6 +Markdown==2.2.0 +MarkupSafe==1.0 +matplotlib==2.0.2 +memory-profiler==0.47 +mock==2.0.0 +nose==1.3.7 +numpy==1.13.1 +packaging==16.8 +pbr==3.1.1 +pexpect==4.0.1 +posix-ipc==1.0.0 +protobuf==3.3.0 +ptyprocess==0.5 +py==1.4.33 +pycurl==7.43.0 +pydot==1.2.3 +pydot-ng==1.0.0 +pyfst==0.2.3 +pygpu==0.6.5 +pyliblzma==0.5.3 +pyparsing==2.2.0 +pysqlite==1.0.1 +pytest==3.0.7 +python-apt==1.1.0b1 +python-dateutil==2.6.0 +python-speech-features==0.5 +pytools==2016.2.6 +pytz==2017.2 +PyYAML==3.12 +resampy==0.1.5 +rpm-python==4.12.0.1 +scikit-learn==0.18.1 +scipy==0.19.1 +simplegeneric==0.8.1 +six==1.10.0 +subprocess32==3.2.7 +tensorflow-gpu==1.2.0 +tfrbm==0.0.2 +Theano==0.9.0 +tkinter==0.2.0 +tqdm==4.14.0 +urlgrabber==3.9.1 +virtualenv==15.0.1 +Werkzeug==0.12.2 +yum-metadata-parser==1.1.4 diff --git a/scripts/DNN_training/runDatasetGen.py b/scripts/DNN_training/runDatasetGen.py new file mode 100644 index 00000000..d44d47b6 --- /dev/null +++ b/scripts/DNN_training/runDatasetGen.py @@ -0,0 +1,41 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate numpy array from features and alignments produced by Sphinx", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_fileids', type=str, required=True, + help="list of training files") +parser.add_argument('-val_fileids',type=str,required=True, + help='list of validation files') +parser.add_argument('-test_fileids',type=str,required=False, + help='list of test files') +parser.add_argument('-nfilts',type=int,required=True, + help='number of filters used for extracting features. (The dimensionality of the feature vector)') +parser.add_argument('-feat_dir', type=str, required=True, + help='the directory where feature files are stored (prepended to filepaths in the train, val and test filelists when looking for features)') +parser.add_argument('-feat_ext',type=str,required=True, + help='extension to be appended to each file path when looking for feature files') +parser.add_argument('-stseg_dir',type=str,required=True, + help='directory where the state-segmentation for each feature file is stored (prepended to filepaths in the train, val and test filelists when looking for labels)') +parser.add_argument('-stseg_ext',type=str,required=True, + help='extension to be appended to each file path when looking for state-segmentation files') +parser.add_argument('-mdef',type=str,required=True, + help='path to the mdef file for the Sphinx model. Needed to map phones/triphones in segmentation to state labels') +parser.add_argument('-outfile_prefix',type=str,default="", required=False, + help='prepended to the names of the output files') +parser.add_argument('-keep_utts',nargs='?',required=False, default=False, const=True, + help='store features and labels in a 3D array in which each index points to the list of features/labels for one utterance') +args = vars(parser.parse_args()) + +from genLabels import genDataset +genDataset(args['train_fileids'], + args['val_fileids'], + args['test_fileids'], + args['nfilts'], + args['feat_dir'], + args['feat_ext'], + args['stseg_dir'], + args['stseg_ext'], + args['mdef'], + args['outfile_prefix'], + keep_utts=args['keep_utts']) + diff --git a/scripts/DNN_training/runNNPredict.py b/scripts/DNN_training/runNNPredict.py new file mode 100644 index 00000000..c2dfa281 --- /dev/null +++ b/scripts/DNN_training/runNNPredict.py @@ -0,0 +1,48 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate Predictions from a Keras Model and save them in PockeSphinx readable .sen files.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-keras_model', type=str, required=True, + help="Keras model to be used for prediction in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-ctldir',type=str, required=True, + help="the directory for the control files, prepended to each file path in ctllist") +parser.add_argument('-ctllist', type=str,required=True, + help='list of input files, each representing an utterance') +parser.add_argument('-inext', type=str, required=True, + help='the extension of the control files, appended to each file path in ctllist') +parser.add_argument('-outdir', type=str,required=True, + help='Directory where the predictions are stored. The structure of this directory will be identical to ctldir') +parser.add_argument('-outext', type=str, required=True, + help='the extension of the output files') +parser.add_argument('-nfilts', type=int, required=True, + help='dimensionality of the feature vectors') +parser.add_argument('-acoustic_weight',type=float,required=False, + help='The weight to scale the predictions by. Sometimes needed to get meaningful predictions from PocketSphinx') +parser.add_argument('-context_win',type=int, required=False, default=0, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from keras.models import load_model +from utils import * + +model = load_model(keras_model,custom_objects={'dummy_loss':dummy_loss, + 'decoder_dummy_loss':decoder_dummy_loss, + 'ler':ler}) +# model = Model(inputs=[model.get_layer(name='x').input], +# outputs=[model.get_layer(name='softmax').output]) +print model.summary() +getPredsFromFilelist(model,args['ctllist'], + args['ctldir'], + args['inext'], + args['outdir'], + args['outext'], + context_len=args['context_win'], + # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), + # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), + weight=args['acoustic_weight'] if args['acoustic_weight'] != None else 0.1, + n_feat=args['nfilts']) \ No newline at end of file diff --git a/scripts/DNN_training/runNNTrain.py b/scripts/DNN_training/runNNTrain.py new file mode 100644 index 00000000..82049fce --- /dev/null +++ b/scripts/DNN_training/runNNTrain.py @@ -0,0 +1,168 @@ +from argparse import ArgumentParser +import numpy as np + +parser = ArgumentParser(description="Train a Keras neural network model.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_data',type=str, required=True, + help="the training data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-train_labels',type=str, required=True, + help="the training labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-val_data',type=str, required=True, + help="the validation data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-val_labels',type=str, required=True, + help="the validation labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-nn_config',type=str, required=True, + help='file containing the neural network configuration information (look at sample_mlp.cfg)') +parser.add_argument('-context_win',type=int, required=False, default=5, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +parser.add_argument('-pretrain', nargs='?', required=False, default=False, const=True, + help='Perform layer-wise pretraining of the MLP before starting training. (Use only with dense MLPs)') +parser.add_argument('-keras_model', type=str, required=False, + help="Keras model to be trained in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-model_name', type=str, required=True, + help='Name to be assigned to the output files') +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from NNTrain import * +from utils import * +from keras.models import load_model + +def read_config(filename): + with open(filename) as f: + lines = f.readlines() + lines = filter(lambda x: x[0] != '#' and len(x) > 2, lines) + args = {} + for l in lines: + split = l.split() + if split[0] in args: + args[split[0]].append(split[1:]) + else: + args[split[0]] = split[1:] if len(split) > 1 else [] + if len(args[split[0]]) == 1: + args[split[0]] = args[split[0]][0] + return args + +def init_model(args,input_dim,output_dim, nframes): + print args + nn_type = args['type'] + + if nn_type == 'mlp': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + BN = 'batch_norm' in args, + dropout = float(args.setdefault('dropout',False)), + activation = args.setdefault('activation','sigmoid')) + if nn_type == 'resnet': + model = mlp4(input_dim, + output_dim, + int(args['n_blocks']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + dropout=float(args.setdefault('dropout',False)), + BN='batch_norm' in args, + shortcut=True) + if nn_type == 'conv' or nn_type == 'conv+resnet': + print args + assert(len(args['conv']) == len(args['pooling']) or + (type(args['conv']) == str and + type(args['pooling'] == str))) + filts = [] + filt_dims = [] + pooling = [] + max='max' + avg='avg' + if type(args['conv']) == str: + conv = [args['conv']] + pool = [args['pooling']] + else: + conv = args['conv'] + pool = args['pooling'] + for i in range(len(conv)): + filt, dims = eval(conv[i]) + filts.append(int(filt)) + filt_dims.append(dims) + + pooling.append(eval(pool[i])) + if nn_type == 'conv': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True) + else: + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True, + shortcut=True) + + if 'ctc_loss' in args: + model = ctc_model(model) + return model + +x_train = np.load(args['train_data']) +y_train = np.load(args['train_labels']) + +x_test = np.load(args['val_data']) +y_test = np.load(args['val_labels']) + +nClasses = max(map(np.max,y_train)) + 1 + +meta = {} +meta['nFrames_Train'] = sum(map(lambda x: x.shape[0], x_train)) +meta['nFrames_Dev'] = sum(map(lambda x: x.shape[0], x_test)) +meta['state_freq_train'] = np.zeros(nClasses) +for u in y_train: + for r in u: + meta['state_freq_train'][r] += 1 + +# model = mlp1(x_train[0].shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) +conf = read_config(args['nn_config']) +context_len = args['context_win'] +if args['keras_model'] != None: + model = load_model(args['keras_model']) +else: + if 'ctc_loss' in conf: + model = init_model(conf, (None,x_train[0].shape[-1],), + nClasses + 1, 2 * context_len + 1) + fg = gen_bracketed_data(for_CTC=True, n_states=nClasses) + # trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=2,ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) + else: + model = init_model(conf, (x_train[0].shape[-1] * (2 * context_len + 1),), + nClasses, 2 * context_len + 1) + fg = gen_bracketed_data(context_len=context_len) +trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=int(conf['batch_size']),ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) + +# parser.add_argument('ctldir', metavar='-ctldir',type=str, nargs=1, +# help="the directory for the control files, prepended to each file path in ctllist") +# parser.add_argument('ctllist', metavar='-ctllist',type=str,nargs=1, +# help='list of input files, each representing an utterance') +# parser.add_argument('inext', metavar='-inext', type=str, nargs=1, +# help='the extension of the control files, appended to each file path in ctllist') +# parser.add_argument('infmt', metavar='-infmt', type=str, nargs=1, +# default='yes', choices=['mswav','mfc'], +# help='format of the files in the ctllist') +# parser.add_argument('nfilts', metavar='-nfilts',type=int, nargs=1, +# required=False, help="number of features in the input files. Only used if infmt is mfc") +# parser.add_argument('stsegdir', metavar='-stsegdir',type=str,nargs=1, +# help='the directory in which forced alignments are stored') +# parser.add \ No newline at end of file diff --git a/scripts/DNN_training/sample_nn.cfg b/scripts/DNN_training/sample_nn.cfg new file mode 100644 index 00000000..851e9aba --- /dev/null +++ b/scripts/DNN_training/sample_nn.cfg @@ -0,0 +1,22 @@ +#type resnet +#width 2048 +#block_depth 3 +#n_blocks 5 + +type mlp +width 2048 +depth 3 +#dropout 0.25 +batch_norm +activation sigmoid +#ctc_loss +batch_size 512 +optimizer SGD +lr 0.001 + + +#type conv +#conv [84,(6,8)] [168,(3,4)] +#pooling None [max,(3,3),(1,1)] +#width 2048 +#depth 3 \ No newline at end of file diff --git a/scripts/DNN_training/test.csv b/scripts/DNN_training/test.csv new file mode 100644 index 00000000..e69de29b diff --git a/scripts/DNN_training/utils.py b/scripts/DNN_training/utils.py new file mode 100644 index 00000000..c9398b89 --- /dev/null +++ b/scripts/DNN_training/utils.py @@ -0,0 +1,333 @@ +import numpy as np +import struct +import matplotlib.pyplot as plt +import pylab as pl +from sys import stdout +import os +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +from scipy.sparse import coo_matrix +from sklearn.preprocessing import StandardScaler + +def dummy_loss(y_true,y_pred): + return y_pred +def decoder_dummy_loss(y_true,y_pred): + return K.zeros((1,)) +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def dense2sparse(a): + # rows,cols = a.nonzero() + # data = map(lambda i: a[rows[i],cols[i]], range(rows.shape[0])) + # return coo_matrix((data,(rows,cols)), shape=a.shape,dtype='int32') + return coo_matrix(a,shape=a.shape,dtype='int32') + +def readMFC(fname,nFeats): + data = [] + with open(fname,'rb') as f: + v = f.read(4) + head = struct.unpack('I',v)[0] + v = f.read(nFeats * 4) + while v: + frame = list(struct.unpack('%sf' % nFeats, v)) + data .append(frame) + v = f.read(nFeats * 4) + data = np.array(data) + # print data.shape, head + assert(data.shape[0] * data.shape[1] == head) + return data + +def ctc_labels(labels, blank_labels = []): + new_labels = [] + for i in range(len(labels)): + l_curr = labels[i] + if l_curr not in blank_labels: + if i == 0: + new_labels.append(l_curr) + else: + if l_curr != labels[i-1]: + new_labels.append(l_curr) + return np.array(new_labels) +def _gen_bracketed_data_2D(x,y,nFrames, + context_len,fix_length, + for_CTC): + max_len = ((np.max(nFrames) + 50)/100) * 100 #rounding off to the nearest 100 + batch_size = 2 + while 1: + pos = 0 + nClasses = np.max(y) + 1 + if for_CTC: + alldata = [] + alllabels = [] + for i in xrange(len(nFrames)): + data = x[pos:pos + nFrames[i]] + labels = y[pos:pos + nFrames[i]] + # if for_CTC: + # labels = ctc_labels(labels,blank_labels=range(18) + [108,109,110]) + # if len(labels.shape) == 1: + # labels = to_categorical(labels,num_classes=nClasses) + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if for_CTC: + if batch_size != None: + alldata.append(data) + alllabels.append(labels) + + if len(alldata) == batch_size: + alldata = np.array(alldata) + alllabels = np.array(alllabels) + if fix_length: + alldata = pad_sequences(alldata,maxlen=1000,dtype='float32',truncating='post') + alllabels = pad_sequences(alllabels,maxlen=1000,dtype='float32',value=138,truncating='post') + inputs = {'x': alldata, + 'y': alllabels, + 'x_len': np.array(map(lambda x: len(x), alldata)), + 'y_len': np.array(map(lambda x: len(x), alllabels))} + outputs = {'ctc': np.ones([batch_size])} + yield (inputs,outputs) + alldata = [] + alllabels = [] + else: + data = np.array([data]) + labels = np.array([labels]) + inputs = {'x': data, + 'y': labels, + 'x_len': [data.shape[0]], + 'y_len': [labels.shape[0]]} + outputs = {'ctc': labels} + yield (inputs,outputs) + else: + yield (data,labels) + pos += nFrames[i] + +def _gen_bracketed_data_3D(x,y,batch_size,context_len): + epoch_no = 1 + while 1: + print epoch_no + batch_data = [] + batch_labels = [] + for i in range(len(x)): + data = x[i] + labels = y[i] + if context_len != 0: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + seq_len = 0 + while seq_len < len(data) and data[seq_len].any(): + seq_len += 1 + idxs = range(seq_len) + np.random.shuffle(idxs) + for j in idxs: + if len(batch_data) < batch_size: + batch_data.append(data[j]) + batch_labels.append(labels[j]) + else: + batch_data = np.array(batch_data) + batch_labels = np.array(batch_labels) + yield(batch_data,batch_labels) + batch_data = [] + batch_labels = [] + epoch_no += 1 +def gen_ctc_data(alldata,alllabels,batch_size, n_states): + while 1: + for i in range(batch_size,alldata.shape[0]+1,batch_size): + x = alldata[i-batch_size:i] + y = alllabels[i-batch_size:i] + # .reshape(batch_size,alllabels.shape[1]) + max_len = max(map(len,x)) + x = pad_sequences(x,maxlen=max_len,dtype='float32',padding='post') + y = pad_sequences(y,maxlen=max_len,dtype='float32',padding='post',value=n_states) + x = np.array(x) + y = np.array(y) + # print x.shape, y.shape + y_len = [] + # print y + for b in y: + # # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and int(b[pad_len]) != 138: + pad_len += 1 + y_len.append(pad_len) + y_len = np.array(y_len) + x_len = [] + for b in x: + # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and b[pad_len].any(): + pad_len += 1 + x_len.append(pad_len) + x_len = np.array(x_len) + # x_len = np.array(map(lambda x: len(x), x)) + # y_len = np.array(map(lambda x: len(x), y)) + # print x.shape,y.shape,x_len,y_len + # print y.shape + # y = dense2sparse(y) + inputs = {'x': x, + 'y': y, + 'x_len': x_len, + 'y_len': y_len} + outputs = {'ctc': np.ones([batch_size]), + 'decoder': dense2sparse(y), + 'softmax': y.reshape(y.shape[0],y.shape[1],1)} + yield(inputs,outputs) + +def gen_bracketed_data(context_len=None,fix_length=False, + for_CTC=False, n_states=None): + if for_CTC: + assert(n_states != None) + return lambda x,y,batch_size: gen_ctc_data(x,y,batch_size,n_states) + else: + return lambda x,y,batch_size: _gen_bracketed_data_3D(x,y,batch_size,context_len) + # return lambda x,y,nf: _gen_bracketed_data(x,y,nf,context_len,fix_length, + # for_CTC) + +def plotFromCSV(modelName, loss_cols=[2,5], acc_cols=[1,4]): + data = np.loadtxt(modelName+'.csv',skiprows=1,delimiter=',') + epoch = data[:,[0]] + acc = data[:,[acc_cols[0]]] + loss = data[:,[loss_cols[0]]] + val_acc = data[:,[acc_cols[1]]] + val_loss = data[:,[loss_cols[1]]] + + fig, ax1 = plt.subplots() + ax1.plot(acc) + ax1.plot(val_acc) + ax2 = ax1.twinx() + ax2.plot(loss,color='r') + ax2.plot(val_loss,color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + +def writeSenScores(filename,scores,weight,offset): + n_active = scores.shape[1] + s = '' + s = """s3 +version 0.1 +mdef_file ../../en_us.cd_cont_4000/mdef +n_sen 138 +logbase 1.000100 +endhdr +""" + s += struct.pack('I',0x11223344) + + scores = np.log(scores)/np.log(1.0001) + scores *= -1 + scores -= np.min(scores,axis=1).reshape(-1,1) + # scores = scores.astype(int) + scores *= weight + scores += offset + truncateToShort = lambda x: 32676 if x > 32767 else (-32768 if x < -32768 else x) + vf = np.vectorize(truncateToShort) + scores = vf(scores) + # scores /= np.sum(scores,axis=0) + for r in scores: + # print np.argmin(r) + s += struct.pack('h',n_active) + r_str = struct.pack('%sh' % len(r), *r) + # r_str = reduce(lambda x,y: x+y,r_str) + s += r_str + with open(filename,'w') as f: + f.write(s) + +def getPredsFromArray(model,data,nFrames,filenames,res_dir,res_ext,freqs,preds_in=False,weight=0.1,offset=0): + if preds_in: + preds = data + else: + preds = model.predict(data,verbose=1,batch_size=2048) + pos = 0 + for i in range(len(nFrames)): + fname = filenames[i][:-4] + fname = reduce(lambda x,y: x+'/'+y,fname.split('/')[4:]) + stdout.write("\r%d/%d " % (i,len(filenames))) + stdout.flush() + res_file_path = res_dir+fname+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + # preds = model.predict(data[pos:pos+nFrames[i]],batch_size=nFrames[i]) + writeSenScores(res_file_path,preds[pos:pos+nFrames[i]],freqs,weight,offset) + pos += nFrames[i] + +def getPredsFromFilelist(model,filelist,file_dir,file_ext, + res_dir,res_ext,n_feat=40,context_len=None, + weight=1,offset=0, data_preproc_fn=None, + data_postproc_fn=None): + with open(filelist) as f: + files = f.readlines() + files = map(lambda x: x.strip(),files) + filepaths = map(lambda x: file_dir+x+file_ext,files) + scaler = StandardScaler(copy=False,with_std=False) + for i in range(len(filepaths)): + stdout.write("\r%d/%d " % (i,len(filepaths))) + stdout.flush() + + f = filepaths[i] + if not os.path.exists(f): + print ("\n",f) + continue + data = readMFC(f,n_feat) + data = scaler.fit_transform(data) + + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + data[0] + pad_bot = np.zeros((context_len,data.shape[1])) + data[-1] + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if data_preproc_fn != None: + _data = data_preproc_fn(data) + preds = model.predict(_data) + preds = np.squeeze(preds) + else: + preds = model.predict(data) + + if data_postproc_fn != None: + preds = data_postproc_fn(preds) + if preds.shape[0] != data.shape[0]: + preds = preds[:data.shape[0]] + # print np.sum(preds) + # print preds.shape + res_file_path = res_dir+files[i]+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + writeSenScores(res_file_path,preds,weight,offset) + +# a = dense2sparse(np.array([[1,2,3],[4,0,6]])) +# print a.shape +# print np.asarray(a,dtype=long) \ No newline at end of file From 17178ffa92e2d2a240c4a16fa8978db3fc96c93c Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Sun, 27 Aug 2017 07:25:22 -0400 Subject: [PATCH 03/12] removed .pyc --- scripts/DNN_training/NNTrain.pyc | Bin 16362 -> 0 bytes scripts/DNN_training/ctc.pyc | Bin 4534 -> 0 bytes scripts/DNN_training/genLabels.pyc | Bin 14192 -> 0 bytes scripts/DNN_training/utils.pyc | Bin 11188 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 scripts/DNN_training/NNTrain.pyc delete mode 100644 scripts/DNN_training/ctc.pyc delete mode 100644 scripts/DNN_training/genLabels.pyc delete mode 100644 scripts/DNN_training/utils.pyc diff --git a/scripts/DNN_training/NNTrain.pyc b/scripts/DNN_training/NNTrain.pyc deleted file mode 100644 index 9ae37de6c3b110642b8f7d4c3350ac02e9b1bc9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16362 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 diff --git a/scripts/DNN_training/ctc.pyc b/scripts/DNN_training/ctc.pyc deleted file mode 100644 index ed7ba087c11729143c498c3ecc49eb7694ce1f2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4534 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 UgHQJbV}mE>2TxB<>vr?M0n1+JH~;_u From a03ef0513780241fb048f6d2369d03809a2dae76 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 05:49:47 -0400 Subject: [PATCH 04/12] added perl script for training nn --- scripts/19.nn_train/nn_train.pl | 165 ++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 scripts/19.nn_train/nn_train.pl diff --git a/scripts/19.nn_train/nn_train.pl b/scripts/19.nn_train/nn_train.pl new file mode 100644 index 00000000..657a5bde --- /dev/null +++ b/scripts/19.nn_train/nn_train.pl @@ -0,0 +1,165 @@ +#!/usr/bin/perl +## ==================================================================== +## +## Copyright (c) 2006 Carnegie Mellon University. All rights +## reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions +## are met: +## +## 1. Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## +## 2. Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## +## This work was supported in part by funding from the Defense Advanced +## Research Projects Agency and the National Science Foundation of the +## United States of America, and the CMU Sphinx Speech Consortium. +## +## THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND +## ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY +## NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## ==================================================================== +## +## Author: David Huggins-Daines +## + +use strict; +use File::Copy; +use File::Basename; +use File::Spec::Functions; +use File::Path; +use File::Temp; + +use lib catdir(dirname($0), updir(), 'lib'); +use SphinxTrain::Config; +use SphinxTrain::Util; + +die "Usage: $0 \n" unless @ARGV == 2; +my ($part, $npart) = @ARGV; + +my $hmm_dir = defined($ST::CFG_FORCE_ALIGN_MODELDIR) + ? $ST::CFG_FORCE_ALIGN_MODELDIR + : "$ST::CFG_MODEL_DIR/$ST::CFG_EXPTNAME.ci_$ST::CFG_DIRLABEL"; +my $logdir = "$ST::CFG_LOG_DIR/11.force_align"; +my $outdir = "$ST::CFG_BASE_DIR/falignout"; +my $outfile = "$outdir/$ST::CFG_EXPTNAME.alignedtranscripts.$part"; + +my $statepdeffn = $ST::CFG_HMM_TYPE; # indicates the type of HMMs +my $mwfloor = 1e-8; +my $minvar = 1e-4; +my $listoffiles = $ST::CFG_LISTOFFILES; +my $transcriptfile = "$outdir/$ST::CFG_EXPTNAME.aligninput"; +my $dict = defined($ST::CFG_FORCE_ALIGN_DICTIONARY) + ? $ST::CFG_FORCE_ALIGN_DICTIONARY + : "$outdir/$ST::CFG_EXPTNAME.falign.dict"; +my $fdict = defined($ST::CFG_FORCE_ALIGN_FILLERDICT) + ? $ST::CFG_FORCE_ALIGN_FILLERDICT + : "$outdir/$ST::CFG_EXPTNAME.falign.fdict"; +my $beam = defined($ST::CFG_FORCE_ALIGN_BEAM) ? $ST::CFG_FORCE_ALIGN_BEAM : 1e-100; +my $logfile = "$logdir/${ST::CFG_EXPTNAME}.$part.falign.log"; + +# Get the number of utterances +open INPUT,"${ST::CFG_LISTOFFILES}" or die "Failed to open $ST::CFG_LISTOFFILES: $!"; +# Check control file format (determines if we add ,CTL below) +my $line = ; +my $ctlext; +if (split(" ", $line) == 1 or $line =~ m,/,) { + # Use full file path + $ctlext = ",CTL"; +} +else { + # Use utterance ID + $ctlext = ""; +} +my $ctl_counter = 1; +while () { + $ctl_counter++; +} +close INPUT; +$ctl_counter = int ($ctl_counter / $npart) if $npart; +$ctl_counter = 1 unless ($ctl_counter); + +Log("Force alignment starting: ($part of $npart) ", 'result'); + +my @phsegdir; + +if (defined($ST::CFG_STSEG_DIR)) { + push @phsegdir, (-stsegdir => "$ST::CFG_STSEG_DIR"); +} +else{ + LogError("Please specity CFG_STSEG_DIR") +} + +my $return_value = RunTool + ('sphinx3_align', $logfile, $ctl_counter, + -hmm => $hmm_dir, + -senmgau => $statepdeffn, + -mixwfloor => $mwfloor, + -varfloor => $minvar, + -dict => $dict, + -fdict => $fdict, + -ctl => $ST::CFG_LISTOFFILES, + -ctloffset => $ctl_counter * ($part-1), + -ctlcount => $ctl_counter, + -cepdir => $ST::CFG_FEATFILES_DIR, + -cepext => ".$ST::CFG_FEATFILE_EXTENSION", + -insent => $transcriptfile, + -outsent => $outfile, + @phsegdir, + -beam => $beam, + -agc => $ST::CFG_AGC, + -cmn => $ST::CFG_CMN, + -varnorm => $ST::CFG_VARNORM, + -feat => $ST::CFG_FEATURE, + -ceplen => $ST::CFG_VECTOR_LENGTH, + ); + +if ($return_value) { + LogError("Failed to run sphinx3_align"); +} +$ENV{PYTHONPATH} .= ':' . File::Spec->catdir($ST::CFG_SPHINXTRAIN_DIR, 'python'); + +my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runDatasetGen.py'), + -train_fileids => $ST::CFG_LISTOFFILES, + -val_fileids => $ST::CFG_LISTOFFILES, + -n_filts => $ST::CFG_VECTOR_LENGTH, + -feat_dir => $ST::CFG_FEATFILES_DIR, + -feat_ext => ".$ST::CFG_FEATFILE_EXTENSION", + -stseg_dir => "$ST::CFG_STSEG_DIR", + -stseg_ext => "stseg.txt", + -mdef => catfile("$hmm_dir,mdef"), + -outfile_prefix => "$ST::CFG_BASE_DIR/", + -keep_utts); + +if ($return_value) { + LogError("Failed to run runDatasetGen.py"); +} + +my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runNNTrain.py'), + -train_data => catfile("$ST::CFG_BASE_DIR","train.py"), + -train_label => catfile("$ST::CFG_BASE_DIR","train_labels.py"), + -val_data => catfile("$ST::CFG_BASE_DIR","dev.py"), + -val_labels => catfile("$ST::CFG_BASE_DIR","dev_labels.py") + -nn_config => catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'sample_nn.cfg') + -config_win => "4", + -model_name => catfile("$ST::CFG_BASE_DIR","nn","keras_mode.h5") +if ($return_value) { + LogError("Failed to run runNNTrain.py"); +} + + +exit ($return_value); From fac3badbf490b9ca27ae2384a4254081d0ef5180 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 06:57:08 -0400 Subject: [PATCH 05/12] added perl script for training nn --- scripts/19.nn_train/nn_train.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/19.nn_train/nn_train.pl b/scripts/19.nn_train/nn_train.pl index 657a5bde..53a103a1 100644 --- a/scripts/19.nn_train/nn_train.pl +++ b/scripts/19.nn_train/nn_train.pl @@ -78,7 +78,7 @@ my $line = ; my $ctlext; if (split(" ", $line) == 1 or $line =~ m,/,) { - # Use full file path + # Use full file path1 $ctlext = ",CTL"; } else { @@ -131,6 +131,10 @@ if ($return_value) { LogError("Failed to run sphinx3_align"); } + +my $return_value = RunTool("gcc -o stseg-read $ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read.c") +my $return_value = RunTool("$ST::CFG_SPHINXTRAIN_DIR/python/DNN_training/readStSeg.sh $ST::CFG_STSEG_DIR" + $ENV{PYTHONPATH} .= ':' . File::Spec->catdir($ST::CFG_SPHINXTRAIN_DIR, 'python'); my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runDatasetGen.py'), From 31c10b6fda60077a24e7b98ed29ea56cf562c5b2 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 07:00:41 -0400 Subject: [PATCH 06/12] with stseg -> asii script --- python/DNN_training/NNTrain.py | 386 +++++++++++++++++++ python/DNN_training/README.md | 137 +++++++ python/DNN_training/genLabels.py | 278 +++++++++++++ python/DNN_training/makeFileListFromTrans.py | 19 + python/DNN_training/readSen.py | 96 +++++ python/DNN_training/readStSegs.sh | 9 + python/DNN_training/requirements.txt | 67 ++++ python/DNN_training/runDatasetGen.py | 41 ++ python/DNN_training/runNNPredict.py | 44 +++ python/DNN_training/runNNTrain.py | 153 ++++++++ python/DNN_training/sample_nn.cfg | 22 ++ python/DNN_training/test.csv | 9 + python/DNN_training/test.png | Bin 0 -> 47155 bytes python/DNN_training/utils.py | 333 ++++++++++++++++ 14 files changed, 1594 insertions(+) create mode 100644 python/DNN_training/NNTrain.py create mode 100644 python/DNN_training/README.md create mode 100644 python/DNN_training/genLabels.py create mode 100644 python/DNN_training/makeFileListFromTrans.py create mode 100644 python/DNN_training/readSen.py create mode 100755 python/DNN_training/readStSegs.sh create mode 100644 python/DNN_training/requirements.txt create mode 100644 python/DNN_training/runDatasetGen.py create mode 100644 python/DNN_training/runNNPredict.py create mode 100644 python/DNN_training/runNNTrain.py create mode 100644 python/DNN_training/sample_nn.cfg create mode 100644 python/DNN_training/test.csv create mode 100644 python/DNN_training/test.png create mode 100644 python/DNN_training/utils.py diff --git a/python/DNN_training/NNTrain.py b/python/DNN_training/NNTrain.py new file mode 100644 index 00000000..b9e5d57e --- /dev/null +++ b/python/DNN_training/NNTrain.py @@ -0,0 +1,386 @@ +from keras.models import Sequential, Model +from keras.optimizers import SGD,Adagrad, Adam +from keras.layers.normalization import BatchNormalization +from keras.layers import ( + Input, + Dense, + Activation, + Dropout, + Conv1D, + Conv2D, + LocallyConnected2D, + MaxPooling2D, + AveragePooling2D, + Reshape, + Flatten, + Masking) +from keras.layers.core import Lambda +from keras.layers.merge import add, concatenate +from keras.utils import to_categorical, plot_model +from keras.models import load_model, Model +from keras.callbacks import History,ModelCheckpoint,CSVLogger,ReduceLROnPlateau +from keras import regularizers +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +import numpy as np +import matplotlib.pyplot as plt +import tensorflow as tf +from tensorflow.python.ops import math_ops +from tensorflow.python.ops import array_ops +from tfrbm import GBRBM,BBRBM +from sys import stdout +from sklearn.preprocessing import StandardScaler +import struct +from utils import * + +""" + This module provides functions for training different neural network architectures + Below is a bried summary of the different functions and their purpose, more detail + can be found below: + - mlp1: creates a MLP consisting of a number dense layers + - mlp_wCTC: creates a MLP that calculates the ctc loss during training + - mlp4: create convolutional neural networks and residual networks + - DBN_DNN: performs DBN pretraining on simple MLPs + - preTrain: performs layer-wise pretraining on simple MLPs + - trainAndTest: runs training on a provided model using the given dataset +""" + +def ctc_lambda_func(args): + import tensorflow as tf + y_pred, labels, input_length, label_length = args + label_length = K.cast(tf.squeeze(label_length), 'int32') + input_length = K.cast(tf.squeeze(input_length), 'int32') + # return K.ctc_batch_cost(labels, y_pred, input_length, label_length) + labels = K.ctc_label_dense_to_sparse(labels,label_length) + return tf.nn.ctc_loss(labels,y_pred,input_length, + preprocess_collapse_repeated=True, + ctc_merge_repeated=False, + time_major=False, + ignore_longer_outputs_than_inputs=True) + +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def decode_output_shape(inputs_shape): + y_pred_shape, seq_len_shape = inputs_shape + return (y_pred_shape[:1], None) + +def decode(args): + import tensorflow as tf + y_pred, label_len = args + label_len = K.cast(tf.squeeze(label_len), 'int32') + # ctc_labels = tf.nn.ctc_greedy_decoder(y_pred, label_len)[0][0] + # return ctc_labels + ctc_labels = K.ctc_decode(y_pred,label_len,greedy=False)[0][0] + return K.ctc_label_dense_to_sparse(ctc_labels, label_len) + +def mlp_wCTC(input_dim,output_dim,depth,width,BN=False): + print locals() + x = Input(name='x', shape=(1000,input_dim)) + h = x + h = Masking()(h) + for i in range(depth): + h = Dense(width)(h) + if BN: + h = BatchNormalization()(h) + h = Activation('sigmoid')(h) + out = Dense(output_dim,name='out')(h) + softmax = Activation('softmax', name='softmax')(out) + # a = 1.0507 * 1.67326 + # b = -1 + # # out = Lambda(lambda x : a * K.pow(x,3) + b)(h) + # out = Lambda(lambda x: a * K.exp(x) + b, name='out')(h) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def ctc_model(model): + x = model.get_layer(name='x').input + + out = model.get_layer(name='out').output + softmax = Activation('softmax', name='softmax')(out) + y = Input(name='y',shape=[None,],dtype='int32') + x_len = Input(name='x_len', shape=[1],dtype='int32') + y_len = Input(name='y_len', shape=[1],dtype='int32') + + dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) + # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) + + loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) + model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) + + sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) + opt = Adam(lr=0.0001, clipnorm=5) + model.compile(loss={'ctc': dummy_loss, + 'decoder': decoder_dummy_loss, + 'softmax': 'sparse_categorical_crossentropy'}, + optimizer=opt, + metrics={'decoder': ler, + 'softmax': 'accuracy'}, + loss_weights=[1,0,0]) + return model +def _bn_act(input,activation='relu'): + """Helper to build a BN -> relu block + """ + norm = BatchNormalization()(input) + return Activation(activation)(norm) + +def make_dense_res_block(inp, size, width, drop=False,BN=False,regularize=False): + x = inp + for i in range(size): + x = Dense(width, + kernel_regularizer=regularizers.l2(0.05) if regularize else None)(x) + if i < size - 1: + if drop: + x = Dropout(0.15)(x) + if BN: + x = _bn_relu(x) + return x + +def mlp4(input_dim,output_dim,nBlocks,width, n_frames, block_depth=1, + n_filts=[84], filt_dims=[(11,8)], pooling=[['max',(6,6),(2,2)]], + block_width=None, dropout=False, BN=False, activation='relu', + parallelize=False, conv=False, regularize=False, + exp_boost=False, quad_boost=False, shortcut=False, + opt='adam', lr=0.001): + + print locals() + if block_width == None: + block_width = width + inp = Input(shape=input_dim, name='x') + x = inp + if conv: + x = Reshape((n_frames,input_dim/n_frames,1))(x) + for i in range(len(n_filts)): + print i + + x = LocallyConnected2D(n_filts[i],filt_dims[i], + padding='valid')(x) + x = _bn_act(x,activation=activation) + if pooling[i] != None: + pooling_type, win_size, stride = pooling[i] + if pooling_type == 'max': + x = MaxPooling2D(win_size,strides=stride,padding='same')(x) + if pooling_type == 'avg': + x = AveragePooling2D(win_size,strides=stride,padding='same')(x) + x = Flatten()(x) + if block_width != width: + x = Dense(block_width)(x) + for i in range(nBlocks): + y = make_dense_res_block(x,block_depth,block_width,BN=BN,drop=dropout,regularize=regularize) + if shortcut: + x = add([x,y]) + else: + x = y + if dropout: + x = Dropout(dropout)(x) + if BN: + x = _bn_act(x,activation=activation) + else: + x = Activation(activation)(x) + + if exp_boost: + x = Dense(output_dim)(x) + z = Lambda(lambda x : K.exp(x))(x) + if quad_boost: + x = Dense(output_dim)(x) + a = 0.001 + b = 0.4 + z = Lambda(lambda x : a * K.pow(x,3) + b)(x) + else: + z = Dense(output_dim, name='out')(x) + z = Activation('softmax', name='softmax')(z) + model = Model(inputs=inp, outputs=z) + if parallelize: + model = make_parallel(model, len(CUDA_VISIBLE_DEVICES.split(','))) + # opt = Adam(lr=25/(np.sqrt(width * output_dim))) + if opt == 'sgd': + opt = SGD + if opt == 'adam': + opt = Adam + if opt == 'adagrad': + opt = Adagrad + opt = opt(lr=lr) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model + +def resnet_wrapper(input_dim,output_dim,depth,width,reshape_layer): + builder = resnet.ResnetBuilder() + model = builder.build_resnet_18(input_dim, output_dim,reshape_layer) + x = model.get_layer(name='flatten_1').get_output_at(-1) + for i in range(depth): + x = Dense(width,activation='relu')(x) + softmax = Dense(output_dim,activation='softmax')(x) + model = Model(inputs=model.inputs, outputs=softmax) + opt = Adam(lr=10/np.sqrt(input_dim * output_dim)) + # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) + model.compile(optimizer=opt, + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + return model +def DBN_DNN(inp,nClasses,depth,width,batch_size=2048): + RBMs = [] + weights = [] + bias = [] + # batch_size = inp.shape + nEpoches = 5 + if len(inp.shape) == 3: + inp = inp.reshape((inp.shape[0] * inp.shape[1],inp.shape[2])) + sigma = np.std(inp) + # sigma = 1 + rbm = GBRBM(n_visible=inp.shape[-1],n_hidden=width,learning_rate=0.002, momentum=0.90, use_tqdm=True,sample_visible=True,sigma=sigma) + rbm.fit(inp,n_epoches=15,batch_size=batch_size,shuffle=True) + RBMs.append(rbm) + for i in range(depth - 1): + print 'training DBN layer', i + rbm = BBRBM(n_visible=width,n_hidden=width,learning_rate=0.02, momentum=0.90, use_tqdm=True) + for e in range(nEpoches): + batch_size *= 1 + (e*0.5) + n_batches = (inp.shape[-2] / batch_size) + (1 if inp.shape[-2]%batch_size != 0 else 0) + for j in range(n_batches): + stdout.write("\r%d batch no %d/%d epoch no %d/%d" % (int(time.time()),j+1,n_batches,e,nEpoches)) + stdout.flush() + b = np.array(inp[j*batch_size:min((j+1)*batch_size, inp.shape[0])]) + for r in RBMs: + b = r.transform(b) + rbm.partial_fit(b) + RBMs.append(rbm) + for r in RBMs: + (W,_,Bh) = r.get_weights() + weights.append(W) + bias.append(Bh) + model = mlp1(x_train.shape[1],nClasses,depth-1,width) + print len(weights), len(model.layers) + assert len(weights) == len(model.layers) - 1 + for i in range(len(weights)): + W = [weights[i],bias[i]] + model.layers[i].set_weights(W) + return model +# def gen_data(active): + + +def preTrain(model,modelName,x_train,y_train,meta,skip_layers=[],outEqIn=False,fit_generator=None): + print model.summary() + layers = model.layers + output = layers[-1] + outdim = output.output_shape[-1] + for i in range(len(layers) - 1): + if i in skip_layers: + print 'skipping layer ',i + continue + if len(model.layers[i].get_weights()) == 0: + print 'skipping layer ',i + continue + last = model.layers[i].get_output_at(-1) + if outEqIn: + preds = Dense(outdim)(last) + else: + preds = Dense(outdim,activation='softmax')(last) + model_new = Model(model.input,preds) + for j in range(len(model_new.layers) - 2): + print "untrainable layer ",j + model_new.layers[j].trainable=False + model_new.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + print model_new.summary() + batch_size = 2048 + if fit_generator == None: + model_new.fit(x_train,y_train,epochs=1,batch_size=2048) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=3) + # model.fit_generator(gen_bracketed_data(x_train,y_train,meta['framePos_Train'],4), + # steps_per_epoch=len(meta['framePos_Train']), epochs=3, + # callbacks=[ModelCheckpoint('%s_CP.h5' % modelName,monitor='loss',mode='min')]) + # model.fit_generator(gen_data(x_train,y_train,batch_size), + # steps_per_epoch = x_train.shape[0] / batch_size, + # epochs = 1) + model.layers[i].set_weights(model_new.layers[-2].get_weights()) + for l in model.layers: + l.trainable = True + return model + +def trainNtest(model,x_train,y_train,x_test,y_test,meta, + modelName,testOnly=False,pretrain=False, batch_size=512, + init_epoch=0, fit_generator=None, ctc_train=False, n_epochs=50): + print 'TRAINING MODEL:',modelName + if not testOnly: + if pretrain: + print 'pretraining model...' + model = preTrain(model,modelName,x_train,y_train,meta,fit_generator=fit_generator) + if ctc_train: + model = ctc_model(model) + print model.summary() + print 'starting fit...' + callback_arr = [ModelCheckpoint('%s_CP.h5' % modelName,save_best_only=True,verbose=1), + ReduceLROnPlateau(patience=5,factor=0.5,min_lr=10**(-6), verbose=1), + CSVLogger(modelName+'.csv',append=True)] + + if fit_generator == None: + history = model.fit(x_train,y_train,epochs=n_epochs,batch_size=batch_size, + initial_epoch=init_epoch, + validation_data=(x_test,y_test), + callbacks=callback_arr) + else: + history = model.fit_generator(fit_generator(x_train,y_train,batch_size), + steps_per_epoch= (meta['nFrames_Train'])/batch_size, epochs=n_epochs, + validation_data=fit_generator(x_test,y_test,batch_size), + validation_steps = (meta['nFrames_Dev']) / batch_size, + callbacks=callback_arr) + model = Model(inputs=[model.get_layer(name='x').input], + outputs=[model.get_layer(name='softmax').output]) + print model.summary() + model.compile(loss='sparse_categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + print 'saving model...' + model.save(modelName+'.h5') + # model.save_weights(modelName+'_W.h5') + print(history.history.keys()) + print history.history['lr'] + print 'plotting graphs...' + # summarize history for accuracy + fig, ax1 = plt.subplots() + ax1.plot(history.history['acc']) + ax1.plot(history.history['val_acc']) + ax2 = ax1.twinx() + ax2.plot(history.history['loss'],color='r') + ax2.plot(history.history['val_loss'],color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + else: + model = load_model(modelName) + print 'scoring...' + score = model.evaluate_generator(gen_bracketed_data(x_test,y_test,meta['framePos_Dev'],4), + len(meta['framePos_Dev'])) + print score diff --git a/python/DNN_training/README.md b/python/DNN_training/README.md new file mode 100644 index 00000000..3a7d668a --- /dev/null +++ b/python/DNN_training/README.md @@ -0,0 +1,137 @@ +# DNNs For ASR +The work is part of a Google Summer of Code project, the goal of which was to integrate DNNs with CMUSphinx. This particular repository contains some convenient scripts that wrap Keras code and allow for easy training of DNNs. +## Getting Started +Start by cloning the repository. +### Prerequisites +The required python libraries available from pypi are in the requirements.txt file. Install them by running: +``` +pip install -r requirements.txt +``` +Additional libraries not available from pypi: +- tfrbm- for DBN-DNN pretraining. + - available at https://github.com/meownoid/tensorfow-rbm +## Getting Started +Since the project is primarily intended to be used with PocketSphinx the file formats for feature files, state-segmentation output files and the prediction files are in sphinx format. +### Feature File Format +``` +N: number of frames +M: dimensions of the feature vector +N*M (4 bytes) +Frame 1: f_1...f_M (4*M bytes) +. +. +. +Frame N: f_1,...,f_M (4*M bytes) +``` +Look at readMFC in utils.py +### state-segmentation files +format for each frame: +``` + 2 2 2 1 4 bytes +st1 [st2 st3] pos scr +``` +### Prediction output +format for each frame: +``` +N: number of states +N (2 bytes) +scr_1...scr_N (2*N bytes) +``` +### Wrapper Scripts +``` +runDatasetGen.py -train_fileids -val_fileids [-test_fileids] -n_filts -feat_dir -feat_ext -stseg_dir -stseg_ext -mdef [-outfile_prefix] [-keep_utts] +``` +runDatasetGen takes feature files and state-segmentation files stored in sphinx format along with the definition file of the GMM-HMM model to generate a set of numpy arrays that form a python readable dataset. +runDatasetGen writes the following files in the directory it was called in: +- Data Files + - _train.npy + - _dev.npy + - _test.npy +- label files + - _train_label.npy + - _dev_label.npy + - _test_label.npy +- metadata file + - _meta.npz + +The metadata file is a zipped collection of arrays with the follwing keys: +- File names for utterances + - filenames_Train + - filenames_Dev + - filenames_Test +- Number of frames per utterance (useful if -keep_utts is not set) + - framePos_Train + - framePos_Dev + - framePos_Test +- State Frequencies (useful for scaling in some cases) + - state_freq_Train + - state_freq_Dev + - state_freq_Test +``` +runNNTrain.py -train_data -train_labels -val_data -val_labels -nn_config [-context_win] [-cuda_device_id] [-pretrain] [-keras_model] -model_name +``` +runNNTrain takes the training and validation data files (as generated by runDatasetGen) and trains a neural network on them. +The architecture and parameters of the neural network is defined in a text file. Currently this script supports 4 network types: +- MLP (mlp) +- Convolutional Neural Network (conv) +- MLP with short cut connections (resnet) +- Convolutional Network with residual connections in the fully connected layers (conv + resnet) +See sample_nn.cfg for an example. +The format for the configuration file consists of ```param``` and ```value``` pairs +if value has multiple elemets (represented by ... below) they should be separated by spaces. +Params and possible values: +- **type** mlp, conv, resnet, conv+resnet +- **width** any integer value +- **depth** any integer value +- **dropout** float in (0,1) +- **batch_norm** - +- **activation** sigmoid, hard_sigmoid, elu, relu, selu, tanh, softplus, softsign, softmax, linear +- **optimizer** sgd, adam, adagrad +- **lr** float in (0,1) +- **batch_size** any integer value +- **ctc_loss** - +- for type = conv and type = conv+resnet + - **conv** [n_filters, filter_window]... + - **pooling** None, [max/avg, window_size, stride_size] +- for type = resnet and type = conv+resnet + - **block_depth** any integer value + - **n_blocks** any integer value +``` +runNNPredict -keras_model -ctldir -inext -outdir -outext -nfilts [-acoustic_weight] [-context_win] [-cuda_device_id] +``` +runNNPredict takes a keras model and a list of feature files to generate predictions. The predictions are stored as binary files in sphinx readable format (defined above). +Please ensure that the dimensionality of the feature vectors matches nfilts and the context window is the same as that for which the model was trained. +The acoustic_weight is used to scale the output scores. This is required because if the scores are passed through a GMM-GMM decoder like PocketSphinx are too small or too large then the decoding performance suffers. One way of estimating this weight is to generate scores from the GMM-HMM decoder being used, fit a linear regression between the GMM-HMM scores and the NN-scores and use the coefficient as the weight. +``` +readSen.py -gmm_score_dir -gmm_ctllist -nn_score_dir -nn_ctllist [-gmm_ext] [-nn_ext] +``` +readSen takes scores (stored in sphinx readable binary files) obtained from a GMM-HMM decoder and a NN, and fit a regression to them. + +## Example workflow with CMUSphinx +- Feature extraction using sphinx_fe: + ``` + sphinx_fe -argfile ../../en_us.ci_cont/feat.params -c etc/wsj0_train.fileids -di wav/ -do feat_ci_mls -mswav yes -eo mls -ei wav -ofmt sphinx -logspec yes + ``` +- State-segmentation using sphinx3_align + ``` + sphinx3_align -hmm ../../en_us.ci_cont/ -dict etc/cmudict.0.6d.wsj0 -ctl etc/wsj0_train.fileids -cepdir feat_ci_mls/ -cepext .mfc -insent etc/wsj0.transcription -outsent wsj0.out -stsegdir stateseg_ci_dir/ -cmn batch + ``` +- Generate dataset using runDatasetGen.py +- Train NN using runNNtrain.py +### EITHER +- Generate predictions from the NN using runNNPredct.py +- Generate predictions from PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir feat_ci_mfc/ -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -senlogdir sendump_ci/ -compallsen yes -bestpath no -fwdflat no -remove_noise no -remove_silence no -logbase 1.0001 -pl_window 0 +``` +- Compute the acoustic weight using readSen.py +- Decode the scaled NN predictions with PocketSphinx +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir senscores/ -cepext .sen -hyp NN2.hyp -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -compallsen yes -logbase 1.0001 -pl_window 0 -senin yes +``` +### OR +- predict and decode with the PocketSphinx DNN decoder by passing your keras model to it and setting the other required parameters. +``` +pocketsphinx_batch -hmm ../../en_us.ci_cont_2/ -lm ../../tcb20onp.Z.DMP -cepdir feat_ci_dev_mls/ -cmn batch -hyp test_ci_2-2.hyp -ctl etc/wsj0_dev.fileids -dict etc/cmudict.0.6d.wsj0 -nnmgau ../../GSOC/bestModels/best_CI.h5 -pl_window 0 -ceplen 25 -ncep 25 -cudaid 2 +``` +NOTE: If you are using the PocketSphinx DNN decoder please ensure that you select the appropriate feature type for your model. You need to be extra careful if you are training models that process the data utterance-wise instead of frame-wise since the default behaviour of Pocketsphinx is to perform frame-wise classification. diff --git a/python/DNN_training/genLabels.py b/python/DNN_training/genLabels.py new file mode 100644 index 00000000..7517bef3 --- /dev/null +++ b/python/DNN_training/genLabels.py @@ -0,0 +1,278 @@ +import numpy as np +import os +import sys +from sklearn.preprocessing import StandardScaler +import utils +from keras.preprocessing.sequence import pad_sequences +import librosa +""" + TODO: Test with different model and file naming scheme +""" +def ping(): + curr_time = int(time.time()) + while done == 0: + if (int(time.time()) != curr_time): + curr_time = int(time.time()) + sys.stdout.write('.') + sys.stdout.flush() + + +def read_sen_labels_from_mdef(fname): + labels = np.loadtxt(fname,dtype=str,skiprows=10,usecols=(0,1,2,3,6,7,8)) + labels = map(lambda x: + [reduce(lambda a,b: a+' '+b, + filter(lambda y: y != '-', x[:4]))] + list(x[4:]), labels) + + phone2state = {} + for r in labels: + phone2state[r[0]] = map(int, r[1:]) + return phone2state + +def frame2state(fname, phone2state): + with open(fname,'r') as f: + lines = f.readlines()[2:] + lines = map(lambda x: x.split()[2:], lines) + + lines = map(lambda x: [x[0], reduce(lambda a,b: a+' '+b,x[1:])],lines) + for l in lines: + if l[1] not in phone2state: + l[1] = l[1].split()[0] + states = map(lambda x: phone2state[x[1]][int(x[0])], lines) + return (list(states)) + +def loadDict(filename): + def mySplit(line): + line = line.split() + for i in range(1,len(line)): + line[i] = "{0}1 {0}2 {0}3".format(line[i]) + line = [line[0], reduce(lambda x,y: x+ ' ' +y, line[1:])] + return line + with open(filename) as f: + d = f.readlines() + d = map(lambda x: x.split(),d) + myDict = {} + for r in d: + myDict[r[0]] = r[1:] + return myDict + +def loadTrans(trans_file,pDict): + trans = {} + with open(trans_file) as f: + lines = f.readlines() + for line in lines: + line = line.split() + fname = line[-1][1:-1] + labels = map(lambda x: pDict.setdefault(x,-1), line[:-1]) + labels = filter(lambda x: x!=-1, labels) + if labels == []: + continue + labels = reduce(lambda x,y: x + y, labels) + trans[fname] = labels + return trans + +def trans2labels(trans,phone2state): + d = {} + for u in trans: + labels = trans[u] + labels = map(lambda x: phone2state[x], labels) + labels = reduce(lambda x,y: x + y, labels) + d[u] = labels + return d + +def genDataset(train_flist, dev_flist, test_flist, n_feats, + feat_path, feat_ext, stseg_path, stseg_ext, mdef_fname, + outfile_prefix, context_len=None, + keep_utts=False, ctc_labels=False, pDict_file=None, + trans_file=None, make_graph=False,cqt=False, + max_len=None,n_deltas=0,pad=False): + assert(os.path.exists(stseg_path)) + train_files = np.loadtxt(train_flist,dtype=str) + dev_files = np.loadtxt(dev_flist,dtype=str) + if test_flist != None: + test_files = np.loadtxt(test_flist,dtype=str) + else: + test_files = [] + phone2state = read_sen_labels_from_mdef(mdef_fname) + + stseg_files_train = map(lambda x: x.split('/')[-1]+stseg_ext,train_files) + stseg_files_test = map(lambda x: x.split('/')[-1]+stseg_ext,test_files) + stseg_files_dev = map(lambda x: x.split('/')[-1]+stseg_ext,dev_files) + stseg_files_train = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_train) + stseg_files_test = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_test) + stseg_files_dev = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_dev) + + stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test + print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) + + train_files = map(lambda x: feat_path+x+feat_ext,train_files) + dev_files = map(lambda x: feat_path+x+feat_ext,dev_files) + test_files = map(lambda x: feat_path+x+feat_ext,test_files) + + X_Train = [] + Y_Train = [] + X_Test = [] + Y_Test = [] + X_Dev = [] + Y_Dev = [] + framePos_Train = [] + framePos_Test = [] + framePos_Dev = [] + filenames_Train = [] + filenames_Test = [] + filenames_Dev = [] + active_states_Train = [] + active_states_Test = [] + active_states_Dev = [] + # allData = [] + # allLabels = [] + pos = 0 + scaler = StandardScaler(copy=False,with_std=False) + n_states = np.max(phone2state.values())+1 + print n_states + state_freq_Train = [0]*n_states + state_freq_Dev = [0]*n_states + state_freq_Test = [0]*n_states + + + + for i in range(len(stseg_files)): + if i < len(stseg_files_train): + # print '\n train' + frames = framePos_Train + allData = X_Train + allLabels = Y_Train + filenames = filenames_Train + state_freq = state_freq_Train + files = train_files + active_state = active_states_Train + elif i < len(stseg_files_train) + len(stseg_files_dev): + # print '\n dev' + frames = framePos_Dev + allData = X_Dev + allLabels = Y_Dev + filenames = filenames_Dev + state_freq = state_freq_Dev + files = dev_files + active_state = active_states_Dev + else: + # print '\n test' + frames = framePos_Test + allData = X_Test + allLabels = Y_Test + filenames = filenames_Test + state_freq = state_freq_Test + files = test_files + active_state = active_states_Test + + sys.stdout.write("\r%d/%d " % (i,len(stseg_files))) + sys.stdout.flush() + f = stseg_files[i] + + [data_file] = filter(lambda x: f[:-9] in x, files) + if cqt: + y,fs=librosa.load(data_file,sr=None) + data = np.absolute(librosa.cqt(y,sr=fs,window=np.hamming, + hop_length=160, n_bins=64, bins_per_octave=32).T) + # print data.shape + else: + data = utils.readMFC(data_file,n_feats).astype('float32') + data = scaler.fit_transform(data) + labels = frame2state(stseg_path + f, phone2state) + nFrames = min(len(labels), data.shape[0]) + sys.stdout.write('(%d,%d) (%d,)' % (data.shape + np.array(labels).shape)) + data = data[:nFrames] + labels = labels[:nFrames] + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if n_deltas > 0: + pad_top = np.zeros((n_deltas,data.shape[1])) + pad_bot = np.zeros((n_deltas,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + data = [] + for j in range(n_deltas,len(padded_data) - n_deltas): + delta_top = padded_data - padded_data[j - n_deltas:j] + delta_bot = padded_data - padded_data[j:j + n_deltas] + new_row = delta_top + padded_data + delta_bot + data.append(new_row) + for l in labels: + state_freq[l] += 1 + filenames.append(data_file) + frames.append(nFrames) + if keep_utts: + allData.append(data) + allLabels.append(np.array(labels)) + else: + allData += list(data) + allLabels += list(labels) + pos += nFrames + if not ctc_labels: + assert(len(allLabels) == len(allData)) + # print allData + print len(allData), len(allLabels) + if max_len == None: + max_len = 100 * ((max(map(len,X_Train)) + 99)/ 100) + print 'max_len', max_len + if keep_utts and pad: + X_Train = pad_sequences(X_Train,maxlen=max_len,dtype='float32',padding='post') + Y_Train = pad_sequences(Y_Train,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Train = Y_Train.reshape(Y_Train.shape[0],Y_Train.shape[1],1) + X_Dev = pad_sequences(X_Dev,maxlen=max_len,dtype='float32',padding='post') + Y_Dev = pad_sequences(Y_Dev,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Dev = Y_Dev.reshape(Y_Dev.shape[0],Y_Dev.shape[1],1) + X_Test = pad_sequences(X_Test,maxlen=max_len,dtype='float32',padding='post') + Y_Test = pad_sequences(Y_Test,maxlen=max_len,dtype='float32',padding='post',value=n_states) + Y_Test = Y_Test.reshape(Y_Test.shape[0],Y_Test.shape[1],1) + # np.savez('wsj0_phonelabels_NFrames',NFrames_Train=NFrames_Train,NFrames_Test=NFrames_Test) + # t = threading.Thread(target=ping) + # t.start() + if context_len != None: + np.save(outfile_prefix + 'bracketed_train.npy',X_Train) + np.save(outfile_prefix + 'bracketed_dev.npy',X_Dev) + np.save(outfile_prefix + 'bracketed_train_labels.npy',Y_Train) + np.save(outfile_prefix + 'bracketed_dev_labels.npy',Y_Dev) + if len(X_Test) != 0: + np.save(outfile_prefix + 'bracketed_test.npy',X_Test) + np.save(outfile_prefix + 'bracketed_test_labels.npy',Y_Test) + np.savez(outfile_prefix + 'bracketed_meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + else: + np.save(outfile_prefix + 'train.npy',X_Train) + np.save(outfile_prefix + 'dev.npy',X_Dev) + np.save(outfile_prefix + 'train_labels.npy',Y_Train) + np.save(outfile_prefix + 'dev_labels.npy',Y_Dev) + if len(X_Test) != 0: + np.save(outfile_prefix + 'test.npy',X_Test) + np.save(outfile_prefix + 'test_labels.npy',Y_Test) + np.savez(outfile_prefix + 'meta.npz',framePos_Train=framePos_Train, + framePos_Test=framePos_Test, + framePos_Dev=framePos_Dev, + filenames_Train=filenames_Train, + filenames_Dev=filenames_Dev, + filenames_Test=filenames_Test, + state_freq_Train=state_freq_Train, + state_freq_Dev=state_freq_Dev, + state_freq_Test=state_freq_Test) + +if __name__ == '__main__': + genDataset('../wsj/wsj0/etc/wsj0_train.fileids','../wsj/wsj0/etc/wsj0_dev.fileids','../wsj/wsj0/etc/wsj0_test.fileids',40,'../wsj/wsj0/feat_cd_mls/','../wsj/wsj0/stateseg_ci_dir/','../en_us.ci_cont/mdef', + keep_utts=True, context_len=None, cqt=True, + trans_file='../wsj/wsj0/etc/wsj0.transcription', + pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') \ No newline at end of file diff --git a/python/DNN_training/makeFileListFromTrans.py b/python/DNN_training/makeFileListFromTrans.py new file mode 100644 index 00000000..5de9ac1c --- /dev/null +++ b/python/DNN_training/makeFileListFromTrans.py @@ -0,0 +1,19 @@ +import numpy as np +def getFileListFromTran(trans,outFile): + with open(trans,'r') as f: + lines = f.readlines() + lines = map(lambda x: x.strip(), lines) + files = map(lambda x: x.split('(')[-1][:-1], lines) + np.savetxt(outFile,files,fmt='%s') + +def fixTran(trans): + with open(trans,'r') as f: + lines = f.readlines() + lines = map(lambda x: x.strip(), lines) + lines = map(lambda x: x.split('('), lines) + for l in lines: + l[-1] = l[-1].split('/')[-1] + lines = map(lambda x: reduce(lambda a,b: a+'('+b,x),lines) + np.savetxt(trans+'2',lines,fmt='%s') +# getFileListFromTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans", "../wsj/wsj0/wsj0.filelist") +fixTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans") \ No newline at end of file diff --git a/python/DNN_training/readSen.py b/python/DNN_training/readSen.py new file mode 100644 index 00000000..b47b38a8 --- /dev/null +++ b/python/DNN_training/readSen.py @@ -0,0 +1,96 @@ +import os +import struct +import numpy as np +from sklearn.linear_model import LinearRegression +from argparse import ArgumentParser + +def readSen(fname, print_most_prob_sen=False): + print fname + f = open(fname,'rb') + s = '' + while 'endhdr\n' not in s: + v = f.read(1) + s += struct.unpack('s',v)[0] + magic_num = struct.unpack('I',f.read(4))[0] + assert magic_num == 0x11223344 + count = 0 + data = [] + while v: + v = f.read(2) + if not v: + continue + n_active = struct.unpack('h',v)[0] + # print n_active + assert n_active == 138 + + v = f.read(2*n_active) + scores = list(struct.unpack('%sh' % n_active, v)) + # print np.argmax(scores) + count += 1 + data += scores + print count + return np.array(data) + +if __name__=='__main__': + parser = ArgumentParser(description="""Given two sets of sen files fits a regression to them and returns the coefficient and the intercept. + Useful in determining the appropriate acoustic weight to scale the outputs of the NN by. Improperly + scaled output perform much worse than appropriatly scaled outputs""", + usage='%(prog)s [options] \nUse --help for option list') + parser.add_argument('-gmm_score_dir',type=str, required=True, + help="The directory where the sen files generated by GMM-HMM decoder are stored. Preppended to file paths in gmm_ctllist") + parser.add_argument('-gmm_ctllist', type=str, required=True, + help='List of all the sen files generated by the GMM-HMM decoder') + parser.add_argument('-nn_score_dir',type=str, required=True, + help="The directory where the sen files generated by a ANN are stored. Preppended to file paths in gmm_ctllist") + parser.add_argument('-nn_ctllist', type=str, required=True, + help='List of all the sen files generated by the ANN') + parser.add_argument('-gmm_ext', type=str, required=False, default='', + help='the file extension applied to all the files in gmm_ctllist') + parser.add_argument('-nn_ext', type=str, required=False, default='', + help='the file extension applied to all the files in nn_ctllist') + args = vars(parser.parse_args()) + # readSen('../wsj/wsj0/senscores/11_14_1/wsj0/si_et_20/440/440c0401.wv1.flac.sen') + ndx_list = map(lambda x: args['nn_score_dir']+x+args['nn_ext'], np.loadtxt(args['nn_ctllist'],dtype=str)) + file_list = map(lambda x: args['gmm_score_dir']+x+args['gmm_ext'], np.loadtxt(args['gmm_ctllist'],dtype=str)) + # file_list = map(lambda x: '../wsj/wsj0/sendump_dev_ci/' + x, os.listdir('../wsj/wsj0/sendump_dev_ci/')) + # file_list.sort() + # file_list = file_list[:-1] + # ndx_list = ['../wsj/wsj0/single_dev_NN/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] + # file_list = ['../wsj/wsj0/single_dev/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] + x = [] + y = [] + for i in range(len(file_list)): + if i >= 0: + if os.path.exists(ndx_list[i]): + print i,ndx_list[i], file_list[i] + _y = list(readSen(ndx_list[i])) + _x = list(readSen(file_list[i])) + if len(_x) != len(_y): + continue + y += _y + x += _x + frame_len = min(len(x),len(y)) + # x = x[:frame_len] + # y = y[:frame_len] + print len(x),len(y), len(x)/138, len(y)/138 + assert len(x) == len(y) + else: + continue + else: + print i,ndx_list[i+1], file_list[i] + y += list(readSen(ndx_list[i+1])) + x += list(readSen(file_list[i])) + x = np.array(x).reshape(-1,1) + y = np.array(y).reshape(-1,1) + # print x.shape, y.shape + data = np.concatenate((x,y),axis=1) + # np.save('data4regression.npy',data) + + # data = np.load('data4regression.npy') + lreg = LinearRegression(normalize=True,n_jobs=-1) + lreg.fit(data[:,[1]],data[:,[0]]) + print "coefficient: %f\t\tintercept: %f" % (lreg.coef_, lreg.intercept_) + + # vs = np.std(data[:,[1]]) + # va = np.std(data[:,[0]]) + # print va/vs diff --git a/python/DNN_training/readStSegs.sh b/python/DNN_training/readStSegs.sh new file mode 100755 index 00000000..44d98e49 --- /dev/null +++ b/python/DNN_training/readStSegs.sh @@ -0,0 +1,9 @@ +stseg_fldr="$1" +echo $stseg_fldr +files=$(find "$stseg_fldr/" -name "*.stseg") +for f in $files +do + echo "CONVERTING: "$f + cat $f | ../../src/libs/libcommon/.libs/stseg-read.o > $f.txt + break +done diff --git a/python/DNN_training/requirements.txt b/python/DNN_training/requirements.txt new file mode 100644 index 00000000..c2d0f232 --- /dev/null +++ b/python/DNN_training/requirements.txt @@ -0,0 +1,67 @@ +appdirs==1.4.3 +audioread==2.1.5 +backports.weakref==1.0rc1 +bleach==1.5.0 +cycler==0.10.0 +Cython==0.25.2 +daemonize==2.4.7 +decorator==4.0.6 +editdistance==0.3.1 +funcsigs==1.0.2 +functools32==3.2.3.post2 +graphviz==0.7.1 +guppy==0.1.10 +h5py==2.7.0 +htk-io==0.5 +html5lib==0.9999999 +ipython==2.4.1 +joblib==0.11 +Keras==2.0.6 +Lasagne==0.2.dev1 +librosa==0.5.1 +Mako==1.0.6 +Markdown==2.2.0 +MarkupSafe==1.0 +matplotlib==2.0.2 +memory-profiler==0.47 +mock==2.0.0 +nose==1.3.7 +numpy==1.13.1 +packaging==16.8 +pbr==3.1.1 +pexpect==4.0.1 +posix-ipc==1.0.0 +protobuf==3.3.0 +ptyprocess==0.5 +py==1.4.33 +pycurl==7.43.0 +pydot==1.2.3 +pydot-ng==1.0.0 +pyfst==0.2.3 +pygpu==0.6.5 +pyliblzma==0.5.3 +pyparsing==2.2.0 +pysqlite==1.0.1 +pytest==3.0.7 +python-apt==1.1.0b1 +python-dateutil==2.6.0 +python-speech-features==0.5 +pytools==2016.2.6 +pytz==2017.2 +PyYAML==3.12 +resampy==0.1.5 +rpm-python==4.12.0.1 +scikit-learn==0.18.1 +scipy==0.19.1 +simplegeneric==0.8.1 +six==1.10.0 +subprocess32==3.2.7 +tensorflow-gpu==1.2.0 +tfrbm==0.0.2 +Theano==0.9.0 +tkinter==0.2.0 +tqdm==4.14.0 +urlgrabber==3.9.1 +virtualenv==15.0.1 +Werkzeug==0.12.2 +yum-metadata-parser==1.1.4 diff --git a/python/DNN_training/runDatasetGen.py b/python/DNN_training/runDatasetGen.py new file mode 100644 index 00000000..d44d47b6 --- /dev/null +++ b/python/DNN_training/runDatasetGen.py @@ -0,0 +1,41 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate numpy array from features and alignments produced by Sphinx", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_fileids', type=str, required=True, + help="list of training files") +parser.add_argument('-val_fileids',type=str,required=True, + help='list of validation files') +parser.add_argument('-test_fileids',type=str,required=False, + help='list of test files') +parser.add_argument('-nfilts',type=int,required=True, + help='number of filters used for extracting features. (The dimensionality of the feature vector)') +parser.add_argument('-feat_dir', type=str, required=True, + help='the directory where feature files are stored (prepended to filepaths in the train, val and test filelists when looking for features)') +parser.add_argument('-feat_ext',type=str,required=True, + help='extension to be appended to each file path when looking for feature files') +parser.add_argument('-stseg_dir',type=str,required=True, + help='directory where the state-segmentation for each feature file is stored (prepended to filepaths in the train, val and test filelists when looking for labels)') +parser.add_argument('-stseg_ext',type=str,required=True, + help='extension to be appended to each file path when looking for state-segmentation files') +parser.add_argument('-mdef',type=str,required=True, + help='path to the mdef file for the Sphinx model. Needed to map phones/triphones in segmentation to state labels') +parser.add_argument('-outfile_prefix',type=str,default="", required=False, + help='prepended to the names of the output files') +parser.add_argument('-keep_utts',nargs='?',required=False, default=False, const=True, + help='store features and labels in a 3D array in which each index points to the list of features/labels for one utterance') +args = vars(parser.parse_args()) + +from genLabels import genDataset +genDataset(args['train_fileids'], + args['val_fileids'], + args['test_fileids'], + args['nfilts'], + args['feat_dir'], + args['feat_ext'], + args['stseg_dir'], + args['stseg_ext'], + args['mdef'], + args['outfile_prefix'], + keep_utts=args['keep_utts']) + diff --git a/python/DNN_training/runNNPredict.py b/python/DNN_training/runNNPredict.py new file mode 100644 index 00000000..eb9227ad --- /dev/null +++ b/python/DNN_training/runNNPredict.py @@ -0,0 +1,44 @@ +from argparse import ArgumentParser + +parser = ArgumentParser(description="Generate Predictions from a Keras Model and save them in PockeSphinx readable .sen files.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-keras_model', type=str, required=True, + help="Keras model to be used for prediction in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-ctldir',type=str, required=True, + help="the directory for the control files, prepended to each file path in ctllist") +parser.add_argument('-ctllist', type=str,required=True, + help='list of input files, each representing an utterance') +parser.add_argument('-inext', type=str, required=True, + help='the extension of the control files, appended to each file path in ctllist') +parser.add_argument('-outdir', type=str,required=True, + help='Directory where the predictions are stored. The structure of this directory will be identical to ctldir') +parser.add_argument('-outext', type=str, required=True, + help='the extension of the output files') +parser.add_argument('-nfilts', type=int, required=True, + help='dimensionality of the feature vectors') +parser.add_argument('-acoustic_weight',type=float,required=False, + help='The weight to scale the predictions by. Sometimes needed to get meaningful predictions from PocketSphinx') +parser.add_argument('-context_win',type=int, required=False, default=0, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from keras.models import load_model +from utils import * + +model = load_model(keras_model,custom_objects={'dummy_loss':dummy_loss, + 'decoder_dummy_loss':decoder_dummy_loss, + 'ler':ler}) +print model.summary() +getPredsFromFilelist(model,args['ctllist'], + args['ctldir'], + args['inext'], + args['outdir'], + args['outext'], + context_len=args['context_win'], + weight=args['acoustic_weight'] if args['acoustic_weight'] != None else 0.1, + n_feat=args['nfilts']) \ No newline at end of file diff --git a/python/DNN_training/runNNTrain.py b/python/DNN_training/runNNTrain.py new file mode 100644 index 00000000..3a5b210f --- /dev/null +++ b/python/DNN_training/runNNTrain.py @@ -0,0 +1,153 @@ +from argparse import ArgumentParser +import numpy as np + +parser = ArgumentParser(description="Train a Keras neural network model.", + usage='%(prog)s [options] \nUse --help for option list') +parser.add_argument('-train_data',type=str, required=True, + help="the training data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-train_labels',type=str, required=True, + help="the training labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-val_data',type=str, required=True, + help="the validation data for the neural network as a saved numpy array of 2D numpy arrays") +parser.add_argument('-val_labels',type=str, required=True, + help="the validation labels for the neural network as a saved numpy array of 1D numpy arrays") +parser.add_argument('-nn_config',type=str, required=True, + help='file containing the neural network configuration information (look at sample_mlp.cfg)') +parser.add_argument('-n_epochs',type=int, required=True, + help='Number of epochs for which to train the model.') +parser.add_argument('-context_win',type=int, required=False, default=0, + help='number of contextual frames to include from before and after the target frame (defaults to 5)') +parser.add_argument('-cuda_device_id', type=str, required=False, default="", + help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") +parser.add_argument('-pretrain', nargs='?', required=False, default=False, const=True, + help='Perform layer-wise pretraining of the MLP before starting training. (Use only with dense MLPs)') +parser.add_argument('-keras_model', type=str, required=False, + help="Keras model to be trained in hd5 format (must be compatible with keras.load_model)") +parser.add_argument('-model_name', type=str, required=True, + help='Name to be assigned to the output files') +args = vars(parser.parse_args()) + +import os +CUDA_VISIBLE_DEVICES = args["cuda_device_id"] +os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES +from NNTrain import * +from utils import * +from keras.models import load_model + +def read_config(filename): + with open(filename) as f: + lines = f.readlines() + lines = filter(lambda x: x[0] != '#' and len(x) > 2, lines) + args = {} + for l in lines: + split = l.split() + if split[0] in args: + args[split[0]].append(split[1:]) + else: + args[split[0]] = split[1:] if len(split) > 1 else [] + if len(args[split[0]]) == 1: + args[split[0]] = args[split[0]][0] + return args + +def init_model(args,input_dim,output_dim, nframes): + print args + nn_type = args['type'] + + if nn_type == 'mlp': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + BN = 'batch_norm' in args, + dropout = float(args.setdefault('dropout',False)), + activation = args.setdefault('activation','sigmoid')) + if nn_type == 'resnet': + model = mlp4(input_dim, + output_dim, + int(args['n_blocks']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + dropout=float(args.setdefault('dropout',False)), + BN='batch_norm' in args, + shortcut=True) + if nn_type == 'conv' or nn_type == 'conv+resnet': + print args + assert(len(args['conv']) == len(args['pooling']) or + (type(args['conv']) == str and + type(args['pooling'] == str))) + filts = [] + filt_dims = [] + pooling = [] + max='max' + avg='avg' + if type(args['conv']) == str: + conv = [args['conv']] + pool = [args['pooling']] + else: + conv = args['conv'] + pool = args['pooling'] + for i in range(len(conv)): + filt, dims = eval(conv[i]) + filts.append(int(filt)) + filt_dims.append(dims) + + pooling.append(eval(pool[i])) + if nn_type == 'conv': + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True) + else: + model = mlp4(input_dim, + output_dim, + int(args['depth']), + int(args['width']), + nframes, + block_depth=int(args['block_depth']), + n_filts=filts, + filt_dims=filt_dims, + pooling=pooling, + conv=True, + shortcut=True) + + if 'ctc_loss' in args: + model = ctc_model(model) + return model + +x_train = np.load(args['train_data']) +y_train = np.load(args['train_labels']) + +x_test = np.load(args['val_data']) +y_test = np.load(args['val_labels']) + +nClasses = max(map(np.max,y_train)) + 1 + +meta = {} +meta['nFrames_Train'] = sum(map(lambda x: x.shape[0], x_train)) +meta['nFrames_Dev'] = sum(map(lambda x: x.shape[0], x_test)) +meta['state_freq_train'] = np.zeros(nClasses) +for u in y_train: + for r in u: + meta['state_freq_train'][r] += 1 + +conf = read_config(args['nn_config']) +context_len = args['context_win'] +if args['keras_model'] != None: + model = load_model(args['keras_model']) +else: + if 'ctc_loss' in conf: + model = init_model(conf, (None,x_train[0].shape[-1],), + nClasses + 1, 2 * context_len + 1) + fg = gen_bracketed_data(for_CTC=True, n_states=nClasses) + else: + model = init_model(conf, (x_train[0].shape[-1] * (2 * context_len + 1),), + nClasses, 2 * context_len + 1) + fg = gen_bracketed_data(context_len=context_len) +trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=int(conf['batch_size']),ctc_train=False,fit_generator=fg, pretrain=args['pretrain'], n_epochs=args['n_epochs']) diff --git a/python/DNN_training/sample_nn.cfg b/python/DNN_training/sample_nn.cfg new file mode 100644 index 00000000..851e9aba --- /dev/null +++ b/python/DNN_training/sample_nn.cfg @@ -0,0 +1,22 @@ +#type resnet +#width 2048 +#block_depth 3 +#n_blocks 5 + +type mlp +width 2048 +depth 3 +#dropout 0.25 +batch_norm +activation sigmoid +#ctc_loss +batch_size 512 +optimizer SGD +lr 0.001 + + +#type conv +#conv [84,(6,8)] [168,(3,4)] +#pooling None [max,(3,3),(1,1)] +#width 2048 +#depth 3 \ No newline at end of file diff --git a/python/DNN_training/test.csv b/python/DNN_training/test.csv new file mode 100644 index 00000000..798e666a --- /dev/null +++ b/python/DNN_training/test.csv @@ -0,0 +1,9 @@ +epoch,acc,loss,lr,val_acc,val_loss +0,0.11622738801684533,5.8389106012230449,0.001,0.10160732136648122,5.7048709947973366 +1,0.16153809341500766,4.8325580953638916,0.001,0.10914953494436717,5.4223426403024435 +2,0.18681057379402757,4.4621437494093934,0.001,0.12780201451668985,5.2290357653056798 +3,0.21127847434915772,4.1832528039470747,0.001,0.14062635822322669,5.0586822548562527 +4,0.2326776057618683,3.9420465787738608,0.001,0.15207753824756606,4.8969079582681241 +0,0.11584453962480858,5.8249653400724917,0.001,0.10603784553198888,5.6919887321217502 +1,0.16048675583843797,4.8297243269807897,0.001,0.10991421462100139,5.4031377342712235 +2,0.18789032589969373,4.4382342056329911,0.001,0.12922543245827539,5.2118432286385863 diff --git a/python/DNN_training/test.png b/python/DNN_training/test.png new file mode 100644 index 0000000000000000000000000000000000000000..080e0e73524ee2b2b78af7624ae5b96eccc9ba88 GIT binary patch literal 47155 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 literal 0 HcmV?d00001 diff --git a/python/DNN_training/utils.py b/python/DNN_training/utils.py new file mode 100644 index 00000000..c9398b89 --- /dev/null +++ b/python/DNN_training/utils.py @@ -0,0 +1,333 @@ +import numpy as np +import struct +import matplotlib.pyplot as plt +import pylab as pl +from sys import stdout +import os +from keras.preprocessing.sequence import pad_sequences +import keras.backend as K +from scipy.sparse import coo_matrix +from sklearn.preprocessing import StandardScaler + +def dummy_loss(y_true,y_pred): + return y_pred +def decoder_dummy_loss(y_true,y_pred): + return K.zeros((1,)) +def ler(y_true, y_pred, **kwargs): + """ + Label Error Rate. For more information see 'tf.edit_distance' + """ + return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) + +def dense2sparse(a): + # rows,cols = a.nonzero() + # data = map(lambda i: a[rows[i],cols[i]], range(rows.shape[0])) + # return coo_matrix((data,(rows,cols)), shape=a.shape,dtype='int32') + return coo_matrix(a,shape=a.shape,dtype='int32') + +def readMFC(fname,nFeats): + data = [] + with open(fname,'rb') as f: + v = f.read(4) + head = struct.unpack('I',v)[0] + v = f.read(nFeats * 4) + while v: + frame = list(struct.unpack('%sf' % nFeats, v)) + data .append(frame) + v = f.read(nFeats * 4) + data = np.array(data) + # print data.shape, head + assert(data.shape[0] * data.shape[1] == head) + return data + +def ctc_labels(labels, blank_labels = []): + new_labels = [] + for i in range(len(labels)): + l_curr = labels[i] + if l_curr not in blank_labels: + if i == 0: + new_labels.append(l_curr) + else: + if l_curr != labels[i-1]: + new_labels.append(l_curr) + return np.array(new_labels) +def _gen_bracketed_data_2D(x,y,nFrames, + context_len,fix_length, + for_CTC): + max_len = ((np.max(nFrames) + 50)/100) * 100 #rounding off to the nearest 100 + batch_size = 2 + while 1: + pos = 0 + nClasses = np.max(y) + 1 + if for_CTC: + alldata = [] + alllabels = [] + for i in xrange(len(nFrames)): + data = x[pos:pos + nFrames[i]] + labels = y[pos:pos + nFrames[i]] + # if for_CTC: + # labels = ctc_labels(labels,blank_labels=range(18) + [108,109,110]) + # if len(labels.shape) == 1: + # labels = to_categorical(labels,num_classes=nClasses) + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if for_CTC: + if batch_size != None: + alldata.append(data) + alllabels.append(labels) + + if len(alldata) == batch_size: + alldata = np.array(alldata) + alllabels = np.array(alllabels) + if fix_length: + alldata = pad_sequences(alldata,maxlen=1000,dtype='float32',truncating='post') + alllabels = pad_sequences(alllabels,maxlen=1000,dtype='float32',value=138,truncating='post') + inputs = {'x': alldata, + 'y': alllabels, + 'x_len': np.array(map(lambda x: len(x), alldata)), + 'y_len': np.array(map(lambda x: len(x), alllabels))} + outputs = {'ctc': np.ones([batch_size])} + yield (inputs,outputs) + alldata = [] + alllabels = [] + else: + data = np.array([data]) + labels = np.array([labels]) + inputs = {'x': data, + 'y': labels, + 'x_len': [data.shape[0]], + 'y_len': [labels.shape[0]]} + outputs = {'ctc': labels} + yield (inputs,outputs) + else: + yield (data,labels) + pos += nFrames[i] + +def _gen_bracketed_data_3D(x,y,batch_size,context_len): + epoch_no = 1 + while 1: + print epoch_no + batch_data = [] + batch_labels = [] + for i in range(len(x)): + data = x[i] + labels = y[i] + if context_len != 0: + pad_top = np.zeros((context_len,data.shape[1])) + pad_bot = np.zeros((context_len,data.shape[1])) + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + seq_len = 0 + while seq_len < len(data) and data[seq_len].any(): + seq_len += 1 + idxs = range(seq_len) + np.random.shuffle(idxs) + for j in idxs: + if len(batch_data) < batch_size: + batch_data.append(data[j]) + batch_labels.append(labels[j]) + else: + batch_data = np.array(batch_data) + batch_labels = np.array(batch_labels) + yield(batch_data,batch_labels) + batch_data = [] + batch_labels = [] + epoch_no += 1 +def gen_ctc_data(alldata,alllabels,batch_size, n_states): + while 1: + for i in range(batch_size,alldata.shape[0]+1,batch_size): + x = alldata[i-batch_size:i] + y = alllabels[i-batch_size:i] + # .reshape(batch_size,alllabels.shape[1]) + max_len = max(map(len,x)) + x = pad_sequences(x,maxlen=max_len,dtype='float32',padding='post') + y = pad_sequences(y,maxlen=max_len,dtype='float32',padding='post',value=n_states) + x = np.array(x) + y = np.array(y) + # print x.shape, y.shape + y_len = [] + # print y + for b in y: + # # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and int(b[pad_len]) != 138: + pad_len += 1 + y_len.append(pad_len) + y_len = np.array(y_len) + x_len = [] + for b in x: + # print b[-1], int(b[-1]) != 138 + pad_len = 0 + while pad_len < len(b) and b[pad_len].any(): + pad_len += 1 + x_len.append(pad_len) + x_len = np.array(x_len) + # x_len = np.array(map(lambda x: len(x), x)) + # y_len = np.array(map(lambda x: len(x), y)) + # print x.shape,y.shape,x_len,y_len + # print y.shape + # y = dense2sparse(y) + inputs = {'x': x, + 'y': y, + 'x_len': x_len, + 'y_len': y_len} + outputs = {'ctc': np.ones([batch_size]), + 'decoder': dense2sparse(y), + 'softmax': y.reshape(y.shape[0],y.shape[1],1)} + yield(inputs,outputs) + +def gen_bracketed_data(context_len=None,fix_length=False, + for_CTC=False, n_states=None): + if for_CTC: + assert(n_states != None) + return lambda x,y,batch_size: gen_ctc_data(x,y,batch_size,n_states) + else: + return lambda x,y,batch_size: _gen_bracketed_data_3D(x,y,batch_size,context_len) + # return lambda x,y,nf: _gen_bracketed_data(x,y,nf,context_len,fix_length, + # for_CTC) + +def plotFromCSV(modelName, loss_cols=[2,5], acc_cols=[1,4]): + data = np.loadtxt(modelName+'.csv',skiprows=1,delimiter=',') + epoch = data[:,[0]] + acc = data[:,[acc_cols[0]]] + loss = data[:,[loss_cols[0]]] + val_acc = data[:,[acc_cols[1]]] + val_loss = data[:,[loss_cols[1]]] + + fig, ax1 = plt.subplots() + ax1.plot(acc) + ax1.plot(val_acc) + ax2 = ax1.twinx() + ax2.plot(loss,color='r') + ax2.plot(val_loss,color='g') + plt.title('model loss & accuracy') + ax1.set_ylabel('accuracy') + ax2.set_ylabel('loss') + ax1.set_xlabel('epoch') + ax1.legend(['training acc', 'testing acc']) + ax2.legend(['training loss', 'testing loss']) + fig.tight_layout() + plt.savefig(modelName+'.png') + plt.clf() + +def writeSenScores(filename,scores,weight,offset): + n_active = scores.shape[1] + s = '' + s = """s3 +version 0.1 +mdef_file ../../en_us.cd_cont_4000/mdef +n_sen 138 +logbase 1.000100 +endhdr +""" + s += struct.pack('I',0x11223344) + + scores = np.log(scores)/np.log(1.0001) + scores *= -1 + scores -= np.min(scores,axis=1).reshape(-1,1) + # scores = scores.astype(int) + scores *= weight + scores += offset + truncateToShort = lambda x: 32676 if x > 32767 else (-32768 if x < -32768 else x) + vf = np.vectorize(truncateToShort) + scores = vf(scores) + # scores /= np.sum(scores,axis=0) + for r in scores: + # print np.argmin(r) + s += struct.pack('h',n_active) + r_str = struct.pack('%sh' % len(r), *r) + # r_str = reduce(lambda x,y: x+y,r_str) + s += r_str + with open(filename,'w') as f: + f.write(s) + +def getPredsFromArray(model,data,nFrames,filenames,res_dir,res_ext,freqs,preds_in=False,weight=0.1,offset=0): + if preds_in: + preds = data + else: + preds = model.predict(data,verbose=1,batch_size=2048) + pos = 0 + for i in range(len(nFrames)): + fname = filenames[i][:-4] + fname = reduce(lambda x,y: x+'/'+y,fname.split('/')[4:]) + stdout.write("\r%d/%d " % (i,len(filenames))) + stdout.flush() + res_file_path = res_dir+fname+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + # preds = model.predict(data[pos:pos+nFrames[i]],batch_size=nFrames[i]) + writeSenScores(res_file_path,preds[pos:pos+nFrames[i]],freqs,weight,offset) + pos += nFrames[i] + +def getPredsFromFilelist(model,filelist,file_dir,file_ext, + res_dir,res_ext,n_feat=40,context_len=None, + weight=1,offset=0, data_preproc_fn=None, + data_postproc_fn=None): + with open(filelist) as f: + files = f.readlines() + files = map(lambda x: x.strip(),files) + filepaths = map(lambda x: file_dir+x+file_ext,files) + scaler = StandardScaler(copy=False,with_std=False) + for i in range(len(filepaths)): + stdout.write("\r%d/%d " % (i,len(filepaths))) + stdout.flush() + + f = filepaths[i] + if not os.path.exists(f): + print ("\n",f) + continue + data = readMFC(f,n_feat) + data = scaler.fit_transform(data) + + if context_len != None: + pad_top = np.zeros((context_len,data.shape[1])) + data[0] + pad_bot = np.zeros((context_len,data.shape[1])) + data[-1] + padded_data = np.concatenate((pad_top,data),axis=0) + padded_data = np.concatenate((padded_data,pad_bot),axis=0) + + data = [] + for j in range(context_len,len(padded_data) - context_len): + new_row = padded_data[j - context_len: j + context_len + 1] + new_row = new_row.flatten() + data.append(new_row) + data = np.array(data) + if data_preproc_fn != None: + _data = data_preproc_fn(data) + preds = model.predict(_data) + preds = np.squeeze(preds) + else: + preds = model.predict(data) + + if data_postproc_fn != None: + preds = data_postproc_fn(preds) + if preds.shape[0] != data.shape[0]: + preds = preds[:data.shape[0]] + # print np.sum(preds) + # print preds.shape + res_file_path = res_dir+files[i]+res_ext + dirname = os.path.dirname(res_file_path) + if not os.path.exists(dirname): + os.makedirs(dirname) + writeSenScores(res_file_path,preds,weight,offset) + +# a = dense2sparse(np.array([[1,2,3],[4,0,6]])) +# print a.shape +# print np.asarray(a,dtype=long) \ No newline at end of file From 1a6f415e7e829ddf58b362e0ecddd075b578bbae Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 07:03:30 -0400 Subject: [PATCH 07/12] with stseg -> asii script --- python/DNN_training/readStSegs.sh | 2 +- src/libs/libcommon/stseg-read.c | 155 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/libs/libcommon/stseg-read.c diff --git a/python/DNN_training/readStSegs.sh b/python/DNN_training/readStSegs.sh index 44d98e49..e00fcb4d 100755 --- a/python/DNN_training/readStSegs.sh +++ b/python/DNN_training/readStSegs.sh @@ -4,6 +4,6 @@ files=$(find "$stseg_fldr/" -name "*.stseg") for f in $files do echo "CONVERTING: "$f - cat $f | ../../src/libs/libcommon/.libs/stseg-read.o > $f.txt + cat $f | ../../src/libs/libcommon/stseg-read > $f.txt break done diff --git a/src/libs/libcommon/stseg-read.c b/src/libs/libcommon/stseg-read.c new file mode 100644 index 00000000..9c0688a7 --- /dev/null +++ b/src/libs/libcommon/stseg-read.c @@ -0,0 +1,155 @@ +/* ==================================================================== + * Copyright (c) 1995-2002 Carnegie Mellon University. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * This work was supported in part by funding from the Defense Advanced + * Research Projects Agency and the National Science Foundation of the + * United States of America, and the CMU Sphinx Speech Consortium. + * + * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND + * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY + * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ==================================================================== + * + */ +/* + * stseg.c -- Read and display .stseg file created by s3align. + * + * ********************************************** + * CMU ARPA Speech Project + * + * Copyright (c) 1996 Carnegie Mellon University. + * ALL RIGHTS RESERVED. + * ********************************************** + * + * HISTORY + * + * 19-Jul-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University + * Created. + */ + + +#include +#include +#include +#include +#include + +/* "\nCI.8 LC.8 RC.8 POS.3(HI)-ST.5(LO) SCR(32)" */ + +static char *phone[100]; +static int n_phone; +static char *posname = "besiu"; + + +static skip_line (FILE *fp) +{ + int c; + + while (((c = fgetc (fp)) >= 0) && (c != '\n')); +} + + +main () +{ + int i, k, nf, scr; + int16_t c; + FILE *fp; + int16_t str[3]; + char str1[1024]; + fp = stdin; + n_phone = 0; + + /* Skip version# string */ + skip_line (fp); + + /* Read CI phone names */ + for (;;) { + for (i = 0;; i++) { + if (((c = fgetc(fp)) == ' ') || (c == '\n')) + break; + str1[i] = c; + } + str1[i] = '\0'; + + if (c == ' ') { + phone[n_phone] = (char *) malloc (i+1); + strcpy (phone[n_phone], str1); + n_phone++; + } else + break; + } + printf ("%d phones\n", n_phone); + + /* Skip format line */ + skip_line (fp); + + /* Skip end-comment line */ + skip_line (fp); + + /* Read byteorder magic no. */ + fread (&i, sizeof(int), 1, fp); + assert (i == 0x11223344); + + /* Read no. frames */ + fread (&nf, sizeof(int), 1, fp); + printf ("#frames = %d\n", nf); + + char pos[1]; + /* Read state info per frame */ + for (i = 0; i < nf; i++) { + k = fread (str, sizeof(uint16_t), 3, fp); + str[3] = 0; + assert (k == 3); + k = fread (pos, sizeof(char), 1, fp); + assert (k == 1); + k = fread (&scr, sizeof(int), 1, fp); + assert (k == 1); + + c = str[0]; + //printf("c=%d\n",c); + assert ((c >= 0) && (c < n_phone)); + printf ("%5d %11d %2d %s", i, scr, pos[0] & 0x001f, phone[c]); + + c = str[1]; + //printf("c2=%d\n",c); + if (c != -1) { + assert ((c >= 0) && (c < n_phone)); + printf (" %s", phone[c]); + } + + c = str[2]; + //printf("c3=%d\n",c); + if (c != -1) { + assert ((c >= 0) && (c < n_phone)); + printf (" %s", phone[c]); + } + + c = (pos[0] >> 5) & 0x07; + if ((c >= 0) && (c < 4)) + printf (" %c", posname[c]); + + printf ("\n"); + } +} From ed4b1c660435f6502ad85032182883eb592f619f Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 07:09:58 -0400 Subject: [PATCH 08/12] removed from scripts folder --- scripts/DNN_training/NNTrain.py | 521 ------------------ scripts/DNN_training/README.md | 134 ----- scripts/DNN_training/ctc.py | 137 ----- scripts/DNN_training/genLabels.py | 339 ------------ scripts/DNN_training/makeFileListFromTrans.py | 19 - scripts/DNN_training/readSen.py | 96 ---- scripts/DNN_training/requirements.txt | 67 --- scripts/DNN_training/runDatasetGen.py | 41 -- scripts/DNN_training/runNNPredict.py | 48 -- scripts/DNN_training/runNNTrain.py | 168 ------ scripts/DNN_training/sample_nn.cfg | 22 - scripts/DNN_training/test.csv | 0 scripts/DNN_training/utils.py | 333 ----------- 13 files changed, 1925 deletions(-) delete mode 100644 scripts/DNN_training/NNTrain.py delete mode 100644 scripts/DNN_training/README.md delete mode 100644 scripts/DNN_training/ctc.py delete mode 100644 scripts/DNN_training/genLabels.py delete mode 100644 scripts/DNN_training/makeFileListFromTrans.py delete mode 100644 scripts/DNN_training/readSen.py delete mode 100644 scripts/DNN_training/requirements.txt delete mode 100644 scripts/DNN_training/runDatasetGen.py delete mode 100644 scripts/DNN_training/runNNPredict.py delete mode 100644 scripts/DNN_training/runNNTrain.py delete mode 100644 scripts/DNN_training/sample_nn.cfg delete mode 100644 scripts/DNN_training/test.csv delete mode 100644 scripts/DNN_training/utils.py diff --git a/scripts/DNN_training/NNTrain.py b/scripts/DNN_training/NNTrain.py deleted file mode 100644 index 9bddc8aa..00000000 --- a/scripts/DNN_training/NNTrain.py +++ /dev/null @@ -1,521 +0,0 @@ -from keras.models import Sequential, Model -from keras.optimizers import SGD,Adagrad, Adam -from keras.layers.normalization import BatchNormalization -from keras.layers import ( - Input, - Dense, - Activation, - Dropout, - Conv1D, - Conv2D, - LocallyConnected2D, - MaxPooling2D, - AveragePooling2D, - Reshape, - Flatten, - Masking) -from keras.layers.core import Lambda -from keras.layers.merge import add, concatenate -from keras.utils import to_categorical, plot_model -from keras.models import load_model, Model -from keras.callbacks import History,ModelCheckpoint,CSVLogger,ReduceLROnPlateau -from keras import regularizers -from keras.preprocessing.sequence import pad_sequences -import keras.backend as K -import numpy as np -import matplotlib.pyplot as plt -import tensorflow as tf -from tensorflow.python.ops import math_ops -from tensorflow.python.ops import array_ops -from tfrbm import GBRBM,BBRBM -from sys import stdout -import time -import gc -from sklearn.preprocessing import StandardScaler -from guppy import hpy -import threading -import struct -from utils import * -import ctc - -""" - This module provides functions for training different neural network architectures - Below is a bried summary of the different functions and their purpose, more detail - can be found below: - - mlp1: creates a MLP consisting of a number dense layers - - mlp_wCTC: creates a MLP that calculates the ctc loss during training - - mlp4: create convolutional neural networks and residual networks - - DBN_DNN: performs DBN pretraining on simple MLPs - - preTrain: performs layer-wise pretraining on simple MLPs - - trainAndTest: runs training on a provided model using the given dataset -""" - -def mlp1(input_dim,output_dim,depth,width,dropout=False, - BN=False, regularize=False, lin_boost=False, activation='sigmoid'): - print locals() - model = Sequential() - model.add(Dense(width, activation=activation, input_shape=(input_dim,), - kernel_regularizer=regularizers.l2(0.05) if regularize else None)) - if BN: - model.add(BatchNormalization()) - if dropout: - model.add(Dropout(dropout)) - for i in range(depth - 1): - model.add(Dense(width, activation=activation, - kernel_regularizer=regularizers.l2(0.05) if regularize else None)) - if dropout: - model.add(Dropout(dropout)) - if BN: - model.add(BatchNormalization()) - if lin_boost: - model.add(Dense(output_dim)) - model.add(Lambda(lambda x: K.exp(x))) - else: - model.add(Dense(output_dim, name='out')) - model.add(Activation('softmax', name='softmax')) - opt = Adam(lr=10/(np.sqrt(input_dim * width * output_dim))) - model.compile(optimizer=opt, - loss='sparse_categorical_crossentropy', - metrics=['accuracy']) - return model - -def ctc_lambda_func(args): - import tensorflow as tf - y_pred, labels, input_length, label_length = args - label_length = K.cast(tf.squeeze(label_length), 'int32') - input_length = K.cast(tf.squeeze(input_length), 'int32') - # return K.ctc_batch_cost(labels, y_pred, input_length, label_length) - labels = K.ctc_label_dense_to_sparse(labels,label_length) - return tf.nn.ctc_loss(labels,y_pred,input_length, - preprocess_collapse_repeated=True, - ctc_merge_repeated=False, - time_major=False, - ignore_longer_outputs_than_inputs=True) - -def ler(y_true, y_pred, **kwargs): - """ - Label Error Rate. For more information see 'tf.edit_distance' - """ - return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) - -def decode_output_shape(inputs_shape): - y_pred_shape, seq_len_shape = inputs_shape - return (y_pred_shape[:1], None) - -def decode(args): - import tensorflow as tf - y_pred, label_len = args - label_len = K.cast(tf.squeeze(label_len), 'int32') - # ctc_labels = tf.nn.ctc_greedy_decoder(y_pred, label_len)[0][0] - # return ctc_labels - ctc_labels = K.ctc_decode(y_pred,label_len,greedy=False)[0][0] - return K.ctc_label_dense_to_sparse(ctc_labels, label_len) - -# def ler(args): -# y_pred, y_true, input_length, label_length = args -# label_length = K.cast(tf.squeeze(label_length), 'int32') -# input_length = K.cast(tf.squeeze(input_length), 'int32') - -# y_pred = K.ctc_decode(y_pred,input_length)[0][0] -# # y_pred = tf.nn.ctc_greedy_decoder(y_pred,input_length)[0][0] -# y_pred = K.cast(y_pred,'int32') -# # y_pred = math_ops.to_int32(y_pred) -# # y_true = math.ops.to_int64(y_true) -# y_true = K.ctc_label_dense_to_sparse(y_true,label_length) -# y_pred = K.ctc_label_dense_to_sparse(y_pred,input_length) -# return tf.reduce_mean(tf.edit_distance(y_pred, y_true)) -# def ler(y_true, y_pred, **kwargs): -# """ -# Label Error Rate. For more information see 'tf.edit_distance' -# """ -# return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) - -def mlp_wCTC(input_dim,output_dim,depth,width,BN=False): - print locals() - x = Input(name='x', shape=(1000,input_dim)) - h = x - h = Masking()(h) - for i in range(depth): - h = Dense(width)(h) - if BN: - h = BatchNormalization()(h) - h = Activation('sigmoid')(h) - out = Dense(output_dim,name='out')(h) - softmax = Activation('softmax', name='softmax')(out) - # a = 1.0507 * 1.67326 - # b = -1 - # # out = Lambda(lambda x : a * K.pow(x,3) + b)(h) - # out = Lambda(lambda x: a * K.exp(x) + b, name='out')(h) - y = Input(name='y',shape=[None,],dtype='int32') - x_len = Input(name='x_len', shape=[1],dtype='int32') - y_len = Input(name='y_len', shape=[1],dtype='int32') - - dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) - # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) - - loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) - model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) - - sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) - opt = Adam(lr=0.0001, clipnorm=5) - model.compile(loss={'ctc': dummy_loss, - 'decoder': decoder_dummy_loss, - 'softmax': 'sparse_categorical_crossentropy'}, - optimizer=opt, - metrics={'decoder': ler, - 'softmax': 'accuracy'}, - loss_weights=[1,0,0]) - return model -def ctc_model(model): - x = model.get_layer(name='x').input - - out = model.get_layer(name='out').output - softmax = Activation('softmax', name='softmax')(out) - y = Input(name='y',shape=[None,],dtype='int32') - x_len = Input(name='x_len', shape=[1],dtype='int32') - y_len = Input(name='y_len', shape=[1],dtype='int32') - - dec = Lambda(decode, output_shape=decode_output_shape, name='decoder')([out,x_len]) - # edit_distance = Lambda(ler, output_shape=(1,), name='edit_distance')([out,y,x_len,y_len]) - - loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([out, y, x_len, y_len]) - model = Model(inputs=[x, y, x_len, y_len], outputs=[loss_out,dec,softmax]) - - sgd = SGD(lr=0.001, decay=1e-6, momentum=0.99, nesterov=True, clipnorm=5) - opt = Adam(lr=0.0001, clipnorm=5) - model.compile(loss={'ctc': dummy_loss, - 'decoder': decoder_dummy_loss, - 'softmax': 'sparse_categorical_crossentropy'}, - optimizer=opt, - metrics={'decoder': ler, - 'softmax': 'accuracy'}, - loss_weights=[1,0,0]) - return model -def _bn_act(input,activation='relu'): - """Helper to build a BN -> relu block - """ - norm = BatchNormalization()(input) - return Activation(activation)(norm) - -def make_dense_res_block(inp, size, width, drop=False,BN=False,regularize=False): - x = inp - for i in range(size): - x = Dense(width, - kernel_regularizer=regularizers.l2(0.05) if regularize else None)(x) - if i < size - 1: - if drop: - x = Dropout(0.15)(x) - if BN: - x = _bn_relu(x) - return x - -def mlp4(input_dim,output_dim,nBlocks,width, n_frames, block_depth=1, - n_filts=[84], filt_dims=[(11,8)], pooling=[['max',(6,6),(2,2)]], - block_width=None, dropout=False, BN=False, activation='relu', - parallelize=False, conv=False, regularize=False, - exp_boost=False, quad_boost=False, shortcut=False, - opt='adam', lr=0.001): - - print locals() - if block_width == None: - block_width = width - inp = Input(shape=input_dim, name='x') - x = inp - if conv: - x = Reshape((n_frames,input_dim/n_frames,1))(x) - for i in range(len(n_filts)): - print i - - x = LocallyConnected2D(n_filts[i],filt_dims[i], - padding='valid')(x) - x = _bn_act(x,activation=activation) - if pooling[i] != None: - pooling_type, win_size, stride = pooling[i] - if pooling_type == 'max': - x = MaxPooling2D(win_size,strides=stride,padding='same')(x) - if pooling_type == 'avg': - x = AveragePooling2D(win_size,strides=stride,padding='same')(x) - x = Flatten()(x) - if block_width != width: - x = Dense(block_width)(x) - for i in range(nBlocks): - y = make_dense_res_block(x,block_depth,block_width,BN=BN,drop=dropout,regularize=regularize) - if shortcut: - x = add([x,y]) - else: - x = y - if dropout: - x = Dropout(dropout)(x) - if BN: - x = _bn_act(x,activation=activation) - else: - x = Activation(activation)(x) - - if exp_boost: - x = Dense(output_dim)(x) - z = Lambda(lambda x : K.exp(x))(x) - if quad_boost: - x = Dense(output_dim)(x) - a = 0.001 - b = 0.4 - z = Lambda(lambda x : a * K.pow(x,3) + b)(x) - else: - z = Dense(output_dim, name='out')(x) - z = Activation('softmax', name='softmax')(z) - model = Model(inputs=inp, outputs=z) - if parallelize: - model = make_parallel(model, len(CUDA_VISIBLE_DEVICES.split(','))) - # opt = Adam(lr=25/(np.sqrt(width * output_dim))) - if opt == 'sgd': - opt = SGD - if opt == 'adam': - opt = Adam - if opt == 'adagrad': - opt = Adagrad - opt = opt(lr=lr) - # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) - model.compile(optimizer=opt, - loss='sparse_categorical_crossentropy', - metrics=['accuracy']) - return model - -def resnet_wrapper(input_dim,output_dim,depth,width,reshape_layer): - builder = resnet.ResnetBuilder() - model = builder.build_resnet_18(input_dim, output_dim,reshape_layer) - x = model.get_layer(name='flatten_1').get_output_at(-1) - for i in range(depth): - x = Dense(width,activation='relu')(x) - softmax = Dense(output_dim,activation='softmax')(x) - model = Model(inputs=model.inputs, outputs=softmax) - opt = Adam(lr=10/np.sqrt(input_dim * output_dim)) - # opt = SGD(lr=1/(np.sqrt(input_dim * width)), decay=1e-6, momentum=0.9, nesterov=True) - model.compile(optimizer=opt, - loss='sparse_categorical_crossentropy', - metrics=['accuracy']) - return model -def DBN_DNN(inp,nClasses,depth,width,batch_size=2048): - RBMs = [] - weights = [] - bias = [] - # batch_size = inp.shape - nEpoches = 5 - if len(inp.shape) == 3: - inp = inp.reshape((inp.shape[0] * inp.shape[1],inp.shape[2])) - sigma = np.std(inp) - # sigma = 1 - rbm = GBRBM(n_visible=inp.shape[-1],n_hidden=width,learning_rate=0.002, momentum=0.90, use_tqdm=True,sample_visible=True,sigma=sigma) - rbm.fit(inp,n_epoches=15,batch_size=batch_size,shuffle=True) - RBMs.append(rbm) - for i in range(depth - 1): - print 'training DBN layer', i - rbm = BBRBM(n_visible=width,n_hidden=width,learning_rate=0.02, momentum=0.90, use_tqdm=True) - for e in range(nEpoches): - batch_size *= 1 + (e*0.5) - n_batches = (inp.shape[-2] / batch_size) + (1 if inp.shape[-2]%batch_size != 0 else 0) - for j in range(n_batches): - stdout.write("\r%d batch no %d/%d epoch no %d/%d" % (int(time.time()),j+1,n_batches,e,nEpoches)) - stdout.flush() - b = np.array(inp[j*batch_size:min((j+1)*batch_size, inp.shape[0])]) - for r in RBMs: - b = r.transform(b) - rbm.partial_fit(b) - RBMs.append(rbm) - for r in RBMs: - (W,_,Bh) = r.get_weights() - weights.append(W) - bias.append(Bh) - model = mlp1(x_train.shape[1],nClasses,depth-1,width) - print len(weights), len(model.layers) - assert len(weights) == len(model.layers) - 1 - for i in range(len(weights)): - W = [weights[i],bias[i]] - model.layers[i].set_weights(W) - return model -# def gen_data(active): - - -def preTrain(model,modelName,x_train,y_train,meta,skip_layers=[],outEqIn=False,fit_generator=None): - print model.summary() - layers = model.layers - output = layers[-1] - outdim = output.output_shape[-1] - for i in range(len(layers) - 1): - if i in skip_layers: - print 'skipping layer ',i - continue - if len(model.layers[i].get_weights()) == 0: - print 'skipping layer ',i - continue - last = model.layers[i].get_output_at(-1) - if outEqIn: - preds = Dense(outdim)(last) - else: - preds = Dense(outdim,activation='softmax')(last) - model_new = Model(model.input,preds) - for j in range(len(model_new.layers) - 2): - print "untrainable layer ",j - model_new.layers[j].trainable=False - model_new.compile(optimizer='adam', - loss='sparse_categorical_crossentropy', - metrics=['accuracy']) - print model_new.summary() - batch_size = 2048 - if fit_generator == None: - model_new.fit(x_train,y_train,epochs=1,batch_size=2048) - else: - history = model.fit_generator(fit_generator(x_train,y_train,batch_size), - steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=3) - # model.fit_generator(gen_bracketed_data(x_train,y_train,meta['framePos_Train'],4), - # steps_per_epoch=len(meta['framePos_Train']), epochs=3, - # callbacks=[ModelCheckpoint('%s_CP.h5' % modelName,monitor='loss',mode='min')]) - # model.fit_generator(gen_data(x_train,y_train,batch_size), - # steps_per_epoch = x_train.shape[0] / batch_size, - # epochs = 1) - model.layers[i].set_weights(model_new.layers[-2].get_weights()) - for l in model.layers: - l.trainable = True - return model - -def trainNtest(model,x_train,y_train,x_test,y_test,meta, - modelName,testOnly=False,pretrain=False, batch_size=512, - init_epoch=0, fit_generator=None, ctc_train=False): - print 'TRAINING MODEL:',modelName - if not testOnly: - if pretrain: - print 'pretraining model...' - model = preTrain(model,modelName,x_train,y_train,meta,fit_generator=fit_generator) - if ctc_train: - model = ctc_model(model) - print model.summary() - print 'starting fit...' - callback_arr = [ModelCheckpoint('%s_CP.h5' % modelName,save_best_only=True,verbose=1), - ReduceLROnPlateau(patience=5,factor=0.5,min_lr=10**(-6), verbose=1), - CSVLogger(modelName+'.csv',append=True)] - - if fit_generator == None: - history = model.fit(x_train,y_train,epochs=100,batch_size=batch_size, - initial_epoch=init_epoch, - validation_data=(x_test,y_test), - callbacks=callback_arr) - else: - history = model.fit_generator(fit_generator(x_train,y_train,batch_size), - steps_per_epoch=(meta['nFrames_Train'])/batch_size, epochs=75, - validation_data=fit_generator(x_test,y_test,batch_size), - validation_steps = (meta['nFrames_Dev']) / batch_size, - callbacks=callback_arr) - model = Model(inputs=[model.get_layer(name='x').input], - outputs=[model.get_layer(name='softmax').output]) - print model.summary() - model.compile(loss='sparse_categorical_crossentropy', - optimizer='adam', - metrics=['accuracy']) - print 'saving model...' - model.save(modelName+'.h5') - # model.save_weights(modelName+'_W.h5') - print(history.history.keys()) - print history.history['lr'] - print 'plotting graphs...' - # summarize history for accuracy - fig, ax1 = plt.subplots() - ax1.plot(history.history['acc']) - ax1.plot(history.history['val_acc']) - ax2 = ax1.twinx() - ax2.plot(history.history['loss'],color='r') - ax2.plot(history.history['val_loss'],color='g') - plt.title('model loss & accuracy') - ax1.set_ylabel('accuracy') - ax2.set_ylabel('loss') - ax1.set_xlabel('epoch') - ax1.legend(['training acc', 'testing acc']) - ax2.legend(['training loss', 'testing loss']) - fig.tight_layout() - plt.savefig(modelName+'.png') - plt.clf() - else: - model = load_model(modelName) - print 'scoring...' - score = model.evaluate_generator(gen_bracketed_data(x_test,y_test,meta['framePos_Dev'],4), - len(meta['framePos_Dev'])) - print score - -if __name__ == '__main__': - print 'PROCESS-ID =', os.getpid() - print 'loading data...' - meta = np.load('../GSOC/wsj0_phonelabels_cqt_meta.npz') - x_train = np.load('../GSOC/wsj0_phonelabels_cqt_train.npy') - y_train = np.load('../GSOC/wsj0_phonelabels_cqt_train_labels.npy') - print x_train.shape - print y_train.shape - nClasses = int(np.max(map(np.max,y_train)))+1 - print nClasses - - print 'loading test data...' - x_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev.npy') - y_test = np.load('../GSOC/wsj0_phonelabels_cqt_dev_labels.npy') - - print 'initializing model...' - # model = load_model('dbn-3x2048-sig-adagrad_CP.h5') - # model = resnet_wrapper((x_train.shape[1:]),nClasses,1,1024,Reshape(x_train.shape[1:] + (1,))) - # model = mlp4(x_train[0].shape[-1] * 21, nClasses,1,1,2048, - # shortcut=False,BN=True,conv=True,dropout=False, - # regularize=False) - # model = mlp1(x_train.shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) - # # model = mlp_wCTC(x_train.shape[-1],nClasses,3,2048,BN=True) - # # model = DBN_DNN(x_train, nClasses,5,3072,batch_size=128) - # # print 'wrapping ctc...' - # # model = ctc_model(model) - # # model = DBN_DNN(x_train, nClasses,5,2560,batch_size=128) - # # model = load_model('mlp4-2x2560-cd-adam-bn-drop-conv-noshort_CP.h5') - # fg = gen_bracketed_data(context_len=5) - # trainNtest(model,x_train,y_train,x_test,y_test,meta,'mlp4-1x2048-conv-cqt-BN',ctc_train=False,fit_generator=fg) - - meta = np.load('../GSOC/wsj0_phonelabels_ci_meta.npz') - model = load_model('bestModels/best_CI.h5',custom_objects={'dummy_loss':dummy_loss, - 'decoder_dummy_loss':decoder_dummy_loss, - 'ler':ler}) - # model = Model(inputs=[model.get_layer(name='x').input], - # outputs=[model.get_layer(name='softmax').output]) - print model.summary() - # # # getPredsFromFilelist(model,'../wsj/wsj0/single_dev.txt','/home/mshah1/wsj/wsj0/feat_cd_mls/','.mls','/home/mshah1/wsj/wsj0/single_dev_NN/','.sen',meta['state_freq_Train'],context_len=5,weight=0.00035457) - # # # getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev2/','.sen',meta['state_freq_Train']) - getPredsFromFilelist(model,'../wsj/wsj0/etc/wsj0_dev.fileids','/home/mshah1/wsj/wsj0/feat_ci_dev_mls/','.mfc','/home/mshah1/wsj/wsj0/senscores_dev_ci/','.sen',meta['state_freq_Train'], - context_len=4, - # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), - # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), - weight=0.1,n_feat=25) - # *0.00311573 - # 00269236 - # # getPredsFromArray(model,np.load('DEV_PRED.npy'),meta['framePos_Dev'],meta['filenames_Dev'],'/home/mshah1/wsj/wsj0/senscores_dev_ci_hammad/','.sen',meta['state_freq_Train'],preds_in=True,weight=-0.00075526,offset=234.90414376) - # f = filter(lambda x : '22go0208.wv1.flac' in x, meta['filenames_Dev'])[0] - # file_idx = list(meta['filenames_Dev']).index(f) - # print file_idx - # # split = lambda x: x[sum(meta['framePos_Dev'][:file_idx]):sum(meta['framePos_Dev'][:file_idx+1])] - # pred = model.predict(x_test[file_idx:file_idx+1],verbose=1) - # pred = np.array(map(lambda x: np.argmax(x,axis=-1),pred)) - # print pred - # print y_test[file_idx] - # data = split(x_test) - # context_len = 5 - # pad_top = np.zeros((context_len,data.shape[1])) - # pad_bot = np.zeros((context_len,data.shape[1])) - # padded_data = np.concatenate((pad_top,data),axis=0) - # padded_data = np.concatenate((padded_data,pad_bot),axis=0) - - # data = [] - # for j in range(context_len,len(padded_data) - context_len): - # new_row = padded_data[j - context_len: j + context_len + 1] - # new_row = new_row.flatten() - # data.append(new_row) - # data = np.array(data) - # pred = model.predict(data,verbose=1) - # pred = pred.reshape(1,pred.shape[0],pred.shape[1]) - # print pred.shape - # [bp],out = K.ctc_decode(pred,[pred.shape[1]]) - # print K.eval(bp), len(K.eval(bp)[0]) - # print K.eval(out) - - # print pred - # # writeSenScores('senScores',pred) - # np.save('pred.npy',np.log(pred)/np.log(1.001)) - - # plotFromCSV('mlp4-1x2048-conv-cqt-BN') \ No newline at end of file diff --git a/scripts/DNN_training/README.md b/scripts/DNN_training/README.md deleted file mode 100644 index 6996623c..00000000 --- a/scripts/DNN_training/README.md +++ /dev/null @@ -1,134 +0,0 @@ -# DNNs For ASR -The work is part of a Google Summer of Code project, the goal of which was to integrate DNNs with CMUSphinx. This particular repository contains some convenient scripts that wrap Keras code and allow for easy training of DNNs. -## Getting Started -Start by cloning the repository. -### Prerequisites -The required python libraries available from pypi are in the requirements.txt file. Install them by running: -``` -pip install -r requirements.txt -``` -Additional libraries not available from pypi: -- tfrbm- for DBN-DNN pretraining. - - available at https://github.com/meownoid/tensorfow-rbm -## Getting Started -Since the project is primarily intended to be used with PocketSphinx the file formats for feature files, state-segmentation output files and the prediction files are in sphinx format. -### Feature File Format -``` -N: number of frames -M: dimensions of the feature vector -N*M (4 bytes) -Frame 1: f_1...f_M (4*M bytes) -. -. -. -Frame N: f_1,...,f_M (4*M bytes) -``` -Look at readMFC in utils.py -### state-segmentation files -format for each frame: -``` - 2 2 2 1 4 bytes -st1 [st2 st3] pos scr -``` -### Prediction output -format for each frame: -``` -N: number of states -N (2 bytes) -scr_1...scr_N (2*N bytes) -``` -### Wrapper Scripts -``` -runDatasetGen.py -train_fileids -val_fileids [-test_fileids] -n_filts -feat_dir -feat_ext -stseg_dir -stseg_ext -mdef [-outfile_prefix] [-keep_utts] -``` -runDatasetGen takes feature files and state-segmentation files stored in sphinx format along with the definition file of the GMM-HMM model to generate a set of numpy arrays that form a python readable dataset. -runDatasetGen writes the following files in the directory it was called in: -- Data Files - - _train.npy - - _dev.npy - - _test.npy -- label files - - _train_label.npy - - _dev_label.npy - - _test_label.npy -- metadata file - - _meta.npz - -The metadata file is a zipped collection of arrays with the follwing keys: -- File names for utterances - - filenames_Train - - filenames_Dev - - filenames_Test -- Number of frames per utterance (useful if -keep_utts is not set) - - framePos_Train - - framePos_Dev - - framePos_Test -- State Frequencies (useful for scaling in some cases) - - state_freq_Train - - state_freq_Dev - - state_freq_Test -``` -runNNTrain.py -train_data -train_labels -val_data -val_labels -nn_config [-context_win] [-cuda_device_id] [-pretrain] [-keras_model] -model_name -``` -runNNTrain takes the training and validation data files (as generated by runDatasetGen) and trains a neural network on them. -The architecture and parameters of the neural network is defined in a text file. Currently this script supports 4 network types: -- MLP (mlp) -- Convolutional Neural Network (conv) -- MLP with short cut connections (resnet) -- Convolutional Network with residual connections in the fully connected layers (conv + resnet) -See sample_nn.cfg for an example. -The format for the configuration file consists of ```param``` and ```value``` pairs -if value has multiple elemets (represented by ... below) they should be separated by spaces. -Params and possible values: -- **type** mlp, conv, resnet, conv+resnet -- **width** any integer value -- **depth** any integer value -- **dropout** float in (0,1) -- **batch_norm** - -- **activation** sigmoid, hard_sigmoid, elu, relu, selu, tanh, softplus, softsign, softmax, linear -- **optimizer** sgd, adam, adagrad -- **lr** float in (0,1) -- **batch_size** any integer value -- **ctc_loss** - -- for type = conv and type = conv+resnet - - **conv** [n_filters, filter_window]... - - **pooling** None, [max/avg, window_size, stride_size] -- for type = resnet and type = conv+resnet - - **block_depth** any integer value - - **n_blocks** any integer value -``` -runNNPredict -keras_model -ctldir -inext -outdir -outext -nfilts [-acoustic_weight] [-context_win] [-cuda_device_id] -``` -runNNPredict takes a keras model and a list of feature files to generate predictions. The predictions are stored as binary files in sphinx readable format (defined above). -Please ensure that the dimensionality of the feature vectors matches nfilts and the context window is the same as that for which the model was trained. -The acoustic_weight is used to scale the output scores. This is required because if the scores are passed through a GMM-GMM decoder like PocketSphinx are too small or too large then the decoding performance suffers. One way of estimating this weight is to generate scores from the GMM-HMM decoder being used, fit a linear regression between the GMM-HMM scores and the NN-scores and use the coefficient as the weight. -``` -readSen.py -gmm_score_dir -gmm_ctllist -nn_score_dir -nn_ctllist [-gmm_ext] [-nn_ext] -``` -readSen takes scores (stored in sphinx readable binary files) obtained from a GMM-HMM decoder and a NN, and fit a regression to them. - -## Example workflow with CMUSphinx -- Feature extraction using sphinx_fe: - ``` - sphinx_fe -argfile ../../en_us.ci_cont/feat.params -c etc/wsj0_train.fileids -di wav/ -do feat_ci_mls -mswav yes -eo mls -ei wav -ofmt sphinx -logspec yes - ``` -- State-segmentation using sphinx3_align - ``` - sphinx3_align -hmm ../../en_us.ci_cont/ -dict etc/cmudict.0.6d.wsj0 -ctl etc/wsj0_train.fileids -cepdir feat_ci_mls/ -cepext .mfc -insent etc/wsj0.transcription -outsent wsj0.out -stsegdir stateseg_ci_dir/ -cmn batch - ``` -- Generate dataset using runDatasetGen.py -- Train NN using runNNtrain.py -- Generate predictions from the NN using runNNPredct.py -- Generate predictions from PocketSphinx -``` -pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir feat_ci_mfc/ -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -senlogdir sendump_ci/ -compallsen yes -bestpath no -fwdflat no -remove_noise no -remove_silence no -logbase 1.0001 -pl_window 0 -``` -- Compute the acoustic weight using readSen.py -- Decode the scaled NN predictions with PocketSphinx -``` -pocketsphinx_batch -hmm ../../en_us.ci_cont/ -lm ../../tcb20onp.Z.DMP -cepdir senscores/ -cepext .sen -hyp NN2.hyp -ctl ../../GSOC/SI_ET_20.NDX -dict etc/cmudict.0.6d.wsj0 -compallsen yes -logbase 1.0001 -pl_window 0 -senin yes -``` - - - - diff --git a/scripts/DNN_training/ctc.py b/scripts/DNN_training/ctc.py deleted file mode 100644 index 87363173..00000000 --- a/scripts/DNN_training/ctc.py +++ /dev/null @@ -1,137 +0,0 @@ -import sys -import fst -import random -import math -import numpy as np -from scipy.sparse import bsr_matrix -reload(sys) -sys.setdefaultencoding('utf8') - -def ran_lab_prob(n_samps): - r = [random.random() for i in range(138)] - s = sum(r) - return [[i/s for i in r]]*n_samps - -def genBigGraph(label_prob, symbols, seq_len, label='x'): - t = fst.Transducer() - sym=fst.SymbolTable() - - symbols = map(str,symbols) - x=0 - for j in range(seq_len): - for i in range(len(symbols)): - prob = label_prob[j][i] #"%.4f" % - t.add_arc(0+x, 1+x,str(label+str(j)),symbols[i],-math.log(prob)) - x+=1 - t[j+1].final = -1 - return t - -def gen_utt_graph(labels,symdict): - t2=fst.Transducer() - sym=fst.SymbolTable() - #3x3 states for this example - count = 0 - x = 0 - # print labels - for l in labels: - symbols = symdict[l] - symbols = map(str,symbols) - for i in range(len(symbols)): - if i == 0: - t2.add_arc(0+x,1+x,symbols[i],str(l+"/"+"("+symbols[i]+")")) - else: - t2.add_arc(0+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) - t2.add_arc(1+x,1+x,symbols[i],str(sym.find(0)+"("+symbols[i]+")")) - - x+=1 - - t2[x].final=True - return t2 - -def gen_parents_dict(graph): - parents={} - for state in graph.states: - for arc in state.arcs: - if arc.nextstate in parents: - parents[arc.nextstate].append(state.stateid) - else: - parents[arc.nextstate]=[state.stateid] - return parents - -def make_prob_dict(graph,n_samps,n_labels): - y_t_s = np.zeros((n_samps + 1,n_labels)) # dictionary to store probabilities indexed by time and label - F = [0] - for t in range(n_samps + 1): - # y_t_s[t] = {} - for s in F: - arcs = graph[s].arcs - for a in arcs: - osym = graph.osyms.find(a.olabel) - osym = osym[osym.find("(")+1:osym.find(")")] - y_t_s[t][int(osym)] = np.exp(-1 * float(a.weight)) - F = map(lambda x: map(lambda y: y.nextstate,graph[x].arcs),F) - F = set([s for ss in F for s in ss]) - y_t_s = bsr_matrix(y_t_s,dtype='float32') - return y_t_s - -def calc_alpha(n_samps, symbols, y_t_s): - alpha = {} - # symbols = map(str,symbols) - for t in range(n_samps + 1): - alpha[t] = {} - for i in range(len(symbols)): - # print alpha - # print t,i, - if t == 0: - if i == 0: - alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) - else: - alpha[t][symbols[i]] = 0.0 - else: - if i == 0: - alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * alpha[t-1][symbols[i]] - else: - alpha[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * (alpha[t-1][symbols[i]] + alpha[t-1][symbols[i-1]]) - # print alpha[t][symbols[i]] - return alpha - -def calc_beta(n_samps,symbols,y_t_s): - beta = {} - # symbols = map(str,symbols) - for t in range(n_samps,0,-1): - beta[t] = {} - for i in range(len(symbols)): - if t == n_samps: - if i == len(symbols) - 1: - beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) - else: - beta[t][symbols[i]] = 0.0 - else: - if i < len(symbols) - 1: - score = beta[t+1][symbols[i]] + beta[t+1][symbols[i+1]] - else: - score = beta[t+1][symbols[i]] - beta[t][symbols[i]] = float(y_t_s[t,symbols[i]]) * score - return beta - -def print_graph(t): - for state in t.states: - for arc in state.arcs: - print('{} -> {} / {}:{} / {}'.format(state.stateid, - arc.nextstate, - t.isyms.find(arc.ilabel), - t.osyms.find(arc.olabel), - arc.weight)) -# symbols = ['G1','G2','G3','UH1','UH2','UH3','D1','D2','D3'] -# t = genBigGraph(ran_lab_prob,symbols,11) -# labels = ['G','UH','D'] - -# symdict={'G': ['G1','G2','G3'], -# 'UH': ['UH1','UH2','UH3'], -# 'D': ['D1','D2','D3']} -# t2 = gen_utt_graph(labels, symdict) -# t3 = t>>t2 -# parents = gen_parents_dict(t3) -# y_t_s = make_prob_dict(t3) -# print calc_alpha(10,symbols,y_t_s) -# print calc_beta(10,symbols,y_t_s) \ No newline at end of file diff --git a/scripts/DNN_training/genLabels.py b/scripts/DNN_training/genLabels.py deleted file mode 100644 index cb38ca88..00000000 --- a/scripts/DNN_training/genLabels.py +++ /dev/null @@ -1,339 +0,0 @@ -import numpy as np -from functools import reduce -import os -import threading -import time -import sys -from sklearn.preprocessing import StandardScaler -import utils -from keras.preprocessing.sequence import pad_sequences -import ctc -import fst -import librosa - -done = 0 -def ping(): - curr_time = int(time.time()) - while done == 0: - if (int(time.time()) != curr_time): - curr_time = int(time.time()) - sys.stdout.write('.') - sys.stdout.flush() - - -def read_sen_labels_from_mdef(fname, onlyPhone=True): - labels = np.loadtxt(fname,dtype=str,skiprows=10,usecols=(0,1,2,3,6,7,8)) - labels = map(lambda x: - [reduce(lambda a,b: a+' '+b, - filter(lambda y: y != '-', x[:4]))] + list(x[4:]), labels) - if onlyPhone: - labels = labels[:44] - phone2state = {} - for r in labels: - phone2state[r[0]] = map(int, r[1:]) - return phone2state - -def frame2state(fname, phone2state, onlyPhone=True): - with open(fname,'r') as f: - lines = f.readlines()[2:] - lines = map(lambda x: x.split()[2:], lines) - if onlyPhone: - lines = map(lambda x: x[:2],lines) - else: - lines = map(lambda x: [x[0], reduce(lambda a,b: a+' '+b,x[1:])],lines) - for l in lines: - if l[1] not in phone2state: - l[1] = l[1].split()[0] - states = map(lambda x: phone2state[x[1]][int(x[0])], lines) - return (list(states)) - -def loadDict(filename): - def mySplit(line): - line = line.split() - for i in range(1,len(line)): - line[i] = "{0}1 {0}2 {0}3".format(line[i]) - line = [line[0], reduce(lambda x,y: x+ ' ' +y, line[1:])] - return line - with open(filename) as f: - d = f.readlines() - d = map(lambda x: x.split(),d) - myDict = {} - for r in d: - myDict[r[0]] = r[1:] - return myDict - -def loadTrans(trans_file,pDict): - trans = {} - with open(trans_file) as f: - lines = f.readlines() - for line in lines: - line = line.split() - fname = line[-1][1:-1] - labels = map(lambda x: pDict.setdefault(x,-1), line[:-1]) - labels = filter(lambda x: x!=-1, labels) - if labels == []: - continue - labels = reduce(lambda x,y: x + y, labels) - trans[fname] = labels - return trans - -def trans2labels(trans,phone2state): - d = {} - for u in trans: - labels = trans[u] - labels = map(lambda x: phone2state[x], labels) - labels = reduce(lambda x,y: x + y, labels) - d[u] = labels - return d - -def genDataset(train_flist, dev_flist, test_flist, n_feats, - feat_path, feat_ext, stseg_path, stseg_ext, mdef_fname, - outfile_prefix, context_len=None, - keep_utts=False, ctc_labels=False, pDict_file=None, - trans_file=None, make_graph=False,cqt=False, - max_len=None,n_deltas=0,pad=False): - assert(os.path.exists(stseg_path)) - train_files = np.loadtxt(train_flist,dtype=str) - dev_files = np.loadtxt(dev_flist,dtype=str) - if test_flist != None: - test_files = np.loadtxt(test_flist,dtype=str) - else: - test_files = [] - phone2state = read_sen_labels_from_mdef(mdef_fname,onlyPhone=False) - - if ctc_labels: - pDict = loadDict(pDict_file) - trans = loadTrans(trans_file,pDict) - label_dict = trans2labels(trans, phone2state) - stseg_files_train = filter(lambda x: x.split('/')[-1] in label_dict, train_files) - stseg_files_test = filter(lambda x: x.split('/')[-1] in label_dict, test_files) - stseg_files_dev = filter(lambda x: x.split('/')[-1] in label_dict, dev_files) - stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test - print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) - else: - stseg_files_train = map(lambda x: x.split('/')[-1]+stseg_ext,train_files) - stseg_files_test = map(lambda x: x.split('/')[-1]+stseg_ext,test_files) - stseg_files_dev = map(lambda x: x.split('/')[-1]+stseg_ext,dev_files) - stseg_files_train = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_train) - stseg_files_test = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_test) - stseg_files_dev = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_dev) - - stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test - print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) - - train_files = map(lambda x: feat_path+x+feat_ext,train_files) - dev_files = map(lambda x: feat_path+x+feat_ext,dev_files) - test_files = map(lambda x: feat_path+x+feat_ext,test_files) - - X_Train = [] - Y_Train = [] - X_Test = [] - Y_Test = [] - X_Dev = [] - Y_Dev = [] - framePos_Train = [] - framePos_Test = [] - framePos_Dev = [] - filenames_Train = [] - filenames_Test = [] - filenames_Dev = [] - active_states_Train = [] - active_states_Test = [] - active_states_Dev = [] - # allData = [] - # allLabels = [] - pos = 0 - scaler = StandardScaler(copy=False,with_std=False) - n_states = np.max(phone2state.values())+1 - print n_states - state_freq_Train = [0]*n_states - state_freq_Dev = [0]*n_states - state_freq_Test = [0]*n_states - - - - for i in range(len(stseg_files)): - if i < len(stseg_files_train): - # print '\n train' - frames = framePos_Train - allData = X_Train - allLabels = Y_Train - filenames = filenames_Train - state_freq = state_freq_Train - files = train_files - active_state = active_states_Train - elif i < len(stseg_files_train) + len(stseg_files_dev): - # print '\n dev' - frames = framePos_Dev - allData = X_Dev - allLabels = Y_Dev - filenames = filenames_Dev - state_freq = state_freq_Dev - files = dev_files - active_state = active_states_Dev - else: - # print '\n test' - frames = framePos_Test - allData = X_Test - allLabels = Y_Test - filenames = filenames_Test - state_freq = state_freq_Test - files = test_files - active_state = active_states_Test - - sys.stdout.write("\r%d/%d " % (i,len(stseg_files))) - sys.stdout.flush() - f = stseg_files[i] - - [data_file] = filter(lambda x: f[:-9] in x, files) - if cqt: - y,fs=librosa.load(data_file,sr=None) - data = np.absolute(librosa.cqt(y,sr=fs,window=np.hamming, - hop_length=160, n_bins=64, bins_per_octave=32).T) - # print data.shape - else: - data = utils.readMFC(data_file,n_feats).astype('float32') - data = scaler.fit_transform(data) - - if ctc_labels: - labels = label_dict[data_file.split('/')[-1][:-4]] - if make_graph: - t = ctc.genBigGraph(ctc.ran_lab_prob(data.shape[0]), - set(labels), - data.shape[0]) - t2 = ctc.gen_utt_graph(trans[data_file.split('/')[-1][:-4]],phone2state) - assert set([e for (e,_) in t.osyms.items()]) == set([e for (e,_) in t2.isyms.items()]) - t.osyms = t2.isyms - t3 = t >> t2 - parents = ctc.gen_parents_dict(t3) - y_t_s = ctc.make_prob_dict(t3,data.shape[0],n_states) - active_state.append(y_t_s) - # print active_state - nFrames = data.shape[0] - else: - labels = frame2state(stseg_path + f, phone2state,onlyPhone=False) - nFrames = min(len(labels), data.shape[0]) - sys.stdout.write('(%d,%d) (%d,)' % (data.shape + np.array(labels).shape)) - data = data[:nFrames] - labels = labels[:nFrames] - if context_len != None: - pad_top = np.zeros((context_len,data.shape[1])) - pad_bot = np.zeros((context_len,data.shape[1])) - padded_data = np.concatenate((pad_top,data),axis=0) - padded_data = np.concatenate((padded_data,pad_bot),axis=0) - - data = [] - for j in range(context_len,len(padded_data) - context_len): - new_row = padded_data[j - context_len: j + context_len + 1] - new_row = new_row.flatten() - data.append(new_row) - data = np.array(data) - if n_deltas > 0: - pad_top = np.zeros((n_deltas,data.shape[1])) - pad_bot = np.zeros((n_deltas,data.shape[1])) - padded_data = np.concatenate((pad_top,data),axis=0) - padded_data = np.concatenate((padded_data,pad_bot),axis=0) - data = [] - for j in range(n_deltas,len(padded_data) - n_deltas): - delta_top = padded_data - padded_data[j - n_deltas:j] - delta_bot = padded_data - padded_data[j:j + n_deltas] - new_row = delta_top + padded_data + delta_bot - data.append(new_row) - for l in labels: - state_freq[l] += 1 - filenames.append(data_file) - frames.append(nFrames) - if keep_utts: - allData.append(data) - allLabels.append(np.array(labels)) - else: - allData += list(data) - allLabels += list(labels) - pos += nFrames - if not ctc_labels: - assert(len(allLabels) == len(allData)) - # print allData - print len(allData), len(allLabels) - if max_len == None: - max_len = 100 * ((max(map(len,X_Train)) + 99)/ 100) - print 'max_len', max_len - if keep_utts and pad: - X_Train = pad_sequences(X_Train,maxlen=max_len,dtype='float32',padding='post') - Y_Train = pad_sequences(Y_Train,maxlen=max_len,dtype='float32',padding='post',value=n_states) - Y_Train = Y_Train.reshape(Y_Train.shape[0],Y_Train.shape[1],1) - X_Dev = pad_sequences(X_Dev,maxlen=max_len,dtype='float32',padding='post') - Y_Dev = pad_sequences(Y_Dev,maxlen=max_len,dtype='float32',padding='post',value=n_states) - Y_Dev = Y_Dev.reshape(Y_Dev.shape[0],Y_Dev.shape[1],1) - X_Test = pad_sequences(X_Test,maxlen=max_len,dtype='float32',padding='post') - Y_Test = pad_sequences(Y_Test,maxlen=max_len,dtype='float32',padding='post',value=n_states) - Y_Test = Y_Test.reshape(Y_Test.shape[0],Y_Test.shape[1],1) - # np.savez('wsj0_phonelabels_NFrames',NFrames_Train=NFrames_Train,NFrames_Test=NFrames_Test) - # t = threading.Thread(target=ping) - # t.start() - if context_len != None: - np.save('wsj0_phonelabels_bracketed_train.npy',X_Train) - np.save('wsj0_phonelabels_bracketed_test.npy',X_Test) - np.save('wsj0_phonelabels_bracketed_dev.npy',X_Dev) - np.save('wsj0_phonelabels_bracketed_train_labels.npy',Y_Train) - np.save('wsj0_phonelabels_bracketed_test_labels.npy',Y_Test) - np.save('wsj0_phonelabels_bracketed_dev_labels.npy',Y_Dev) - if make_graph: - np.save('wsj0_phonelabels_bracketed_train_active.npy',active_states_Train) - np.save('wsj0_phonelabels_bracketed_test_active.npy',active_states_Test) - np.save('wsj0_phonelabels_bracketed_dev_active.npy',active_states_Dev) - np.savez('wsj0_phonelabels_bracketed_meta.npz',framePos_Train=framePos_Train, - framePos_Test=framePos_Test, - framePos_Dev=framePos_Dev, - filenames_Train=filenames_Train, - filenames_Dev=filenames_Dev, - filenames_Test=filenames_Test, - state_freq_Train=state_freq_Train, - state_freq_Dev=state_freq_Dev, - state_freq_Test=state_freq_Test) - else: - np.save(outfile_prefix + 'train.npy',X_Train) - np.save(outfile_prefix + 'dev.npy',X_Dev) - np.save(outfile_prefix + 'train_labels.npy',Y_Train) - np.save(outfile_prefix + 'dev_labels.npy',Y_Dev) - if len(X_Test) != 0: - np.save(outfile_prefix + 'test.npy',X_Test) - np.save(outfile_prefix + 'test_labels.npy',Y_Test) - if make_graph: - np.save(outfile_prefix + 'active.npy',active_states_Train) - np.save(outfile_prefix + 'active.npy',active_states_Test) - np.save(outfile_prefix + 'active.npy',active_states_Dev) - np.savez(outfile_prefix + 'meta.npz',framePos_Train=framePos_Train, - framePos_Test=framePos_Test, - framePos_Dev=framePos_Dev, - filenames_Train=filenames_Train, - filenames_Dev=filenames_Dev, - filenames_Test=filenames_Test, - state_freq_Train=state_freq_Train, - state_freq_Dev=state_freq_Dev, - state_freq_Test=state_freq_Test) - # done = 1 - -def normalizeByUtterance(): - data = np.load('wsj0_phonelabels_bracketed_data.npy') - nFrames = np.load('wsj0_phonelabels_bracketed_meta.npz')['framePos_Train'] - # print 'calculating frame indices...' - # nFrames = map(lambda i: sum(nFrames[:i]),xrange(len(nFrames))) - print 'normalizing...' - scaler = StandardScaler(copy=False) - print data - pos = 0 - for i in xrange(len(nFrames)): - sys.stdout.write("\rnormalizing utterance no %d " % i) - sys.stdout.flush() - data[pos:nFrames[i]] = scaler.fit_transform(data[pos:nFrames[i]]) - pos = nFrames[i] - print data -if __name__ == '__main__': - #print(read_sen_labels_from_mdef('../wsj_all_cd30.mllt_cd_cont_4000/mdef')) - # frame2state('../wsj/wsj0/statesegdir/40po031e.wv2.flac.stseg.txt', '../wsj_all_cd30.mllt_cd_cont_4000/mdef') - genDataset('../wsj/wsj0/etc/wsj0_train.fileids','../wsj/wsj0/etc/wsj0_dev.fileids','../wsj/wsj0/etc/wsj0_test.fileids',40,'../wsj/wsj0/feat_cd_mls/','../wsj/wsj0/stateseg_ci_dir/','../en_us.ci_cont/mdef', - keep_utts=True, context_len=None, cqt=True, - trans_file='../wsj/wsj0/etc/wsj0.transcription', - pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') - # normalizeByUtterance() - # ../wsj/wsj0/feat_mls/11_6_1/wsj0/sd_dt_20/00b/00bo0t0e.wv1.flac.mls 00bo0t0e.wv1.flac.stseg.txt \ No newline at end of file diff --git a/scripts/DNN_training/makeFileListFromTrans.py b/scripts/DNN_training/makeFileListFromTrans.py deleted file mode 100644 index 5de9ac1c..00000000 --- a/scripts/DNN_training/makeFileListFromTrans.py +++ /dev/null @@ -1,19 +0,0 @@ -import numpy as np -def getFileListFromTran(trans,outFile): - with open(trans,'r') as f: - lines = f.readlines() - lines = map(lambda x: x.strip(), lines) - files = map(lambda x: x.split('(')[-1][:-1], lines) - np.savetxt(outFile,files,fmt='%s') - -def fixTran(trans): - with open(trans,'r') as f: - lines = f.readlines() - lines = map(lambda x: x.strip(), lines) - lines = map(lambda x: x.split('('), lines) - for l in lines: - l[-1] = l[-1].split('/')[-1] - lines = map(lambda x: reduce(lambda a,b: a+'('+b,x),lines) - np.savetxt(trans+'2',lines,fmt='%s') -# getFileListFromTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans", "../wsj/wsj0/wsj0.filelist") -fixTran("../wsj/wsj0/transcripts/wsj0/wsj0.trans") \ No newline at end of file diff --git a/scripts/DNN_training/readSen.py b/scripts/DNN_training/readSen.py deleted file mode 100644 index b47b38a8..00000000 --- a/scripts/DNN_training/readSen.py +++ /dev/null @@ -1,96 +0,0 @@ -import os -import struct -import numpy as np -from sklearn.linear_model import LinearRegression -from argparse import ArgumentParser - -def readSen(fname, print_most_prob_sen=False): - print fname - f = open(fname,'rb') - s = '' - while 'endhdr\n' not in s: - v = f.read(1) - s += struct.unpack('s',v)[0] - magic_num = struct.unpack('I',f.read(4))[0] - assert magic_num == 0x11223344 - count = 0 - data = [] - while v: - v = f.read(2) - if not v: - continue - n_active = struct.unpack('h',v)[0] - # print n_active - assert n_active == 138 - - v = f.read(2*n_active) - scores = list(struct.unpack('%sh' % n_active, v)) - # print np.argmax(scores) - count += 1 - data += scores - print count - return np.array(data) - -if __name__=='__main__': - parser = ArgumentParser(description="""Given two sets of sen files fits a regression to them and returns the coefficient and the intercept. - Useful in determining the appropriate acoustic weight to scale the outputs of the NN by. Improperly - scaled output perform much worse than appropriatly scaled outputs""", - usage='%(prog)s [options] \nUse --help for option list') - parser.add_argument('-gmm_score_dir',type=str, required=True, - help="The directory where the sen files generated by GMM-HMM decoder are stored. Preppended to file paths in gmm_ctllist") - parser.add_argument('-gmm_ctllist', type=str, required=True, - help='List of all the sen files generated by the GMM-HMM decoder') - parser.add_argument('-nn_score_dir',type=str, required=True, - help="The directory where the sen files generated by a ANN are stored. Preppended to file paths in gmm_ctllist") - parser.add_argument('-nn_ctllist', type=str, required=True, - help='List of all the sen files generated by the ANN') - parser.add_argument('-gmm_ext', type=str, required=False, default='', - help='the file extension applied to all the files in gmm_ctllist') - parser.add_argument('-nn_ext', type=str, required=False, default='', - help='the file extension applied to all the files in nn_ctllist') - args = vars(parser.parse_args()) - # readSen('../wsj/wsj0/senscores/11_14_1/wsj0/si_et_20/440/440c0401.wv1.flac.sen') - ndx_list = map(lambda x: args['nn_score_dir']+x+args['nn_ext'], np.loadtxt(args['nn_ctllist'],dtype=str)) - file_list = map(lambda x: args['gmm_score_dir']+x+args['gmm_ext'], np.loadtxt(args['gmm_ctllist'],dtype=str)) - # file_list = map(lambda x: '../wsj/wsj0/sendump_dev_ci/' + x, os.listdir('../wsj/wsj0/sendump_dev_ci/')) - # file_list.sort() - # file_list = file_list[:-1] - # ndx_list = ['../wsj/wsj0/single_dev_NN/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] - # file_list = ['../wsj/wsj0/single_dev/11_14_1/wsj0/si_et_20/445/445c0403.wv1.flac.sen'] - x = [] - y = [] - for i in range(len(file_list)): - if i >= 0: - if os.path.exists(ndx_list[i]): - print i,ndx_list[i], file_list[i] - _y = list(readSen(ndx_list[i])) - _x = list(readSen(file_list[i])) - if len(_x) != len(_y): - continue - y += _y - x += _x - frame_len = min(len(x),len(y)) - # x = x[:frame_len] - # y = y[:frame_len] - print len(x),len(y), len(x)/138, len(y)/138 - assert len(x) == len(y) - else: - continue - else: - print i,ndx_list[i+1], file_list[i] - y += list(readSen(ndx_list[i+1])) - x += list(readSen(file_list[i])) - x = np.array(x).reshape(-1,1) - y = np.array(y).reshape(-1,1) - # print x.shape, y.shape - data = np.concatenate((x,y),axis=1) - # np.save('data4regression.npy',data) - - # data = np.load('data4regression.npy') - lreg = LinearRegression(normalize=True,n_jobs=-1) - lreg.fit(data[:,[1]],data[:,[0]]) - print "coefficient: %f\t\tintercept: %f" % (lreg.coef_, lreg.intercept_) - - # vs = np.std(data[:,[1]]) - # va = np.std(data[:,[0]]) - # print va/vs diff --git a/scripts/DNN_training/requirements.txt b/scripts/DNN_training/requirements.txt deleted file mode 100644 index c2d0f232..00000000 --- a/scripts/DNN_training/requirements.txt +++ /dev/null @@ -1,67 +0,0 @@ -appdirs==1.4.3 -audioread==2.1.5 -backports.weakref==1.0rc1 -bleach==1.5.0 -cycler==0.10.0 -Cython==0.25.2 -daemonize==2.4.7 -decorator==4.0.6 -editdistance==0.3.1 -funcsigs==1.0.2 -functools32==3.2.3.post2 -graphviz==0.7.1 -guppy==0.1.10 -h5py==2.7.0 -htk-io==0.5 -html5lib==0.9999999 -ipython==2.4.1 -joblib==0.11 -Keras==2.0.6 -Lasagne==0.2.dev1 -librosa==0.5.1 -Mako==1.0.6 -Markdown==2.2.0 -MarkupSafe==1.0 -matplotlib==2.0.2 -memory-profiler==0.47 -mock==2.0.0 -nose==1.3.7 -numpy==1.13.1 -packaging==16.8 -pbr==3.1.1 -pexpect==4.0.1 -posix-ipc==1.0.0 -protobuf==3.3.0 -ptyprocess==0.5 -py==1.4.33 -pycurl==7.43.0 -pydot==1.2.3 -pydot-ng==1.0.0 -pyfst==0.2.3 -pygpu==0.6.5 -pyliblzma==0.5.3 -pyparsing==2.2.0 -pysqlite==1.0.1 -pytest==3.0.7 -python-apt==1.1.0b1 -python-dateutil==2.6.0 -python-speech-features==0.5 -pytools==2016.2.6 -pytz==2017.2 -PyYAML==3.12 -resampy==0.1.5 -rpm-python==4.12.0.1 -scikit-learn==0.18.1 -scipy==0.19.1 -simplegeneric==0.8.1 -six==1.10.0 -subprocess32==3.2.7 -tensorflow-gpu==1.2.0 -tfrbm==0.0.2 -Theano==0.9.0 -tkinter==0.2.0 -tqdm==4.14.0 -urlgrabber==3.9.1 -virtualenv==15.0.1 -Werkzeug==0.12.2 -yum-metadata-parser==1.1.4 diff --git a/scripts/DNN_training/runDatasetGen.py b/scripts/DNN_training/runDatasetGen.py deleted file mode 100644 index d44d47b6..00000000 --- a/scripts/DNN_training/runDatasetGen.py +++ /dev/null @@ -1,41 +0,0 @@ -from argparse import ArgumentParser - -parser = ArgumentParser(description="Generate numpy array from features and alignments produced by Sphinx", - usage='%(prog)s [options] \nUse --help for option list') -parser.add_argument('-train_fileids', type=str, required=True, - help="list of training files") -parser.add_argument('-val_fileids',type=str,required=True, - help='list of validation files') -parser.add_argument('-test_fileids',type=str,required=False, - help='list of test files') -parser.add_argument('-nfilts',type=int,required=True, - help='number of filters used for extracting features. (The dimensionality of the feature vector)') -parser.add_argument('-feat_dir', type=str, required=True, - help='the directory where feature files are stored (prepended to filepaths in the train, val and test filelists when looking for features)') -parser.add_argument('-feat_ext',type=str,required=True, - help='extension to be appended to each file path when looking for feature files') -parser.add_argument('-stseg_dir',type=str,required=True, - help='directory where the state-segmentation for each feature file is stored (prepended to filepaths in the train, val and test filelists when looking for labels)') -parser.add_argument('-stseg_ext',type=str,required=True, - help='extension to be appended to each file path when looking for state-segmentation files') -parser.add_argument('-mdef',type=str,required=True, - help='path to the mdef file for the Sphinx model. Needed to map phones/triphones in segmentation to state labels') -parser.add_argument('-outfile_prefix',type=str,default="", required=False, - help='prepended to the names of the output files') -parser.add_argument('-keep_utts',nargs='?',required=False, default=False, const=True, - help='store features and labels in a 3D array in which each index points to the list of features/labels for one utterance') -args = vars(parser.parse_args()) - -from genLabels import genDataset -genDataset(args['train_fileids'], - args['val_fileids'], - args['test_fileids'], - args['nfilts'], - args['feat_dir'], - args['feat_ext'], - args['stseg_dir'], - args['stseg_ext'], - args['mdef'], - args['outfile_prefix'], - keep_utts=args['keep_utts']) - diff --git a/scripts/DNN_training/runNNPredict.py b/scripts/DNN_training/runNNPredict.py deleted file mode 100644 index c2dfa281..00000000 --- a/scripts/DNN_training/runNNPredict.py +++ /dev/null @@ -1,48 +0,0 @@ -from argparse import ArgumentParser - -parser = ArgumentParser(description="Generate Predictions from a Keras Model and save them in PockeSphinx readable .sen files.", - usage='%(prog)s [options] \nUse --help for option list') -parser.add_argument('-keras_model', type=str, required=True, - help="Keras model to be used for prediction in hd5 format (must be compatible with keras.load_model)") -parser.add_argument('-ctldir',type=str, required=True, - help="the directory for the control files, prepended to each file path in ctllist") -parser.add_argument('-ctllist', type=str,required=True, - help='list of input files, each representing an utterance') -parser.add_argument('-inext', type=str, required=True, - help='the extension of the control files, appended to each file path in ctllist') -parser.add_argument('-outdir', type=str,required=True, - help='Directory where the predictions are stored. The structure of this directory will be identical to ctldir') -parser.add_argument('-outext', type=str, required=True, - help='the extension of the output files') -parser.add_argument('-nfilts', type=int, required=True, - help='dimensionality of the feature vectors') -parser.add_argument('-acoustic_weight',type=float,required=False, - help='The weight to scale the predictions by. Sometimes needed to get meaningful predictions from PocketSphinx') -parser.add_argument('-context_win',type=int, required=False, default=0, - help='number of contextual frames to include from before and after the target frame (defaults to 5)') -parser.add_argument('-cuda_device_id', type=str, required=False, default="", - help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") -args = vars(parser.parse_args()) - -import os -CUDA_VISIBLE_DEVICES = args["cuda_device_id"] -os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES -from keras.models import load_model -from utils import * - -model = load_model(keras_model,custom_objects={'dummy_loss':dummy_loss, - 'decoder_dummy_loss':decoder_dummy_loss, - 'ler':ler}) -# model = Model(inputs=[model.get_layer(name='x').input], -# outputs=[model.get_layer(name='softmax').output]) -print model.summary() -getPredsFromFilelist(model,args['ctllist'], - args['ctldir'], - args['inext'], - args['outdir'], - args['outext'], - context_len=args['context_win'], - # data_preproc_fn = lambda x: pad_sequences([x],maxlen=1000,dtype='float32',padding='post').reshape(1,1000,x.shape[-1]), - # data_postproc_fn = lambda x: x[:,range(138)] / np.sum(x[:,range(138)], axis=1).reshape(-1,1), - weight=args['acoustic_weight'] if args['acoustic_weight'] != None else 0.1, - n_feat=args['nfilts']) \ No newline at end of file diff --git a/scripts/DNN_training/runNNTrain.py b/scripts/DNN_training/runNNTrain.py deleted file mode 100644 index 82049fce..00000000 --- a/scripts/DNN_training/runNNTrain.py +++ /dev/null @@ -1,168 +0,0 @@ -from argparse import ArgumentParser -import numpy as np - -parser = ArgumentParser(description="Train a Keras neural network model.", - usage='%(prog)s [options] \nUse --help for option list') -parser.add_argument('-train_data',type=str, required=True, - help="the training data for the neural network as a saved numpy array of 2D numpy arrays") -parser.add_argument('-train_labels',type=str, required=True, - help="the training labels for the neural network as a saved numpy array of 1D numpy arrays") -parser.add_argument('-val_data',type=str, required=True, - help="the validation data for the neural network as a saved numpy array of 2D numpy arrays") -parser.add_argument('-val_labels',type=str, required=True, - help="the validation labels for the neural network as a saved numpy array of 1D numpy arrays") -parser.add_argument('-nn_config',type=str, required=True, - help='file containing the neural network configuration information (look at sample_mlp.cfg)') -parser.add_argument('-context_win',type=int, required=False, default=5, - help='number of contextual frames to include from before and after the target frame (defaults to 5)') -parser.add_argument('-cuda_device_id', type=str, required=False, default="", - help="The CUDA-capable GPU device to use for execution. If none is specified, the code will execute on the CPU. If specifying multiple devices, separate the id's with commas") -parser.add_argument('-pretrain', nargs='?', required=False, default=False, const=True, - help='Perform layer-wise pretraining of the MLP before starting training. (Use only with dense MLPs)') -parser.add_argument('-keras_model', type=str, required=False, - help="Keras model to be trained in hd5 format (must be compatible with keras.load_model)") -parser.add_argument('-model_name', type=str, required=True, - help='Name to be assigned to the output files') -args = vars(parser.parse_args()) - -import os -CUDA_VISIBLE_DEVICES = args["cuda_device_id"] -os.environ["CUDA_VISIBLE_DEVICES"] = CUDA_VISIBLE_DEVICES -from NNTrain import * -from utils import * -from keras.models import load_model - -def read_config(filename): - with open(filename) as f: - lines = f.readlines() - lines = filter(lambda x: x[0] != '#' and len(x) > 2, lines) - args = {} - for l in lines: - split = l.split() - if split[0] in args: - args[split[0]].append(split[1:]) - else: - args[split[0]] = split[1:] if len(split) > 1 else [] - if len(args[split[0]]) == 1: - args[split[0]] = args[split[0]][0] - return args - -def init_model(args,input_dim,output_dim, nframes): - print args - nn_type = args['type'] - - if nn_type == 'mlp': - model = mlp4(input_dim, - output_dim, - int(args['depth']), - int(args['width']), - nframes, - BN = 'batch_norm' in args, - dropout = float(args.setdefault('dropout',False)), - activation = args.setdefault('activation','sigmoid')) - if nn_type == 'resnet': - model = mlp4(input_dim, - output_dim, - int(args['n_blocks']), - int(args['width']), - nframes, - block_depth=int(args['block_depth']), - dropout=float(args.setdefault('dropout',False)), - BN='batch_norm' in args, - shortcut=True) - if nn_type == 'conv' or nn_type == 'conv+resnet': - print args - assert(len(args['conv']) == len(args['pooling']) or - (type(args['conv']) == str and - type(args['pooling'] == str))) - filts = [] - filt_dims = [] - pooling = [] - max='max' - avg='avg' - if type(args['conv']) == str: - conv = [args['conv']] - pool = [args['pooling']] - else: - conv = args['conv'] - pool = args['pooling'] - for i in range(len(conv)): - filt, dims = eval(conv[i]) - filts.append(int(filt)) - filt_dims.append(dims) - - pooling.append(eval(pool[i])) - if nn_type == 'conv': - model = mlp4(input_dim, - output_dim, - int(args['depth']), - int(args['width']), - nframes, - n_filts=filts, - filt_dims=filt_dims, - pooling=pooling, - conv=True) - else: - model = mlp4(input_dim, - output_dim, - int(args['depth']), - int(args['width']), - nframes, - block_depth=int(args['block_depth']), - n_filts=filts, - filt_dims=filt_dims, - pooling=pooling, - conv=True, - shortcut=True) - - if 'ctc_loss' in args: - model = ctc_model(model) - return model - -x_train = np.load(args['train_data']) -y_train = np.load(args['train_labels']) - -x_test = np.load(args['val_data']) -y_test = np.load(args['val_labels']) - -nClasses = max(map(np.max,y_train)) + 1 - -meta = {} -meta['nFrames_Train'] = sum(map(lambda x: x.shape[0], x_train)) -meta['nFrames_Dev'] = sum(map(lambda x: x.shape[0], x_test)) -meta['state_freq_train'] = np.zeros(nClasses) -for u in y_train: - for r in u: - meta['state_freq_train'][r] += 1 - -# model = mlp1(x_train[0].shape[-1] * 11, nClasses,3,2048,BN=True,regularize=False,lin_boost=False) -conf = read_config(args['nn_config']) -context_len = args['context_win'] -if args['keras_model'] != None: - model = load_model(args['keras_model']) -else: - if 'ctc_loss' in conf: - model = init_model(conf, (None,x_train[0].shape[-1],), - nClasses + 1, 2 * context_len + 1) - fg = gen_bracketed_data(for_CTC=True, n_states=nClasses) - # trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=2,ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) - else: - model = init_model(conf, (x_train[0].shape[-1] * (2 * context_len + 1),), - nClasses, 2 * context_len + 1) - fg = gen_bracketed_data(context_len=context_len) -trainNtest(model,x_train,y_train,x_test,y_test,meta,args['model_name'],batch_size=int(conf['batch_size']),ctc_train=False,fit_generator=fg, pretrain=args['pretrain']) - -# parser.add_argument('ctldir', metavar='-ctldir',type=str, nargs=1, -# help="the directory for the control files, prepended to each file path in ctllist") -# parser.add_argument('ctllist', metavar='-ctllist',type=str,nargs=1, -# help='list of input files, each representing an utterance') -# parser.add_argument('inext', metavar='-inext', type=str, nargs=1, -# help='the extension of the control files, appended to each file path in ctllist') -# parser.add_argument('infmt', metavar='-infmt', type=str, nargs=1, -# default='yes', choices=['mswav','mfc'], -# help='format of the files in the ctllist') -# parser.add_argument('nfilts', metavar='-nfilts',type=int, nargs=1, -# required=False, help="number of features in the input files. Only used if infmt is mfc") -# parser.add_argument('stsegdir', metavar='-stsegdir',type=str,nargs=1, -# help='the directory in which forced alignments are stored') -# parser.add \ No newline at end of file diff --git a/scripts/DNN_training/sample_nn.cfg b/scripts/DNN_training/sample_nn.cfg deleted file mode 100644 index 851e9aba..00000000 --- a/scripts/DNN_training/sample_nn.cfg +++ /dev/null @@ -1,22 +0,0 @@ -#type resnet -#width 2048 -#block_depth 3 -#n_blocks 5 - -type mlp -width 2048 -depth 3 -#dropout 0.25 -batch_norm -activation sigmoid -#ctc_loss -batch_size 512 -optimizer SGD -lr 0.001 - - -#type conv -#conv [84,(6,8)] [168,(3,4)] -#pooling None [max,(3,3),(1,1)] -#width 2048 -#depth 3 \ No newline at end of file diff --git a/scripts/DNN_training/test.csv b/scripts/DNN_training/test.csv deleted file mode 100644 index e69de29b..00000000 diff --git a/scripts/DNN_training/utils.py b/scripts/DNN_training/utils.py deleted file mode 100644 index c9398b89..00000000 --- a/scripts/DNN_training/utils.py +++ /dev/null @@ -1,333 +0,0 @@ -import numpy as np -import struct -import matplotlib.pyplot as plt -import pylab as pl -from sys import stdout -import os -from keras.preprocessing.sequence import pad_sequences -import keras.backend as K -from scipy.sparse import coo_matrix -from sklearn.preprocessing import StandardScaler - -def dummy_loss(y_true,y_pred): - return y_pred -def decoder_dummy_loss(y_true,y_pred): - return K.zeros((1,)) -def ler(y_true, y_pred, **kwargs): - """ - Label Error Rate. For more information see 'tf.edit_distance' - """ - return tf.reduce_mean(tf.edit_distance(y_pred, y_true, **kwargs)) - -def dense2sparse(a): - # rows,cols = a.nonzero() - # data = map(lambda i: a[rows[i],cols[i]], range(rows.shape[0])) - # return coo_matrix((data,(rows,cols)), shape=a.shape,dtype='int32') - return coo_matrix(a,shape=a.shape,dtype='int32') - -def readMFC(fname,nFeats): - data = [] - with open(fname,'rb') as f: - v = f.read(4) - head = struct.unpack('I',v)[0] - v = f.read(nFeats * 4) - while v: - frame = list(struct.unpack('%sf' % nFeats, v)) - data .append(frame) - v = f.read(nFeats * 4) - data = np.array(data) - # print data.shape, head - assert(data.shape[0] * data.shape[1] == head) - return data - -def ctc_labels(labels, blank_labels = []): - new_labels = [] - for i in range(len(labels)): - l_curr = labels[i] - if l_curr not in blank_labels: - if i == 0: - new_labels.append(l_curr) - else: - if l_curr != labels[i-1]: - new_labels.append(l_curr) - return np.array(new_labels) -def _gen_bracketed_data_2D(x,y,nFrames, - context_len,fix_length, - for_CTC): - max_len = ((np.max(nFrames) + 50)/100) * 100 #rounding off to the nearest 100 - batch_size = 2 - while 1: - pos = 0 - nClasses = np.max(y) + 1 - if for_CTC: - alldata = [] - alllabels = [] - for i in xrange(len(nFrames)): - data = x[pos:pos + nFrames[i]] - labels = y[pos:pos + nFrames[i]] - # if for_CTC: - # labels = ctc_labels(labels,blank_labels=range(18) + [108,109,110]) - # if len(labels.shape) == 1: - # labels = to_categorical(labels,num_classes=nClasses) - if context_len != None: - pad_top = np.zeros((context_len,data.shape[1])) - pad_bot = np.zeros((context_len,data.shape[1])) - padded_data = np.concatenate((pad_top,data),axis=0) - padded_data = np.concatenate((padded_data,pad_bot),axis=0) - - data = [] - for j in range(context_len,len(padded_data) - context_len): - new_row = padded_data[j - context_len: j + context_len + 1] - new_row = new_row.flatten() - data.append(new_row) - data = np.array(data) - if for_CTC: - if batch_size != None: - alldata.append(data) - alllabels.append(labels) - - if len(alldata) == batch_size: - alldata = np.array(alldata) - alllabels = np.array(alllabels) - if fix_length: - alldata = pad_sequences(alldata,maxlen=1000,dtype='float32',truncating='post') - alllabels = pad_sequences(alllabels,maxlen=1000,dtype='float32',value=138,truncating='post') - inputs = {'x': alldata, - 'y': alllabels, - 'x_len': np.array(map(lambda x: len(x), alldata)), - 'y_len': np.array(map(lambda x: len(x), alllabels))} - outputs = {'ctc': np.ones([batch_size])} - yield (inputs,outputs) - alldata = [] - alllabels = [] - else: - data = np.array([data]) - labels = np.array([labels]) - inputs = {'x': data, - 'y': labels, - 'x_len': [data.shape[0]], - 'y_len': [labels.shape[0]]} - outputs = {'ctc': labels} - yield (inputs,outputs) - else: - yield (data,labels) - pos += nFrames[i] - -def _gen_bracketed_data_3D(x,y,batch_size,context_len): - epoch_no = 1 - while 1: - print epoch_no - batch_data = [] - batch_labels = [] - for i in range(len(x)): - data = x[i] - labels = y[i] - if context_len != 0: - pad_top = np.zeros((context_len,data.shape[1])) - pad_bot = np.zeros((context_len,data.shape[1])) - padded_data = np.concatenate((pad_top,data),axis=0) - padded_data = np.concatenate((padded_data,pad_bot),axis=0) - - data = [] - for j in range(context_len,len(padded_data) - context_len): - new_row = padded_data[j - context_len: j + context_len + 1] - new_row = new_row.flatten() - data.append(new_row) - data = np.array(data) - seq_len = 0 - while seq_len < len(data) and data[seq_len].any(): - seq_len += 1 - idxs = range(seq_len) - np.random.shuffle(idxs) - for j in idxs: - if len(batch_data) < batch_size: - batch_data.append(data[j]) - batch_labels.append(labels[j]) - else: - batch_data = np.array(batch_data) - batch_labels = np.array(batch_labels) - yield(batch_data,batch_labels) - batch_data = [] - batch_labels = [] - epoch_no += 1 -def gen_ctc_data(alldata,alllabels,batch_size, n_states): - while 1: - for i in range(batch_size,alldata.shape[0]+1,batch_size): - x = alldata[i-batch_size:i] - y = alllabels[i-batch_size:i] - # .reshape(batch_size,alllabels.shape[1]) - max_len = max(map(len,x)) - x = pad_sequences(x,maxlen=max_len,dtype='float32',padding='post') - y = pad_sequences(y,maxlen=max_len,dtype='float32',padding='post',value=n_states) - x = np.array(x) - y = np.array(y) - # print x.shape, y.shape - y_len = [] - # print y - for b in y: - # # print b[-1], int(b[-1]) != 138 - pad_len = 0 - while pad_len < len(b) and int(b[pad_len]) != 138: - pad_len += 1 - y_len.append(pad_len) - y_len = np.array(y_len) - x_len = [] - for b in x: - # print b[-1], int(b[-1]) != 138 - pad_len = 0 - while pad_len < len(b) and b[pad_len].any(): - pad_len += 1 - x_len.append(pad_len) - x_len = np.array(x_len) - # x_len = np.array(map(lambda x: len(x), x)) - # y_len = np.array(map(lambda x: len(x), y)) - # print x.shape,y.shape,x_len,y_len - # print y.shape - # y = dense2sparse(y) - inputs = {'x': x, - 'y': y, - 'x_len': x_len, - 'y_len': y_len} - outputs = {'ctc': np.ones([batch_size]), - 'decoder': dense2sparse(y), - 'softmax': y.reshape(y.shape[0],y.shape[1],1)} - yield(inputs,outputs) - -def gen_bracketed_data(context_len=None,fix_length=False, - for_CTC=False, n_states=None): - if for_CTC: - assert(n_states != None) - return lambda x,y,batch_size: gen_ctc_data(x,y,batch_size,n_states) - else: - return lambda x,y,batch_size: _gen_bracketed_data_3D(x,y,batch_size,context_len) - # return lambda x,y,nf: _gen_bracketed_data(x,y,nf,context_len,fix_length, - # for_CTC) - -def plotFromCSV(modelName, loss_cols=[2,5], acc_cols=[1,4]): - data = np.loadtxt(modelName+'.csv',skiprows=1,delimiter=',') - epoch = data[:,[0]] - acc = data[:,[acc_cols[0]]] - loss = data[:,[loss_cols[0]]] - val_acc = data[:,[acc_cols[1]]] - val_loss = data[:,[loss_cols[1]]] - - fig, ax1 = plt.subplots() - ax1.plot(acc) - ax1.plot(val_acc) - ax2 = ax1.twinx() - ax2.plot(loss,color='r') - ax2.plot(val_loss,color='g') - plt.title('model loss & accuracy') - ax1.set_ylabel('accuracy') - ax2.set_ylabel('loss') - ax1.set_xlabel('epoch') - ax1.legend(['training acc', 'testing acc']) - ax2.legend(['training loss', 'testing loss']) - fig.tight_layout() - plt.savefig(modelName+'.png') - plt.clf() - -def writeSenScores(filename,scores,weight,offset): - n_active = scores.shape[1] - s = '' - s = """s3 -version 0.1 -mdef_file ../../en_us.cd_cont_4000/mdef -n_sen 138 -logbase 1.000100 -endhdr -""" - s += struct.pack('I',0x11223344) - - scores = np.log(scores)/np.log(1.0001) - scores *= -1 - scores -= np.min(scores,axis=1).reshape(-1,1) - # scores = scores.astype(int) - scores *= weight - scores += offset - truncateToShort = lambda x: 32676 if x > 32767 else (-32768 if x < -32768 else x) - vf = np.vectorize(truncateToShort) - scores = vf(scores) - # scores /= np.sum(scores,axis=0) - for r in scores: - # print np.argmin(r) - s += struct.pack('h',n_active) - r_str = struct.pack('%sh' % len(r), *r) - # r_str = reduce(lambda x,y: x+y,r_str) - s += r_str - with open(filename,'w') as f: - f.write(s) - -def getPredsFromArray(model,data,nFrames,filenames,res_dir,res_ext,freqs,preds_in=False,weight=0.1,offset=0): - if preds_in: - preds = data - else: - preds = model.predict(data,verbose=1,batch_size=2048) - pos = 0 - for i in range(len(nFrames)): - fname = filenames[i][:-4] - fname = reduce(lambda x,y: x+'/'+y,fname.split('/')[4:]) - stdout.write("\r%d/%d " % (i,len(filenames))) - stdout.flush() - res_file_path = res_dir+fname+res_ext - dirname = os.path.dirname(res_file_path) - if not os.path.exists(dirname): - os.makedirs(dirname) - # preds = model.predict(data[pos:pos+nFrames[i]],batch_size=nFrames[i]) - writeSenScores(res_file_path,preds[pos:pos+nFrames[i]],freqs,weight,offset) - pos += nFrames[i] - -def getPredsFromFilelist(model,filelist,file_dir,file_ext, - res_dir,res_ext,n_feat=40,context_len=None, - weight=1,offset=0, data_preproc_fn=None, - data_postproc_fn=None): - with open(filelist) as f: - files = f.readlines() - files = map(lambda x: x.strip(),files) - filepaths = map(lambda x: file_dir+x+file_ext,files) - scaler = StandardScaler(copy=False,with_std=False) - for i in range(len(filepaths)): - stdout.write("\r%d/%d " % (i,len(filepaths))) - stdout.flush() - - f = filepaths[i] - if not os.path.exists(f): - print ("\n",f) - continue - data = readMFC(f,n_feat) - data = scaler.fit_transform(data) - - if context_len != None: - pad_top = np.zeros((context_len,data.shape[1])) + data[0] - pad_bot = np.zeros((context_len,data.shape[1])) + data[-1] - padded_data = np.concatenate((pad_top,data),axis=0) - padded_data = np.concatenate((padded_data,pad_bot),axis=0) - - data = [] - for j in range(context_len,len(padded_data) - context_len): - new_row = padded_data[j - context_len: j + context_len + 1] - new_row = new_row.flatten() - data.append(new_row) - data = np.array(data) - if data_preproc_fn != None: - _data = data_preproc_fn(data) - preds = model.predict(_data) - preds = np.squeeze(preds) - else: - preds = model.predict(data) - - if data_postproc_fn != None: - preds = data_postproc_fn(preds) - if preds.shape[0] != data.shape[0]: - preds = preds[:data.shape[0]] - # print np.sum(preds) - # print preds.shape - res_file_path = res_dir+files[i]+res_ext - dirname = os.path.dirname(res_file_path) - if not os.path.exists(dirname): - os.makedirs(dirname) - writeSenScores(res_file_path,preds,weight,offset) - -# a = dense2sparse(np.array([[1,2,3],[4,0,6]])) -# print a.shape -# print np.asarray(a,dtype=long) \ No newline at end of file From e4a6172a06d290bbcecdb0261660aeea1f48a679 Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 14:21:30 -0400 Subject: [PATCH 09/12] without the alginment code --- scripts/19.nn_train/nn_train.pl | 68 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/scripts/19.nn_train/nn_train.pl b/scripts/19.nn_train/nn_train.pl index 53a103a1..23a4b455 100644 --- a/scripts/19.nn_train/nn_train.pl +++ b/scripts/19.nn_train/nn_train.pl @@ -48,15 +48,16 @@ use SphinxTrain::Config; use SphinxTrain::Util; -die "Usage: $0 \n" unless @ARGV == 2; -my ($part, $npart) = @ARGV; - +# die "Usage: $0 \n" unless @ARGV == 2; +# my ($part, $npart) = @ARGV; +#my $part=0; +#my $npart=0; my $hmm_dir = defined($ST::CFG_FORCE_ALIGN_MODELDIR) ? $ST::CFG_FORCE_ALIGN_MODELDIR : "$ST::CFG_MODEL_DIR/$ST::CFG_EXPTNAME.ci_$ST::CFG_DIRLABEL"; -my $logdir = "$ST::CFG_LOG_DIR/11.force_align"; +my $logdir = "$ST::CFG_LOG_DIR/19.nn_train"; my $outdir = "$ST::CFG_BASE_DIR/falignout"; -my $outfile = "$outdir/$ST::CFG_EXPTNAME.alignedtranscripts.$part"; +my $outfile = "$outdir/$ST::CFG_EXPTNAME.alignedtranscripts.d"; my $statepdeffn = $ST::CFG_HMM_TYPE; # indicates the type of HMMs my $mwfloor = 1e-8; @@ -70,7 +71,7 @@ ? $ST::CFG_FORCE_ALIGN_FILLERDICT : "$outdir/$ST::CFG_EXPTNAME.falign.fdict"; my $beam = defined($ST::CFG_FORCE_ALIGN_BEAM) ? $ST::CFG_FORCE_ALIGN_BEAM : 1e-100; -my $logfile = "$logdir/${ST::CFG_EXPTNAME}.$part.falign.log"; +my $logfile = "$logdir/${ST::CFG_EXPTNAME}..falign.log"; # Get the number of utterances open INPUT,"${ST::CFG_LISTOFFILES}" or die "Failed to open $ST::CFG_LISTOFFILES: $!"; @@ -90,10 +91,9 @@ $ctl_counter++; } close INPUT; -$ctl_counter = int ($ctl_counter / $npart) if $npart; $ctl_counter = 1 unless ($ctl_counter); -Log("Force alignment starting: ($part of $npart) ", 'result'); +#Log("Force alignment starting: ($part of $npart) ", 'result'); my @phsegdir; @@ -103,41 +103,23 @@ else{ LogError("Please specity CFG_STSEG_DIR") } - -my $return_value = RunTool - ('sphinx3_align', $logfile, $ctl_counter, - -hmm => $hmm_dir, - -senmgau => $statepdeffn, - -mixwfloor => $mwfloor, - -varfloor => $minvar, - -dict => $dict, - -fdict => $fdict, - -ctl => $ST::CFG_LISTOFFILES, - -ctloffset => $ctl_counter * ($part-1), - -ctlcount => $ctl_counter, - -cepdir => $ST::CFG_FEATFILES_DIR, - -cepext => ".$ST::CFG_FEATFILE_EXTENSION", - -insent => $transcriptfile, - -outsent => $outfile, - @phsegdir, - -beam => $beam, - -agc => $ST::CFG_AGC, - -cmn => $ST::CFG_CMN, - -varnorm => $ST::CFG_VARNORM, - -feat => $ST::CFG_FEATURE, - -ceplen => $ST::CFG_VECTOR_LENGTH, - ); - -if ($return_value) { - LogError("Failed to run sphinx3_align"); -} - -my $return_value = RunTool("gcc -o stseg-read $ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read.c") -my $return_value = RunTool("$ST::CFG_SPHINXTRAIN_DIR/python/DNN_training/readStSeg.sh $ST::CFG_STSEG_DIR" - +Log('Compiling stseg-read'); +my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.stseg_compile.log"); +my $return_value = RunTool("gcc", + $logfile,0, + -o => "$ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read", + "$ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read.c"); +Log('converting stseg files to ASCII'); +my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.stseg2ascii.log"); + +my $return_value = RunTool("$ST::CFG_SPHINXTRAIN_DIR/python/DNN_training/readStSeg.sh $ST::CFG_STSEG_DIR", + $logfile, 0); +Log('generating dataset'); +my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.gendataset.log"); $ENV{PYTHONPATH} .= ':' . File::Spec->catdir($ST::CFG_SPHINXTRAIN_DIR, 'python'); my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runDatasetGen.py'), + $logfile,0, -train_fileids => $ST::CFG_LISTOFFILES, -val_fileids => $ST::CFG_LISTOFFILES, -n_filts => $ST::CFG_VECTOR_LENGTH, @@ -152,15 +134,17 @@ if ($return_value) { LogError("Failed to run runDatasetGen.py"); } - +Log('training nn'); +my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.training.log"); my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runNNTrain.py'), + $logfile,0, -train_data => catfile("$ST::CFG_BASE_DIR","train.py"), -train_label => catfile("$ST::CFG_BASE_DIR","train_labels.py"), -val_data => catfile("$ST::CFG_BASE_DIR","dev.py"), -val_labels => catfile("$ST::CFG_BASE_DIR","dev_labels.py") -nn_config => catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'sample_nn.cfg') -config_win => "4", - -model_name => catfile("$ST::CFG_BASE_DIR","nn","keras_mode.h5") + -model_name => catfile("$ST::CFG_BASE_DIR","nn","keras_mode.h5")); if ($return_value) { LogError("Failed to run runNNTrain.py"); } From 5d695e1b9ead778466bb78797c04fac113db9b3b Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 14:38:06 -0400 Subject: [PATCH 10/12] moved pys to python/cmusphinx --- python/{DNN_training => cmusphinx}/NNTrain.py | 0 python/{DNN_training => cmusphinx}/genLabels.py | 0 python/{DNN_training => cmusphinx}/makeFileListFromTrans.py | 0 python/{DNN_training => cmusphinx}/readSen.py | 0 python/{DNN_training => cmusphinx}/runDatasetGen.py | 0 python/{DNN_training => cmusphinx}/runNNPredict.py | 0 python/{DNN_training => cmusphinx}/runNNTrain.py | 0 python/{DNN_training => cmusphinx}/utils.py | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename python/{DNN_training => cmusphinx}/NNTrain.py (100%) rename python/{DNN_training => cmusphinx}/genLabels.py (100%) rename python/{DNN_training => cmusphinx}/makeFileListFromTrans.py (100%) rename python/{DNN_training => cmusphinx}/readSen.py (100%) rename python/{DNN_training => cmusphinx}/runDatasetGen.py (100%) rename python/{DNN_training => cmusphinx}/runNNPredict.py (100%) rename python/{DNN_training => cmusphinx}/runNNTrain.py (100%) rename python/{DNN_training => cmusphinx}/utils.py (100%) diff --git a/python/DNN_training/NNTrain.py b/python/cmusphinx/NNTrain.py similarity index 100% rename from python/DNN_training/NNTrain.py rename to python/cmusphinx/NNTrain.py diff --git a/python/DNN_training/genLabels.py b/python/cmusphinx/genLabels.py similarity index 100% rename from python/DNN_training/genLabels.py rename to python/cmusphinx/genLabels.py diff --git a/python/DNN_training/makeFileListFromTrans.py b/python/cmusphinx/makeFileListFromTrans.py similarity index 100% rename from python/DNN_training/makeFileListFromTrans.py rename to python/cmusphinx/makeFileListFromTrans.py diff --git a/python/DNN_training/readSen.py b/python/cmusphinx/readSen.py similarity index 100% rename from python/DNN_training/readSen.py rename to python/cmusphinx/readSen.py diff --git a/python/DNN_training/runDatasetGen.py b/python/cmusphinx/runDatasetGen.py similarity index 100% rename from python/DNN_training/runDatasetGen.py rename to python/cmusphinx/runDatasetGen.py diff --git a/python/DNN_training/runNNPredict.py b/python/cmusphinx/runNNPredict.py similarity index 100% rename from python/DNN_training/runNNPredict.py rename to python/cmusphinx/runNNPredict.py diff --git a/python/DNN_training/runNNTrain.py b/python/cmusphinx/runNNTrain.py similarity index 100% rename from python/DNN_training/runNNTrain.py rename to python/cmusphinx/runNNTrain.py diff --git a/python/DNN_training/utils.py b/python/cmusphinx/utils.py similarity index 100% rename from python/DNN_training/utils.py rename to python/cmusphinx/utils.py From be8bed7db532ef8424d34311194a63f4fc6d6afa Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 18:41:14 -0400 Subject: [PATCH 11/12] fixed perl script and integrated with sphinxtrain --- python/Makefile.am | 9 +- python/cmusphinx/genLabels.py | 17 ++-- scripts/19.nn_train/nn_train.pl | 78 +++++++++++------- .../19.nn_train}/readStSegs.sh | 6 +- .../19.nn_train}/sample_nn.cfg | 0 scripts/19.nn_train/stseg-read | Bin 0 -> 13304 bytes .../19.nn_train}/stseg-read.c | 0 7 files changed, 66 insertions(+), 44 deletions(-) rename {python/DNN_training => scripts/19.nn_train}/readStSegs.sh (57%) rename {python/DNN_training => scripts/19.nn_train}/sample_nn.cfg (100%) create mode 100755 scripts/19.nn_train/stseg-read rename {src/libs/libcommon => scripts/19.nn_train}/stseg-read.c (100%) diff --git a/python/Makefile.am b/python/Makefile.am index a6721a1a..9df05301 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -72,6 +72,13 @@ nobase_scripts_SCRIPTS = \ cmusphinx/prune_mixw.py \ cmusphinx/quantize_mixw.py \ cmusphinx/lat2dot.py \ - cmusphinx/qmwx.pyx + cmusphinx/qmwx.pyx \ + cmusphinx/readSen.py \ + cmusphinx/runDatasetGen.py \ + cmusphinx/runNNPredict.py \ + cmusphinx/runNNTrain.py \ + cmusphinx/genLabels.py \ + cmusphinx/utils.py \ + cmusphinx/NNTrain.py EXTRA_DIST = $(nobase_scripts_SCRIPTS) diff --git a/python/cmusphinx/genLabels.py b/python/cmusphinx/genLabels.py index 7517bef3..ec75b2c0 100644 --- a/python/cmusphinx/genLabels.py +++ b/python/cmusphinx/genLabels.py @@ -94,19 +94,20 @@ def genDataset(train_flist, dev_flist, test_flist, n_feats, test_files = [] phone2state = read_sen_labels_from_mdef(mdef_fname) + print len(train_files) stseg_files_train = map(lambda x: x.split('/')[-1]+stseg_ext,train_files) stseg_files_test = map(lambda x: x.split('/')[-1]+stseg_ext,test_files) stseg_files_dev = map(lambda x: x.split('/')[-1]+stseg_ext,dev_files) - stseg_files_train = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_train) - stseg_files_test = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_test) - stseg_files_dev = filter(lambda x: os.path.exists(stseg_path + x), stseg_files_dev) + stseg_files_train = filter(lambda x: os.path.exists(stseg_path + '/' + x), stseg_files_train) + stseg_files_test = filter(lambda x: os.path.exists(stseg_path + '/' + x), stseg_files_test) + stseg_files_dev = filter(lambda x: os.path.exists(stseg_path + '/' + x), stseg_files_dev) stseg_files = stseg_files_train + stseg_files_dev + stseg_files_test print "Training Files: %d Dev Files: %d Testing Files: %d" % (len(stseg_files_train), len(stseg_files_dev), len(stseg_files_test)) - train_files = map(lambda x: feat_path+x+feat_ext,train_files) - dev_files = map(lambda x: feat_path+x+feat_ext,dev_files) - test_files = map(lambda x: feat_path+x+feat_ext,test_files) + train_files = map(lambda x: feat_path+'/'+x+feat_ext,train_files) + dev_files = map(lambda x: feat_path+'/'+x+feat_ext,dev_files) + test_files = map(lambda x: feat_path+'/'+x+feat_ext,test_files) X_Train = [] Y_Train = [] @@ -177,7 +178,7 @@ def genDataset(train_flist, dev_flist, test_flist, n_feats, else: data = utils.readMFC(data_file,n_feats).astype('float32') data = scaler.fit_transform(data) - labels = frame2state(stseg_path + f, phone2state) + labels = frame2state(stseg_path + '/' + f, phone2state) nFrames = min(len(labels), data.shape[0]) sys.stdout.write('(%d,%d) (%d,)' % (data.shape + np.array(labels).shape)) data = data[:nFrames] @@ -275,4 +276,4 @@ def genDataset(train_flist, dev_flist, test_flist, n_feats, genDataset('../wsj/wsj0/etc/wsj0_train.fileids','../wsj/wsj0/etc/wsj0_dev.fileids','../wsj/wsj0/etc/wsj0_test.fileids',40,'../wsj/wsj0/feat_cd_mls/','../wsj/wsj0/stateseg_ci_dir/','../en_us.ci_cont/mdef', keep_utts=True, context_len=None, cqt=True, trans_file='../wsj/wsj0/etc/wsj0.transcription', - pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') \ No newline at end of file + pDict_file='../wsj/wsj0/etc/cmudict.0.6d.wsj0') diff --git a/scripts/19.nn_train/nn_train.pl b/scripts/19.nn_train/nn_train.pl index 23a4b455..e5dceee3 100644 --- a/scripts/19.nn_train/nn_train.pl +++ b/scripts/19.nn_train/nn_train.pl @@ -52,10 +52,15 @@ # my ($part, $npart) = @ARGV; #my $part=0; #my $npart=0; +if ($ST::CFG_TRAIN_DNN ne "yes") { + Log("Skipped: \$ST::CFG_TRAIN_DNN set to \'$ST::CFG_TRAIN_DNN\' in sphinx_train.cfg\n"); + exit(0); +} my $hmm_dir = defined($ST::CFG_FORCE_ALIGN_MODELDIR) ? $ST::CFG_FORCE_ALIGN_MODELDIR : "$ST::CFG_MODEL_DIR/$ST::CFG_EXPTNAME.ci_$ST::CFG_DIRLABEL"; my $logdir = "$ST::CFG_LOG_DIR/19.nn_train"; +#mkdir $logdir, 0755; my $outdir = "$ST::CFG_BASE_DIR/falignout"; my $outfile = "$outdir/$ST::CFG_EXPTNAME.alignedtranscripts.d"; @@ -71,7 +76,7 @@ ? $ST::CFG_FORCE_ALIGN_FILLERDICT : "$outdir/$ST::CFG_EXPTNAME.falign.fdict"; my $beam = defined($ST::CFG_FORCE_ALIGN_BEAM) ? $ST::CFG_FORCE_ALIGN_BEAM : 1e-100; -my $logfile = "$logdir/${ST::CFG_EXPTNAME}..falign.log"; +my $logfile = "$logdir/${ST::CFG_EXPTNAME}.falign.log"; # Get the number of utterances open INPUT,"${ST::CFG_LISTOFFILES}" or die "Failed to open $ST::CFG_LISTOFFILES: $!"; @@ -101,50 +106,59 @@ push @phsegdir, (-stsegdir => "$ST::CFG_STSEG_DIR"); } else{ - LogError("Please specity CFG_STSEG_DIR") + LogError("Please specity CFG_STSEG_DIR"); +} +#Log('Compiling stseg-read'); +#my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.stseg_compile.log"); +#my $return_value = system("gcc -o $ST::CFG_SPHINXTRAIN_DIR/scripts/19.nn_train/19.nn_train/stseg-read $ST::CFG_SPHINXTRAIN_DIR/scripts/19.nn_train/19.nn_train/stseg-read.c"); + +my $return_value = system("sphinx3_align -hmm $hmm_dir -senmgau $statepdeffn -mixwfloor $mwfloor -varfloor $minvar -dict $dict -fdict $fdict -ctl $ST::CFG_LISTOFFILES -cepdir $ST::CFG_FEATFILES_DIR -cepext .$ST::CFG_FEATFILE_EXTENSION -insent $transcriptfile -outsent $outfile @phsegdir -beam $beam -agc $ST::CFG_AGC -cmn $ST::CFG_CMN -varnorm $ST::CFG_VARNORM -feat $ST::CFG_FEATURE -ceplen $ST::CFG_VECTOR_LENGTH > $logdir-align.txt" ); +#my $return_value = RunTool + # ('sphinx3_align', $logfile, $ctl_counter, + # -hmm => $hmm_dir, + # -senmgau => $statepdeffn, + # -mixwfloor => $mwfloor, + # -varfloor => $minvar, + # -dict => $dict, + # -fdict => $fdict, + # -ctl => $ST::CFG_LISTOFFILES, + # -ctlcount => $ctl_counter, + # -cepdir => $ST::CFG_FEATFILES_DIR, + # -cepext => ".$ST::CFG_FEATFILE_EXTENSION", + # -insent => $transcriptfile, + # -outsent => $outfile, + # @phsegdir, + # -beam => $beam, + # -agc => $ST::CFG_AGC, + # -cmn => $ST::CFG_CMN, + # -varnorm => $ST::CFG_VARNORM, + # -feat => $ST::CFG_FEATURE, + # -ceplen => $ST::CFG_VECTOR_LENGTH, + # ); + + +if ($return_value) { + LogError("Failed to run sphinx3_align"); } -Log('Compiling stseg-read'); -my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.stseg_compile.log"); -my $return_value = RunTool("gcc", - $logfile,0, - -o => "$ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read", - "$ST::CFG_SPHINXTRAIN_DIR/src/libs/libcommon/stseg-read.c"); + Log('converting stseg files to ASCII'); -my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.stseg2ascii.log"); +my $logfile = "$logdir/stseg2ascii.log"; -my $return_value = RunTool("$ST::CFG_SPHINXTRAIN_DIR/python/DNN_training/readStSeg.sh $ST::CFG_STSEG_DIR", - $logfile, 0); +my $return_value = system("$ST::CFG_SPHINXTRAIN_DIR/scripts/19.nn_train/readStSegs.sh $ST::CFG_STSEG_DIR $ST::CFG_SPHINXTRAIN_DIR/scripts/19.nn_train > $logdir-convert.txt"); Log('generating dataset'); my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.gendataset.log"); $ENV{PYTHONPATH} .= ':' . File::Spec->catdir($ST::CFG_SPHINXTRAIN_DIR, 'python'); -my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runDatasetGen.py'), - $logfile,0, - -train_fileids => $ST::CFG_LISTOFFILES, - -val_fileids => $ST::CFG_LISTOFFILES, - -n_filts => $ST::CFG_VECTOR_LENGTH, - -feat_dir => $ST::CFG_FEATFILES_DIR, - -feat_ext => ".$ST::CFG_FEATFILE_EXTENSION", - -stseg_dir => "$ST::CFG_STSEG_DIR", - -stseg_ext => "stseg.txt", - -mdef => catfile("$hmm_dir,mdef"), - -outfile_prefix => "$ST::CFG_BASE_DIR/", - -keep_utts); +Log("python $ST::CFG_SPHINXTRAIN_DIR/python/cmusphinx/runDatasetGen.py -train_fileids $ST::CFG_LISTOFFILES -val_fileids $ST::CFG_LISTOFFILES -nfilts $ST::CFG_VECTOR_LENGTH -feat_dir $ST::CFG_FEATFILES_DIR -feat_ext .$ST::CFG_FEATFILE_EXTENSION -stseg_dir $ST::CFG_STSEG_DIR -stseg_ext .stseg.txt -mdef $hmm_dir/mdef -outfile_prefix $ST::CFG_BASE_DIR -keep_utts"); + +my $return_value = system("python $ST::CFG_SPHINXTRAIN_DIR/python/cmusphinx/runDatasetGen.py -train_fileids $ST::CFG_LISTOFFILES -val_fileids $ST::CFG_LISTOFFILES -nfilts $ST::CFG_VECTOR_LENGTH -feat_dir $ST::CFG_FEATFILES_DIR -feat_ext .$ST::CFG_FEATFILE_EXTENSION -stseg_dir $ST::CFG_STSEG_DIR -stseg_ext .stseg.txt -mdef $hmm_dir/mdef -outfile_prefix $ST::CFG_BASE_DIR/ -keep_utts"); if ($return_value) { LogError("Failed to run runDatasetGen.py"); } Log('training nn'); my $logfile = catfile($logdir, "${ST::CFG_EXPTNAME}.training.log"); -my $return_value = RunTool(catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'runNNTrain.py'), - $logfile,0, - -train_data => catfile("$ST::CFG_BASE_DIR","train.py"), - -train_label => catfile("$ST::CFG_BASE_DIR","train_labels.py"), - -val_data => catfile("$ST::CFG_BASE_DIR","dev.py"), - -val_labels => catfile("$ST::CFG_BASE_DIR","dev_labels.py") - -nn_config => catfile($ST::CFG_SPHINXTRAIN_DIR, 'python', 'DNN_training', 'sample_nn.cfg') - -config_win => "4", - -model_name => catfile("$ST::CFG_BASE_DIR","nn","keras_mode.h5")); +my $return_value = system("python $ST::CFG_SPHINXTRAIN_DIR/python/cmusphinx/runNNTrain.py -train_data $ST::CFG_BASE_DIR/train.npy -train_label $ST::CFG_BASE_DIR/train_labels.npy -val_data $ST::CFG_BASE_DIR/dev.npy -val_labels $ST::CFG_BASE_DIR/dev_labels.npy -nn_config $ST::CFG_SPHINXTRAIN_DIR/scripts/19.nn_train/sample_nn.cfg -context_win 4 -model_name $hmm_dir/keras_mode.h5 -n_epochs 3"); if ($return_value) { LogError("Failed to run runNNTrain.py"); } diff --git a/python/DNN_training/readStSegs.sh b/scripts/19.nn_train/readStSegs.sh similarity index 57% rename from python/DNN_training/readStSegs.sh rename to scripts/19.nn_train/readStSegs.sh index e00fcb4d..ece62a12 100755 --- a/python/DNN_training/readStSegs.sh +++ b/scripts/19.nn_train/readStSegs.sh @@ -1,9 +1,9 @@ stseg_fldr="$1" -echo $stseg_fldr +read_fldr="$2" +echo $(pwd) files=$(find "$stseg_fldr/" -name "*.stseg") for f in $files do echo "CONVERTING: "$f - cat $f | ../../src/libs/libcommon/stseg-read > $f.txt - break + cat $f | $read_fldr/stseg-read > $f.txt done diff --git a/python/DNN_training/sample_nn.cfg b/scripts/19.nn_train/sample_nn.cfg similarity index 100% rename from python/DNN_training/sample_nn.cfg rename to scripts/19.nn_train/sample_nn.cfg diff --git a/scripts/19.nn_train/stseg-read b/scripts/19.nn_train/stseg-read new file mode 100755 index 0000000000000000000000000000000000000000..92086dc0b4bb857c8ff3fe80c5934f9ac18d70ca GIT binary patch literal 13304 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 OJqnQi=rZndNBjx;h^8C> literal 0 HcmV?d00001 diff --git a/src/libs/libcommon/stseg-read.c b/scripts/19.nn_train/stseg-read.c similarity index 100% rename from src/libs/libcommon/stseg-read.c rename to scripts/19.nn_train/stseg-read.c From b142cb940562c3f4532379c0a620d074399a12ec Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Shah Date: Mon, 28 Aug 2017 19:05:22 -0400 Subject: [PATCH 12/12] added makefile and sphinxtrain --- scripts/Makefile.am | 5 +++++ scripts/sphinxtrain | 1 + 2 files changed, 6 insertions(+) mode change 100644 => 100755 scripts/sphinxtrain diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 991cc7d8..5de7f52b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -32,6 +32,11 @@ nobase_scripts_SCRIPTS = \ 11.force_align/slave_align.pl \ 12.vtln_align/slave_align.pl \ 12.vtln_align/vtln_align.pl \ + 19.nn_train/nn_train.pl \ + 19.nn_train/readStSegs.sh \ + 19.nn_train/stseg-read.c \ + 19.nn_train/stseg-read \ + 19.nn_train/sample_nn.cfg \ 20.ci_hmm/baum_welch.pl \ 20.ci_hmm/norm_and_launchbw.pl \ 20.ci_hmm/norm.pl \ diff --git a/scripts/sphinxtrain b/scripts/sphinxtrain old mode 100644 new mode 100755 index 61529114..893e5528 --- a/scripts/sphinxtrain +++ b/scripts/sphinxtrain @@ -74,6 +74,7 @@ steps = [ "10.falign_ci_hmm/slave_convg.pl", "11.force_align/slave_align.pl", "12.vtln_align/slave_align.pl", +"19.nn_train/nn_train.pl", "20.ci_hmm/slave_convg.pl", "30.cd_hmm_untied/slave_convg.pl", "40.buildtrees/slave.treebuilder.pl",