miry boosted

This is a summary of the presentation I did today about MXNet.cr for the Crystal Language 1.0 Conference.

Machine Learning with MXNet.cr

MXNet.cr is bindings to the MXNet machine learning/deep learning library and an implementation of the MXNet Gluon deep learning library. MXNet.cr is also kind of a port of a port.

A few years ago I decided I wanted to tune up my machine learning skills, but I didn't want to use Python. At about the same time, I discovered both MXNet, with support for multiple programming languages, and mxnet.rb, a set of Ruby bindings to MXNet by Kenta Murata. For a while I was happy. But Kenta's bindings didn't include an implementation of Gluon.

Gluon is a high-level framework for building deep neural networks. I was running through the lessons in Deep Learning - The Straight Dope and bumped into lessons that required Gluon. The obvious solution was to implement Gluon. Eventually parts of my implementation made their way into mxnet.rb.

Around the time my Ruby code was being merged, I realized I'd found another language that I was really jazzed about—Crystal. You all know about Crystal—it's got Ruby-like syntax and Ruby-like ergonomics, but it's blazingly fast. So again I did the obvious thing and ported my code to Crystal.

Lessons Learned

You can almost mechanically convert Ruby code into Crystal code. Consider the following two blocks of code. Which is Ruby and which is Crystal?

def self.import(filename, inputs, epoch: 0, ctx: MXNet.cpu, allow_missing: false, ignore_extra: false) output = MXNet::Symbol.load('%s-symbol.json' % filename) inputs = [inputs] unless inputs.is_a?(Array) inputs = inputs.map { |i| MXNet::Symbol.var(i) } SymbolBlock.new(output, inputs).tap do |block| if epoch filename = '%s-%04d.params' % [filename, epoch] arg_dict = MXNet::NDArray.load(filename) arg_dict = arg_dict.transform_keys do |k| k.gsub(/^(arg:|aux:)/, '') end

def self.import(filename, inputs, epoch = 0, ctx = MXNet.cpu, allow_missing = false, ignore_extra = false) outputs = [MXNet::Symbol.load("%s-symbol.json" % filename)] inputs = [inputs] unless inputs.is_a?(Array) inputs = inputs.map { |i| MXNet::Symbol.var(i) } SymbolBlock.new(outputs, inputs).tap do |block| if epoch filename = "%s-%04d.params" % [filename, epoch] arg_dict = MXNet::NDArray.load(filename) arg_dict = arg_dict.transform_keys do |k| k.gsub(/^(arg:|aux:)/, "") end

Adding the missing but required type annotations and fixing the parts of the Ruby code that play fast and loose took the most work—for example, the Ruby (and Python, in its own way) code makes use of method_missing which is difficult to replicate in Crystal.

Crystal Language syntax for defining bindings to native libraries is first class. Seriously, I don't know who made the call but they sure got it right. In contrast, the Ruby bindings were difficult to write, although I did learn a lot about writing Ruby extensions in the process. (Ruby extensions have long been in the same boat as Elisp programming—something I am interested in but can't work up the enthusiasm to actually do.)

Crystal macros are powerful tools for removing boilerplate. Almost every operation you need in MXNet is discoverable and dynamically callable at runtime. The Ruby (and Python) way is to introspect all of the operation metadata (names, parameters, their documentation strings, etc.) at runtime and to dynamically create methods for use by application code. This is pretty slick and arguably what you want in Crystal as well, albeit at compile time.  For performance reasons I wrote a tool that dumped the metadata into a Crystal language data structure ahead of time, and then used macros at compile time to create methods.

Work on MXNet.cr has temporarily taken a back seat to work on ktistec, but as ktistec matures I look forward to spending more time on MXNet.cr

#crystalconference2021 #machinelearning #mxnet #crystal

The idea to have just a phone is resonated with me more and more. - is a minimalistic phone designed and made in the EU (Poland). It has an E-ink monitor and ultralow SAR value. It would not replace smartphones for sure. mudita.com/products/pure/

miry boosted

Magic COVID! First time in my life I got packages from in same day. Before I usually waited for 1 month.

Do you expect to have a datetime attribute in each logging event of you application?

miry boosted

RT @wyhaines@twitter.com

I wrote some thoughts about how to dynamically call methods and dispatch execution flow in Ruby vs. Crystal.


🐦🔗: twitter.com/wyhaines/status/13

miry boosted

RT @wontruefree@twitter.com

Ever wonder what benefits Crystal + Lucky has over rails check out this video. @CrystalLanguage@twitter.com @luckyframework@twitter.com
#crystal #crystallang #luckyframwork


🐦🔗: twitter.com/wontruefree/status

miry boosted

RT @luckyframework@twitter.com

OMG! So close! We are at 1,997 Stars on Github. Just a few more to break that 2k mark! github.com/luckyframework/luck

🐦🔗: twitter.com/luckyframework/sta

miry boosted

At last with Alpine and static linking, a app docker image is 10 times smaller.

RT @abhaybhargav@twitter.com

Thrilled beyond words to hear that I’ll be speaking at @usenix@twitter.com LISA21 conference this year. I’ll be speaking on skilling up engineering and security teams, a major passion of mine.

🐦🔗: twitter.com/abhaybhargav/statu

miry boosted

RT @crystalkemal@twitter.com

Kemal 1.0.0 is here 🎉
We're the first Crystal project to fully support Crystal 1.0.0 💯


#crystallang @CrystalLanguage@twitter.com

🐦🔗: twitter.com/crystalkemal/statu

miry boosted

RT @hughbien@twitter.com

Playing around with Crystal & Vimscript. Getting markdown previews working w/ front-matter YAML and fenced code blocks. Crystal is a pleasure to work with 🎉

🐦🔗: twitter.com/hughbien/status/12

RT @sdogruyol@twitter.com

Following Crystal 1.0.0 and Kemal 1.0.0 release PRs,
I just opened a PR for kemal-session 1.0.0 🚀
It also add a new samesite configuration parameter for securing the cookies.



🐦🔗: twitter.com/sdogruyol/status/1

Show older

Server run by the main developers of the project 🐘 It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!