<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mykyta Smyrnov</title>
    <description>The latest articles on DEV Community by Mykyta Smyrnov (@nutscracker87).</description>
    <link>https://dev.to/nutscracker87</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3800583%2F8e960d9a-22f4-4f23-9a7a-3bb6b2b46c29.jpeg</url>
      <title>DEV Community: Mykyta Smyrnov</title>
      <link>https://dev.to/nutscracker87</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nutscracker87"/>
    <language>en</language>
    <item>
      <title>learning Rust by building Neural Networks from scratch. (MLP for MNIST) Part 2</title>
      <dc:creator>Mykyta Smyrnov</dc:creator>
      <pubDate>Fri, 06 Mar 2026 00:11:30 +0000</pubDate>
      <link>https://dev.to/nutscracker87/building-neural-networks-in-rust-from-scratch-52lj</link>
      <guid>https://dev.to/nutscracker87/building-neural-networks-in-rust-from-scratch-52lj</guid>
      <description>&lt;h2&gt;
  
  
  Part 2: Scaling to MNIST — The Challenge of Abstracting Math in Rust
&lt;/h2&gt;

&lt;p&gt;After the first success with Adaline, I felt confident. I thought, "How hard can it be to scale this to a Multi-Layer Perceptron (MLP) for MNIST?" &lt;/p&gt;

&lt;p&gt;The answer: &lt;strong&gt;Hard enough to make me delete everything.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The "AI Trap" and the Great Reset
&lt;/h2&gt;

&lt;p&gt;I've got fully working program with all possible optimisations for 3-4 days after I started, hoverer, looking at the source code, I felt like a stranger to my own logic. I had relied too much on AI for the Rust boilerplate. I had a "working" project, but I wasn't truly learning the mechanics of Rust's ownership or the underlying math. Of course it was a great learning experience - because I've quickly moved from zero knowledge to hero about multi layer perceptron backdrop + dealing with MNIST dataset. But things did not aligned in my head fully...to quick, minimum mental effort from my side to write the new knowledges in stone.&lt;/p&gt;

&lt;p&gt;So, I did the unthinkable: &lt;strong&gt;I deleted the repository.&lt;/strong&gt; Starting over, line by line by myself, was the best decision I made. It forced me to figure out every peace of of the program by myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: The Transition to &lt;code&gt;ndarray&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;My initial attempt used only &lt;code&gt;Vec&amp;lt;f32&amp;gt;&lt;/code&gt;. It worked for Adaline, but for MNIST (60,000 images, 784 pixels each), it was a nightmare. &lt;br&gt;
On my &lt;strong&gt;Mac M2 Pro&lt;/strong&gt;, each epoch took around &lt;strong&gt;4 seconds&lt;/strong&gt;. While it wasn't "slow" for a small test, it became a bottleneck as I started experimenting with hyperparameters. Switching to the &lt;strong&gt;&lt;code&gt;ndarray&lt;/code&gt;&lt;/strong&gt; crate was essential for performance, but it triggered a cascading refactor. &lt;/p&gt;

&lt;p&gt;In Rust, your type system is your contract. Changing &lt;code&gt;Vec&lt;/code&gt; to &lt;code&gt;Array2&lt;/code&gt; meant rewriting everything from data loaders to weight initializers. I used this as an opportunity to restart with a cleaner, modular structure, avoiding AI-assisted boilerplate to ensure I fully understood every architectural decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 2: The "Refactoring Trap"
&lt;/h2&gt;

&lt;p&gt;By late February, I had a working MVP. The code was "dirty" and monolithic, but the math was correct, and the network was learning. Then, I decided to refactor it for modularity.&lt;/p&gt;

&lt;p&gt;And that’s when the "house of cards" collapsed. &lt;/p&gt;

&lt;p&gt;In standard Web Development, we are used to juggling modules and applying design patterns. But with Neural Networks, where the core logic is a dense wall of matrix calculus, abstraction is a double-edged sword. What worked as a single "wall of math" became difficult to follow once broken into separate modules. I realized that in math-heavy code, a "clean" architecture can sometimes break your mental map of the algorithm, making it harder to track how tensors flow through the layers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 3: Results &amp;amp; The "Visual" Architecture
&lt;/h2&gt;

&lt;p&gt;To verify my refactored logic, I focused on concrete metrics and visualization. I chose a specific architecture to satisfy both the math and my curiosity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input Layer:&lt;/strong&gt; 784 (28x28 pixels)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden Layer:&lt;/strong&gt; 36 neurons (Chosen specifically because &lt;strong&gt;36 = 6x6&lt;/strong&gt;, allowing for a perfect square heatmap visualization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output Layer:&lt;/strong&gt; 10 (digits 0-9)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Benchmarks (on Mac M2 Pro):
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Final Test Accuracy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;95.56%&lt;/strong&gt; (9556/10000 correct)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Training Time (per epoch)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~0.65s&lt;/strong&gt; (with &lt;code&gt;ndarray&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial Time (raw vectors)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~4.0s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total Epochs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hyperparameters&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Batch Size: 10, Learning Rate: 3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Phase 4: Seeing the Brain Work
&lt;/h2&gt;

&lt;p&gt;I didn't just want to see numbers; I wanted to see &lt;em&gt;what&lt;/em&gt; the network was learning, so I built a &lt;strong&gt;terminal-based visualizer&lt;/strong&gt; for MNIST digits and implemented &lt;strong&gt;weight heatmaps&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;By auto-detecting grid dimensions (like reassembling the 36 hidden layer weights back into a 6x6 grid), I could finally validate my theories on how different layers respond to features. Seeing the weights evolve from random noise into recognizable patterns confirmed that my modular architecture hadn't corrupted the mathematical logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Performance Gains:&lt;/strong&gt; Moving to &lt;code&gt;ndarray&lt;/code&gt; on M2 Pro cut training time by &lt;strong&gt;~6x&lt;/strong&gt; (from 4s down to 0.65s per epoch).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstractions are Expensive:&lt;/strong&gt; In math-heavy code, "cleaner" isn't always better if it breaks your mental map of the matrix flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visualize for Validation:&lt;/strong&gt; Choosing architecture sizes (like 36 neurons for a 6x6 grid) specifically for visualization is a powerful debugging strategy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deep Dive into the Math
&lt;/h2&gt;

&lt;p&gt;Because this project was about learning the "how" and "why," I didn't stop at the code. I’ve documented the entire mathematical journey in the repository's &lt;strong&gt;README&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you're curious about the calculus behind backpropagation, weight initialization, or the specific program workflow, you'll find a massive breakdown there. I’ve included detailed explanations of matrix transformations and full instructions on how to run the training yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Now that the modular structure is stable and the MLP is hitting 95%+ accuracy, I'm focusing on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weight persistence:&lt;/strong&gt; Saving the trained "brain" to disk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modularity:&lt;/strong&gt; Making activation functions truly swappable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimization:&lt;/strong&gt; Exploring BLAS acceleration for even faster operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check the full source code &amp;amp; math breakdown here:&lt;/strong&gt; &lt;a href="https://github.com/Nutscracker87/rust-mnist" rel="noopener noreferrer"&gt;Nutscracker87/rust-mnist&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Let's connect on LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/smirnov-nikita1987" rel="noopener noreferrer"&gt;Smirnov Nikita&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>machinelearning</category>
      <category>showdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>learning Rust by building Neural Networks from scratch. (Adaline) Part 1</title>
      <dc:creator>Mykyta Smyrnov</dc:creator>
      <pubDate>Thu, 05 Mar 2026 00:55:58 +0000</pubDate>
      <link>https://dev.to/nutscracker87/learning-rust-by-building-neural-networks-from-scratch-4bh5</link>
      <guid>https://dev.to/nutscracker87/learning-rust-by-building-neural-networks-from-scratch-4bh5</guid>
      <description>&lt;h2&gt;
  
  
  Breaking out of the Web Sandbox
&lt;/h2&gt;

&lt;p&gt;For years, &lt;strong&gt;PHP&lt;/strong&gt; has been my "home" language. It's great for the web, it's reliable, and it pays the bills. But there's a catch: PHP was designed to live within the Request/Response cycle. PHP comes alive when you receive a request, processes it, and then "dies". It's a comfortable C-style language, but it can feel limiting when you want to experiment with systems that live outside the web server environment. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Search for a "Desktop Home" Language
&lt;/h2&gt;

&lt;p&gt;I wanted to find a language that could become my "desktop" tool. A language where I could control every byte and build complex systems without the constraints of a web server. Then I found &lt;strong&gt;Rust&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;It promised to resolve one of the most painful experiences in my PHP career: memory management. Most web devs know exactly what I'm talking about. Imagine you're maintaining a legacy OOP monolith. There's a recursive function multiple layers deep, and somewhere in the middle, it's making database calls or triggering a 3rd-party library.&lt;/p&gt;

&lt;p&gt;Suddenly, the process hits the &lt;code&gt;memory_limit&lt;/code&gt; and dies silently. Finding the leak in a sea of implicit references and 'magic' objects is a nightmare. In PHP, you often don't care about memory until it’s already gone.&lt;/p&gt;

&lt;p&gt;Instead of just memorizing syntax, I decided to learn Rust by implementing something that has always appealed to me: &lt;strong&gt;Neural Networks&lt;/strong&gt;. Rust promised speed and memory efficiency, making it the perfect test for a new language involving complex math and matrix operations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: The Adaline Experiment
&lt;/h3&gt;

&lt;p&gt;My first milestone was implementing &lt;strong&gt;Adaline&lt;/strong&gt; (Adaptive Filters from Widrow). It's a simple single-layer network, but it was my first real "clash" with Rust's ownership model.&lt;/p&gt;

&lt;p&gt;I started with raw &lt;code&gt;Vec&amp;lt;f64&amp;gt;&lt;/code&gt; to keep things simple. No math libraries, no shortcuts. Just me and the borrow checker.&lt;/p&gt;

&lt;h4&gt;
  
  
  What I learned in this phase:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ownership is no joke:&lt;/strong&gt; Passing training data around forced me to think about references and lifetimes in a way PHP never did.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit over Implicit:&lt;/strong&gt; In PHP, you often don't care about memory. In Rust, you have to keep in mind exactly where your data is at every single step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't just about AI; it's about the journey of changing your engineering mindset.&lt;/p&gt;




&lt;h3&gt;
  
  
  What's next?
&lt;/h3&gt;

&lt;p&gt;Next, I will be implementing a Multi-Layer Perceptron (MLP) for the MNIST dataset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The code is here:&lt;/strong&gt; &lt;a href="https://github.com/Nutscracker87/adaline" rel="noopener noreferrer"&gt;Nutscracker87/adaline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Original LinkedIn discussion:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/posts/smirnov-nikita1987_okay-the-rust-hype-finally-got-to-me-activity-7428589188083740672-Yadm" rel="noopener noreferrer"&gt;View Post&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Feel free to connect with me on &lt;a href="https://www.linkedin.com/in/smirnov-nikita1987/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; to follow my progress!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>learning</category>
      <category>ai</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
