uisrnn.utils
Utils for UIS-RNN.
1# Copyright 2018 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Utils for UIS-RNN.""" 15 16import random 17import string 18 19import numpy as np 20import torch 21from torch import autograd 22 23 24class Logger: 25 """A class for printing logging information to screen.""" 26 27 def __init__(self, verbosity): 28 self._verbosity = verbosity 29 30 def print(self, level, message): 31 """Print a message if level is not higher than verbosity. 32 33 Args: 34 level: the level of this message, smaller value means more important 35 message: the message to be printed 36 """ 37 if level <= self._verbosity: 38 print(message) 39 40 41def generate_random_string(length=6): 42 """Generate a random string of upper case letters and digits. 43 44 Args: 45 length: length of the generated string 46 47 Returns: 48 the generated string 49 """ 50 return ''.join([ 51 random.choice(string.ascii_uppercase + string.digits) 52 for _ in range(length)]) 53 54 55def enforce_cluster_id_uniqueness(cluster_ids): 56 """Enforce uniqueness of cluster id across sequences. 57 58 Args: 59 cluster_ids: a list of 1-dim list/numpy.ndarray of strings 60 61 Returns: 62 a new list with same length of cluster_ids 63 64 Raises: 65 TypeError: if cluster_ids or its element has wrong type 66 """ 67 if not isinstance(cluster_ids, list): 68 raise TypeError('cluster_ids must be a list') 69 new_cluster_ids = [] 70 for cluster_id in cluster_ids: 71 sequence_id = generate_random_string() 72 if isinstance(cluster_id, np.ndarray): 73 cluster_id = cluster_id.tolist() 74 if not isinstance(cluster_id, list): 75 raise TypeError('Elements of cluster_ids must be list or numpy.ndarray') 76 new_cluster_id = ['_'.join([sequence_id, s]) for s in cluster_id] 77 new_cluster_ids.append(new_cluster_id) 78 return new_cluster_ids 79 80 81def concatenate_training_data(train_sequences, train_cluster_ids, 82 enforce_uniqueness=True, shuffle=True): 83 """Concatenate training data. 84 85 Args: 86 train_sequences: a list of 2-dim numpy arrays to be concatenated 87 train_cluster_ids: a list of 1-dim list/numpy.ndarray of strings 88 enforce_uniqueness: a boolean indicated whether we should enfore uniqueness 89 to train_cluster_ids 90 shuffle: whether to randomly shuffle input order 91 92 Returns: 93 concatenated_train_sequence: a 2-dim numpy array 94 concatenated_train_cluster_id: a list of strings 95 96 Raises: 97 TypeError: if input has wrong type 98 ValueError: if sizes/dimensions of input or their elements are incorrect 99 """ 100 # check input 101 if not isinstance(train_sequences, list) or not isinstance( 102 train_cluster_ids, list): 103 raise TypeError('train_sequences and train_cluster_ids must be lists') 104 if len(train_sequences) != len(train_cluster_ids): 105 raise ValueError( 106 'train_sequences and train_cluster_ids must have same size') 107 train_cluster_ids = [ 108 x.tolist() if isinstance(x, np.ndarray) else x 109 for x in train_cluster_ids] 110 global_observation_dim = None 111 for i, (train_sequence, train_cluster_id) in enumerate( 112 zip(train_sequences, train_cluster_ids)): 113 train_length, observation_dim = train_sequence.shape 114 if i == 0: 115 global_observation_dim = observation_dim 116 elif global_observation_dim != observation_dim: 117 raise ValueError( 118 'train_sequences must have consistent observation dimension') 119 if not isinstance(train_cluster_id, list): 120 raise TypeError( 121 'Elements of train_cluster_ids must be list or numpy.ndarray') 122 if len(train_cluster_id) != train_length: 123 raise ValueError( 124 'Each train_sequence and its train_cluster_id must have same length') 125 126 # enforce uniqueness 127 if enforce_uniqueness: 128 train_cluster_ids = enforce_cluster_id_uniqueness(train_cluster_ids) 129 130 # random shuffle 131 if shuffle: 132 zipped_input = list(zip(train_sequences, train_cluster_ids)) 133 random.shuffle(zipped_input) 134 train_sequences, train_cluster_ids = zip(*zipped_input) 135 136 # concatenate 137 concatenated_train_sequence = np.concatenate(train_sequences, axis=0) 138 concatenated_train_cluster_id = [x for train_cluster_id in train_cluster_ids 139 for x in train_cluster_id] 140 return concatenated_train_sequence, concatenated_train_cluster_id 141 142 143def sample_permuted_segments(index_sequence, number_samples): 144 """Sample sequences with permuted blocks. 145 146 Args: 147 index_sequence: (integer array, size: L) 148 - subsequence index 149 For example, index_sequence = [1,2,6,10,11,12]. 150 number_samples: (integer) 151 - number of subsampled block-preserving permuted sequences. 152 For example, number_samples = 5 153 154 Returns: 155 sampled_index_sequences: (a list of numpy arrays) - a list of subsampled 156 block-preserving permuted sequences. For example, 157 ``` 158 sampled_index_sequences = 159 [[10,11,12,1,2,6], 160 [6,1,2,10,11,12], 161 [1,2,10,11,12,6], 162 [6,1,2,10,11,12], 163 [1,2,6,10,11,12]] 164 ``` 165 The length of "sampled_index_sequences" is "number_samples". 166 """ 167 segments = [] 168 if len(index_sequence) == 1: 169 segments.append(index_sequence) 170 else: 171 prev = 0 172 for i in range(len(index_sequence) - 1): 173 if index_sequence[i + 1] != index_sequence[i] + 1: 174 segments.append(index_sequence[prev:(i + 1)]) 175 prev = i + 1 176 if i + 1 == len(index_sequence) - 1: 177 segments.append(index_sequence[prev:]) 178 # sample permutations 179 sampled_index_sequences = [] 180 for _ in range(number_samples): 181 segments_array = [] 182 permutation = np.random.permutation(len(segments)) 183 for permutation_item in permutation: 184 segments_array.append(segments[permutation_item]) 185 sampled_index_sequences.append(np.concatenate(segments_array)) 186 return sampled_index_sequences 187 188 189def resize_sequence(sequence, cluster_id, num_permutations=None): 190 """Resize sequences for packing and batching. 191 192 Args: 193 sequence: (real numpy matrix, size: seq_len*obs_size) - observed sequence 194 cluster_id: (numpy vector, size: seq_len) - cluster indicator sequence 195 num_permutations: int - Number of permutations per utterance sampled. 196 197 Returns: 198 sub_sequences: A list of numpy array, with obsevation vector from the same 199 cluster in the same list. 200 seq_lengths: The length of each cluster (+1). 201 """ 202 # merge sub-sequences that belong to a single cluster to a single sequence 203 unique_id = np.unique(cluster_id) 204 sub_sequences = [] 205 seq_lengths = [] 206 if num_permutations and num_permutations > 1: 207 for i in unique_id: 208 idx_set = np.where(cluster_id == i)[0] 209 sampled_idx_sets = sample_permuted_segments(idx_set, num_permutations) 210 for j in range(num_permutations): 211 sub_sequences.append(sequence[sampled_idx_sets[j], :]) 212 seq_lengths.append(len(idx_set) + 1) 213 else: 214 for i in unique_id: 215 idx_set = np.where(cluster_id == i) 216 sub_sequences.append(sequence[idx_set, :][0]) 217 seq_lengths.append(len(idx_set[0]) + 1) 218 return sub_sequences, seq_lengths 219 220 221def pack_sequence( 222 sub_sequences, seq_lengths, batch_size, observation_dim, device): 223 """Pack sequences for training. 224 225 Args: 226 sub_sequences: A list of numpy array, with obsevation vector from the same 227 cluster in the same list. 228 seq_lengths: The length of each cluster (+1). 229 batch_size: int or None - Run batch learning if batch_size is None. Else, 230 run online learning with specified batch size. 231 observation_dim: int - dimension for observation vectors 232 device: str - Your device. E.g., `cuda:0` or `cpu`. 233 234 Returns: 235 packed_rnn_input: (PackedSequence object) packed rnn input 236 rnn_truth: ground truth 237 """ 238 num_clusters = len(seq_lengths) 239 sorted_seq_lengths = np.sort(seq_lengths)[::-1] 240 permute_index = np.argsort(seq_lengths)[::-1] 241 242 if batch_size is None: 243 rnn_input = np.zeros((sorted_seq_lengths[0], 244 num_clusters, 245 observation_dim)) 246 for i in range(num_clusters): 247 rnn_input[1:sorted_seq_lengths[i], i, 248 :] = sub_sequences[permute_index[i]] 249 rnn_input = autograd.Variable( 250 torch.from_numpy(rnn_input).float()).to(device) 251 packed_rnn_input = torch.nn.utils.rnn.pack_padded_sequence( 252 rnn_input, sorted_seq_lengths, batch_first=False) 253 else: 254 mini_batch = np.sort(np.random.choice(num_clusters, batch_size)) 255 rnn_input = np.zeros((sorted_seq_lengths[mini_batch[0]], 256 batch_size, 257 observation_dim)) 258 for i in range(batch_size): 259 rnn_input[1:sorted_seq_lengths[mini_batch[i]], 260 i, :] = sub_sequences[permute_index[mini_batch[i]]] 261 rnn_input = autograd.Variable( 262 torch.from_numpy(rnn_input).float()).to(device) 263 packed_rnn_input = torch.nn.utils.rnn.pack_padded_sequence( 264 rnn_input, sorted_seq_lengths[mini_batch], batch_first=False) 265 # ground truth is the shifted input 266 rnn_truth = rnn_input[1:, :, :] 267 return packed_rnn_input, rnn_truth 268 269 270def output_result(model_args, training_args, test_record): 271 """Produce a string to summarize the experiment.""" 272 accuracy_array, _ = zip(*test_record) 273 total_accuracy = np.mean(accuracy_array) 274 output_string = """ 275Config: 276 sigma_alpha: {} 277 sigma_beta: {} 278 crp_alpha: {} 279 learning rate: {} 280 regularization: {} 281 batch size: {} 282 283Performance: 284 averaged accuracy: {:.6f} 285 accuracy numbers for all testing sequences: 286 """.strip().format( 287 training_args.sigma_alpha, 288 training_args.sigma_beta, 289 model_args.crp_alpha, 290 training_args.learning_rate, 291 training_args.regularization_weight, 292 training_args.batch_size, 293 total_accuracy) 294 for accuracy in accuracy_array: 295 output_string += '\n {:.6f}'.format(accuracy) 296 output_string += '\n' + '=' * 80 + '\n' 297 filename = 'layer_{}_{}_{:.1f}_result.txt'.format( 298 model_args.rnn_hidden_size, 299 model_args.rnn_depth, model_args.rnn_dropout) 300 with open(filename, 'a') as file_object: 301 file_object.write(output_string) 302 return output_string 303 304 305def estimate_transition_bias(cluster_ids, smooth=1): 306 """Estimate the transition bias. 307 308 Args: 309 cluster_id: Either a list of cluster indicator sequences, or a single 310 concatenated sequence. The former is strongly preferred, since the 311 transition_bias estimated from the latter will be inaccurate. 312 smooth: int or float - Smoothing coefficient, avoids -inf value in np.log 313 in the case of a sequence with a single speaker and division by 0 in the 314 case of empty sequences. Using a small value for smooth decreases the 315 bias in the calculation of transition_bias but can also lead to underflow 316 in some remote cases, larger values are safer but less accurate. 317 318 Returns: 319 bias: Flipping coin head probability. 320 bias_denominator: The denominator of the bias, used for multiple calls to 321 fit(). 322 """ 323 transit_num = smooth 324 bias_denominator = 2 * smooth 325 for cluster_id_seq in cluster_ids: 326 for entry in range(len(cluster_id_seq) - 1): 327 transit_num += (cluster_id_seq[entry] != cluster_id_seq[entry + 1]) 328 bias_denominator += 1 329 bias = transit_num / bias_denominator 330 return bias, bias_denominator
25class Logger: 26 """A class for printing logging information to screen.""" 27 28 def __init__(self, verbosity): 29 self._verbosity = verbosity 30 31 def print(self, level, message): 32 """Print a message if level is not higher than verbosity. 33 34 Args: 35 level: the level of this message, smaller value means more important 36 message: the message to be printed 37 """ 38 if level <= self._verbosity: 39 print(message)
A class for printing logging information to screen.
31 def print(self, level, message): 32 """Print a message if level is not higher than verbosity. 33 34 Args: 35 level: the level of this message, smaller value means more important 36 message: the message to be printed 37 """ 38 if level <= self._verbosity: 39 print(message)
Print a message if level is not higher than verbosity.
Args: level: the level of this message, smaller value means more important message: the message to be printed
42def generate_random_string(length=6): 43 """Generate a random string of upper case letters and digits. 44 45 Args: 46 length: length of the generated string 47 48 Returns: 49 the generated string 50 """ 51 return ''.join([ 52 random.choice(string.ascii_uppercase + string.digits) 53 for _ in range(length)])
Generate a random string of upper case letters and digits.
Args: length: length of the generated string
Returns: the generated string
56def enforce_cluster_id_uniqueness(cluster_ids): 57 """Enforce uniqueness of cluster id across sequences. 58 59 Args: 60 cluster_ids: a list of 1-dim list/numpy.ndarray of strings 61 62 Returns: 63 a new list with same length of cluster_ids 64 65 Raises: 66 TypeError: if cluster_ids or its element has wrong type 67 """ 68 if not isinstance(cluster_ids, list): 69 raise TypeError('cluster_ids must be a list') 70 new_cluster_ids = [] 71 for cluster_id in cluster_ids: 72 sequence_id = generate_random_string() 73 if isinstance(cluster_id, np.ndarray): 74 cluster_id = cluster_id.tolist() 75 if not isinstance(cluster_id, list): 76 raise TypeError('Elements of cluster_ids must be list or numpy.ndarray') 77 new_cluster_id = ['_'.join([sequence_id, s]) for s in cluster_id] 78 new_cluster_ids.append(new_cluster_id) 79 return new_cluster_ids
Enforce uniqueness of cluster id across sequences.
Args: cluster_ids: a list of 1-dim list/numpy.ndarray of strings
Returns: a new list with same length of cluster_ids
Raises: TypeError: if cluster_ids or its element has wrong type
82def concatenate_training_data(train_sequences, train_cluster_ids, 83 enforce_uniqueness=True, shuffle=True): 84 """Concatenate training data. 85 86 Args: 87 train_sequences: a list of 2-dim numpy arrays to be concatenated 88 train_cluster_ids: a list of 1-dim list/numpy.ndarray of strings 89 enforce_uniqueness: a boolean indicated whether we should enfore uniqueness 90 to train_cluster_ids 91 shuffle: whether to randomly shuffle input order 92 93 Returns: 94 concatenated_train_sequence: a 2-dim numpy array 95 concatenated_train_cluster_id: a list of strings 96 97 Raises: 98 TypeError: if input has wrong type 99 ValueError: if sizes/dimensions of input or their elements are incorrect 100 """ 101 # check input 102 if not isinstance(train_sequences, list) or not isinstance( 103 train_cluster_ids, list): 104 raise TypeError('train_sequences and train_cluster_ids must be lists') 105 if len(train_sequences) != len(train_cluster_ids): 106 raise ValueError( 107 'train_sequences and train_cluster_ids must have same size') 108 train_cluster_ids = [ 109 x.tolist() if isinstance(x, np.ndarray) else x 110 for x in train_cluster_ids] 111 global_observation_dim = None 112 for i, (train_sequence, train_cluster_id) in enumerate( 113 zip(train_sequences, train_cluster_ids)): 114 train_length, observation_dim = train_sequence.shape 115 if i == 0: 116 global_observation_dim = observation_dim 117 elif global_observation_dim != observation_dim: 118 raise ValueError( 119 'train_sequences must have consistent observation dimension') 120 if not isinstance(train_cluster_id, list): 121 raise TypeError( 122 'Elements of train_cluster_ids must be list or numpy.ndarray') 123 if len(train_cluster_id) != train_length: 124 raise ValueError( 125 'Each train_sequence and its train_cluster_id must have same length') 126 127 # enforce uniqueness 128 if enforce_uniqueness: 129 train_cluster_ids = enforce_cluster_id_uniqueness(train_cluster_ids) 130 131 # random shuffle 132 if shuffle: 133 zipped_input = list(zip(train_sequences, train_cluster_ids)) 134 random.shuffle(zipped_input) 135 train_sequences, train_cluster_ids = zip(*zipped_input) 136 137 # concatenate 138 concatenated_train_sequence = np.concatenate(train_sequences, axis=0) 139 concatenated_train_cluster_id = [x for train_cluster_id in train_cluster_ids 140 for x in train_cluster_id] 141 return concatenated_train_sequence, concatenated_train_cluster_id
Concatenate training data.
Args: train_sequences: a list of 2-dim numpy arrays to be concatenated train_cluster_ids: a list of 1-dim list/numpy.ndarray of strings enforce_uniqueness: a boolean indicated whether we should enfore uniqueness to train_cluster_ids shuffle: whether to randomly shuffle input order
Returns: concatenated_train_sequence: a 2-dim numpy array concatenated_train_cluster_id: a list of strings
Raises: TypeError: if input has wrong type ValueError: if sizes/dimensions of input or their elements are incorrect
144def sample_permuted_segments(index_sequence, number_samples): 145 """Sample sequences with permuted blocks. 146 147 Args: 148 index_sequence: (integer array, size: L) 149 - subsequence index 150 For example, index_sequence = [1,2,6,10,11,12]. 151 number_samples: (integer) 152 - number of subsampled block-preserving permuted sequences. 153 For example, number_samples = 5 154 155 Returns: 156 sampled_index_sequences: (a list of numpy arrays) - a list of subsampled 157 block-preserving permuted sequences. For example, 158 ``` 159 sampled_index_sequences = 160 [[10,11,12,1,2,6], 161 [6,1,2,10,11,12], 162 [1,2,10,11,12,6], 163 [6,1,2,10,11,12], 164 [1,2,6,10,11,12]] 165 ``` 166 The length of "sampled_index_sequences" is "number_samples". 167 """ 168 segments = [] 169 if len(index_sequence) == 1: 170 segments.append(index_sequence) 171 else: 172 prev = 0 173 for i in range(len(index_sequence) - 1): 174 if index_sequence[i + 1] != index_sequence[i] + 1: 175 segments.append(index_sequence[prev:(i + 1)]) 176 prev = i + 1 177 if i + 1 == len(index_sequence) - 1: 178 segments.append(index_sequence[prev:]) 179 # sample permutations 180 sampled_index_sequences = [] 181 for _ in range(number_samples): 182 segments_array = [] 183 permutation = np.random.permutation(len(segments)) 184 for permutation_item in permutation: 185 segments_array.append(segments[permutation_item]) 186 sampled_index_sequences.append(np.concatenate(segments_array)) 187 return sampled_index_sequences
Sample sequences with permuted blocks.
Args: index_sequence: (integer array, size: L) - subsequence index For example, index_sequence = [1,2,6,10,11,12]. number_samples: (integer) - number of subsampled block-preserving permuted sequences. For example, number_samples = 5
Returns: sampled_index_sequences: (a list of numpy arrays) - a list of subsampled block-preserving permuted sequences. For example,
sampled_index_sequences =
[[10,11,12,1,2,6],
[6,1,2,10,11,12],
[1,2,10,11,12,6],
[6,1,2,10,11,12],
[1,2,6,10,11,12]]
The length of "sampled_index_sequences" is "number_samples".
190def resize_sequence(sequence, cluster_id, num_permutations=None): 191 """Resize sequences for packing and batching. 192 193 Args: 194 sequence: (real numpy matrix, size: seq_len*obs_size) - observed sequence 195 cluster_id: (numpy vector, size: seq_len) - cluster indicator sequence 196 num_permutations: int - Number of permutations per utterance sampled. 197 198 Returns: 199 sub_sequences: A list of numpy array, with obsevation vector from the same 200 cluster in the same list. 201 seq_lengths: The length of each cluster (+1). 202 """ 203 # merge sub-sequences that belong to a single cluster to a single sequence 204 unique_id = np.unique(cluster_id) 205 sub_sequences = [] 206 seq_lengths = [] 207 if num_permutations and num_permutations > 1: 208 for i in unique_id: 209 idx_set = np.where(cluster_id == i)[0] 210 sampled_idx_sets = sample_permuted_segments(idx_set, num_permutations) 211 for j in range(num_permutations): 212 sub_sequences.append(sequence[sampled_idx_sets[j], :]) 213 seq_lengths.append(len(idx_set) + 1) 214 else: 215 for i in unique_id: 216 idx_set = np.where(cluster_id == i) 217 sub_sequences.append(sequence[idx_set, :][0]) 218 seq_lengths.append(len(idx_set[0]) + 1) 219 return sub_sequences, seq_lengths
Resize sequences for packing and batching.
Args: sequence: (real numpy matrix, size: seq_len*obs_size) - observed sequence cluster_id: (numpy vector, size: seq_len) - cluster indicator sequence num_permutations: int - Number of permutations per utterance sampled.
Returns: sub_sequences: A list of numpy array, with obsevation vector from the same cluster in the same list. seq_lengths: The length of each cluster (+1).
222def pack_sequence( 223 sub_sequences, seq_lengths, batch_size, observation_dim, device): 224 """Pack sequences for training. 225 226 Args: 227 sub_sequences: A list of numpy array, with obsevation vector from the same 228 cluster in the same list. 229 seq_lengths: The length of each cluster (+1). 230 batch_size: int or None - Run batch learning if batch_size is None. Else, 231 run online learning with specified batch size. 232 observation_dim: int - dimension for observation vectors 233 device: str - Your device. E.g., `cuda:0` or `cpu`. 234 235 Returns: 236 packed_rnn_input: (PackedSequence object) packed rnn input 237 rnn_truth: ground truth 238 """ 239 num_clusters = len(seq_lengths) 240 sorted_seq_lengths = np.sort(seq_lengths)[::-1] 241 permute_index = np.argsort(seq_lengths)[::-1] 242 243 if batch_size is None: 244 rnn_input = np.zeros((sorted_seq_lengths[0], 245 num_clusters, 246 observation_dim)) 247 for i in range(num_clusters): 248 rnn_input[1:sorted_seq_lengths[i], i, 249 :] = sub_sequences[permute_index[i]] 250 rnn_input = autograd.Variable( 251 torch.from_numpy(rnn_input).float()).to(device) 252 packed_rnn_input = torch.nn.utils.rnn.pack_padded_sequence( 253 rnn_input, sorted_seq_lengths, batch_first=False) 254 else: 255 mini_batch = np.sort(np.random.choice(num_clusters, batch_size)) 256 rnn_input = np.zeros((sorted_seq_lengths[mini_batch[0]], 257 batch_size, 258 observation_dim)) 259 for i in range(batch_size): 260 rnn_input[1:sorted_seq_lengths[mini_batch[i]], 261 i, :] = sub_sequences[permute_index[mini_batch[i]]] 262 rnn_input = autograd.Variable( 263 torch.from_numpy(rnn_input).float()).to(device) 264 packed_rnn_input = torch.nn.utils.rnn.pack_padded_sequence( 265 rnn_input, sorted_seq_lengths[mini_batch], batch_first=False) 266 # ground truth is the shifted input 267 rnn_truth = rnn_input[1:, :, :] 268 return packed_rnn_input, rnn_truth
Pack sequences for training.
Args:
sub_sequences: A list of numpy array, with obsevation vector from the same
cluster in the same list.
seq_lengths: The length of each cluster (+1).
batch_size: int or None - Run batch learning if batch_size is None. Else,
run online learning with specified batch size.
observation_dim: int - dimension for observation vectors
device: str - Your device. E.g., cuda:0
or cpu
.
Returns: packed_rnn_input: (PackedSequence object) packed rnn input rnn_truth: ground truth
271def output_result(model_args, training_args, test_record): 272 """Produce a string to summarize the experiment.""" 273 accuracy_array, _ = zip(*test_record) 274 total_accuracy = np.mean(accuracy_array) 275 output_string = """ 276Config: 277 sigma_alpha: {} 278 sigma_beta: {} 279 crp_alpha: {} 280 learning rate: {} 281 regularization: {} 282 batch size: {} 283 284Performance: 285 averaged accuracy: {:.6f} 286 accuracy numbers for all testing sequences: 287 """.strip().format( 288 training_args.sigma_alpha, 289 training_args.sigma_beta, 290 model_args.crp_alpha, 291 training_args.learning_rate, 292 training_args.regularization_weight, 293 training_args.batch_size, 294 total_accuracy) 295 for accuracy in accuracy_array: 296 output_string += '\n {:.6f}'.format(accuracy) 297 output_string += '\n' + '=' * 80 + '\n' 298 filename = 'layer_{}_{}_{:.1f}_result.txt'.format( 299 model_args.rnn_hidden_size, 300 model_args.rnn_depth, model_args.rnn_dropout) 301 with open(filename, 'a') as file_object: 302 file_object.write(output_string) 303 return output_string
Produce a string to summarize the experiment.
306def estimate_transition_bias(cluster_ids, smooth=1): 307 """Estimate the transition bias. 308 309 Args: 310 cluster_id: Either a list of cluster indicator sequences, or a single 311 concatenated sequence. The former is strongly preferred, since the 312 transition_bias estimated from the latter will be inaccurate. 313 smooth: int or float - Smoothing coefficient, avoids -inf value in np.log 314 in the case of a sequence with a single speaker and division by 0 in the 315 case of empty sequences. Using a small value for smooth decreases the 316 bias in the calculation of transition_bias but can also lead to underflow 317 in some remote cases, larger values are safer but less accurate. 318 319 Returns: 320 bias: Flipping coin head probability. 321 bias_denominator: The denominator of the bias, used for multiple calls to 322 fit(). 323 """ 324 transit_num = smooth 325 bias_denominator = 2 * smooth 326 for cluster_id_seq in cluster_ids: 327 for entry in range(len(cluster_id_seq) - 1): 328 transit_num += (cluster_id_seq[entry] != cluster_id_seq[entry + 1]) 329 bias_denominator += 1 330 bias = transit_num / bias_denominator 331 return bias, bias_denominator
Estimate the transition bias.
Args: cluster_id: Either a list of cluster indicator sequences, or a single concatenated sequence. The former is strongly preferred, since the transition_bias estimated from the latter will be inaccurate. smooth: int or float - Smoothing coefficient, avoids -inf value in np.log in the case of a sequence with a single speaker and division by 0 in the case of empty sequences. Using a small value for smooth decreases the bias in the calculation of transition_bias but can also lead to underflow in some remote cases, larger values are safer but less accurate.
Returns: bias: Flipping coin head probability. bias_denominator: The denominator of the bias, used for multiple calls to fit().