Search code examples
rustserializationstructrust-cargoserde

Unresolved import 'serde', cannot determine resolution for the derive macro `Serialize`, import resolution is stuck


I wanted to implement saving of my neuralnetwork after it is trained to file and subsequentially also loading of the file. However I ran into this error and I am really stumped as to what is the issue, I might just be overlooking something really simple but I can't find anything:

error[E0432]: unresolved import `serde`
  --> src\neural_network.rs:15:5
   |
15 | use serde::{Serialize, Deserialize};
   |     ^^^^^ help: a similar path exists: `self::serde`

error: cannot determine resolution for the derive macro `Serialize`
  --> src\neural_network.rs:17:10
   |
17 | #[derive(Serialize, Deserialize)]
   |          ^^^^^^^^^
   |
   = note: import resolution is stuck, try simplifying macro imports

error: cannot determine resolution for the derive macro `Deserialize`
  --> src\neural_network.rs:17:21
   |
17 | #[derive(Serialize, Deserialize)]
   |                     ^^^^^^^^^^^
   |
   = note: import resolution is stuck, try simplifying macro imports

warning: unused import: `Read`
 --> src\neural_network.rs:8:28
  |
8 | use std::io::{self, Write, Read};
  |                            ^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0277]: the trait bound `NeuralNetwork: Serialize` is not satisfied
   --> src\neural_network.rs:41:39
    |
41  |         let data = bincode::serialize(&self)?;
    |                    ------------------ ^^^^^ the trait `Serialize` is not implemented for `NeuralNetwork`
    |                    |
    |                    required by a bound introduced by this call
    |
    = help: the following other types implement trait `Serialize`:
              &'a T
              &'a mut T
              ()
              (T,)
              (T0, T1)
              (T0, T1, T2)
              (T0, T1, T2, T3)
              (T0, T1, T2, T3, T4)
            and 127 others
    = note: required for `&NeuralNetwork` to implement `Serialize`
note: required by a bound in `bincode::serialize`
   --> C:\Users\nlion\.cargo\registry\src\github.com-1ecc6299db9ec823\bincode-1.3.3\src\lib.rs:108:8
    |
108 |     T: serde::Serialize,
    |        ^^^^^^^^^^^^^^^^ required by this bound in `bincode::serialize`

error[E0277]: `?` couldn't convert the error to `std::io::Error`
  --> src\neural_network.rs:41:45
   |
41 |         let data = bincode::serialize(&self)?;
   |                                             ^ the trait `From<Box<bincode::ErrorKind>>` is not implemented for `std::io::Error`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
   = help: the following other types implement trait `From<T>`:
             <std::io::Error as From<IntoInnerError<W>>>
             <std::io::Error as From<NulError>>
             <std::io::Error as From<getrandom::error::Error>>
             <std::io::Error as From<rand::Error>>
             <std::io::Error as From<std::io::ErrorKind>>
   = note: required for `Result<(), std::io::Error>` to implement `FromResidual<Result<Infallible, Box<bincode::ErrorKind>>>`

Some errors have detailed explanations: E0277, E0432.
For more information about an error, try `rustc --explain E0277`.
warning: `neural-network-scratch` (bin "neural-network-scratch") generated 1 warning
error: could not compile `neural-network-scratch` due to 5 previous errors; 1 warning emitted

My project has the following structure:

├── dataset
│   └── (4 different parts of the MNIST Datasets)
├── src
│   ├── main.rs
│   └── neural_network.rs
└── Cargo.toml

My Cargo.toml:

[package]
name = "neural-network-scratch"
version = "0.1.0"

[dependencies]
ndarray = { version = "0.16.1", features = ["serde"] }
rand = "0.8.5"
ndarray-rand = "0.15.0"
bincode = "1.3"
serde = { version = "1.0", features = ["derive"] }

And finally my code in neural_network.rs:

extern crate rand;
extern crate ndarray_rand;
extern crate ndarray;
extern crate bincode;
extern crate serde;

use std::fs::File;
use std::io::{self, Write, Read};
use std::path::PathBuf;
use ndarray::{Array2, Array1};
use ndarray_rand::RandomExt;
use ndarray_rand::rand_distr::Uniform;
use ndarray::prelude::*;

// I tried both of these
//use crate::serde::{Serialize, Deserialize};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct NeuralNetwork {
    pub input_size: usize,
    pub hidden_size: usize,
    pub output_size: usize,
    W1: Array2<f64>,
    W2: Array2<f64>,
    b1: Array1<f64>,
    b2: Array1<f64>,
}

impl NeuralNetwork { pub fn new(input_size: usize, hidden_size: usize, output_size: usize) -> Self {
        NeuralNetwork {
            input_size,
            hidden_size,
            output_size,
            W1: Array::random((input_size, hidden_size), Uniform::new(-1.0, 1.0)),
            W2: Array::random((hidden_size, output_size), Uniform::new(-1.0, 1.0)),
            b1: Array::random(hidden_size, Uniform::new(-1.0, 1.0)),
            b2: Array::random(output_size, Uniform::new(-1.0, 1.0)),
        }
    }

    pub fn save(&self, path: &PathBuf) -> io::Result<()> {
        let data = bincode::serialize(&self)?;
        let mut file = File::create(path)?;
        file.write_all(&data)?;
        Ok(())
    }
}

Which is executed in main.rs:

fn main() -> Result<(), io::Error> {
    // We initialize the neural network with 784 input neurons, 64 hidden neurons and 10 output neurons.
    // The weights and biases are set at random.
    let mut neural_network = NeuralNetwork::new(784, 64, 10);

    println!("\nNeural network initialized succesfully with input size: {}, hidden size: {}, output size: {}", neural_network.input_size, neural_network.hidden_size, neural_network.output_size);

    let model_path = PathBuf::from(format!("./model.bin"));
    neural_network.save(&model_path);

    Ok(())
}

I removed some things like the training process as I thought they were unnecessary for this but if you think something is missing that is required to solve this issue feel free to tell me and I'll edit my post. Thanks it advance, I really don't know why this won't work.

I tried to stop using extern crate serde; as I read it was unnecessary. I've looked more into macros and how derive functions but I didn't find anything that I hadn't already tried which led me here. I also deleted the target directory, used cargo clean. cargo add serde, cargo update but to no success.


Solution

  • You are, implicitly, using a very old edition of the Rust language. This is why you are finding a need for extern crate and why name resolution is not working like you expect.

    Fix this by declaring the current edition in your Cargo.toml:

    [package]
    name = "neural-network-scratch"
    version = "0.1.0"
    edition = "2021"
    

    Then you can delete all the extern crates, and your serde imports should work, when written like this:

    use serde::{Serialize, Deserialize};