1

I'm implementing a single-layer perceptron and there is a problem with my weight_coef function such as it is generating 0 every time the function is called. Thus I get inaccurate results when calculating activation. Here is a snippet of my weight_coef function, which is supposed to generate a number between 0 and 1:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
//Helper function to generate a random number between 0 and 1
double weight_coef() {
 //((double)rand() / RAND_MAX);
 srand(time(NULL));
 double random = static_cast<double>(rand() / RAND_MAX);
 random = round(random * 100) / 100.0; //to 2 dec points
 return random;
}
int main() {
 // Set up the variables
 vector<double> w = { weight_coef(), weight_coef(), weight_coef()};
}

Would be grateful if you could suggest what's wrong.

asked May 1, 2023 at 13:39
5
  • 2
    rand() / RAND_MAX is 0. Commented May 1, 2023 at 13:46
  • 2
    Don't reinitialize random at each function call like you do in weight_coef function. Commented May 1, 2023 at 13:46
  • 2
    Also have a look at C++'s random functions : . Specifically uniform_real_distribution where you can specify a range. In any case do not use integer arithmetic to calculate floating point values. Commented May 1, 2023 at 13:47
  • 4
    Other notes : do NOT use 'using namespace std;` and learn to pass vectors by const reference your activiation function will pass copies of the vectors (and again don't mix integer/floating point), the signature should be double activation(const std::vector<double>& x, const std::vector<double>& w) Commented May 1, 2023 at 13:50
  • Tangential: It’s best to reduce the code and explanation to the minimum amount required to reproduce the problem. This question is unrelated to NNs. Commented May 7, 2023 at 13:28

1 Answer 1

1

The problem is that std::rand returns an integer that is guaranteed to be between 0 and RAND_MAX. Thus the weight coefficient code

double weight_coef() {
 srand(time(NULL));
 double random = static_cast<double>(rand() / RAND_MAX); // <-- LOOK
 /* The above line will always set random to 0 */
 random = round(random * 100) / 100.0;
 return random;
}

will always return 0 (actually it will almost always be 0, and will be be 1 with probability 1/RAND_MAX). One solution would be to take the random integer, mod it by 100, and then interpret that as your two decimal digit probability. But note that this will be slightly nonuniform, as RAND_MAX is probably not divisible by 100 (and is likely 2^31 -ひく 1 = 2147483647).

If you want to make a uniform random variable, you can do something like

#include <iostream>
#include <random>
const int LOWER_BOUND = 0;
const int UPPER_BOUND = 100;
std::random_device rand_dev;
std::mt19937 gen;
std::uniform_int_distribution<int> dist;
int random_int() {
 return dist(gen);
}
int main()
{
 gen = std::mt19937(rand_dev());
 dist = std::uniform_int_distribution<int>(LOWER_BOUND, UPPER_BOUND);
 for (int i = 0; i < 10; i++) {
 std::cout << random_int() << "\n"; // generate 10 random integers
 }
}

I note it is also not a good idea to repeatedly reinitialize the seed on every function call. Instead, set the seed once - possibly in main (as done implicitly in the code snippet I posted).

answered May 1, 2023 at 16:17
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.