Source code for dlmfg.transfer_learning.tl_core

""" Contains core classes and methods for initializing a Transfer Learning Class and running transfer learning using a pre-trained model and a small training dataset, the inputs are provided in assemblyconfig file in utilities"""

import os
import sys
current_path=os.path.dirname(__file__)
parentdir = os.path.dirname(current_path)

#Adding Path to various Modules
sys.path.append("../core")
sys.path.append("../visualization")
sys.path.append("../utilities")
sys.path.append("../datasets")
sys.path.append("../trained_models")
sys.path.append("../config")


#Importing Required Modules
import pathlib
import numpy as np
import pandas as pd
import tensorflow as tf
from keras import backend as K
from keras.models import load_model
from keras_contrib.layers.normalization.instancenormalization import InstanceNormalization
from keras_lr_multiplier import LRMultiplier
from keras.utils import plot_model
K.clear_session()

#Importing Config files
import assembly_config as config
import model_config as cftrain

#Importing required modules from the package
from measurement_system import HexagonWlsScanner
from assembly_system import VRMSimulationModel
from wls400a_system import GetInferenceData
from data_import import GetTrainData
from core_model import DLModel
from training_viz import TrainViz
from metrics_eval import MetricsEval
from model_train import TrainModel

[docs]class TransferLearning: """Transfer Learning Class :param tl_type: Type of transfer learning to be done, full fine-tune, partial fine-tune, feature extraction :type tl_type: str (required) :param tl_base: The base model to be used for model :type tl_base: str (required) :param tl_app: The application for transfer learning :type tl_app: str (required) :param model_type: The type of model, regression or classification :type model_type: str (required) :param output_dimension: The number of KCCs for the case study to which the pre-trained model is to be transfered, to be used to reinitialize the last layer :type output_dimension: int (required) :param optimizer: The optimizer to be used for model training (https://keras.io/optimizers/) :type optimizer: keras.optimizer (required) :param loss_function: The loss function to be used for model training (https://keras.io/losses/) :type loss_function: keras.losses (required) :param regularizer_coeff: The regularization coefficient for L2 norm regularization of the fully connected layer (https://keras.io/regularizers/) :type regularizer_coeff: float (required) :param output_type: The type of model, regression or classification :type output_type: str (required) """ def __init__(self, tl_type,tl_base,tl_app,model_type,output_dimension,optimizer,loss_function,regularizer_coeff,output_type): self.tl_type=tl_type self.tl_base=tl_base self.tl_app=tl_app self.output_dimension=output_dimension self.model_type=model_type self.optimizer=optimizer self.loss_function=loss_function self.regularizer_coeff=regularizer_coeff self.output_type=output_type
[docs] def get_trained_model(self): """Imports the pre-trained model based on the object initialization, currently supports Keras modelname.h5 format (refer https://keras.io/models/model/ for more information on keras model) :returns: Pre-trained model with weights :rtype: keras.model """ def weighted_dice_coefficient(y_true, y_pred, axis=(-3, -2, -1), smooth=0.00001): return K.mean(2. * (K.sum(y_true * y_pred, axis=axis) + smooth/2)/(K.sum(y_true, axis=axis) + K.sum(y_pred, axis=axis) + smooth)) def weighted_dice_coefficient_loss(y_true, y_pred): return -weighted_dice_coefficient(y_true, y_pred) model_path='../pre_trained_models/deterministic_models/'+self.tl_base if(self.tl_base=='unet_3d.h5'): base_model=load_model(model_path,custom_objects={'InstanceNormalization': InstanceNormalization,'weighted_dice_coefficient_loss':weighted_dice_coefficient_loss}) else: base_model=load_model(model_path) return base_model
[docs] def build_transfer_model(self,model): """The build_transfer_function takes the pre-trained model removes the final layer and adds another layer based on the new case study parameters, which is trained on a small dataset obtained from the new case study :param model: keras model with preset parameters :type model: keras.model (required) :returns: Updated model with new final layer :rtype: keras.model """ from keras.layers import Conv3D, MaxPool3D, Flatten, Dense, Dropout from keras.models import Model if(self.output_type=="regression"): final_layer_avt='linear' if(self.output_type=="classification"): final_layer_avt='softmax' model.layers.pop() model.layers.pop() x = model.layers[-2].output x = Dense(self.output_dimension, activation=final_layer_avt, name='new_predictions')(x) transfer_model = Model(input=model.input,output=x) return transfer_model
[docs] def set_fixed_train_params(self,model): """The set_fixed_params function is used to freeze the weights of the convolution layer, hence the initial part of the network is to be used only as a feature extractor :param model: keras model with preset parameters :type model: keras.model (required) :returns: Updated model with non trainable convolution layers :rtype: keras.model """ for layer in model.layers: if('conv'in layer.name): layer.trainable = False model.compile(loss=self.loss_function, optimizer=self.optimizer, metrics=['mae']) return model
def full_fine_tune(self,model): model.compile(loss=self.loss_function, optimizer=self.optimizer, metrics=['mae']) return model
[docs] def set_variable_learning_rates(self,model,conv_layer_m,dense_layer_m): """The set_fixed_params function is used to freeze the weights of the convolution layer if the initial part of the network is to be used only as a feature extractor :param model: keras model with preset parameters :type model: keras.model (required) :param conv_layer_m: Learning rate multiplier for convolution layer :type conv_layer_m: float(required) :param dense_layer_m: Learning rate multiplier for dense layer :type dense_layer_m: float(required) :returns: Updated model with variable learning rates :rtype: keras.model """ lr_dict={} for layer in model.layers: if('conv'in layer.name): lr_dict.update({layer.name : conv_layer_m}) if('dense' in layer.name): lr_dict.update({layer.name : dense_layer_m}) key='conv3d_1_input' if key in lr_dict: del lr_dict[key] #print(lr_dict) variable_optimizer=LRMultiplier(self.optimizer,lr_dict) model.compile(loss=self.loss_function, optimizer=variable_optimizer, metrics=['mae']) return model
def tl_mode3(self,model): pass
if __name__ == '__main__': print('Parsing from Assembly Config File....') data_type=config.assembly_system['data_type'] application=config.assembly_system['application'] part_type=config.assembly_system['part_type'] part_name=config.assembly_system['part_name'] data_format=config.assembly_system['data_format'] assembly_type=config.assembly_system['assembly_type'] assembly_kccs=config.assembly_system['assembly_kccs'] assembly_kpis=config.assembly_system['assembly_kpis'] voxel_dim=config.assembly_system['voxel_dim'] point_dim=config.assembly_system['point_dim'] voxel_channels=config.assembly_system['voxel_channels'] noise_type=config.assembly_system['noise_type'] mapping_index=config.assembly_system['mapping_index'] file_names_x=config.assembly_system['data_files_x'] file_names_y=config.assembly_system['data_files_y'] file_names_z=config.assembly_system['data_files_z'] system_noise=config.assembly_system['system_noise'] aritifical_noise=config.assembly_system['aritifical_noise'] data_folder=config.assembly_system['data_folder'] kcc_folder=config.assembly_system['kcc_folder'] kcc_files=config.assembly_system['kcc_files'] print('Parsing from Training Config File') model_type=cftrain.model_parameters['model_type'] output_type=cftrain.model_parameters['output_type'] batch_size=cftrain.model_parameters['batch_size'] epocs=cftrain.model_parameters['epocs'] split_ratio=cftrain.model_parameters['split_ratio'] optimizer=cftrain.model_parameters['optimizer'] loss_func=cftrain.model_parameters['loss_func'] regularizer_coeff=cftrain.model_parameters['regularizer_coeff'] activate_tensorboard=cftrain.model_parameters['activate_tensorboard'] tl_type=cftrain.transfer_learning['tl_type'] tl_base=cftrain.transfer_learning['tl_base'] tl_app=cftrain.transfer_learning['tl_app'] conv_layer_m=cftrain.transfer_learning['conv_layer_m'] dense_layer_m=cftrain.transfer_learning['dense_layer_m'] print('Creating file Structure....') folder_name=part_type train_path='../trained_models/'+part_type pathlib.Path(train_path).mkdir(parents=True, exist_ok=True) tl_path=train_path+'/transfer_learning' pathlib.Path(tl_path).mkdir(parents=True, exist_ok=True) model_path=tl_path+'/model' pathlib.Path(model_path).mkdir(parents=True, exist_ok=True) logs_path=tl_path+'/logs' pathlib.Path(logs_path).mkdir(parents=True, exist_ok=True) plots_path=tl_path+'/plots' pathlib.Path(plots_path).mkdir(parents=True, exist_ok=True) deployment_path=tl_path+'/deploy' pathlib.Path(deployment_path).mkdir(parents=True, exist_ok=True) #Objects of Measurement System, Assembly System, Get Inference Data print('Initializing the Assembly System and Measurement System....') measurement_system=HexagonWlsScanner(data_type,application,system_noise,part_type,data_format) vrm_system=VRMSimulationModel(assembly_type,assembly_kccs,assembly_kpis,part_name,part_type,voxel_dim,voxel_channels,point_dim,aritifical_noise) get_data=GetTrainData(); point_index=get_data.load_mapping_index(mapping_index) print('Training 3D CNN model') if(activate_tensorboard==1): tensorboard_str='tensorboard' + '--logdir '+logs_path print('Visualize at Tensorboard using ', tensorboard_str) print('Importing and Preprocessing Cloud-of-Point Data') dataset=[] dataset.append(get_data.data_import(file_names_x,data_folder)) dataset.append(get_data.data_import(file_names_y,data_folder)) dataset.append(get_data.data_import(file_names_z,data_folder)) point_index=get_data.load_mapping_index(mapping_index) kcc_dataset=get_data.data_import(kcc_files,kcc_folder) input_conv_data, kcc_subset_dump,kpi_subset_dump=get_data.data_convert_voxel_mc(vrm_system,dataset,point_index,kcc_dataset) transfer_learning=TransferLearning(tl_type,tl_base,tl_app,model_type,assembly_kccs,optimizer,loss_func,regularizer_coeff,output_type) base_model=transfer_learning.get_trained_model() print(base_model.summary()) #plot_model(base_model, to_file='model.png') transfer_model=transfer_learning.build_transfer_model(base_model) if(tl_type=='full_fine_tune'): model=transfer_model if(tl_type=='variable_lr'): model=transfer_learning.set_variable_learning_rates(transfer_model,conv_layer_m,dense_layer_m) if(tl_type=='feature_extractor'): model=transfer_learning.set_fixed_train_params(transfer_model) train_model=TrainModel(batch_size,epocs,split_ratio) trained_model,eval_metrics,accuracy_metrics_df=train_model.run_train_model(model,input_conv_data,kcc_subset_dump,model_path,logs_path,plots_path,activate_tensorboard,tl_type=tl_type) accuracy_metrics_df.to_csv(logs_path+'/tl_metrics.csv') print("Transfer Learning Based Model Training Complete..") print("The Model Validation Metrics are ") print(eval_metrics)