Using Pretrained DLCHOMP Optimizer in Unseen Obstacle Environment
This example shows how to use a pretrained DLCHOMP optimizer to work with a target spherical obstacle environment that is different from the environment the optimizer was trained on.
In this example, you'll start with a dlCHOMP
object that has a network that has been pretrained for a robot with an appropriate obstacle set. To use this pretrained network on a new obstacle set, you'll need to retrain the network using transfer learning.
In this example it is assumed that the pretrained dlCHOMP
optimizer is trained for the target robot kukaIiwa7
as specified by its RigidBodyTree
property, has the desired basis point set encoder as specified by its BPSEncoder
property and outputs the desired number of waypoints as specified by its NumWaypoints
property. However the training dataset spherical obstacle environment that the dlCHOMP
optimizer was trained on, as specified by its associated dlCHOMPDataOptions
object, does not match the desired target spherical obstacle environment. Since the pretrained dlCHOMP
object's RigidBodyTree
, the BPSEncoder
and the NumWaypoints
properties meet the desired requirements, but its corresponding dlCHOMPDataOptions
object does not, transfer learning can still be performed by generating a new dataset using a new dlCHOMPDataOptions
object that meets the desired requirements and then retraining the pretrained dlCHOMP
object on this new dataset. If you would like to change the number of predicted waypoints instead, refer to the Using Pretrained DLCHOMP Optimizer to Predict Higher Number of Waypointsexample.
To try out pretrained networks for other robots, see Pretrained Optimizers.
This example uses a new dlCHOMPDataOptions
object to generate a new dataset for a pretrained dlCHOMP
optimizer and then retrains it on this new dataset.
Background
Transfer learning is a deep learning approach in which a model that has been trained for one task is used as a starting point for a model that performs a similar task. Updating and retraining a network with transfer learning is usually much faster and easier than training a network from scratch.
Transfer learning is a popular technique because:
It enables you to train models with less labeled data by reusing popular models that have already been trained on large data sets.
It can reduce training time and computing resources. With transfer learning, the weights are not learned from scratch because the pretrained model has already learned the weights based on previous learnings.
For more information about transfer learning, see What Is Transfer Learning?.
Download Pretrained DLCHOMP Optimizer
The pretrained DLCHOMP optimizer to be downloaded was trained for the target robot kukaIiwa7
as specified by its RigidBodyTree
property and has the desired basis point set encoder as specified by its BPSEncoder
property. Since the RigidBodyTree
and the BPSEncoder
properties meet the desired requirements, but the obstacle environment that it was trained on does not match the environment we desire, transfer learning can be performed by retraining the network on a new dataset representative of the desired target environment. This will be covered in the next section.
For now, download a pretrained DLCHOMP optimizer trained for the kukaIiwa7
robot. Also obtain the dlCHOMPDataOptions
object that was used to generate the training dataset used to train this pretrained optimizer.
dlCHOMPComponent = "rst/data/dlCHOMP/R2024a"; pretrainedDLCHOMPFilename = "kukaIiwa7DLCHOMPTrained.zip"; disp("Downloading previously trained kukaIiwa7 dlCHOMP optimizer (46 MB)...");
Downloading previously trained kukaIiwa7 dlCHOMP optimizer (46 MB)...
pretrainedDLCHOMPFolder = exampleHelperDownloadData(dlCHOMPComponent,pretrainedDLCHOMPFilename); pretrainedDLCHOMPMATPath = fullfile(pretrainedDLCHOMPFolder,"trainedDLCHOMP.mat"); loadedData = load(pretrainedDLCHOMPMATPath,"robotName","trainedDLCHOMP","trainInfo","trainOptions","trainLossType","dataOptions"); pretrainedRobotName = loadedData.robotName; pretrainedDLCHOMP = loadedData.trainedDLCHOMP; pretrainedTrainInfo = loadedData.trainInfo; pretrainedTrainOptions = loadedData.trainOptions; pretrainedTrainLossType = loadedData.trainLossType; pretrainedDataOptions = loadedData.dataOptions;
As can be seen in the training plot above, the pretrainedDLCHOMP
optimizer took 1500 iterations to get trained, and hence converge, from scratch.
Specify Target Spherical Obstacle Environment
This example assumes knowledge of the dlCHOMPDataOptions
object property values that represent the target environment of interest. For more information on obtaining and determining the correct dlCHOMPDataOptions
object property values, see Train Deep-Learning-Based CHOMP Optimizer for Motion Planning.
Create a new dlCHOMPDataOptions
object by specifying the data generation options that represent the target spherical obstacle environment of interest.
desiredDataOptions = dlCHOMPDataOptions(... "RadiusRangeOfObstacles",[0.0500 0.2000],... "CountRangeOfObstacles",[10 15],... "MinDistanceFromBase",0.2100)
desiredDataOptions = dlCHOMPDataOptions with properties: RadiusRangeOfObstacles: [0.0500 0.2000] CountRangeOfObstacles: [10 15] MinDistanceFromBase: 0.2100 NumSamples: 2000 ValidationSplit: 0.2000 RandomStream: 'threefry' Seed: 0
Check Training Dataset Representing Target Spherical Obstacle Environment
Finally, for a given dlCHOMP
optimizer, you can generate its training data using a corresponding dlCHOMPDataOptions
object. This data options object represents the target spherical obstacle environment that the dlCHOMP
optimizer is trying to learn motion planning for. So there is a need to check if the data that was used to train the pretrained dlCHOMP
optimizer matches the desired target environment. For this, check the following properties that affect the environment complexity of the dlCHOMPDataOptions
object that was used to train the pretrained dlCHOMP
optimizer:
RadiusRangeOfObstacles
CountRangeOfObstacles
MinDistanceFromBase
Notice that these properties of a dlCHOMPDataOptions
object are writable post object creation.
Let's compare these property values for the chosenDataOptions
and pretrainedDataOptions
objects.
radiusRangeOfObstaclesMatch = isequal( ...
desiredDataOptions.RadiusRangeOfObstacles,pretrainedDataOptions.RadiusRangeOfObstacles)
radiusRangeOfObstaclesMatch = logical
1
countRangeOfObstaclesMatch = isequal( ...
desiredDataOptions.CountRangeOfObstacles,pretrainedDataOptions.CountRangeOfObstacles)
countRangeOfObstaclesMatch = logical
0
minDistanceFromBaseMatch = isequal( ...
desiredDataOptions.MinDistanceFromBase,pretrainedDataOptions.MinDistanceFromBase)
minDistanceFromBaseMatch = logical
1
environmentChecksPass = radiusRangeOfObstaclesMatch && countRangeOfObstaclesMatch && minDistanceFromBaseMatch
environmentChecksPass = logical
0
As can be seen above, the countRangeOfObstaclesMatch
check does not pass which leads the environment check to fail. This indicates that the pretrainedDLCHOMP
optimizer was trained on a spherical obstacle environment that does not match the desired spherical obstacle environment.
Since the pretrainedDLCHOMP
optimizer matches all the desired objectives except for the desired target spherical obstacle environment of interest, a new small dataset can be generated for retraining the optimizer to meet this one last unsatisfied objective.
Generate Training Dataset Matching Desired Environment
First, modify the dlCHOMPDataOptions
properties of the chosenDataOptions
object that affect environment diversity and the training versus validation data set splits.
As explained in the Background section, there is a need to generate a much smaller training dataset as compared to what the pretrainedDLCHOMP
object was trained on.
For this, decrease the training dataset size in the desiredDataOptions
object to be much smaller than that of the pretrainedDataOptions
object.
For this, set the NumSamples
property of desiredDataOptions
to be a tenth of that of pretrainedDataOptions
which amounts to 500 as compared to 5000 data samples. For more information on these properties, see dlCHOMPDataOptions
.
desiredDataOptions.NumSamples = pretrainedDataOptions.NumSamples/10
desiredDataOptions = dlCHOMPDataOptions with properties: RadiusRangeOfObstacles: [0.0500 0.2000] CountRangeOfObstacles: [10 15] MinDistanceFromBase: 0.2100 NumSamples: 500 ValidationSplit: 0.2000 RandomStream: 'threefry' Seed: 0
Keep 20% of the generated data set for validation and the rest for training. To do this set the ValidationSplit
property to 0.2
.
desiredDataOptions.ValidationSplit = 0.2;
Now, execute the following code snippet to generate the 500 samples. Note that this takes 1 hr on a Windows 10 system with 48 GB of RAM. Hence, this dataset is downloaded by default as generateData
is set to false
below.
If you would like to wait for data generation, set generateData
to true
. Otherwise, set generateData
to false
.
generateData = false;
If generateData
is false
, download the required data. Otherwise, generate the data.
dataSamplesFolder = "allData"; if generateData == false dataSamplesFilename = "kukaIiwa7DataForRetrainingDLCHOMPToNewEnv.zip"; disp("Downloading data for retraining kukaIiwa7 dlCHOMP optimizer (144 MB)..."); dataSamplesFolder = exampleHelperDownloadData(dlCHOMPComponent, ... dataSamplesFilename, 'DataFolder',dataSamplesFolder); validIndices = 1:floor(desiredDataOptions.ValidationSplit * desiredDataOptions.NumSamples); trainIndices = (numel(validIndices)+1):desiredDataOptions.NumSamples; validDS = dlCHOMPDatastore(dataSamplesFolder,validIndices); trainDS = dlCHOMPDatastore(dataSamplesFolder,trainIndices); else seed = 100; rng(seed,"twister"); [trainDS,validDS] = generateSamples(pretrainedDLCHOMP,desiredDataOptions,dataSamplesFolder); end
Downloading data for retraining kukaIiwa7 dlCHOMP optimizer (144 MB)...
Retrain Pretrained DLCHOMP Optimizer
Let's retrain the pretrainedDLCHOMP
optimizer object using the new data that was obtained.
We can use the same training options object pretrainedTrainOptions
by setting its ValidationData
property to the new validDS
we obtained earlier. We keep the other properties the same.
trainOptions = pretrainedTrainOptions; trainOptions.ValidationData = validDS;
Use the loss type pretrainedTrainLossType
that was used to train the pretrainedDLCHOMP
object.
Now, retrain the pretrainedDLCHOMP
optimizer object using the training datastore trainDS
, loss type pretrainedTrainLossType
and the training options trainOptions
. Note that this takes 1 hr using 8 parallel workers on a Windows 10 system with 48 GB of RAM. Hence, this retrained object is downloaded by default as doRetraining
is set to false
below.
If you want to retrain the object yourself, set doRetraining
to true
. Otherwise, set doRetraining
to false.
doRetraining = false;
If doRetraining
is false
, download a new pretrained dlCHOMP
optimizer object. Otherwise, retrain the existing object.
if doRetraining == false retrainedDLCHOMPFilename = "kukaIiwa7DLCHOMPRetrainedForNewEnv.zip"; disp("Downloading previously retrained kukaIiwa7 dlCHOMP optimizer (44 MB)..."); retrainedDLCHOMPFolder = exampleHelperDownloadData(dlCHOMPComponent,retrainedDLCHOMPFilename); retrainedDLCHOMPMATPath = fullfile(retrainedDLCHOMPFolder,"retrainedDLCHOMP.mat"); load(retrainedDLCHOMPMATPath,"retrainedDLCHOMP","retrainInfo"); else retrainInfo = trainDLCHOMP(pretrainedDLCHOMP,trainDS,pretrainedTrainLossType,trainOptions); retrainedDLCHOMP = pretrainedDLCHOMP; end
Downloading previously retrained kukaIiwa7 dlCHOMP optimizer (44 MB)...
As can be seen above, the dlCHOMP
optimizer converged much faster while training, within about 150 iterations, which is much smaller than the nearly 1500 iterations that were needed to train the pretrained dlCHOMP
optimizer from scratch as was shown in the training plot under the Download Pretrained DLCHOMP Optimizer section above. This indicates that the network had already learned weights based on previous learnings and simply had to be tuned to work for the new target spherical obstacle environment.
Infer Using Retrained DLCHOMP Optimizer
Now that the retrained optimizer is available, we can use it for inference on an unseen target environment of interest.
Generate One Unseen Target Environment
Let's generate an unseen target environment using the same dlCHOMPDataOptions
object were chosen for generating the training and validation data sets to ensure the same environment complexity. However, change the properties that affect the environment diversity to ensure that an unseen data sample is generated.
First, to generate only 1 data sample, set the NumSamples
property to 1
and set the ValidationSplit
property to 0
respectively.
desiredDataOptions.NumSamples = 1; desiredDataOptions.ValidationSplit = 0;
Next, to ensure an unseen data sample is generated, change the Seed
value to differ it from the one used when generating the training and validation data sets used to train the optimizer. Since we used the default Seed
value of 0 then, let's use a value of 500
now.
desiredDataOptions.Seed = 500;
Choose a new location for saving the generated unseen sample.
folderForUnseenData = "unseenData";
Generate an unseen target environment.
rng(desiredDataOptions.Seed,"twister");
testDS = retrainedDLCHOMP.generateSamples(desiredDataOptions,folderForUnseenData);
------------------------ Starting data generation [1/1] Data Samples Written | ┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃ 100.00% complete | Total Run Time: 00:00:01 secs Estimated Time Remaining: 00:00:00 secs ------------------------
filePathToUnseenSample = resolve(testDS.FileSet).FileName(1); [unseenStart,unseenGoal,unseenObstacles,chompTrajectory] = exampleHelperExtractDataFromDLCHOMPSample(filePathToUnseenSample);
Infer On Unseen Target Environment
Make the retrainedDLCHOMP
optimizer aware of the unseen spherical obstacles.
retrainedDLCHOMP.SphericalObstacles = unseenObstacles;
Finally, use the retrainedDLCHOMP
optimizer for inference on this unseen target environment.
[optimWptsDLCHOMP,optimTptsDLCHOMP,solninfoDLCHOMP] = retrainedDLCHOMP.optimize(unseenStart,unseenGoal);
Let's visualize this trajectory in an animated fashion.
% Create new figure figure % Show animated robot trajectory ax = show(retrainedDLCHOMP,unseenStart); title("dlCHOMP Optimized End-Effector Trajectory in Unseen Target Environment"); axis(ax,"equal") exampleHelperShowAnimatedRobotTrajectory(ax,retrainedDLCHOMP.RigidBodyTree,optimWptsDLCHOMP);
Conclusion
In conclusion, you learned how to determine if a pretrained dlCHOMP
optimizer can be used in a target spherical obstacle environment. You also learned how to retrain this pretrained dlCHOMP
optimizer meant for one type of spherical obstacle environment for use in a different type of spherical obstacle environment. Finally, you used this retrained dlCHOMP
optimizer for motion planning in an unseen target obstacle environment.