Problem combining ParametricNDSolve with NonlinearModelFit
Specifying a constrained global optimization sub method (e.g., NelderMead, DifferentialEvolution, SimulatedAnnealing) to the NMinimize method as described in the tutorial here seems to help with the stability.
Reproducing your code with the NelderMead sub method is shown below.
eqs = {a'[t] == -k1 a[t] - k2 a[t]^2, b'[t] == k1 a[t] + k2 a[t]^2,
c[t] == q a[t] + r b[t], c[0] == q a0 + r b0, a[0] == a0,
b[0] == b0};
fixedparams = {k1 -> 1.2, b0 -> 0};
fns = {a, b, c};
params = {k2, a0, q, r};
solution =
ParametricNDSolve[eqs /. fixedparams, fns, {t, 0, 5}, params];
fitfn = c /. solution;
paramsForDataSet = {k2 -> 1.263, a0 -> 0.0321, q -> 0.341,
r -> 0.8431};
dataset = {#, ((fitfn @@ params) /. paramsForDataSet)[#] +
RandomVariate[NormalDistribution[0, 0.0002]]} & /@
Range[0, 5, 0.01];
ListPlot[dataset, PlotRange -> Full]
initialGuess = {k2 -> 2.0, a0 -> 0.3, q -> 0.32, r -> 0.88};
tmp = Values@initialGuess;
Dynamic@Column[{Show[ListPlot[dataset, PlotRange -> Full],
Plot[(fitfn @@ tmp)[t], {t, 0, 5}, PlotRange -> Full,
PlotStyle -> Red], PlotRange -> Full, ImageSize -> Large],
ListPlot[{#1, #2 - (fitfn @@ tmp)[#1]} & @@@ dataset,
PlotRange -> Full, AspectRatio -> 0.2, ImageSize -> Large]}]
result = NonlinearModelFit[dataset, (fitfn @@ params)[t],
Evaluate[List @@@ initialGuess], t,
Method -> {NMinimize, Method -> {"NelderMead"}},
StepMonitor :> (tmp = params)]
tmp = Values@result["BestFitParameters"]