Some variable not defined, even though it is

Hi,

I have two similar functions, for training a Boltzmann machine. Here’s the first:

function train(ptrns, n_h, ϵ, n_G_s, steps)
    w = rand(Normal(0,0.01),size(ptrns,2)+1, n_h+1)
    h = hcat(zeros(1,n_h),1);
    hidden_activation = zeros(size(ptrns,1),steps, n_h+1)
    visible_reconstructions = zeros(size(ptrns,1), steps, size(ptrns,2)+1)
    proportions = dropdims(mean(ptrns, dims=1), dims=1);
    visible_biases = log.(proportions./(1 .- proportions));
    w[end,1:end-1] = zeros(n_h)
    w[1:end-1,end] = visible_biases
    w[end,end] = 0
    fantasy_visible = vcat(zeros(size(ptrns,2)),1)
    fantasy_hidden = vcat(zeros(n_h),1)
    for i in 1:steps 
        v = hcat(copy(ptrns),ones(size(ptrns,1)));
        for pt in 1:size(v,1)
            for unts in 1:n_h
                h[unts] = 1/(1+exp(-(v[pt,:]'*w[:,unts])))
            end
            w[end,end] = 0
            for s in 1:n_G_s
                for unts in 1:n_h
                    p = 1/(1+exp(-(fantasy_visible'*w[:,unts])))
                    fantasy_hidden[unts] = rand(Bernoulli(p))
                    end
                end
                for unts in 1:(size(v,2)-1)
                    p = 1/(1+exp(-(fantasy_hidden'*w[unts,:])))
                    fantasy_visible[unts] = rand(Bernoulli(p))
                end
            end
            w = w + ϵ*(v[pt,:]*h) - ϵ*(fantasy_visible*fantasy_hidden')
            w[end,end] = 0
            hidden_activation[pt,i,:] = h
            visible_reconstructions[pt,i,:] = v[pt,:]
        end
    end
    return w , hidden_activation, visible_reconstructions
end;

and I get the following error:

UndefVarError: w not defined

Stacktrace:
 [1] top-level scope at In[1]:37

You can see that I defined w at the beginning of the function, and still Julia complains about w not being defined. What’s bothering me is that I don’t get any error in the following similar function:

function train(ptrns, n_h, ϵ, n_G_s, steps)
    w = rand(Normal(0,0.01),size(ptrns,2)+1, n_h+1)
    h = hcat(zeros(1,n_h),1);
    hidden_activation = zeros(size(ptrns,1),steps, n_h+1)
    visible_reconstructions = zeros(size(ptrns,1), steps, size(ptrns,2)+1)
    proportions = dropdims(mean(ptrns, dims=1), dims=1);
    visible_biases = log.(proportions./(1 .- proportions));
    w[end,1:end-1] = zeros(n_h)
    w[1:end-1,end] = visible_biases
    w[end,end] = 0
    for i in 1:steps 
        v = hcat(copy(ptrns),ones(size(ptrns,1)));
        for pt in 1:size(v,1)
            for unts in 1:n_h
                p = 1/(1+exp(-(v[pt,:]'*w[:,unts])))
                h[unts] = rand(Bernoulli(p))
            end
            w = w + ϵ*(v[pt,:]*h)
            w[end,end] = 0
            for s in 1:n_G_s
                for unts in 1:(size(v,2)-1)
                    p = 1/(1+exp(-((h*w'[:,unts])[1])))
                    v[pt,unts] = p
                end
                for unts in 1:n_h
                    p = 1/(1+exp(-(v[pt,:]'*w[:,unts])))
                    if s == n_G_s
                        h[unts] = p
                    else
                        h[unts] = rand(Bernoulli(p))
                    end
                end
            end
            w = w - ϵ*(v[pt,:]*h)
            w[end,end] = 0
            hidden_activation[pt,i,:] = h
            visible_reconstructions[pt,i,:] = v[pt,:]
        end
    end
    return w , hidden_activation, visible_reconstructions
end;

This function has the same structure as the previous one, yet it runs without any error. What’s the problem? Does it have something to do with scope of variables? If it does, why does the second function runs normally, and how to fix the first function?
Thanks in advance!

Could you suggest some dummy input, so we have a complete, reproducible example?

1 Like

Sure. I should’ve given some dummy input.
So for instance, the first input, ptrns could be zeros(3,10), n_h=20, ϵ=0.15, n_G_s=4, steps=100.

This error appears to occur when defining the function, not while running it, correct? In that case the input isn’t actually needed.

You seem to have an extra end loitering about, probably the one here:

for unts in 1:n_h
    p = 1/(1+exp(-(fantasy_visible'*w[:,unts])))
    fantasy_hidden[unts] = rand(Bernoulli(p))
    end  # <- oops
end
2 Likes

Thanks! The problem’s solved. I’m so sorry! I should’ve double-checked my code, that’s really embarrassing!

Wasn’t that easy to catch. It’s the sort of thing that a linter should help with, I think.

1 Like

Never heard of the word “linter” before. Could you please introduce one?

A ‘linter’ checks your code for things that may be errors or bad style, missing variable definitions, misaligned block delimiters, syntax errors, etc. A brief intro on wikipedia: https://en.wikipedia.org/wiki/Lint_(software)

Both Juno and Julia for VS Code should have linters, but I don’t know how much stuff they will find.

2 Likes