Package: tf-al
Active learning with tensorflow*Currently only supports bayesian active learning tasks.Perform active learning in tensorflow/keras with extendable parts.IndexInstallationDocumentationGetting startedModel wrapperAcquisition functionsBasic active learning loopDevelopmentSetupScriptsContributionIssuesDependenciespython="^3.6"tensorflow="^2.0.0"scikit-learn="^0.24.2"numpy="^1.0.0"tqdm="^4.62.6"Installation$pipinstalltf-al*To use a specific version of tensorflow or if you want gpu support you should manually install tensorflow. Else this package automatically will install the lastest version of tensorflow described in thedependencies.Getting startedFollowing the active learning paradigm the most essential parts are the model and the pool of labeled/unlabeled data.To enable modularity tensorflow models are wrapped. The model wrapper acts as an interface between the active learning loop and the model.
In essence the model wrapper defines methods which are called at different steps in the active learning loop.
To manage the labeled and unlabeled datapoints the pool class can be used. Which offers methods to label and select datapoints, labels and indices.Other parts provided by the library easy the setup of active learning loops. The active learning loop class uses a dataset and model to creat an iterator, which then can be used to perform active learning over a single experiment.(model and query strategy combination)The experiment suit can be used to perform a couple of experiments in a row, which is useful if for example you want to compare differnt acquisition functions.Model wrapperModel wrappers are used to create an interface between the tensorflow model and the active learning loop.
Currently there are two wrappers defined.ModelandMcDropoutfor bayesian active learning.
TheModelwrapper can be used to create custom model wrappers.Here is an example of how to create and wrap a basic McDropout model.fromtensorflow.kerasimportSequentialfromtensorflow.keras.layersimportConv2D,MaxPooling2D,Dropout,Dense,Input,Flattenfromtf_al.wrapperimportMcDropout# Define and wrap model (here McDropout)base_model=Sequential([Conv2D(32,3,activation=tf.nn.relu,padding="same",input_shape=input_shape),Conv2D(64,3,activation=tf.nn.relu,padding="same"),MaxPooling2D(),Dropout(.25),Flatten(),Dense(128,activation=tf.nn.relu),Dropout(.5),Dense(output,activation="softmax")])# Wrap, configure and compilemodel_config=Config(fit={"epochs":200,"batch_size":10},query={"sample_size"25},eval={"batch_size":900,"sample_size":25})model=McDropout(base_model,config=model_config)model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=[keras.metrics.SparseCategoricalAccuracy()])Basic methodsThe model wrapper in essence can be used like a regular tensorflow model.model=McDropout(base_model)model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=[keras.metrics.SparseCategoricalAccuracy()])# Fit model to datamodel.fit(inputs,targets,batch_size=25,epochs=100)# Use model to predict output valuesmodel(inputs)# Evaluate model returning loss and accuracymodel.evaluate(some_inputs,some_targets)To define a custom  custom model wrapper, simply extend your own class using theModelclass and
overwrite functions as needed. The regular tensorflow model can be accessed viaself._model.To provide your model wrappers as a package you can simply use thetemplate on github, which already offers a poetry package setup.fromtf_alimportModelclassCustomModel(Model):def__init__(self,model,**kwargs):super().__init__(model,,model_type="custom",**kwargs)def__call__(self,*args,**kwargs):# Custom __call__ or standard tensorflow __call__defpredict(self,inputs,**kwargs):# Custom prediction method or the standard tensorflow call model(inputs)defevaluate(self,inputs,targets,**kwargs):# Defining custom evaluate method# else standard evaluate method of tensorflow used.return{"metric_1":some_value,"metrics_2":some_other_value}deffit(self,*args,**kwargs):# Custom fitting procedure, else tensorflow .fit() method is used.defcompile(self,*args,**kwargs):# Custom compile method else using tensorflow .compile(**kwargs)defreset(self,pool,dataset):# In Which way to reset the network after each active learning round# standard is re-loading weights when enabledAcquisition functionsBasic active learning loopimporttensorflow.kerasaskerasfromtensorflow.kerasimportSequentialfromtensorflow.keras.layersimportConv2D,MaxPooling2D,Dropout,Dense,Input,Flattenfromtf_alimportActiveLearningLoop,Datasetfromtf_al.wrapperimportMcDropout# Load dataset and pack into dataset(x_train,y_train),test_set=keras.datasets.mnist.load()inital_pool_size=20dataset=Dataset(x_train,y_train,test=test_set,init_size=initial_pool_size)# Create and wrap modelbase_model=Sequential([Conv2D(32,3,activation=tf.nn.relu,padding="same",input_shape=input_shape),Conv2D(64,3,activation=tf.nn.relu,padding="same"),MaxPooling2D(),Dropout(.25),Flatten(),Dense(128,activation=tf.nn.relu),Dropout(.5),Dense(output,activation="softmax")])mc_model=McDropout(base_model)mc_model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=[keras.metrics.SparseCategoricalAccuracy()])# Create and start experiment suit (Collection of different experiments model + query_strategy)query_strategy="random"active_learning_loop=ActiveLearningLoop(mc_model,dataset,query_strategy,step_size=10,# Number of new datapoints to select after each roundmax_rounds=100# How many active learning rounds per experiment?)# To completely run through the active learning loopactive_learning_loop.run()# Manually iterate over active learning loopforstepinactive_learning_loop:# Dict with accumulated metrics# ["train", "train_time", "query_time", "optim", "optim_time", "eval", "eval_time", "indices_selected"]step["train"]# Alternativly iterate step inside the loopnum_rounds=10foriinrange(num_rounds):metrics=active_learning_loop.step()# ... do something with the metricsBasic experiment suit setupimporttensorflowastffromtensorflow.kerasimportModel,Sequentialfromtensorflow.keras.layersimportConv2D,MaxPooling2D,Dropout,Dense,Input,Flattenfromtf_alimportActiveLearningLoop,Dataset,Config,ExperimentSuit,AcquisitionFunctionfromtf_al.wrapperimportMcModel# Split data and put into a datasetx_train,x_test,y_train,y_test=train_test_split(some_inputs,some_targets,test_size=test_set_size)# Number of initial datapoints in pool of labeled datainitial_pool_size=20dataset=Dataset(x_train,y_train,test=(x_test,y_test),init_size=initial_pool_size)# Define and wrap model (here McDropout)base_model=Sequential([Conv2D(32,3,activation=tf.nn.relu,padding="same",input_shape=input_shape),Conv2D(64,3,activation=tf.nn.relu,padding="same"),MaxPooling2D(),Dropout(.25),Flatten(),Dense(128,activation=tf.nn.relu),Dropout(.5),Dense(output,activation="softmax")])model_config=Config(fit={"epochs":200,"batch_size":10},# Passed to fit() of the wrapperquery={"sample_size"25},# Configuration passed to acquisition function during query stepeval={"batch_size":900,"sample_size":25}# Parameters passed to evaluation method of the wrapper)model=McDropout(base_model,config=model_config)model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=[keras.metrics.SparseCategoricalAccuracy()])# Over which model to perform experiments single or list [model_1, ..., model_n]models=model# Define which acquisition functions to apply in separate runs either single one or a list [acquisition_1, ...]acquisition_functions=["random",AcqusitionFunction("max_entropy",batch_size=900)]experiments=ExperimentSuit(models,acquisition_functions,step_size=10,# Number of new datapoints to select after each roundmax_rounds=100# How many active learning rounds per experiment?)DevelopmentSetupFork and clone the forked repositoryCreate a virtual env (optional)Install and Setup PoetryInstall package dependenciesusing poetryor set them up manuallyStart developmentScriptsCreate documentationTo create documentation for the./tf_aldirectory. Execute following command
in./docs$makehtmlTo clear the generated documentation use following command.$makecleanRun testsTo perform automated unittests run following command in the root package directory.$pytestTo generate additional coverage reports run.$pytest--covContributionIssues