Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MethodError: no method matching getindex(::Pair{Symbol,Array{Float64,1}}, ::Symbol) #1404

Closed
yeruoforever opened this issue Nov 23, 2020 · 5 comments

Comments

@yeruoforever
Copy link

using Flux

data=[Dict(:x=>rand(10),:y=>rand(4)) for i in 1:3]

struct MyModel
    W
end

Flux.@functor MyModel

MyModel(in,out)=MyModel(
    rand(out,in)
)


m=MyModel(10,4)
opt=Descent(0.1)
ps=params(m)

function loss(x)
    for each in x
        each[:x_new]=m.W*each[:x]
    end
    l=sum(x) do each
        Flux.Losses.mse(each[:x_new],each[:y])
    end
end
Flux.train!(loss,ps,data,opt)
ERROR: LoadError: MethodError: no method matching getindex(::Pair{Symbol,Array{Float64,1}}, ::Symbol)
Closest candidates are:
  getindex(::Pair, ::Int64) at pair.jl:59
  getindex(::Pair, ::Real) at pair.jl:60
@DrChainsaw
Copy link
Contributor

I haven't run your code, but I think the error is in your loss function.

I will try to break it down a bit as the code looks a bit unusual.

data is an array of three Dicts where each Dict maps the Symbol :x to a random vector with 10 elements and the Symbol :y to a random vector with 3 elements. Is this how you want to represent your data?

Now, I'm pretty certain that Flux.train! will just iterate over data and call loss with each element of it. This means that x in loss will be one of those Dicts which has :x and :y in it. The first thing which happens in loss thus an iteration over the Dict x which will iterate over each key-value Pair. Iow, each will first be the Pair :x => [10 random numbers] and then :y => [4 random numbers] and the error is because you can't assign pairs like this. It looks like the intention of the code is to insert a new value in each Dict and to accomplish this you just need to remove both the for loop as well as the sum construct.

If you instead want to get the whole array of Dicts as input to loss, then you can wrap it in an array or tuple so that the whole array becomes the element of the iteration: Flux.train!(loss, ps, (data,), opt) and keep the loops.

As I said above, using a dict like this looks a bit unusual to me. I understand its an mwe, but if you explain what you are trying to achieve then perhaps there is a simpler and more efficient solution.

@CarloLucibello
Copy link
Member

@DrChainsaw is right here, passing (data,) instead of data works as expected

@yeruoforever
Copy link
Author

yeruoforever commented Nov 25, 2020

I haven't run your code, but I think the error is in your loss function.

I will try to break it down a bit as the code looks a bit unusual.

data is an array of three Dicts where each Dict maps the Symbol :x to a random vector with 10 elements and the Symbol :y to a random vector with 3 elements. Is this how you want to represent your data?

Now, I'm pretty certain that Flux.train! will just iterate over data and call loss with each element of it. This means that x in loss will be one of those Dicts which has :x and :y in it. The first thing which happens in loss thus an iteration over the Dict x which will iterate over each key-value Pair. Iow, each will first be the Pair :x => [10 random numbers] and then :y => [4 random numbers] and the error is because you can't assign pairs like this. It looks like the intention of the code is to insert a new value in each Dict and to accomplish this you just need to remove both the for loop as well as the sum construct.

If you instead want to get the whole array of Dicts as input to loss, then you can wrap it in an array or tuple so that the whole array becomes the element of the iteration: Flux.train!(loss, ps, (data,), opt) and keep the loops.

As I said above, using a dict like this looks a bit unusual to me. I understand its an mwe, but if you explain what you are trying to achieve then perhaps there is a simpler and more efficient solution.

Thank you for your replies and suggestions.

I am a beginner in neural networks and I am trying to implement a simple graph neural network. I used MetaGraphs.jl to index the attribute vector of nodes and the attribute vector of edges in the network. In MetaGraphs. jl, the attribute vector is indexed using Dict, so I simplified it to the above code.
Thank you again, your clear suggestion solves the problem in mwe concisely and efficiently. Maybe it's my negligence, I still can't solve the problem in my code.Here, I apologize for my carelessness and impoliteness. I will check my code carefully and be grateful if you can recommend a platform for our newbies to communicate.

@CarloLucibello
Copy link
Member

I suggest you take a look at https://github.com/yuehhua/GeometricFlux.jl

@DrChainsaw
Copy link
Contributor

Discourse is also a good place for questions: https://discourse.julialang.org/
Another even less formal place is Zulip chat: https://julialang.zulipchat.com/#

Btw, I didn't find anyting about your issue careless or impolite. Its not always easy to find exactly where the problem is. Hopefully you can get some help with that in the provided resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants