Fitting slpSUSTAIN using optim
ceredmunds opened this issue · 14 comments
I am trying to use optim to fit SUSTAIN to several category structures. However, I receive an error I don't receive whilst just inputting parameter values into slpSUSTAIN. I've attached a minimal example of what I'm trying to do. Thanks!
Hi! Step by step I found out how to resolve the error. When I run the code line by line, everything works until optim
. So, because the error says it cannot replace st$dims
, it is likely because how you tried to handle the lists containing the parameters. Thereof I put the parameters that remain constant outside of the fitting function (see parfun
in the code below).
The error message I got afterwards, related to lambda
being negative. I don't know if there is a scenario in which lamba
should be negative, at the moment just set it bigger than zero. It can be manipulated so that the model is more sensitive to a particular dimension, but then it should be a vector, and I am unsure how optim
would handle that. More importantly, the tuning of the receptive field lambda
is learned by the model (see p.6 in Love, Medin, and Gureckis, 2004) and not optimised per se, so put it into parfun
, alongside with tau
- which you dont need because you are doing supervised learning. So all in all, the code that works for me looks like this:
require('catlearn')
#source('slpSUSTAIN.R')
source('trainingMatrices.R')
trlength <- trlength[, c(-2, -7)]
randomiseTrials <- function(data) {
control <- data[, 1]
data <- data[sample(nrow(data)), ]
data[,1] <- control
return(data)
}
data <- randomiseTrials(get("trlength"))
# parameters to be optimised
par <- list(r = 2.844642, # attentional focus
beta = 2.386305, # cluster competition
d = 12.0, # decision consistency
eta = 0.09361126 # learning rate
)
# parameters required by the function that are constant
parfun <- list(lambda = c(1, 1), # tuning of receptive fields
tau = 0.0, # unsupervised threshold
dims = c(1, 1),
w = NA,
cluster = NA,
colskip = 1)
fitSUSTAIN <- function(par, data, xtdo = T) {
out.list <- list()
st.all <- c(par, parfun) # combine the two set of parameters
out.list <- slpSUSTAIN(st = st.all, tr = data, xtdo = TRUE)
return(sum((data[, 5] - out.list$xtdo[, 1]) ^ 2) ^ 0.5)
}
optim(par = par, fitSUSTAIN, data = data)
Let me know if that works!
Afraid not. Cutting and pasting your code gives me:
Error in if (in.order[1] == in.order[2]) new.cluster <- TRUE :
missing value where TRUE/FALSE needed
The traceback just points to slpSUSTAIN. I checked that I definitely have the latest version of catlearn, cos I thought that might be it, but I do :S
Any ideas?
I was running it a few times and got two types of error messages as well as proper outputs, which includes the error message above and also this:
Error in if (target[fac.queried][t.queried] < 1) new.cluster <- TRUE: argument is of length zero
Traceback in both cases points to slpSUSTAIN.
But because in the whole process only the parameters change and using c(par, parfun)
directly with slpSUSTAIN works as expected, I still suspect the problem originates from the parameters, i.e. how optim is chaning the parameters. Revisiting the paper, it states at r, beta, and d that they are required to be always non-negative.
Maybe we should try setting some bounds? For example, those parameters can only be positive numbers:
optim(par = par, fitSUSTAIN, data = data, lower = c(0, 0, 0, 0), method="L-BFGS-B")
For me, it gives an output - not necessarily the right one though, the learning rate, eta, will be 0, which makes the model create a cluster for every trial, but it is progress. Would you mind giving it a try? Hopefully, we are getting closer to a resolution.
Hmmm... I've never managed to get it to run. I always get
Error in if (in.order[1] == in.order[2]) new.cluster <- TRUE :
missing value where TRUE/FALSE needed
That's incredibly annoying! What version of R, Rstudio and catlearn are you using? Maybe that's the difference?
Aside: I think we should probably edit the description of slpSUSTAIN to include the limits on parameter values. What about eta? Does that matter?
One step forward, two steps back: Can't get slpSUSTAIN to evaluate from scratch either. Tried to go backwards, but still nope! Any ideas? (Minimal example attached)
R version 3.5.1 (2018-07-02), x86_64-pc-linux-gnu (64-bit )Ubuntu 18.04.1 LTS, Rstudio 1.1.453. But it runs in other environments too on my machine (command line, Atom).
Our main problem is that I cannot even reproduce the errors at the moment. I will try to run it on other operating systems too and report back on how it went. I attached the code that I will be using.
Aside: Yes, the documentation will require some work too, and some more clarification. There is no info about its bounds in the 2004 paper, but I will look into that in the near future. Given we get the code working, I might just write up a quick tutorial with the errors we encountered.
Error_wexample.txt
Hmm, not versions. You're using version 0.6 of catlearn??
Sorry! Yes, I am using the latest stable version, v0.6 fried chicken.
Fried chicken? What?
Release name. Check out: https://github.com/ajwills72/catlearn/releases
Can you provide the output of your sessionInfo() after you get the error message?
LOL!
Session info:
R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS 10.14
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods
[7] base
other attached packages:
[1] catlearn_0.6
loaded via a namespace (and not attached):
[1] compiler_3.5.1 parallel_3.5.1 tools_3.5.1
[4] yaml_2.1.19 Rcpp_0.12.17 codetools_0.2-15
[7] doParallel_1.0.11 iterators_1.0.10 foreach_1.4.4
Any ideas about this yet?
It looks like that we might be using a slightly different training matrices recently. It is on me, because my R workspace was not cleared after looking at the first code. This was the cause of MinimalExample2: the line trlength <- trlength[, c(-2, -7)]
removed one feature leaving only the one feature of the stimuli for the model, whereas lambda and dims defined two features. This is redundant, as tr
only has the controls, input pattern and category membership, so no extra columns. Otherwise, all the previous changes we did are still valid, so I attach both the most recent version and the old version of the code below with the training matrices.
Thanks! This totally works :)