This repository has been archived by the owner on Apr 17, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
f2cnn.py
167 lines (152 loc) · 8.99 KB
/
f2cnn.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import os
import argparse
from scripts.processing.OrganiseFiles import OrganiseAllFiles
from scripts.processing.GammatoneFiltering import FilterAllOrganisedFiles
from scripts.processing.EnvelopeExtraction import ExtractAllEnvelopes
from scripts.processing.LabelDataGenerator import GenerateLabelData
from scripts.processing.InputGenerator import GenerateInputData
from scripts.plotting.PlottingProcessing import PlotEnvelopesAndFormantsFromFile
from scripts.CNN.Evaluating import EvaluateOneWavFile, EvaluateRandom, EvaluateWithNoise
from scripts.CNN.Training import TrainAndPlotLoss
from configure import configure
def All(LPF=False, CUTOFF=100):
"""
Does all the treatments required for the training
"""
OrganiseAllFiles()
FilterAllOrganisedFiles()
ExtractAllEnvelopes(LPF, CUTOFF)
GenerateLabelData()
GenerateInputData(LPF, CUTOFF)
def main():
# Dictionaries linking arguments and functions to call
PREPARE_FUNCTIONS = {
'all': All,
'organize': OrganiseAllFiles,
'filter': FilterAllOrganisedFiles,
'envelope': ExtractAllEnvelopes,
'label': GenerateLabelData,
'input': GenerateInputData
}
CNN_FUNCTIONS = {
'train': TrainAndPlotLoss,
'eval': EvaluateOneWavFile, # Applies the CNN to one specified file
'evalnoise': EvaluateWithNoise, # Applies the CNN to one specified file
'evalrand': EvaluateRandom
}
PLOT_FUNCTIONS = {
'gtg': PlotEnvelopesAndFormantsFromFile
}
# Help texts for some argument groups
preparationHelpText = """Data Processing Commands:\n\t\
organize:\tOrganizes the files as needed for the rest\n\t\t\t(Check OrganiseFiles.py documentation)\n\t\
filter:\t\tApplies the GammaTone FilterBank to the organized files.\n\t\t\tSaves its outputs in .GFB.npy format\n\t\
envelope:\tExtracts the filtered files' envelopes.\n\t\t\tUsing --cutoff CUTOFF as low pass filter cutoff frequency.\n\t\t\tSaves them in .ENV1.npy format\n\t\
label:\t\tGenerates Labeling data for the CNN\n\t\
input\t\tGenerates Input data for the CNN, requires label first\n\t\
all:\t\tDoes all of the above, can take some time.
"""
cnnHelpText = """CNN Related Commands:\n\t\
train:\tTrains the CNN.\n\t\tUse --file command to give the path to an input data numpy matrix\n\t\tOtherwise, uses the input_data.npy file in trainingData/ directory.\n\t\
eval:\tEvaluates a keras model using one WAV file.\n\t\t
evalrand:\tEvaluates all the .WAV files in resources/f2cnn/* in a random order.\n\t\tMay be interrupted whenever, if needed.
"""
fileHelpText = "Used to give a file path as an argument to some scripts."
inputHelpText = "Used to give a path to an input numpy file as an argument to some scripts."
labelHelpText = "Used to give a path to a label csv file as an argument to some scripts."
modelHelpText = "Used to give the path to a keras model as an argument to some scripts."
# ##### PARSING
parser = argparse.ArgumentParser(description="F2CNN Project's entry script.",
epilog="For additional information, add -h after any positional argument")
parser.add_argument('--configure','-c', action='store_true', help='Generates a configuration file for the project')
subparsers = parser.add_subparsers()
# Parser for data processing purposes
parser_prepare = subparsers.add_parser('prepare', help='Runs the command given in argument.',
formatter_class=argparse.RawTextHelpFormatter)
parser_prepare.add_argument('--cutoff', '-c', action='store', dest='CUTOFF', type=int,
help="If used, low pass filter of given argument as cutoff frequency will be used")
parser_prepare.add_argument('prepare_command', choices=PREPARE_FUNCTIONS.keys(), help=preparationHelpText)
parser_prepare.add_argument('--file', '-f', action='store', dest='file', nargs='?', help=fileHelpText)
parser_prepare.add_argument('--input', '-i', action='store', dest='inputFile', nargs='?', help=inputHelpText)
parser_prepare.add_argument('--label', '-l', action='store', dest='labelFile', nargs='?', help=labelHelpText)
# Parser for plotting purposes
parser_plot = subparsers.add_parser('plot', help='For plotting spectrogram-like figure from .WAV file.')
parser_plot.add_argument('plot_type', choices=PLOT_FUNCTIONS.keys(),
help="gtg: Plots a spectrogram like figure from the output of a GammaTone FilterBank applied\
to the given file, and if a .FB file exists in the dir, also plots the Formants.")
parser_plot.add_argument('--file', '-f', action='store', dest='file', nargs='?', help=fileHelpText)
# Parser for the CNN
parser_cnn = subparsers.add_parser('cnn', help='Commands related to training, testing and using the CNN.',
formatter_class=argparse.RawTextHelpFormatter)
parser_cnn.add_argument('--file', '-f', action='store', dest='file', nargs='?', help=fileHelpText)
parser_cnn.add_argument('--input', '-i', action='store', dest='inputFile', nargs='?', help=inputHelpText)
parser_cnn.add_argument('--label', '-l', action='store', dest='labelFile', nargs='?', help=labelHelpText)
parser_cnn.add_argument('--model', '-m', action='store', dest='model', nargs='?', help=modelHelpText)
parser_cnn.add_argument('cnn_command', choices=CNN_FUNCTIONS.keys(), help=cnnHelpText)
parser_cnn.add_argument('--count', '-c', action='store', type=int, help="Number of files to be evaluated")
parser_cnn.add_argument('--lpf', action='store', type=int, dest='CUTOFF',
help="Use Low Pass Filtering on Input Data")
parser_cnn.add_argument('--noise', '-n', action='store', type=float, dest='SNRdB',
help="To use with evalnoise to give a SNR in dB.")
# Processes the input arguments
args = parser.parse_args()
# print("Arguments:")
# for arg in args.__dict__.keys():
# print("\t{}: {}".format(arg,args.__dict__[arg]))
# Calls to functions according to arguments
if 'prepare_command' in args:
prepare_args={}
if args.prepare_command in ['envelope', 'input', 'all']: # In case we need to use a low pass filter
prepare_args['LPF']=False if args.CUTOFF is None else True
prepare_args['CUTOFF']=args.CUTOFF
if args.prepare_command == 'input':
if args.labelFile is not None:
prepare_args['labelFile']=args.labelFile
if args.inputFile is not None:
prepare_args['inputFile']=args.inputFile
PREPARE_FUNCTIONS[args.prepare_command](**prepare_args)
elif 'plot_type' in args:
if args.file is None:
print("Please use --file or -f to give input file")
else:
print("Plotting for file {}...".format(args.file))
PlotEnvelopesAndFormantsFromFile(args.file)
elif 'cnn_command' in args:
if args.cnn_command == 'train':
inputFile = args.file or os.path.join('trainingData', 'last_input_data.npy')
labelFile = args.labelFile or os.path.join('trainingData', 'label_data.csv')
if not os.path.isfile(inputFile):
print(
"Please first generate the input data file with 'prepare input',\n\
or give a path to an input data file with --input")
print(
"Reminder: input data files generated with 'prepare input' are stored in \n\
trainingData/ as 'input_data_LPFX.npy or 'input_data_NOLPF.npy', depending on Low Pass Filtering used.")
if not os.path.isfile(labelFile):
print(
"Please first generate a label data file with 'prepare label',\n\
or give a path to a label data file with --label")
print(
"Reminder: label data files generated with 'prepare label' are stored in \n\
trainingData/ as 'label_data.csv'.")
CNN_FUNCTIONS[args.cnn_command](labelFile=labelFile, inputFile=inputFile)
return
elif 'file' in args and args.file is not None:
evalArgs = {'file': args.file}
if 'CUTOFF' in args and args.CUTOFF is not None:
evalArgs['LPF'] = True
evalArgs['CUTOFF'] = args.CUTOFF
if 'model' in args and args.model is not None:
evalArgs['model'] = args.model
if args.cnn_command == 'evalnoise' and 'SNRdB' in args and args.SNRdB is not None:
evalArgs['SNRdB'] = args.SNRdB
if args.cnn_command == 'evalrand' and 'count' in args and args.count is not None:
evalArgs['COUNT'] = args.count
CNN_FUNCTIONS[args.cnn_command](**evalArgs)
elif args.configure:
configure()
else:
print("No valid command given.")
print("For help, use python3 f2cnn.py --help or -h, or check the documentation on github.")
if __name__ == '__main__':
main()