HNHacker News
TopNewBestAskShowJobs

mcabbott

105 karma · joined January 14, 2019

https://github.com/mcabbott
submissionscomments
mcabbott··on Deep learning may need a new programming language
Then challenge yourself to write some code completely agnostic to the indexing, which will force you to learn some neat features. Doing pointer arithmetic with your bare hands (however much muscle memory they have) is very seldom necessary, computers are pretty good at that stuff.
mcabbott··on Einsum Is All You Need – Einstein Summation in Deep Learning (2018)
But that would sum everything, not just the parts which need it. You'd actually have to write this:

\sum_a(A_ia x_a) + v_i + \sum_a(x_a y_a) ( w_i + \sum_b(B_ib z_b) )

My example is actually still easier without indices. (Although you lose some information, like the fact that x & y are vectors in the indexed by a,b.) Here it's clear that Ax and x⋅y each involve a sum, which never includes v:

Ax + v + (x⋅y)(w + Bz)

mcabbott··on Einsum Is All You Need – Einstein Summation in Deep Learning (2018)
You insert kronecker deltas: ∂M_ab / ∂M_cd = δ_ac δ_bd , and a,b here remain contracted with whatever M was originally contracted with. Then you simplify, δ_ac Z_xya = Z_xyc and so on.
mcabbott··on Einsum Is All You Need – Einstein Summation in Deep Learning (2018)
Right, changing the order would be a pain. Although if the reason for doing so is memory layout (for speed), then a lazy permutedims(A) would decouple index order from this. Perhaps when creating a tensor for the first time there ought to be a way to specify the layout? Haven't thought much but something like A[n^4, μ,ν, c^1] := .... would not be hard to do.

In your prod<2>(a, b, ... example, if p1 and p2 are in the same space, how would a*b know which one to contract? Or do they have different names from when a was created?

mcabbott··on Einsum Is All You Need – Einstein Summation in Deep Learning (2018)
I made a thing to audit that you are consistent with your indices [1] as an alternative to explicit named-tensor objects. And found, but have not used, another package in a similar spirit [2].

Although to be honest, simply writing A[n,μ,ν,c] etc. (using different letters for different spaces) makes it pretty easy to visually check that you are getting this right. This is one of the attractions of the notation, even on paper. Unfortunately np.einsum's string notation makes this harder to see, as the indices aren't adjacent to the variable name.

[1] https://github.com/mcabbott/TensorCast.jl#checking (Julia)

[2] https://github.com/ofnote/tsalib (Python)

mcabbott··on Einsum Is All You Need – Einstein Summation in Deep Learning (2018)
If you have just one term, then leaving out the summation sign saves little. But in larger expressions, the rule applies sums per term, and then the savings in clutter can be quite large. For example, here v_i is not summed, and the term with z_b has two sums:

A_ia x_a + v_i + x_a y_a ( w_i + B_ib z_b )

You should not need to check the LHS, x_a y_a should always mean the dot product of these two. At least this is the convention among the heavy addicts; among lighter users you will sometimes find other setups.

mcabbott··on Julia Language Co-Creators Win James H. Wilkinson Prize for Numerical Software
There are also differences of building styles, maybe this is part of how we ended up with different terminology. The prototypical Parisian building has a paved driveway to the courtyard which is on the ground level. The prototypical New England house has a first floor which is a wooden thing with floorboards, 3 feet or so above ground.
mcabbott··on Einstein Summation in Numpy
I guess lots of things distinguish rows & columns which, for complex numbers, you can think of as up & downstairs -- rows are conjugated. But otherwise everybody seems to live in flat space.

If you had reason to do so, it would be easy to bolt something onto the front of @tensor etc. which understood say A^[i]_[j] * B^[j,k] . Something similar would not be so hard to do to np.einsum either, just messing with the string... it could take exactly your "email Latex notation". In fact I'm a bit surprised that I can't find someone who's done this, in a few minutes' googling. I did find that opt-einsum has a notation in which the indices at least follow the array:

https://optimized-einsum.readthedocs.io/en/latest/input_form...

mcabbott··on Julia Language Co-Creators Win James H. Wilkinson Prize for Numerical Software
But why should you have to care, why not just sum(range)? Or

    @threads for i in eachindex(object) 
and let the details about how many cores be written once, correctly, elsewhere?
mcabbott··on Einstein Summation in Numpy
The julia DSL for this is closer to what you want: "M_ij = A_ik * B_kj" reads

    @einsum M[i,j] := A[i,k] * B[k,j]
Or faster with @tensor from https://github.com/Jutho/TensorOperations.jl & the same notation. I'm not aware of any attempt to distinguish co-vectors; you can have g = Diagonal([-1,1,1,1]) and insert A[i,k]g[k,k′]B[k′,j] and this is handled efficiently.
mcabbott··on Einstein Summation in Numpy
It always seems a bit weird to me that np.einsum needs to parse a string in its own private syntax. I guess it's a good thing that at least it has tools for this!
mcabbott··on Julia Language Co-Creators Win James H. Wilkinson Prize for Numerical Software
If you want to take it for a spin, challenge yourself not to write anything which cares about this. It will force you to learn the some neat features (e.g. for N-dim arrays) instead of indexing with your bare hands like you're in C. And is good style anyway, to be generic to things like https://github.com/JuliaArrays/OffsetArrays.jl
mcabbott··on Tensor Considered Harmful Part 2
Some operations are quite tensor-ish. For instance the re-shaping which einops writes like this

    Rearrange('b c h w -> b (c h w)')
is literally a tensor product of the vector spaces indexed by c,h,w. The same space that np.kron maps into (possibly modulo the order of indices) rather than np.hstack (of row vectors) which maps to the direct sum, ⊕ not ⊗.
mcabbott··on Tensor Considered Harmful Part 2
Index notation is often less confusing than numbered dimensions, without requiring an you to use an explicit NamedTensor.

Perhaps of interest, here's a quick prototype of how this could be useful. If you use an index "n"-for-number on the dimension for which you previously used an index "c"-for-colour (when performing any einsum or slicing or re-shaping operation) then you will get a warning:

https://github.com/mcabbott/TensorSlice.jl#checking

← PreviousPage 2 of 2