HackerTrans
TopNewTrendsCommentsPastAskShowJobs

oraziorillo

45 karmajoined 2 tahun yang lalu

Submissions

What loss.backward() actually does

oraziorillo.com
2 points·by oraziorillo·kemarin·1 comments

Show HN: Microcrad – Micrograd Reimplemented in C

github.com
79 points·by oraziorillo·25 hari yang lalu·28 comments

comments

oraziorillo
·kemarin·discuss
Following up on my post on microcrad — many of you liked and supported the project, thank you for that — I published a long-form piece on automatic differentiation, where I explain backpropagation in simple terms so that everyone will (hopefully) be able to understand it. Questions/suggestions are welcome!
oraziorillo
·21 hari yang lalu·discuss
My experience on this project was that the checks proved to be useful way before I could run the program for the first time.

The first version of the code had relatively few null checks. Later I went through and added them consistently at function boundaries, and that process ended up revealing a surprising number of bugs and bad assumptions.

Sanitizers and static analyzers could have surely caught many of these issues later, but adding the checks was a useful way to reason about the code while writing it. It felt less defensive and more proactively preventive.
oraziorillo
·21 hari yang lalu·discuss
I haven’t really looked into performance comparisons with tensor-based frameworks. This was mainly a learning project, so my goal wasn’t to make it fast.

My guess is that a scalar engine might have an advantage on tiny optimization problems (among others) with only a handful of variables, where the overhead of tensor frameworks dominates the runtime.
oraziorillo
·22 hari yang lalu·discuss
I love the idea! The next step is to add role play games in town squares.
oraziorillo
·22 hari yang lalu·discuss
Thank you for pointing this out, and to those adding clarifications to this statement as well. I've fixed the issue by renaming the reserved identifiers.
oraziorillo
·22 hari yang lalu·discuss
I re-read the second part with more calm once I got back home. There were at least a couple of things I wasn't familiar with (and therefore didn't even consider), specifically FAM and variably modified types. Thanks for the pointer, I'm realizing that having written this post and reading the comments is teaching me more about C than coding the project itself, that's crazy!

I can answer about the include guards, though. I consciously added them for portability, following the same general approach that led me to handle the big-endian to little-endian conversion explicitly in examples/mnist/idx.c: even if that safeguard is not strictly necessary on most modern systems, I love the idea that this project is potentially buildable and runnable in most environments.
oraziorillo
·22 hari yang lalu·discuss
I see, I agree that especially checking for null really comes to styles and opinions, I still don't have one I can call mine. Thanks for the explanation!
oraziorillo
·22 hari yang lalu·discuss
[deprecated post-edit] I guess I used function names beginning with underscore as it didn’t occur to me that it might be un-idiomatic. The intention was to make clear to myself that those functions are private and meant to be only used only in that file. [\deprecated post-edit]

About the second paragraph, first of all, thank you for the suggestions. Can I ask you to elaborate a little on the reasons for your proposals? For instance, even if redundant in some cases, I thought to myself it couldn’t be a bad thing to check for null pointers (though I could improve the error handling itself).
oraziorillo
·22 hari yang lalu·discuss
ngl, it distracts from backprop itself a little, but teaches a lot about memory management. I did it this way because in parallel I wanted to get better at C, but if your aim is to purely work on ML fundamentals, it’s probably better to do it in python
oraziorillo
·22 hari yang lalu·discuss
In general yes, but not if you are disciplined.

I’d put it this way: though the idea of ref counting felt very natural at the beginning for my use case, at some point I realized there were probably better techniques to achieve the same goal. I found myself multiple times writing nonsense like:

sum = value_add(v1, v2) mul = value_mul(sum, v3) [...] value_release(sum) value_release(mul)

so that later I could release the sum. When you only have one intermediate value it’s still acceptable, but at 3-4 it starts getting cumbersome.

After asking for feedback, someone rightfully pointed out that the better and faster approach for an autograd engine is using an arena allocator. My reason for saying “rightfully” is that arenas are ideal when you have many “objects” that have the same lifespan, such as the values involved in the forward/backward pass. RC is better when you have a lot of “objects” with independent lifespans.
oraziorillo
·22 hari yang lalu·discuss
Mainly did it for learning, as dgellow correctly presumed, but also there’s something intrinsically beautiful in writing code with zero dependencies
oraziorillo
·25 hari yang lalu·discuss
[dead]
oraziorillo
·25 hari yang lalu·discuss
Hey HN, I'm Orazio. I built microcrad (with a 'c'), a tiny scalar-valued automatic differentiation engine, with a small multi-layer perceptron implementation on top. It's reimplementation of Andrej Karpathy's micrograd in C. For me, this was a learning project to revisit backpropagation from first principles, with the additional difficulties that come with programming in C.

The basic idea is the same as micrograd: each number is a `Value` node in a computation graph, ops connect nodes, and the `backward` function topologically sorts the graph before applying the chain rule in reverse. The C-specific parts are memory management and two simple data structures I needed to implement backprop: sets and vectors.

The source code is about 1,350 lines, MIT licensed, and well documented. Dependencies are just the standard library and libm. In addition, the repo contains two examples to showcase how the engine works: a toy regression and an MNIST task.

What this is not: a framework to build and train neural networks in production. Being scalar-valued makes it slow, and it wasn't built for numerical robustness or large datasets. There's no commercial aim here; it's a learning project.

If you read through it, I'd like to hear thoughts, both on the ML engineering aspect and on anything that reads as un-idiomatic C.