Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dy2stat] Fix test_mobile_net random failed #25364

Merged
merged 1 commit into from
Jul 4, 2020

Conversation

Aurelius84
Copy link
Contributor

@Aurelius84 Aurelius84 commented Jul 3, 2020

PR types

Others

PR changes

Others

Describe

Fix test_mobile_net random failed using local_random = np.random.RandomState(SEED) instead of np.random.seed(SEED).

I found that the numpy.random outputs unstable random data when run twice independent if wrapping it into DataLoader.

So,the random behavior of numpy in DataLoader is not stable or unsafe. We should use local_random = np.random.RandomState(SEED) instead of it.

See reason in detail: #24727

The repetition code as followed:

1. It's ok if only use numpy.random

import time
import numpy as np
import unittest

SEED = 2020

def fake_data_reader(batch_size, label_size):
    def reader():
        batch_data = []
        while True:
            img = np.random.random([3, 224, 224]).astype('float32')
            label = np.random.randint(0, label_size, [1]).astype('int64')
            
            batch_data.append([img, label])
            if len(batch_data) == batch_size:
                yield batch_data
                batch_data = []

    return reader

def load_data():
    np_data = []
    np.random.seed(SEED)

    reader = fake_data_reader(batch_size=1, label_size=3)

    for data in reader():
        img, label = data[0]

        np_data.append(img[0,0,:6].tolist())
        break
        
    return np.array(np_data)


class TestNumpyRandom(unittest.TestCase):
    def test_data(self):
        for i in range(100):
            data1 = load_data()
            data2 = load_data()
            # print(data1)
            # print(data2)
            self.assertTrue(np.array_equal(data1, data2), msg="data1\n: {}\n, data2:\n {}\n".format(data1, data2))

if __name__ == '__main__':
    unittest.main()

**2. It failed if only use numpy.random + DataLoader. But when I add time.sleep(1), it's ok. **

import time
import numpy as np
import paddle.fluid as fluid
import unittest


SEED = 2020


def fake_data_reader(batch_size, label_size):
    def reader():
        batch_data = []
        while True:
            img = np.random.random([3, 224, 224]).astype('float32')
            label = np.random.randint(0, label_size, [1]).astype('int64')
            
            batch_data.append([img, label])
            if len(batch_data) == batch_size:
                yield batch_data
                batch_data = []

    return reader

def train():

    place = fluid.CPUPlace()
    with fluid.dygraph.guard(place):
        np.random.seed(SEED)

        train_reader = fake_data_reader(4, 3)
        train_data_loader = fluid.io.DataLoader.from_generator(capacity=16)
        train_data_loader.set_sample_list_generator(train_reader, place)
        
        np_data = []
        for img, label in train_data_loader():

            img_data = img.numpy()[0,0,0,:6].tolist()
            print("img: ", img_data)
            print("label: ", label.numpy().flatten().tolist())

            np_data.append(img_data)
            time.sleep(1)
            break
            
    return np.array(np_data)

class testNumpyRandom2(unittest.TestCase):
    def test_data(self):
        for i in range(10):
            print("data1: ")
            data1 = train()
            print("data2:")
            data2 = train()
            self.assertTrue(np.array_equal(data1, data2), msg="data1\n: {}\n, data2:\n {}\n".format(data1, data2))

if __name__ == '__main__':
    unittest.main()

Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Aurelius84 Aurelius84 merged commit bdad383 into PaddlePaddle:develop Jul 4, 2020
@Aurelius84 Aurelius84 deleted the fix_mobile_net branch April 12, 2021 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants