Rustで深層学習の推論基盤構築

背景 書籍「ゼロから作るDeep Learning」(以降,「ゼロつく」と呼びます)のRust実装を研究室の勉強会で行うことになりました. 基本的に勉強会なので,どこまでやるかは自分次第です. 私は,自作モデルでMNISTデータセットの手書き数字認識の推論精度を95%以上にすることを目標としました. 目的 本記事では,後学のため,学習済みモデルを動作させて精度を計算する部分までをまとめます. つまり,第3章の手書き数字認識を学習済みモデルで解くところまでです. 手法 実験には研究室から貸与されたノートPCを使用しました. スペック詳細は割愛します. OSにはWSL(Windows Subsystem for Linux)上のUbuntu 24.04.4 LTSを用い,ビルドと実行はすべてこの環境で行いました. また,実験に際してエディタにはVSCodeを利用し,Rust公式が開発している拡張機能であるrust-analyzerを導入しました1. プロジェクトにはRustのワークスペース機能を利用しました2. ワークスペース機能は,複数のCargoプロジェクトをまとめて管理するための機能です. 採用した理由は,推論用のコードと学習用のコードを別々のプロジェクトに分けたかったためです. また,ワークスペースとして構成しておくことで,先述のrust-analyzerが各プロジェクトを正しく読み込めるという利点もあります. ディレクトリ構造は以下のとおりです. $ tree -L 1 . ├── Cargo.lock ├── Cargo.toml ├── README.md ├── common # 共通で使用するコード(MNISTデータセットを読み出すコード等) ├── data # MNISTデータセット置き場 ├── learn # 学習に使用するコード(Cargoプロジェクト) ├── predict # 推論を行うコード(Cargoプロジェクト) ├── target # ビルド済みバイナリ └── weight # 重みとバイアスの保存場所 7 directories, 3 files このうちlearnは,今後の学習フェーズの実装を見越して用意したもので,今回は中身が空の状態です. 本記事で実装したのは推論のみであるため,実際に使用したのは以下の4つのディレクトリです. predict : ニューラルネットワークの構造体と推論ロジックの実装 common : シグモイド関数・ソフトマックス関数・MNISTデータ読み出しコード weight : 学習済みの重み(pickle形式)と,pickle形式データをnpy形式に変換するためのPythonスクリプト data : MNISTデータセット 以降では,各ディレクトリの構造と,含まれるソースコードについて説明します. ...

2026年7月28日

Rustにおける構造体のデータ格納場所分析

概要 このページで「String構造体もスタックに入りますが、ヒープに入るデータの参照アドレスが一つ入ります。」とあった。 分析することで確認する。 GDBを用いて分析する。 筆者はWindows11においてWSLを用いてUbuntu24.04を使用している。 2025年11月1日現在、筆者の環境ではGDBは以下のコマンドでインストールできる。 sudo apt install gdb 分析 本稿では、前述のページにあるサンプルコードに対して分析を行う。リンク切れをしたときに備えて、対象にするソースコードを示しておく。 以下の文章では、ソースコードといったら、以下のRustコードのことを指すものとする。 struct SeaCreature { animal_type: String, name: String, arms: i32, legs: i32, weapon: String, } fn main() { // SeaCreatureのデータはスタックに入ります。 let ferris = SeaCreature { // String構造体もスタックに入りますが、 // ヒープに入るデータの参照アドレスが一つ入ります。 animal_type: String::from("crab"), name: String::from("Ferris"), arms: 2, legs: 4, weapon: String::from("claw"), }; let sarah = SeaCreature { animal_type: String::from("octopus"), name: String::from("Sarah"), arms: 8, legs: 0, weapon: String::from("none"), }; println!( "{} is a {}. They have {} arms, {} legs, and a {} weapon", ferris.name, ferris.animal_type, ferris.arms, ferris.legs, ferris.weapon ); println!( "{} is a {}. They have {} arms, and {} legs. They have no weapon..", sarah.name, sarah.animal_type, sarah.arms, sarah.legs ); } 構造体のインスタンスとなる変数の場所 ソースコードにおける、main関数の中で定義されているferrisとsarahはSeaCreature構造体のインスタンスである。 これはメモリ上どこにあるのだろうか? ...

2026年5月2日