Julia Impressions
eyeballtrees.com
eyeballtrees.com
https://github.com/ninjin/ppod/tree/master/hck/rnn_perf
Disappointingly enough I was unable to push the performance of Julia beyond that of pure (and ugly) Matlab. I tried asking over at #julia, but it seems that my implementation should be reasonably canonical. This is really a pity for me since I would love to remain highly productive in terms of code and use something scripting-esque rather than have to re-consider going back to C. I have also had a look at Nimrod, but the scientific library support appears somewhat lacking at the moment.
https://github.com/ninjin/ppod/commit/ce7665a2cfd045332e9861...
Julia is really tempting for my next project, the benefits of scripting without all the OOP cruft and a community that just shines. Also, did I mention the awesome meta programming?
I've been focusing on mastering the scientific libraries of Python and waiting until I hit performance walls before I took Julia on, but perhaps I'll start now.
I think this is an odd statement, seeing as how Cython allows you to write pure C code without making any use of the Python C API, so by definition Cython can be as efficient as C minus a single function call from Python to C.
I think your benchmark is way too small to be interesting. You're only testing raw numerical performance, and of course C wins there. Any of these languages allow you to wrap a C library with more or less convenience. I think the more interesting questions are how well these languages allow you to build larger applications with performance-sensitive components, how extensive the ecosystem of libraries is, and the quality of debugging and profiling facilities.
https://github.com/bachase/nnadl-julia.
The notes file on the optimization branch is a very rough outline of things I discovered while iterating on performance. Outside of Iain's great advice and without profiling your code, for a larger sized network, you might benefit from reordering loops for column major storage, or doing normal matrix multiplication (which uses BLAS) followed by a devectorized tanh.
As for the language, I love being able to get something working quickly while writing in a Matlab/"mathy" style. The built in profiler and timer tools are then excellent for zeroing in on hotspots and memory allocations. I'm just amazed at how simply I can drill down from scripting style code to LLVM IR to native asm all in an ijulia notebook browser window.
On the downside, I'm not a fan of having to manually devectorize to avoid temporaries, especially given the success of c++ libraries like Blitz that figure it out for you. I'm sure Julia will improve in this area as it matures.
http://chronos.isir.upmc.fr/~mouret/tmp/nn_eigen3.cc
It seems pretty fast!
I'm kind of desperate to get away from R at this point, but reluctant to move to Python (not that I have anything against Python, but I would really like to add a high performance language to my toolkit than something inbetween).
[1] http://harlanh.github.io/DataFrames.jl/
[2] http://distributionsjl.readthedocs.org/en/latest/
[3] https://github.com/dcjones/Gadfly.jl
As you mention, the vast selection of libraries (and the continual development of these libraries) make even the python module universe look small (in reference to statistical methods, statistical algorithms/machine learning, plotting).
Further, not only are there a lot of libraries.. but many of them are bleeding edge written by the same people who originally invented the given algorithm. Most similar libraries in other languages (like Python) have incomplete ports of these libraries to them often not written by the same people. Not to mention, the documentation behind these algorithms is often excellent - besides the usual man files, there's "vignettes" (detailed instruction manual) as well as an entire journal that now has become a place to publish papers detailing the usage and implementation of many of these algorithms.
So I'm curious, why leave?
But after trying really hard over the past 3 years I'm sort of giving up ever being able to use it in a productive reliable fashion for building more complex software. It's a failing on my own part in many ways, but the loose typing and poor support for structuring code interact very badly with my personal style. When I'm working in R I literally spend 80% of my time fighting with the type system, debugging weird and wonderful features of R. I'm at the point where whenever I write an R function the first 50 lines of the code are type checks to make sure the data coming in is what I expect. I came to this point after I started systematically tracking why I was wasting so much time, and nearly every time it would come back to the type of my data being something other than what I had expected or assumed.
So I'm sort of figuring if I'm at the point where I'm writing manually statically typed code in R ... I should look around for a language that's just like R but has at least slightly stronger data types built in.
I am not so sure about the scope of the 'bleeding edge' part. It is popular among old school, statisticians. Another population (no pun intended) that R is popular in is one where one knows neither statistics nor machine learning but just wants to try out a laundry list of canned methods without a need to understand: pretty plot goes up, yay awesome; pretty plot goes down, ok try the next algorithm (or the other way round). Here I think R is pretty unbeatable in its breadth.
It is not that popular among machine learners. Part of it is cultural, a typical machine learning person will be coming from a CS background and then R grates more.
It has been claimed that R is lisp meets stats, I think that would be Julia now and Lush then. http://lush.sourceforge.net/. To quote Yann LeCun:
"Lush combines three languages in one: a very simple to use, loosely-typed interpreted language, a strongly-typed compiled language with the same syntax, and the C language, which can be freely mixed with the other languages within a single source file, and even within a single function."
I disagree with you premise that R is not popular among machine learners and the implication that has for the "bleeding edge" comment. Perhaps it is less popular with ML people coming from a CS background - but it seems to be the most widespread language for ML (or "statistical learning") among statistics people. And that fact is not to be discounted - perhaps the preeminent book on machine learning (or at the very least one of the most popular) - "The Elements of Statistical Learning" - is written by statisticians (and in fact uses R exclusively!). The Journal of Statistical software, which features papers detailing many ML libraries, has far larger coverage of R packages than any other language: http://www.jstatsoft.org/ . I would suggest this is the evidence for the "bleeding edge" comment. Other languages' packages, say Python's ML libraries (scikit-learn, pyBrain, etc.), do note even come close to the breadth of capability in this space.
Coming from a statistics background,- I would venture to ask.. what's wrong with "pushbutton" libraries? And why are they only useful to people who do not know/understand much about ML/statistics?
Say you have a dataset and you believe ,say, a Random Forest would be well suited to predicting some response. Let's assume you have a very good understanding of Random Forests. Why would you not want a push-button library? Why would you WANT to recode the thing yourself? It's not as if your Random Forest will be any better or "more correct" than the one on CRAN or whatever language's repository you are using. I would argue it's more likely to have mistakes (coding something like this from scratch is no small task and the ones on CRAN have often gone through many iterations, improvements, and reviews from many experts in the field). And let's say you have some domain knowledge or some informed belief about how the Random Forest needs to be adapted to your particular problem (a different loss function or something) - you can easily edit the R package source code to do that - no need to rebuild the car just to give it a new paint job...
>I disagree with you premise that R is not popular among machine learners
I know what you are saying, and I agree, that is why I chose my words carefully.
I am not so sure about the *scope* of the 'bleeding edge' part
The word I wanted to highlight is "scope". The population that identifies themselves with any of these labels: machine learners, statistician, data scientist, data modeler, actuarial scientist, prediction consultant and all other variations...is huge. So whether R is popular or not depends on whom you want to include and whom you want to exclude.There is a quite a lot of variation here. In one subset, if you know the ins and outs of R you will be taken for a wizard, in another subset just listing R/MATLAB as one of your major skill will actually work against you.
> what's wrong with "pushbutton" libraries?
Nothing at all and I did not claim its wrong either. In fact I said that is one of R's strengths. For people who arent into the theory of statistics or ML then R can be a heaven sent. Especially if all they want to do is try out a catalog of algorithms.
The analogy I use is that of an automobile industry. If your goal is to be a run off the mill automobile driver/chauffeur R is your competitive advantage. If your goal is to be an automotive engineer (design new models and algorithms) R is an inferior tool. In fact if you want to be a F1 racer, you have to look elsewhere too. Like every tool it has its sweet spot, as long you don't venture outside its golden.
R is bad building material, but if you dont want to build something novel in the first place (in a statistical or machine learning sense), just call a canned solution on your (medium sized data) data, then R is the boss. If you try to do anything meaty or clever then you have to be careful with R's gotchas. It helps commoditize data analysis and popularize techniques amongst its large base. If you want statisticians to be aware of some cool technique, you have to release an R package, because if it isnt in CRAN it does not exist.
I have still not taken a serious plunge with Julia, testing waters.
Any plans for doing the same to individual scripts ? It would be handy to start off from the last known set of JIT'ed functions, may be retiring paths that are no longer frequented.
There is a mechanism for including package/user code in the system image if you compile Julia yourself. It works well with a wide range of packages, but the goal is to generalize this and make it usable with binary releases, and probably to compile packages to separate shared libraries.
(Aside from that I really love the language, and I'm looking forward to doing more with it.)
Do you have any suggestions for slowly introducing Julia to the team?
And to be extremely bold: what are you paying for all those licenses?
[1] http://lostechies.com/derekgreer/2010/04/19/double-dispatch-...
julia> function foo(s::String) "$(s)!!!" end
foo (generic function with 1 method)
julia> function foo(n::Int) n + 1 end
foo (generic function with 2 methods)
julia> foo(rand() < 0.5 ? "Hello" : 41)
42
I'm not used to this kind of dispatch for bare functions, but it seems to me that it could offer similar capabilities to what subtype polymorphism provides in OO†, without having to define new types for this methods to live in or polluting the existing types.† Probably more, as the dispatch can be resolved based on many arguments.
http://nbviewer.ipython.org/gist/StefanKarpinski/b8fe9dbb36c...
(he gave this as a talk at Strange Loop 2013, but the video seems to still be embargoed)
Edit: after a little searching, I found this.
> Filters and guards don't mix with multidimensional comprehensions. For 1-d comprehensions, I'm not convinced that it's really worth the additional syntax. What's the case for making it part of the syntax instead of just using a filter function?
For a one-dimensional array comprehension it does make sense to allow filtering and this can be easily expressed in Julia by making a coroutine that produces the values and collecting its output in an array.
Multidimensional (here multi=2) array result:
julia> [i+j for i=1:3, j=1:3]
3x3 Array{Int32,2}:
2 3 4
3 4 5
4 5 6
One dimensional array result, with filtering: julia> collect(@task for i=1:6; if i%3>0; produce(i); end; end)
4-element Array{Any,1}:
1
2
4
5
Notice that this last technique is more powerful than typical comprehensions, since it doesn't just add the possibility of filtering but arbitrary code to generate the elements.I'll have to give Julia a go. :)
That said, Julia is still developing. The kinds of people who are interested in Julia right now are probably different from the people who we hope to attract and be broadly useful for in 2-5 years. But feedback now is important so the language and ecosystem can get there!
It's a very small nitpick, but I wish Julia had a postfix function application syntax. It would be nice to be able to say `foo = 'hello'.reverse` and have it be syntactic sugar for `foo = reverse(hello)`. Or some other operator since `.` is in use. This reads nicer for long function chains, and especially when a function modifies its argument, it's nice to have that argument come first, which gives an OO-impression. E.g. for me this:
app = make_app(options)
app.route("/", _ -> "hello, world!"),
app.route("/submit", POST, req -> "hello, $(req.params["name"])!")
app.start(3000)
than this: app = make_app(options)
route(app, "/", _ -> "hello, world!"),
route(app, "/submit", POST, req -> "hello, $(req.params["name"])!")
start(app, 3000) julia> "hello" |> reverse |> uppercase
"OLLEH"Or is that not what you were referring to?
Julia is specifically designed to be a great high-performance high-level language for scientific computing. See http://julialang.org/blog/2012/02/why-we-created-julia/
public static void main(String[] args) {
System.out.println("That's why");
}
}--------------------------------
Then I clicked on the site's about: "Welcome to Eyeball Trees. My name is Stephen Malone and I cannot be trusted."
I'm really confused!