สิ่งที่ไม่np.random.seed
ทำในด้านล่างรหัสจาก Scikit เรียนรู้กวดวิชา? ฉันไม่คุ้นเคยกับสิ่งที่เครื่องกำเนิดรัฐแบบสุ่มของ NumPy ดังนั้นฉันขอขอบคุณคำอธิบายคำศัพท์ของคนธรรมดาในเรื่องนี้
np.random.seed(0)
indices = np.random.permutation(len(iris_X))
สิ่งที่ไม่np.random.seed
ทำในด้านล่างรหัสจาก Scikit เรียนรู้กวดวิชา? ฉันไม่คุ้นเคยกับสิ่งที่เครื่องกำเนิดรัฐแบบสุ่มของ NumPy ดังนั้นฉันขอขอบคุณคำอธิบายคำศัพท์ของคนธรรมดาในเรื่องนี้
np.random.seed(0)
indices = np.random.permutation(len(iris_X))
คำตอบ:
np.random.seed(0)
ทำให้ตัวเลขสุ่มสามารถคาดเดาได้
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55, 0.72, 0.6 , 0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55, 0.72, 0.6 , 0.54])
ด้วยการตั้งค่าเมล็ดพันธุ์ (ทุกครั้ง) ที่เดียวกันชุดของตัวเลขจะปรากฏทุกครั้ง
หากไม่ได้รีเซ็ตเมล็ดแบบสุ่มตัวเลขที่แตกต่างกันจะปรากฏขึ้นพร้อมกับทุกการเรียกใช้
>>> numpy.random.rand(4)
array([ 0.42, 0.65, 0.44, 0.89])
>>> numpy.random.rand(4)
array([ 0.96, 0.38, 0.79, 0.53])
(หลอก) - ตัวเลขสุ่มทำงานโดยเริ่มต้นด้วยจำนวน (เมล็ด) คูณด้วยจำนวนมากเพิ่มออฟเซ็ตจากนั้นรับโมดูโลของผลรวมนั้น หมายเลขผลลัพธ์จะถูกใช้เป็นเมล็ดเพื่อสร้างหมายเลข "สุ่ม" ถัดไป เมื่อคุณตั้งค่าเมล็ด (ทุกครั้ง) มันจะทำสิ่งเดียวกันทุกครั้งทำให้คุณมีตัวเลขเท่ากัน
หากคุณต้องการตัวเลขสุ่มดูเหมือนอย่าตั้งค่าเมล็ด หากคุณมีรหัสที่ใช้ตัวเลขสุ่มที่คุณต้องการตรวจแก้จุดบกพร่องมันจะมีประโยชน์มากในการตั้งค่า seed ก่อนการเรียกใช้แต่ละครั้งเพื่อให้รหัสทำสิ่งเดียวกันทุกครั้งที่คุณเรียกใช้
numpy.random.seed()
ที่จะได้รับการสุ่มตัวเลขมากที่สุดสำหรับการทำงานในแต่ละสาย สิ่งนี้จะทำให้ numpy ตั้งค่า seed เป็นตัวเลขสุ่มที่ได้รับจาก/dev/urandom
Windows analog หรือถ้าไม่มีทั้งคู่ก็จะใช้นาฬิกา
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้เมล็ดพันธุ์ที่จะสร้างตัวเลขสุ่มหลอกให้ดูที่วิกิพีเดีย
numpy.random.seed(None)
มัน "จะพยายามอ่านข้อมูลจาก / dev / urandom (หรืออะนาล็อก Windows) หากมีหรือเป็นแบบอื่นจากนาฬิกา"
numpy.random.seed(None)
เกี่ยวกับ ฉันอัปเดตคำตอบด้วยข้อมูลนั้นและลิงก์ไปยังเอกสาร
seed
เข้ากันได้
หากคุณตั้งค่าnp.random.seed(a_fixed_number)
ทุกครั้งที่คุณเรียกฟังก์ชั่นสุ่มอื่น ๆ ของ numpy ผลลัพธ์จะเหมือนกัน:
>>> import numpy as np
>>> np.random.seed(0)
>>> perm = np.random.permutation(10)
>>> print perm
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.rand(4)
[0.5488135 0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0)
>>> print np.random.rand(4)
[0.5488135 0.71518937 0.60276338 0.54488318]
อย่างไรก็ตามหากคุณเพียงแค่เรียกมันครั้งเดียวและใช้ฟังก์ชั่นแบบสุ่มที่หลากหลายผลลัพธ์จะยังคงแตกต่างกัน:
>>> import numpy as np
>>> np.random.seed(0)
>>> perm = np.random.permutation(10)
>>> print perm
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10)
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10)
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4)
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4)
[0.87008726 0.47360805 0.80091075 0.52047748]
np.random
โทรที่ตามมาทั้งหมดจนกว่าจะเปลี่ยนเมล็ดหรือไม่? ต้องโทรหาทุกครั้งที่ดูเหมือนว่าไม่จำเป็นและง่ายต่อการลืม
def seed_first(fun, seed=0):
| \tdef wrapped(*args, **kwargs):
| \t\tnp.random.seed(seed)
| \t\treturn fun(*args, **kwargs)
| \treturn wrapped
แล้วfor m in np.random.__all__:
| \tif m != 'seed':
| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))
อย่างไรก็ตามสิ่งนี้อาจนำไปสู่ข้อบกพร่องที่ลึกซึ้งมากและพฤติกรรมแปลก ๆ ในระยะยาว (แทนที่ \ t ด้วยสี่ช่องว่างและ | ด้วยตัวแบ่งบรรทัด ... )
np.random.seed()
ครั้งเดียวเมื่อเริ่มต้นโปรแกรมจะให้ผลลัพธ์เดียวกันเสมอ สำหรับเมล็ดเดียวกันเนื่องจากการเรียกnp.random
ฟังก์ชันที่ตามมาจะเปลี่ยนเมล็ดสำหรับการโทรในภายหลัง การโทรnp.random.seed()
ก่อนการเรียกnp.random
ฟังก์ชั่นทุกครั้งอาจทำให้ได้ผลลัพธ์ที่ไม่พึงประสงค์
ตามที่ระบุไว้ numpy.random.seed (0) ตั้งค่าเมล็ดสุ่มเป็น 0 ดังนั้นตัวเลขสุ่มหลอกที่คุณได้รับจากการสุ่มจะเริ่มจากจุดเดียวกัน นี่อาจเป็นผลดีสำหรับการดีบักในบางกรณี อย่างไรก็ตามหลังจากอ่านบางครั้งดูเหมือนว่าจะเป็นวิธีที่ผิดไปถ้าคุณมีหัวข้อเพราะมันไม่ปลอดภัยเธรด
จากความแตกต่างระหว่าง -numpy-random-and-random-in-python :
สำหรับ numpy.random.seed () ปัญหาหลักคือมันไม่ปลอดภัยสำหรับเธรด - นั่นคือมันไม่ปลอดภัยที่จะใช้ถ้าคุณมีหลายเธรดที่แตกต่างกันเพราะมันไม่รับประกันว่าจะทำงานถ้าสองเธรดที่แตกต่างกันกำลังดำเนินการ ฟังก์ชั่นในเวลาเดียวกัน หากคุณไม่ได้ใช้เธรดและหากคุณสามารถคาดหวังได้อย่างสมเหตุสมผลว่าคุณไม่จำเป็นต้องเขียนโปรแกรมด้วยวิธีนี้อีกในอนาคต numpy.random.seed () ควรใช้ได้เพื่อการทดสอบ หากมีเหตุผลใดที่สงสัยว่าคุณอาจต้องใช้เธรดในอนาคตมันปลอดภัยกว่าในระยะยาวที่จะทำตามที่แนะนำและเพื่อให้เป็นตัวอย่างของ numpy.random.Random เท่าที่ฉันสามารถบอกได้ random.random.seed () ปลอดภัยต่อการเป็นเกลียว (หรืออย่างน้อยฉันก็ไม่พบหลักฐานใด ๆ ที่ตรงกันข้าม)
ตัวอย่างของวิธีการเกี่ยวกับเรื่องนี้:
from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
อาจให้:
[3 0 4 6 8 2 1 9 7 5]
[1 6 9 0 2 7 8 3 5 4]
[8 1 5 0 7 2 9 4 3 6]
[8 1 5 0 7 2 9 4 3 6]
สุดท้ายโปรดทราบว่าอาจมีบางกรณีที่การเริ่มต้นเป็น 0 (ตรงข้ามกับเมล็ดที่ไม่มีบิตทั้งหมด 0) อาจส่งผลให้มีการแจกแจงแบบไม่สม่ำเสมอสำหรับการวนซ้ำสองสามครั้งแรกเนื่องจากวิธีการทำงานของ xor แต่ขึ้นอยู่กับอัลกอริทึม และอยู่นอกเหนือความกังวลในปัจจุบันของฉันและขอบเขตของคำถามนี้
ฉันใช้สิ่งนี้บ่อยครั้งในเครือข่ายประสาท เป็นที่ทราบกันดีว่าเมื่อเราเริ่มฝึกโครงข่ายประสาทเทียมเราจะเริ่มต้นน้ำหนักแบบสุ่ม แบบจำลองนี้ได้รับการฝึกอบรมเกี่ยวกับน้ำหนักเหล่านี้ในชุดข้อมูลเฉพาะ หลังจากจำนวนยุคคุณจะได้รับชุดของน้ำหนักที่ผ่านการฝึกอบรม
ตอนนี้สมมติว่าคุณต้องการฝึกอีกครั้งตั้งแต่เริ่มต้นหรือคุณต้องการส่งแบบจำลองให้ผู้อื่นทำซ้ำผลลัพธ์ของคุณน้ำหนักจะถูกกำหนดค่าเริ่มต้นอีกครั้งเป็นตัวเลขสุ่มซึ่งส่วนใหญ่จะแตกต่างจากรุ่นก่อนหน้า น้ำหนักที่ผ่านการฝึกอบรมที่ได้รับหลังจากจำนวน epochs จำนวนเท่ากัน (การเก็บข้อมูลและพารามิเตอร์อื่น ๆ ) เท่าที่จะแตกต่าง ปัญหาคือโมเดลของคุณไม่สามารถทำซ้ำได้มากขึ้นนั่นคือทุกครั้งที่คุณฝึกฝนโมเดลของคุณตั้งแต่เริ่มต้นมันให้น้ำหนักที่แตกต่างกัน นี่เป็นเพราะโมเดลถูกเริ่มต้นด้วยตัวเลขสุ่มที่แตกต่างกันทุกครั้ง
จะเกิดอะไรขึ้นถ้าทุกครั้งที่คุณเริ่มฝึกตั้งแต่เริ่มต้นโมเดลจะถูกกำหนดค่าเริ่มต้นเป็นชุดน้ำหนักเริ่มต้นแบบสุ่มชุดเดียวกัน ในกรณีนี้แบบจำลองของคุณอาจทำซ้ำได้ สิ่งนี้สามารถทำได้โดย numpy.random.seed (0) โดยการกล่าวถึง seed () ให้กับหมายเลขที่เจาะจงคุณจะได้รับการสุ่มไปยังหมายเลขสุ่มชุดเดียวกันเสมอ
ลองนึกภาพคุณกำลังแสดงให้ใครเห็นถึงวิธีการเขียนโค้ดบางอย่างด้วยตัวเลข "สุ่ม" จำนวนหนึ่ง โดยการใช้เมล็ดพันธุ์ที่มีจำนวนมากพวกเขาสามารถใช้หมายเลขเมล็ดเดียวกันและได้รับหมายเลข "สุ่ม" ชุดเดียวกัน
ดังนั้นมันจึงไม่ใช่การสุ่มอย่างแน่นอนเพราะอัลกอริทึมแยกตัวเลขออกมา แต่มันดูเหมือนว่าเป็นกลุ่มที่สร้างขึ้นแบบสุ่ม
การสุ่มเมล็ดระบุจุดเริ่มต้นเมื่อคอมพิวเตอร์สร้างลำดับหมายเลขสุ่ม
ตัวอย่างเช่นสมมติว่าคุณต้องการสร้างตัวเลขสุ่มใน Excel (หมายเหตุ: Excel ตั้งค่าขีด จำกัด 9999 สำหรับเมล็ดพันธุ์) หากคุณป้อนตัวเลขลงในกล่องสุ่มเมล็ดในระหว่างกระบวนการคุณจะสามารถใช้หมายเลขสุ่มชุดเดียวกันอีกครั้ง หากคุณพิมพ์“ 77” ลงในกล่องและพิมพ์“ 77” ในครั้งต่อไปที่คุณเรียกใช้ตัวสร้างตัวเลขแบบสุ่ม Excel จะแสดงตัวเลขสุ่มชุดเดียวกัน หากคุณพิมพ์“ 99” คุณจะได้รับชุดตัวเลขที่แตกต่างอย่างสิ้นเชิง แต่ถ้าคุณย้อนกลับไปเป็นเมล็ด 77 คุณจะได้รับหมายเลขสุ่มชุดเดียวกับที่คุณเริ่มต้นด้วย
ตัวอย่างเช่น“ รับหมายเลข x เพิ่ม 900 + x จากนั้นลบ 52” เพื่อให้กระบวนการเริ่มต้นคุณต้องระบุหมายเลขเริ่มต้น x (เมล็ด) ลองใช้หมายเลขเริ่มต้น 77:
เพิ่ม 900 + 77 = 977 ลบ 52 = 925 ทำตามขั้นตอนวิธีเดียวกันหมายเลข“ สุ่ม” ตัวที่สองจะเป็น:
900 + 925 = 1825 ลบ 52 = 1773 ตัวอย่างง่ายๆนี้ตามรูปแบบ แต่อัลกอริทึมที่อยู่เบื้องหลังการสร้างหมายเลขคอมพิวเตอร์มีความซับซ้อนมากขึ้น
ตัวเลขสุ่มทั้งหมดที่สร้างขึ้นหลังจากตั้งค่าเมล็ดโดยเฉพาะจะเหมือนกันในทุกแพลตฟอร์ม / ระบบ
มีคำอธิบายที่มีความสุขในเอกสาร Numpy คือ https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.RandomState.html มันหมายถึงMersenne Twister เครื่องกำเนิดไฟฟ้าจำนวนสุ่มหลอก รายละเอียดเพิ่มเติมเกี่ยวกับอัลกอริทึมที่นี่: https://en.wikipedia.org/wiki/Mersenne_Twister
numpy.random.seed(0)
numpy.random.randint(10, size=5)
สิ่งนี้สร้างผลลัพธ์ต่อไปนี้:
array([5, 0, 3, 3, 7])
อีกครั้งถ้าเราเรียกใช้รหัสเดียวกันเราจะได้ผลลัพธ์เดียวกัน
ตอนนี้ถ้าเราเปลี่ยนค่าเมล็ด 0 เป็น 1 หรืออื่น ๆ :
numpy.random.seed(1)
numpy.random.randint(10, size=5)
สิ่งนี้สร้างเอาต์พุตต่อไปนี้: array([5 8 9 5 0])
แต่ตอนนี้เอาต์พุตไม่เหมือนกันด้านบน
คำตอบทั้งหมดข้างต้นแสดงการใช้งานของnp.random.seed()
ในรหัส ฉันจะพยายามอย่างดีที่สุดเพื่ออธิบายสั้น ๆ ว่าทำไมมันเกิดขึ้นจริง คอมพิวเตอร์เป็นเครื่องจักรที่ออกแบบตามอัลกอริทึมที่กำหนดไว้ล่วงหน้า เอาต์พุตใด ๆ จากคอมพิวเตอร์คือผลลัพธ์ของอัลกอริทึมที่ใช้กับอินพุต ดังนั้นเมื่อเราขอคอมพิวเตอร์เพื่อสร้างตัวเลขสุ่มแน่ใจว่าพวกมันสุ่ม แต่คอมพิวเตอร์ไม่ได้มากับพวกมันแบบสุ่ม!
ดังนั้นเมื่อเราเขียนขั้นตอนวิธีการออกจะเฉพาะชุดของตัวเลขที่เป็นเอกลักษณ์ของการโต้แย้งnp.random.seed(any_number_here)
any_number_here
มันเกือบจะเป็นเหมือนชุดสุ่มตัวเลขที่เฉพาะเจาะจงสามารถรับได้ถ้าเราผ่านการโต้แย้งที่ถูกต้อง แต่สิ่งนี้จะทำให้เราต้องรู้ว่าอัลกอริทึมทำงานอย่างไรซึ่งค่อนข้างน่าเบื่อ
ตัวอย่างเช่นถ้าฉันเขียนnp.random.seed(10)
ชุดตัวเลขเฉพาะที่ฉันได้รับจะยังคงเหมือนเดิมแม้ว่าฉันจะดำเนินการบรรทัดเดียวกันหลังจาก 10 ปีเว้นแต่ว่าการเปลี่ยนแปลงอัลกอริทึม