def siso_regression_tut( gpu_id: int, dataset: str, frac: float, validation_split: float, preprocessor: str, batch_size: int, epochs: int, optimizer: str, dropout: float, corruption_level: float, dae_hidden_layers: list, sdae_hidden_layers: list, cache: bool, regression_hidden_layers: list, verbose: int ): """Multi-floor indoor localization based on three-dimensional regression of location coordinates using a single-input and single-output (SISO) deep neural network (DNN) model and TUT datasets. Keyword arguments: """ ### initialize numpy, random, TensorFlow, and keras np.random.seed() # based on current time or OS-specific randomness source rn.seed() # " tf.set_random_seed(rn.randint(0, 1000000)) if gpu_id >= 0: os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id) else: os.environ["CUDA_VISIBLE_DEVICES"] = '' sess = tf.Session( graph=tf.get_default_graph(), config=session_conf) K.set_session(sess) ### load datasets after scaling print("Loading data ...") if dataset == 'tut': from tut import TUT tut = TUT( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) elif dataset == 'tut2': from tut import TUT2 tut = TUT2( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0, testing_split=0.2) elif dataset == 'tut3': from tut import TUT3 tut = TUT3( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) else: print("'{0}' is not a supported data set.".format(dataset)) sys.exit(0) flr_height = tut.floor_height training_df = tut.training_df training_data = tut.training_data testing_df = tut.testing_df testing_data = tut.testing_data ### build and train a SIMO model print( "Building and training a SISO model for three-dimensional regression ..." ) rss = training_data.rss_scaled coord = training_data.coord_3d_scaled coord_scaler = training_data.coord_3d_scaler # for inverse transform labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input # (optional) build deep autoencoder or stacked denoising autoencoder if dae_hidden_layers != '': print("- Building a DAE model ...") model = deep_autoencoder( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) elif sdae_hidden_layers != '': print("- Building an SDAE model ...") model = sdae( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=sdae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, corruption_level=corruption_level, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) else: x = input # regression hidden layers x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) if regression_hidden_layers != '': for units in regression_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) # coordinates regression output x = Dense(coord.shape[1], kernel_initializer='normal')(x) x = BatchNormalization()(x) coordinates_output = Activation( 'linear', name='coordinates_output')(x) # 'linear' activation model = Model(inputs=input, outputs=coordinates_output) model.compile(optimizer=optimizer, loss='mean_squared_error', metrics=['mean_squared_error']) weights_file = os.path.expanduser("~/tmp/best_weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=0) print("- Training a coordinates regressor ...", end='') startTime = timer() history = model.fit( x={'input': rss}, y={'coordinates_output': coord}, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model ### evaluate the model print("Evaluating the model ...") rss = testing_data.rss_scaled labels = testing_data.labels flrs = labels.floor coord = testing_data.coord_3d # original coordinates # calculate the classification accuracies and localization errors coords_scaled_pred = model.predict(rss, batch_size=batch_size) coord_est = coord_scaler.inverse_transform(coords_scaled_pred) # inverse-scaling tmp = np.maximum(np.minimum(coord_est[:,2], 4*tut.floor_height), 0) # clamping to [0, 4*tut.floor_height] flrs_pred = np.floor(tmp/tut.floor_height+0.5) # floor number (0..4); N.B. round() behavior in Python 3 has been changed,so we cannot use it. flr_results = (np.equal(np.argmax(flrs, axis=1), flrs_pred)).astype(int) flr_acc = flr_results.mean() # calculate 2D localization errors dist_2d = norm(coord - coord_est, axis=1) mean_error_2d = dist_2d.mean() median_error_2d = np.median(dist_2d) # calculate 3D localization errors flr_diff = np.absolute(np.argmax(flrs, axis=1) - flrs_pred) z_diff_squared = (flr_height**2)*np.square(flr_diff) dist_3d = np.sqrt(np.sum(np.square(coord - coord_est), axis=1) + z_diff_squared) mean_error_3d = dist_3d.mean() median_error_3d = np.median(dist_3d) LocalizationResults = namedtuple('LocalizationResults', ['flr_acc', 'mean_error_2d', 'median_error_2d', 'mean_error_3d', 'median_error_3d', 'elapsedTime']) return LocalizationResults(flr_acc=flr_acc, mean_error_2d=mean_error_2d, median_error_2d=median_error_2d, mean_error_3d=mean_error_3d, median_error_3d=median_error_3d, elapsedTime=elapsedTime)
) rss = training_data.rss_scaled coord = training_data.coord_scaled coord_scaler = training_data.coord_scaler # for inverse transform labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input # (optional) build deep autoencoder or stacked denoising autoencoder if dae_hidden_layers != '': print("\nPart 2.0: building a DAE model ...") model = deep_autoencoder( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) elif sdae_hidden_layers != '': print("\nPart 2.0: building an SDAE model ...") model = sdae( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=sdae_hidden_layers, cache=cache, model_fname=None,
utm = training_data.utm_scaled labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input tensorboard = TensorBoard( log_dir="logs/{}".format(time()), write_graph=True) adaptive_loss_weights = AdaptiveLossWeights( building_weight, floor_weight, location_weight, coordinates_weight) # (optional) build deep autoencoder if dae_hidden_layers != '': print("\nPart 2.0: buidling a DAE model ...") model = deep_autoencoder( rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) else: x = input # common hidden layers x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) for units in common_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x)
def simo_hybrid_uji( gpu_id: int, dataset: str, frac: float, validation_split: float, preprocessor: str, batch_size: int, epochs: int, optimizer: str, dropout: float, corruption_level: float, dae_hidden_layers: list, sdae_hidden_layers: list, cache: bool, common_hidden_layers: list, floor_hidden_layers: list, coordinates_hidden_layers: list, floor_weight: float, coordinates_weight: float, verbose: int ): """Multi-building and multi-floor indoor localization based on hybrid building/floor classification and coordinates regression using a single-input and multi-output (SIMO) deep neural network (DNN) model and UJIIndoorLoc datasets. Keyword arguments: """ ### initialize numpy, random, TensorFlow, and keras np.random.seed() # based on current time or OS-specific randomness source rn.seed() # " tf.set_random_seed(rn.randint(0, 1000000)) if gpu_id >= 0: os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id) else: os.environ["CUDA_VISIBLE_DEVICES"] = '' sess = tf.Session( graph=tf.get_default_graph(), config=session_conf) K.set_session(sess) ### load datasets after scaling print("Loading data ...") if dataset == 'uji': from ujiindoorloc import UJIIndoorLoc uji = UJIIndoorLoc( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical') else: print("'{0}' is not a supported data set.".format(dataset)) sys.exit(0) flr_height = uji.floor_height training_df = uji.training_df training_data = uji.training_data testing_df = uji.testing_df testing_data = uji.testing_data ### build and train a SIMO model print( "Building and training a SIMO model for hybrid classification and regression ..." ) rss = training_data.rss_scaled coord = training_data.coord_scaled coord_scaler = training_data.coord_scaler # for inverse transform labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input # (optional) build deep autoencoder or stacked denoising autoencoder if dae_hidden_layers != '': print("- Building a DAE model ...") model = deep_autoencoder( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) elif sdae_hidden_layers != '': print("- Building an SDAE model ...") model = sdae( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=sdae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, corruption_level=corruption_level, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) else: x = input # common hidden layers # x = BatchNormalization()(x) # x = Activation('relu')(x) # x = Dropout(dropout)(x) # if common_hidden_layers != '': # for units in common_hidden_layers: # x = Dense(units)(x) # x = BatchNormalization()(x) # x = Activation('relu')(x) # x = Dropout(dropout)(x) # common_hl_output = x # floor classification output # if floor_hidden_layers != '': # for units in floor_hidden_layers: # x = Dense(units)(x) # x = BatchNormalization()(x) # x = Activation('relu')(x) # x = Dropout(dropout)(x) # x = Dense(labels.floor.shape[1])(x) # x = BatchNormalization()(x) # floor_output = Activation( # 'softmax', name='floor_output')(x) # no dropout for an output layer # # x = Lambda(lambda x: K.expand_dims(x, axis=-1))(x) # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # # x = MaxPooling1D(pool_size=5)(x) # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # # x = MaxPooling1D(pool_size=5)(x) # # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # # x = Dropout(dropout)(x) # x = Flatten()(x) # # x = Dense(labels.floor.shape[1])(x) # x = BatchNormalization()(x) # floor_output = Activation('softmax', name='floor_output')(x) # # coordinates regression output # x = common_hl_output # for units in coordinates_hidden_layers: # x = Dense(units, kernel_initializer='normal')(x) # x = BatchNormalization()(x) # x = Activation('relu')(x) # x = Dropout(dropout)(x) # x = Dense(coord.shape[1], kernel_initializer='normal')(x) # x = BatchNormalization()(x) # coordinates_output = Activation( # 'linear', name='coordinates_output')(x) # 'linear' activation # x = common_hl_output # x = Lambda(lambda x:K.expand_dims(x,axis=-1))(x) # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # # x = MaxPooling1D(pool_size=5)(x) # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # # x = MaxPooling1D(pool_size=5)(x) # x = Conv1D(filters=99, kernel_size=12, activation='relu')(x) # x = Dropout(dropout)(x) # x = Flatten()(x) # x = Dense(coord.shape[1],kernel_initializer='normal')(x) # x = BatchNormalization()(x) # coordinates_output = Activation( # 'linear', name='coordinates_output')(x) # 1D_CNN by John x = Lambda(lambda x:K.expand_dims(x,axis=-1))(x) x = Conv1D(filters=99, kernel_size=22, activation='relu')(x) x = Dropout(dropout)(x) # x = Conv1D(filters=128, kernel_size=10, activation='relu')(x) # x = MaxPooling1D(pool_size=2)(x) x = Conv1D(filters=66, kernel_size=22, activation='relu')(x) # x = MaxPooling1D(pool_size=2)(x) x = Conv1D(filters=33, kernel_size=22, activation='relu')(x) x = MaxPooling1D(pool_size=2)(x) x = Flatten()(x) #1D_CNN by John #1DCNN by John n = x x = Dense(labels.floor.shape[1])(x) # x = BatchNormalization()(x) floor_output = Activation('softmax', name='floor_output')(x) common_hl_output = n x = common_hl_output x = Dense(coord.shape[1], kernel_initializer='normal')(x) # x = BatchNormalization()(x) coordinates_output = Activation( 'linear', name='coordinates_output')(x) #1DCNN by John model = Model( inputs=input, outputs=[ floor_output, coordinates_output ]) model.compile( optimizer=optimizer, loss=[ 'categorical_crossentropy', 'mean_squared_error' ], loss_weights={ 'floor_output': floor_weight, 'coordinates_output': coordinates_weight }, metrics={ 'floor_output': 'accuracy', 'coordinates_output': 'mean_squared_error' }) weights_file = os.path.expanduser("~/tmp/best_weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=0) print("- Training a hybrid floor classifier and coordinates regressor ...", end='') startTime = timer() history = model.fit( x={'input': rss}, y={ 'floor_output': labels.floor, 'coordinates_output': coord }, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model ### evaluate the model print("Evaluating the model ...") rss = testing_data.rss_scaled labels = testing_data.labels flrs = labels.floor coord = testing_data.coord # original coordinates # calculate the classification accuracies and localization errors flrs_pred, coords_scaled_pred = model.predict(rss, batch_size=batch_size) flr_results = (np.equal( np.argmax(flrs, axis=1), np.argmax(flrs_pred, axis=1))).astype(int) flr_acc = flr_results.mean() coord_est = coord_scaler.inverse_transform(coords_scaled_pred) # inverse-scaling # calculate 2D localization errors dist_2d = norm(coord - coord_est, axis=1) mean_error_2d = dist_2d.mean() median_error_2d = np.median(dist_2d) # calculate 3D localization errors flr_diff = np.absolute( np.argmax(flrs, axis=1) - np.argmax(flrs_pred, axis=1)) z_diff_squared = (flr_height**2)*np.square(flr_diff) dist_3d = np.sqrt(np.sum(np.square(coord - coord_est), axis=1) + z_diff_squared) mean_error_3d = dist_3d.mean() median_error_3d = np.median(dist_3d) LocalizationResults = namedtuple('LocalizationResults', ['flr_acc', 'mean_error_2d', 'median_error_2d', 'mean_error_3d', 'median_error_3d', 'elapsedTime']) return LocalizationResults(flr_acc=flr_acc, mean_error_2d=mean_error_2d, median_error_2d=median_error_2d, mean_error_3d=mean_error_3d, median_error_3d=median_error_3d, elapsedTime=elapsedTime)
def simo_swt_hybrid_tut( gpu_id: int, dataset: str, frac: float, validation_split: float, preprocessor: str, batch_size: int, epochs: int, optimizer: str, dropout: float, corruption_level: float, dae_hidden_layers: list, sdae_hidden_layers: list, cache: bool, common_hidden_layers: list, floor_hidden_layers: list, coordinates_hidden_layers: list, verbose: int ): """Multi-floor indoor localization based on hybrid floor classification and coordinates regression using a stage-wise trained single-input and multi-output (SIMO) deep neural network (DNN) model and TUT datasets. Keyword arguments: """ ### initialize numpy, random, TensorFlow, and keras np.random.seed() # based on current time or OS-specific randomness source rn.seed() # " tf.set_random_seed(rn.randint(0, 1000000)) if gpu_id >= 0: os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id) else: os.environ["CUDA_VISIBLE_DEVICES"] = '' sess = tf.Session( graph=tf.get_default_graph(), config=session_conf) K.set_session(sess) ### load datasets after scaling print("Loading data ...") if dataset == 'tut': from tut import TUT tut = TUT( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) elif dataset == 'tut2': from tut import TUT2 tut = TUT2( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0, testing_split=0.2) elif dataset == 'tut3': from tut import TUT3 tut = TUT3( cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) else: print("'{0}' is not a supported data set.".format(dataset)) sys.exit(0) flr_height = tut.floor_height training_df = tut.training_df training_data = tut.training_data testing_df = tut.testing_df testing_data = tut.testing_data ### build and do stage-wise training of a SIMO model print( "Building and stage-wise training a SIMO model for hybrid classification and regression ..." ) rss = training_data.rss_scaled coord = training_data.coord_scaled coord_scaler = training_data.coord_scaler # for inverse transform labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input # (optional) build deep autoencoder or stacked denoising autoencoder if dae_hidden_layers != '': print("- Building a DAE model ...") model = deep_autoencoder( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) elif sdae_hidden_layers != '': print("- Building an SDAE model ...") model = sdae( dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=sdae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, corruption_level=corruption_level, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) else: x = input # common hidden layers x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) if common_hidden_layers != '': for i in range(len(common_hidden_layers)): x = Dense(common_hidden_layers[i], name='common_hidden_layer_{:d}'.format(i))(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) common_hl_output = x # floor classification output if floor_hidden_layers != '': for i in range(len(floor_hidden_layers)): x = Dense(floor_hidden_layers[i], name='floor_hidden_layer_{:d}'.format(i))(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) i += 1 else: i = 0 x = Dense(labels.floor.shape[1], name='floor_hidden_layer_{:d}'.format(i))(x) x = BatchNormalization()(x) floor_output = Activation( 'softmax', name='floor_output')(x) # no dropout for an output layer # coordinates regression output x = common_hl_output if coordinates_hidden_layers != '': for i in range(len(coordinates_hidden_layers)): x = Dense(coordinates_hidden_layers[i], kernel_initializer='normal', name='coordinates_hidden_layer_{:d}'.format(i))(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) i += 1 else: i = 0 x = Dense(coord.shape[1], kernel_initializer='normal', name='coordinates_hidden_layer_{:d}'.format(i))(x) x = BatchNormalization()(x) coordinates_output = Activation( 'linear', name='coordinates_output')(x) # 'linear' activation # build model model = Model( inputs=input, outputs=[ floor_output, coordinates_output ]) print("- Stage-wise training with floor information ...", end='') model.compile( optimizer=optimizer, loss=[ 'categorical_crossentropy', 'mean_squared_error' ], loss_weights={ 'floor_output': 1.0, 'coordinates_output': 0.0 }, metrics={ 'floor_output': 'accuracy', 'coordinates_output': 'mean_squared_error' }) weights_file = os.path.expanduser("~/tmp/best_f-weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', patience=10, verbose=0) startTime = timer() f_history = model.fit( x={'input': rss}, y={ 'floor_output': labels.floor, 'coordinates_output': coord }, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime elapsedTime_total = elapsedTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model print( "- Stage-wise training with floor-coordinates information ...", end='' ) # reinitialize hidden layers based on # https://www.codementor.io/nitinsurya/how-to-re-initialize-keras-model-weights-et41zre2g # - common if common_hidden_layers != '': for i in range(len(common_hidden_layers)): layer = model.get_layer('common_hidden_layer_{:d}'.format(i)) if hasattr(layer, 'kernel_initializer'): layer.kernel.initializer.run(session=sess) # # - floor # if floor_hidden_layers != '': # for i in range(len(floor_hidden_layers)): # layer = model.get_layer('floor_hidden_layer_{:d}'.format(i)) # if hasattr(layer, 'kernel_initializer'): # layer.kernel.initializer.run(session=sess) # i += 1 # else: # i = 0 # layer = model.get_layer('floor_hidden_layer_{:d}'.format(i)) # if hasattr(layer, 'kernel_initializer'): # layer.kernel.initializer.run(session=sess) # - coordinats if coordinates_hidden_layers != '': for i in range(len(coordinates_hidden_layers)): layer = model.get_layer('coordinates_hidden_layer_{:d}'.format(i)) if hasattr(layer, 'kernel_initializer'): layer.kernel.initializer.run(session=sess) i += 1 else: i = 0 layer = model.get_layer('coordinates_hidden_layer_{:d}'.format(i)) if hasattr(layer, 'kernel_initializer'): layer.kernel.initializer.run(session=sess) model.compile( optimizer=optimizer, loss=[ 'categorical_crossentropy', 'mean_squared_error' ], loss_weights={ 'floor_output': 1.0, 'coordinates_output': 1.0 }, metrics={ 'floor_output': 'accuracy', 'coordinates_output': 'mean_squared_error' }) weights_file = os.path.expanduser("~/tmp/best_fc-weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', patience=10, verbose=0) startTime = timer() fc_history = model.fit( x={'input': rss}, y={ 'floor_output': labels.floor, 'coordinates_output': coord }, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime elapsedTime_total += elapsedTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model ### evaluate the model print("Evaluating the model ...") rss = testing_data.rss_scaled labels = testing_data.labels flrs = labels.floor coord = testing_data.coord # original coordinates x_col_name = 'X' y_col_name = 'Y' # calculate the classification accuracies and localization errors flrs_pred, coords_scaled_pred = model.predict(rss, batch_size=batch_size) flr_results = (np.equal( np.argmax(flrs, axis=1), np.argmax(flrs_pred, axis=1))).astype(int) flr_acc = flr_results.mean() coord_est = coord_scaler.inverse_transform(coords_scaled_pred) # inverse-scaling # calculate 2D localization errors dist_2d = norm(coord - coord_est, axis=1) mean_error_2d = dist_2d.mean() median_error_2d = np.median(dist_2d) # calculate 3D localization errors flr_diff = np.absolute( np.argmax(flrs, axis=1) - np.argmax(flrs_pred, axis=1)) z_diff_squared = (flr_height**2)*np.square(flr_diff) dist_3d = np.sqrt(np.sum(np.square(coord - coord_est), axis=1) + z_diff_squared) mean_error_3d = dist_3d.mean() median_error_3d = np.median(dist_3d) LocalizationResults = namedtuple('LocalizationResults', ['flr_acc', 'mean_error_2d', 'median_error_2d', 'mean_error_3d', 'median_error_3d', 'elapsedTime']) return LocalizationResults(flr_acc=flr_acc, mean_error_2d=mean_error_2d, median_error_2d=median_error_2d, mean_error_3d=mean_error_3d, median_error_3d=median_error_3d, elapsedTime=elapsedTime)
def simo_hybrid(gpu_id, random_seed, epochs, batch_size, validation_split, dropout, dae_hidden_layers, common_hidden_layers, floor_location_hidden_layers, building_hidden_layers, floor_hidden_layers, location_hidden_layers, building_weight, floor_weight, location_weight): """Multi-building and multi-floor indoor localisztion based on Wi-Fi fingerprinting with a single-input and multi-output deep neural network Keyword arguments: gpu_id -- ID of GPU device to run this script; set it to a negative number for CPU (i.e., no GPU) random_seed -- a seed for random number generator epoch -- number of epochs batch_size -- batch size validation_split -- fraction of training data to be used as validation data dropout -- dropout rate before and after hidden layers dae_hidden_layers -- list of numbers of units in DAE hidden layers common_hidden_layers -- list of numbers of units in common hidden layers floor_location_hidden_layers -- list of numbers of units in floor/location hidden layers building_hidden_layers --list of numbers of units in building classifier hidden layers floor_hidden_layers --list of numbers of units in floor classifier hidden layers location_hidden_layers --list of numbers of units in location hidden layers building_weight -- loss weight for a building classifier floor_weight -- loss weight for a floor classifier location_weight -- loss weight for a location regressor """ np.random.seed(random_seed) # initialize random number generator #-------------------------------------------------------------------- # import keras and its backend (e.g., tensorflow) #-------------------------------------------------------------------- os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152 if gpu_id >= 0: os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id) else: os.environ["CUDA_VISIBLE_DEVICES"] = '' os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # supress warning messages import tensorflow as tf from keras import backend as K from keras.layers import Activation, Dense, Dropout, Input from keras.layers.normalization import BatchNormalization from keras.models import Model, Sequential, load_model from keras.callbacks import TensorBoard K.clear_session() # avoid clutter from old models / layers. # read both train and test dataframes for consistent label formation through one-hot encoding training_df = pd.read_csv( training_data_file, header=0) # pass header=0 to be able to replace existing names testing_df = pd.read_csv( validation_data_file, header=0) # turn the validation set into a testing set # scale numerical data (over their flattened versions for joint scaling) rss_scaler = StandardScaler( ) # the same scaling will be applied to test data later utm_scaler = StandardScaler() # ditto col_aps = [col for col in training_df.columns if 'WAP' in col] num_aps = len(col_aps) rss = np.asarray(training_df[col_aps], dtype=np.float32) rss = (rss_scaler.fit_transform(rss.reshape((-1, 1)))).reshape(rss.shape) utm_x = np.asarray(training_df['LONGITUDE'], dtype=np.float32) utm_y = np.asarray(training_df['LATITUDE'], dtype=np.float32) utm = utm_scaler.fit_transform(np.column_stack((utm_x, utm_y))) num_coords = utm.shape[1] # # map reference points to sequential IDs per building & floor before building labels # training_df['REFPOINT'] = training_df.apply(lambda row: str(int(row['SPACEID'])) + str(int(row['RELATIVEPOSITION'])), axis=1) # add a new column # blds = np.unique(training_df[['BUILDINGID']]) # flrs = np.unique(training_df[['FLOOR']]) # for bld in blds: # for flr in flrs: # cond = (training_df['BUILDINGID']==bld) & (training_df['FLOOR']==flr) # _, idx = np.unique(training_df.loc[cond, 'REFPOINT'], return_inverse=True) # refer to numpy.unique manual # training_df.loc[cond, 'REFPOINT'] = idx # build labels for the classification of a building, a floor, and a reference point num_training_samples = len(training_df) num_testing_samples = len(testing_df) blds_all = np.asarray( pd.get_dummies( pd.concat([ training_df['BUILDINGID'], testing_df['BUILDINGID'] ]))) # for consistency in one-hot encoding for both dataframes num_blds = blds_all.shape[1] flrs_all = np.asarray( pd.get_dummies(pd.concat([training_df['FLOOR'], testing_df['FLOOR']]))) # ditto num_flrs = flrs_all.shape[1] blds = blds_all[:num_training_samples] flrs = flrs_all[:num_training_samples] # rfps = np.asarray(pd.get_dummies(training_df['REFPOINT'])) # num_rfps = rfps.shape[1] # labels is an array of 19937 x 118 # - 3 for BUILDINGID # - 5 for FLOOR, # - 110 for REFPOINT # OUTPUT_DIM = training_labels.shape[1] # split the training set into a training and a validation set; the original # validation set is used as a testing set. mask_training = np.random.rand( len(rss)) < 1.0 - validation_split # mask index array rss_training = rss[mask_training] utm_training = utm[mask_training] blds_training = blds[mask_training] flrs_training = flrs[mask_training] # rfps_training = rfps[mask_training] rss_validation = rss[~mask_training] utm_validation = utm[~mask_training] blds_validation = blds[~mask_training] flrs_validation = flrs[~mask_training] # rfps_validation = rfps[~mask_training] ### build deep autoencoder model print("\nPart 1: buidling a DAE encoder ...") model = deep_autoencoder(rss_training, hidden_layers=dae_hidden_layers, validation_split=validation_split) ### build and train a complete model with the trained DAE encoder and a new classifier print("\nPart 2: buidling a complete model ...") input = Input(shape=(num_aps, ), name='input') x = model(input) # denoise the input data using the DAE encoder x = BatchNormalization()(x) x = Activation('relu')(x) denoised_input = Dropout(dropout)(x) # common hidden layers for all if common_hidden_layers == '': common_input = denoised_input else: # x = Dropout(dropout)(denoised_input) for units in common_hidden_layers[:-1]: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(common_hidden_layers[-1])(x) x = BatchNormalization()(x) x = Activation('relu')(x) common_input = Dropout(dropout, name='common_input')(x) # building classifier output for units in building_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(num_blds)(x) x = BatchNormalization()(x) building_output = Activation('softmax', name='building_output')( x) # no dropout for an output layer # common hidden layers for floor and location/position if floor_location_hidden_layers == '': floor_location_input = common_input else: # x = Dropout(dropout)(common_input) for units in floor_location_hidden_layers[:-1]: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(floor_location_hidden_layers[-1])(x) x = BatchNormalization()(x) x = Activation('relu')(x) floor_location_input = Dropout(dropout, name='floor_location_input')(x) # floor classifier output for units in floor_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(num_flrs)(x) x = BatchNormalization()(x) floor_output = Activation('softmax', name='floor_output')( x) # no dropout for an output layer # location/position regressor output for units in location_hidden_layers: x = Dense(units, kernel_initializer='normal')(x) x = BatchNormalization()(x) x = Activation(REGRESSOR_ACTIVATION)(x) x = Dropout(dropout)(x) x = Dense(num_coords, kernel_initializer='normal')(x) x = BatchNormalization()(x) location_output = Activation(REGRESSOR_ACTIVATION, name='location_output')(x) # build and compile a SIMO model model = Model(inputs=[input], outputs=[building_output, floor_output, location_output]) model.compile(optimizer=OPTIMIZER, loss=[ 'categorical_crossentropy', 'categorical_crossentropy', 'mean_squared_error' ], loss_weights={ 'building_output': building_weight, 'floor_output': floor_weight, 'location_output': location_weight }, metrics={ 'building_output': 'accuracy', 'floor_output': 'accuracy', 'location_output': 'mean_squared_error' }) # train the model tensorboard = TensorBoard(log_dir="logs/{}".format(time()), write_graph=True) startTime = timer() history = model.fit(x={'input': rss_training}, y={ 'building_output': blds_training, 'floor_output': flrs_training, 'location_output': utm_training }, validation_data=({ 'input': rss_validation }, { 'building_output': blds_validation, 'floor_output': flrs_validation, 'location_output': utm_validation }), batch_size=batch_size, epochs=epochs, verbose=VERBOSE, callbacks=[tensorboard], shuffle=True) elapsedTime = timer() - startTime print("Model trained in %e s." % elapsedTime) ### evaluate the model print("\nPart 3: evaluating the model ...") # turn the given validation set into a testing set rss_testing = np.asarray(testing_df[col_aps], dtype=np.float32) rss_testing = (rss_scaler.transform(rss_testing.reshape( (-1, 1)))).reshape(rss_testing.shape) utm_x_testing = np.asarray(testing_df['LONGITUDE'], dtype=np.float32) utm_y_testing = np.asarray(testing_df['LATITUDE'], dtype=np.float32) utm_testing_original = np.column_stack((utm_x_testing, utm_y_testing)) utm_testing = utm_scaler.transform(utm_testing_original) # scaled version blds_testing = blds_all[num_training_samples:] flrs_testing = flrs_all[num_training_samples:] # rst = model.evaluate( # x={'input': rss_testing}, # y={'building_output': blds_testing, 'floor_output': flrs_testing, 'location_output': utm_testing} # ) # Results = namedtuple('Results', ['losses', 'metrics', 'history']) # Losses = namedtuple('Losses', ['overall', 'building', 'floor', 'location']) # Metrics = namedtuple('Metrics', ['building_acc', 'floor_acc', 'location_mse']) # results = Results( # losses=Losses(overall=rst[0], building=rst[1], floor=rst[2], location=rst[3]), # metrics=Metrics(building_acc=rst[4], floor_acc=rst[5], location_mse=rst[6]), # history=history # ) # calculate the classification accuracies and localization errors preds = model.predict(rss_testing, batch_size=batch_size ) # a list of arrays (one for each output) returned blds_results = (np.equal(np.argmax(blds_testing, axis=1), np.argmax(preds[0], axis=1))).astype(int) blds_acc = blds_results.mean() flrs_results = (np.equal(np.argmax(flrs_testing, axis=1), np.argmax(preds[1], axis=1))).astype(int) flrs_acc = flrs_results.mean() bf_acc = (blds_results * flrs_results).mean() # rfps_results = (np.equal(np.argmax(test_labels[:, 8:118], axis=1), np.argmax(preds[:, 8:118], axis=1))).astype(int) # acc_rfp = rfps_results.mean() # acc = (blds_results*flrs_results*rfps_results).mean() utm_preds = utm_scaler.inverse_transform( preds[2]) # inverse-scaled version location_mse = ((utm_testing_original - utm_preds)**2).mean() # calculate localization errors per EvAAL/IPIN 2015 competition dist = norm(utm_testing_original - utm_preds, axis=1) # Euclidean distance flrs_diff = np.absolute( np.argmax(flrs_testing, axis=1) - np.argmax(preds[1], axis=1)) error = dist + 50 * (1 - blds_results) + 4 * flrs_diff # individual error [m] mean_error = error.mean() median_error = np.median(error) Results = namedtuple('Results', ['metrics', 'history']) Metrics = namedtuple('Metrics', [ 'building_acc', 'floor_acc', 'bf_acc', 'location_mse', 'mean_error', 'median_error' ]) results = Results(metrics=Metrics(building_acc=blds_acc, floor_acc=flrs_acc, bf_acc=bf_acc, location_mse=location_mse, mean_error=mean_error, median_error=median_error), history=history) return results
def simo_classification_tut( gpu_id: int, dataset: str, frac: float, validation_split: float, preprocessor: str, grid_size: float, batch_size: int, epochs: int, optimizer: str, dropout: float, corruption_level: float, num_neighbors: int, scaling: float, dae_hidden_layers: list, sdae_hidden_layers: list, cache: bool, common_hidden_layers: list, floor_hidden_layers: list, location_hidden_layers: list, floor_weight: float, location_weight: float, verbose: int): """Multi-floor indoor localization based on floor and coordinates classification using a single-input and multi-output (SIMO) deep neural network (DNN) model and TUT datasets. Keyword arguments: """ ### initialize numpy, random, TensorFlow, and keras np.random.seed() # based on current time or OS-specific randomness source rn.seed() # " tf.set_random_seed(rn.randint(0, 1000000)) if gpu_id >= 0: os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id) else: os.environ["CUDA_VISIBLE_DEVICES"] = '' sess = tf.Session(graph=tf.get_default_graph(), config=session_conf) K.set_session(sess) ### load datasets after scaling print("Loading data ...") if dataset == 'tut': from tut import TUT tut = TUT(cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) elif dataset == 'tut2': from tut import TUT2 tut = TUT2(cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0, testing_split=0.2) elif dataset == 'tut3': from tut import TUT3 tut = TUT3(cache=cache, frac=frac, preprocessor=preprocessor, classification_mode='hierarchical', grid_size=0) else: print("'{0}' is not a supported data set.".format(dataset)) sys.exit(0) flr_height = tut.floor_height training_df = tut.training_df training_data = tut.training_data testing_df = tut.testing_df testing_data = tut.testing_data ### build and train a SIMO model print("Building and training a SIMO model for classification ...") rss = training_data.rss_scaled coord = training_data.coord_scaled coord_scaler = training_data.coord_scaler # for inverse transform labels = training_data.labels input = Input(shape=(rss.shape[1], ), name='input') # common input # (optional) build deep autoencoder or stacked denoising autoencoder if dae_hidden_layers != '': print("- Building a DAE model ...") model = deep_autoencoder(dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=dae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) elif sdae_hidden_layers != '': print("- Building an SDAE model ...") model = sdae(dataset=dataset, input_data=rss, preprocessor=preprocessor, hidden_layers=sdae_hidden_layers, cache=cache, model_fname=None, optimizer=optimizer, corruption_level=corruption_level, batch_size=batch_size, epochs=epochs, validation_split=validation_split) x = model(input) else: x = input # common hidden layers x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) if common_hidden_layers != '': for units in common_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) common_hl_output = x # floor classification output if floor_hidden_layers != '': for units in floor_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(labels.floor.shape[1])(x) x = BatchNormalization()(x) floor_output = Activation('softmax', name='floor_output')( x) # no dropout for an output layer # location classification output if location_hidden_layers != '': for units in location_hidden_layers: x = Dense(units)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(dropout)(x) x = Dense(labels.location.shape[1])(x) x = BatchNormalization()(x) location_output = Activation('softmax', name='location_output')( x) # no dropout for an output layer # build model model = Model(inputs=input, outputs=[floor_output, location_output]) # for stage-wise training with floor information only model.compile( optimizer=optimizer, loss=['categorical_crossentropy', 'categorical_crossentropy'], loss_weights={ 'floor_output': 1.0, 'location_output': 0.0 }, metrics={ 'floor_output': 'accuracy', 'location_output': 'accuracy' }) weights_file = os.path.expanduser("~/tmp/best_weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=0) print("- Stage-wise training with floor information ...", end='') startTime = timer() f_history = model.fit(x={'input': rss}, y={ 'floor_output': labels.floor, 'location_output': labels.location }, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model # for stage-wise training with both floor and location information model.compile( optimizer=optimizer, loss=['categorical_crossentropy', 'categorical_crossentropy'], loss_weights={ 'floor_output': 1.0, 'location_output': 1.0 }, metrics={ 'floor_output': 'accuracy', 'location_output': 'accuracy' }) weights_file = os.path.expanduser("~/tmp/best_weights.h5") checkpoint = ModelCheckpoint(weights_file, monitor='val_loss', save_best_only=True, verbose=0) early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=0) print("- Stage-wise training with both floor and location information ...", end='') startTime = timer() fl_history = model.fit(x={'input': rss}, y={ 'floor_output': labels.floor, 'location_output': labels.location }, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=[checkpoint, early_stop], validation_split=validation_split, shuffle=True) elapsedTime = timer() - startTime print(" completed in {0:.4e} s".format(elapsedTime)) model.load_weights(weights_file) # load weights from the best model ### evaluate the model print("Evaluating the model ...") rss = testing_data.rss_scaled labels = testing_data.labels blds = labels.building flrs = labels.floor coord = testing_data.coord # original coordinates x_col_name = 'X' y_col_name = 'Y' # calculate the classification accuracies and localization errors flrs_pred, locs_pred = model.predict(rss, batch_size=batch_size) flr_results = (np.equal(np.argmax(flrs, axis=1), np.argmax(flrs_pred, axis=1))).astype(int) flr_acc = flr_results.mean() # calculate positioning error based on locations n_samples = len(flrs) n_locs = locs_pred.shape[1] # number of locations (reference points) idxs = np.argpartition( locs_pred, -num_neighbors )[:, -num_neighbors:] # (unsorted) indexes of up to num_neighbors nearest neighbors threshold = scaling * np.amax(locs_pred, axis=1) training_labels = np.concatenate( (training_data.labels.floor, training_data.labels.location), axis=1) training_coord_avg = training_data.coord_avg coord_est = np.zeros((n_samples, 2)) coord_est_weighted = np.zeros((n_samples, 2)) for i in range(n_samples): xs = [] ys = [] ws = [] for j in idxs[i]: if locs_pred[i][j] >= threshold[i]: loc = np.zeros(n_locs) loc[j] = 1 rows = np.where((training_labels == np.concatenate( (flrs[i], loc))).all(axis=1)) # tuple of row indexes if rows[0].size > 0: xs.append(training_df.loc[training_df.index[rows[0][0]], x_col_name]) ys.append(training_df.loc[training_df.index[rows[0][0]], y_col_name]) ws.append(locs_pred[i][j]) if len(xs) > 0: coord_est[i] = np.array((xs, ys)).mean(axis=1) coord_est_weighted[i] = np.array( (np.average(xs, weights=ws), np.average(ys, weights=ws))) else: if rows[0].size > 0: key = str(np.argmax(blds[i])) + '-' + str(np.argmax(flrs[i])) else: key = str(np.argmax(blds[i])) coord_est[i] = coord_est_weighted[i] = training_coord_avg[key] # calculate 2D localization errors dist_2d = norm(coord - coord_est, axis=1) dist_weighted_2d = norm(coord - coord_est_weighted, axis=1) mean_error_2d = dist_2d.mean() mean_error_weighted_2d = dist_weighted_2d.mean() median_error_2d = np.median(dist_2d) median_error_weighted_2d = np.median(dist_weighted_2d) # calculate 3D localization errors flr_diff = np.absolute( np.argmax(flrs, axis=1) - np.argmax(flrs_pred, axis=1)) z_diff_squared = (flr_height**2) * np.square(flr_diff) dist_3d = np.sqrt( np.sum(np.square(coord - coord_est), axis=1) + z_diff_squared) dist_weighted_3d = np.sqrt( np.sum(np.square(coord - coord_est_weighted), axis=1) + z_diff_squared) mean_error_3d = dist_3d.mean() mean_error_weighted_3d = dist_weighted_3d.mean() median_error_3d = np.median(dist_3d) median_error_weighted_3d = np.median(dist_weighted_3d) LocalizationResults = namedtuple('LocalizationResults', [ 'flr_acc', 'mean_error_2d', 'mean_error_weighted_2d', 'median_error_2d', 'median_error_weighted_2d', 'mean_error_3d', 'mean_error_weighted_3d', 'median_error_3d', 'median_error_weighted_3d', 'elapsedTime' ]) return LocalizationResults( flr_acc=flr_acc, mean_error_2d=mean_error_2d, mean_error_weighted_2d=mean_error_weighted_2d, median_error_2d=median_error_2d, median_error_weighted_2d=median_error_weighted_2d, mean_error_3d=mean_error_3d, mean_error_weighted_3d=mean_error_weighted_3d, median_error_3d=median_error_3d, median_error_weighted_3d=median_error_weighted_3d, elapsedTime=elapsedTime)