Hacker News new | ask | show | jobs
by wokwokwok 2012 days ago
Concise isn’t always better.

You’re throwing alway all the names of the arguments and using arbitrary words like “conv” to represent operations.

This is typical bad clojure in my experience; write once, forget wtf the magic was, throw away and rewrite it again later.

Clojure doesn’t have to be incomprehensible arcane magic that does everything in 10 lines.

The more complex the code, the more important it is that what you do is clear and clearly documented.

Don’t write a 1 line regex to solve a complicated problem; it’s the wrong tool for that job, no matter how smart your substring matches are.

You don’t win a prize for making unmaintainable code.

I similarly think the goal of being burning my concise in ML code is deeply misguided.

2 comments

How is "conv" arbitrary? There is a function object that represents a convolutional layer in the network. It is bound to two symbols (because why not). You can either use "convolution" if you prefer full names, or "conv" if you prefer shorter. It doesn't represent the operation, but the layer. There are functions (with longer names) representing the convolution operation, which follow cuDNN and DNNL naming schemes.

Regarding the magic, I believe you haven't read my writings related to this. Exactly the opposite - there is no magic other than usual Clojure-fu, which I explain in a layered way.

But it's difficult to exactly reply to your critique, because you haven't given any example of an approach that would be good Clojure. Ok, give me an example of how you would do it in a comprehensible way (if what I provide is incomprehensible). You don't have to actually implement it. Show a non-working alternative. How would it look like?

Concision is a style choice to be used with care. Spending screen space on additional characters and descriptions detracts from the ability to fit more logic on the screen at once and grok the larger flow. Splashing symbolic alphabet soup into your IDE in the name of concision isn't usually a good idea, but naming something "conv" in the immediate local context of a convolutional layer doesn't seem so bad.
Does 'convo' refer to a 2D convolution or a 1D convolution? Given the large number [1] of arguments that a convolution can take, which ones are being specified? I can probably guess, since only 2 are given, but if there were more, which order would they be in and which would refer to which?

The code is on github [2, 3] see for yourself if you think it's more or less obvious than the python equivalent of a 'trivial' network.

I would say 'conv2d' is probably reasonably standard in meaning; I refer to 'convo' as arbitrary, because it is. Either (ideally) avoid abbreviations, or use standard ones.

[1] - https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.ht...

[1] - https://github.com/uncomplicate/deep-diamond/blob/master/tes...

[2] - https://github.com/uncomplicate/deep-diamond/blob/master/tes...

I know nothing about neural networks, but it looks to me like convo is smart enough to create the convolution of the correct dimension based on the arguments. Where as Keras seem to force you to use a different constructor for different dimensions. That explains why it's called convo, since it creates convolutions of any dimension.

Also, most options are provided as a map to convo as well it looks like, so you'd have similar named arguments for convo once you get to defining optional things like padding and strides.

convo is smart enough to cover 1D, 2D, 3D, and any other convolution layer that the backend can support. You only need to specify the data that it can't figure out, but you can specify more if you want.