一次彩票探索如何让我了解 PyTorch 的强大功能
介绍
在某个时间点,您可能听说过中奖彩票的机会非常渺茫。与所有与概率相关的事情一样,多次试验可能会导致结果对你有利。现在,如果你参加很多次彩票,你中奖的机会会更大一些,这取决于你参加了多少次彩票。这仍然不能保证你最终会中奖,但是是均匀分布的,并根据大数定律(在本例中意味着大量彩票),我们可以得出相对更有可能的可能性。
重要的是要了解,每个新彩票都是独立于其他彩票的,并且相同的彩票“彩票号码”可以赢得许多不同的彩票(遵循大数定律)。您也可能会运气不好,无论您尝试了多少次,每次都选错了号码。您现在有两个选择:
- 您每次都可以尝试随机数。
- 您每次都可以尝试相同号码。
理论上(和数学上),这两种情况发生的可能性相同。然而,场景 2 会给你带来轻微的优势。随着次数接近无穷大,最终每一个数字都会被选中。问题是,对于场景 1,您需要尝试更多次,希望您当时选择的数字与获胜的数字相匹配。在场景 2 中,您确信随着试验趋于无限,您的数字将在某个时刻“获胜”。对于本博文,我们将使用场景 2。
那么,在我告诉你答案之前,你认为你能回答这个问题吗?
“如果您周围的所有彩票都有正好 100 万人的老虎机,并且您为每个玩过的人都选择了同一张彩票 [x],那么您需要玩多少张彩票才能最终成为中奖者?” (欢迎评论您最初的答案)
答案是...
大约1440万次。
这篇博文的其余部分将介绍我如何得出该值、如何进行模拟以及一些注意事项。从这里开始事情会变得更加技术化。
逻辑
100万人的彩票号码范围为1 - 1,000,000(或0 - 999,999)。玩家每次抽奖只能选择该范围内的号码,中奖彩票也只能来自该范围。本质上,我们可以说我们将拥有一组 100 万个数字。
考虑到用户可以选择该范围内的任何数字,我们需要满足集合中的每个项目至少被击中一次的条件。这是因为,如果每个号码至少被叫过一次,那么它将涵盖玩家可能选择的任何可能的票号。这也意味着我们不关心每个数字运行了多少次,从而使“集合”成为用于我们的模拟的理想 Python 数据结构。我们将从一个空集开始,并在每次迭代时用随机生成的数字填充它,直到该集包含指定范围内的每个数字。由于 Python 集合不重复数字,因此我们不必担心确保唯一性。
def calculate_lottery_chances(lottery_players_count): number_set = set() count = 0 while len(number_set) < lottery_players_count: gen_number = random.randint(1, lottery_players_count) number_set.add(gen_number) count += 1 return count
对于 1,000,000 人的彩票,函数调用如下:calculate_lottery_chances(1000000),它将返回中奖之前尝试彩票的次数。以这种方式排列代码使其具有很强的可扩展性。
问题
简单来说,问题的根源就是“变异”。第一次运行该函数时,我得到了“1310 万”次作为我的值。我重新运行了一下,得到了大约 1390 万的结果。我这样做了更多次,得到的答案差异很大——在某个时候,我得到了 1500 万个。很明显,我需要这样做并找到平均值。按照到目前为止的现有模式,我认为随着平均迭代次数趋于无穷大,我将更接近于得到一个可靠的答案。需要一些可以做到这一点并且快速完成的东西,这促使我编写了这个函数:
def average_over_n_times(function, function_arg, n): """ This returns the average of the returned value of a function when it is called n times, with its (one) arg """ total = 0 for x in range(0, n): total += function(function_arg) return round(total/n)
随后,所有内容都会被修补为:
num_of_trials = average_over_n_times(calculate_lottery_chances, lottery_players_count, n)
其中“n”表示对结果进行平均的次数。然而,这带来了另一个问题,我们将在下一节中讨论。
“n”应该是什么?
n 的值越大,结果越接近“平均情况”。然而,考虑到仍然没有绝对性或确定性,执行这一系列任务太多次就会失去生产力。我这么说有以下原因:
- 时间不是无限的,我们不能无限期地执行这些计算,这意味着每次运行时总会有变化(无论多小),这违背了“绝对”的想法。
- 计算资源是有限的。
- 这个实验的假设之一是计算机生成的“随机性”可以准确地模拟现实。
- 就像算法运行时一样,较小的幅度不再与较大的幅度一样重要。当处理大于 13,000,000 的值时,大约 100,000 的变化不会那么显着。
牢记这些,我用以下值测试了“n”:10、20、30、50、100、1000 和 5000 次。
PyTorch 从何而来?
此时,您可能想知道为什么博文标题中没有提到“PyTorch”一词。好吧,虽然我提到用不同的值测试 n,但它与我用于所有测试的代码并不相同。
这些都是计算量很大的实验,我的 CPU 跟我说了一句话。我之前分享的代码片段是在一个具有零外部包依赖性的文件中编写的,并且该文件在 bash shell 中运行,并在前面添加了 time 命令来跟踪执行时间。以下是仅使用 CPU 时的执行时间:
n | Time (min and sec) |
---|---|
10 | 1m34.494s |
20 | 3m2.591s |
30 | 5m19.903s |
50 | 10m58.844s |
100 | 14m56.157s |
在 1000 时,我无法再让程序运行了。我不确定是不是中途断了没能停止执行,但我在4小时57分钟后取消了。我认为有几个因素影响了这一点,我将在“注意事项”部分中讨论这些因素。不管怎样,我的风扇噪音很刺耳,我知道我可能已经把笔记本电脑功率适中的 CPU 推得有点太多了。我拒绝接受失败,在思考如何至少运行 4 位迭代时,我想起了一位使用 PyTorch 的朋友告诉我的话:
“GPU 在计算密集型方面通常比 CPU 更高效”
PyTorch 使用 GPU,使其成为完成这项工作的完美工具。
重构
PyTorch 将用于我们目的的计算,因此重构现有的calculate_lottery_chances() 代码意味着更改依赖于CPU 的数值运算并切换到合适的PyTorch 数据结构。简而言之:
- Python set() 数据类型将不再足够。
- Python randint() 函数将替换为其 PyTorch 等效函数。
- 由于 set() 数据类型不够,因此会切换为生成与 lottery_players_count 大小相匹配的零张量,并用布尔值来指示某个号码之前是否中奖。
calculate_lottery_chances 的重构如下:
def calculate_lottery_chances(lottery_players_count): number_set = set() count = 0 while len(number_set) < lottery_players_count: gen_number = random.randint(1, lottery_players_count) number_set.add(gen_number) count += 1 return count
我将设备设置为“xpu”,因为我的计算机使用 PyTorch 支持的 Intel Graphics GPU。
输出
为了确保在执行过程中使用我的 GPU,我在运行之前打开了 Windows 任务管理器并导航到“性能”部分。运行时,我发现 GPU 资源使用量出现明显峰值。
对于上下文,这是之前和之后的对比:
之前:
请注意 GPU 使用率为 1%
之后:
请注意,GPU 使用率为 49%
对于不同 n 值的运行时间,GPU 的速度要快几倍。它在不到一分钟的时间内始终运行低于 100 的 n 值,并且能够计算 5000(五千!)
的 n 值这是使用 GPU 的运行时表:
n | Time (min and sec) |
---|---|
10 | 0m13.920s |
20 | 0m18.797s |
30 | 0m24.749s |
50 | 0m34.076s |
100 | 1m12.726s |
1000 | 16m9.831s |
为了直观地了解本实验中 GPU 和 CPU 操作之间的性能差距有多大,可以考虑以下数据可视化:
x 轴的上限为 100,因为我无法再从 CPU 获得实际的“及时”输出,因此没有空间与 GPU 进行比较。使用 1000 - 5000 范围内的数字进行实验,结果往往是“1440 万次”。这就是我之前得到答案的方式。
注意事项
这个实验做出了假设并依赖于某些做事方式。此外,我对 PyTorch 的经验不足可能意味着可能有更有效的方法。以下是一些需要考虑的因素可能影响了我的发现的准确性或执行时间:
- 我做了一个微妙的假设,即计算机生成的随机性模仿了现实生活(物理世界)中的随机性。
- 虽然我切换了一些逻辑以使用 PyTorch,但其余代码仍然依赖于 CPU。例如,在 Average_over_n_times() 函数中,循环中的加法和求平均值可能都受益于 PyTorch 的等效项。我怀疑性能会有所提升。
- 我不确定我使用的batch_size对准确性和性能的影响。
- 所有 CPU 和 GPU 测试都是在我的电脑接通电源的情况下完成的,以便让机器发挥最佳状态。使用电池供电的设备运行它们可能会获得更长的运行时间。
- PyTorch 的 CUDA 可能比“XPU”更有优势,但我的电脑不支持前者。
- 测试期间我避免让我的电脑“休眠”。如果您的计算机处于睡眠状态,测试可能需要更长时间才能运行。
最后,我想指出,这是我第一次使用 PyTorch 做任何事,它的性能给我留下了深刻的印象。
结论
当我陷入困境时,我没想到会看到性能上的如此提升。我了解了张量背后的想法以及一些有关计算更复杂的任务背后的支持机制的知识。您可以随意使用、复制或修改代码片段。
感谢您对我的包容,希望您阅读愉快。
下次再见,
干杯。 ?
以上是一次彩票探索如何让我了解 PyTorch 的强大功能的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。
