cs50ai2

这篇具有很好参考价值的文章主要介绍了cs50ai2。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

cs50ai2-------Uncertainty


  • cs50ai2-------Uncertainty
    • 基础知识
    • 课后题目
    • 代码实践
    • 学习链接
    • 总结

基础知识

在这节课中,前面主要介绍了一些概率论的基础知识,比如说条件概率、贝叶斯规则、联合概率以及一些概率公式等等
贝叶斯规则:
cs50ai2
概率公式:
cs50ai2

接着介绍了贝叶斯网络
它是用来表示随机变量之间的依赖关系的一种数据结构
cs50ai2
比如说像上面这样一个简化的贝叶斯网络,具有基本的四个特征:
(1)有向图结构
(2)图中的每个结点代表着一个随机变量
(3)x指向y的箭头代表着x是y的父节点,即y的概率分布依赖于x的值
(4)每个节点都存储着P(X | Parents(X))的概率

利用贝叶斯网络,我们可以计算某些联合概率:
cs50ai2

也可以利用枚举推理的思想,去计算条件概率:
cs50ai2
cs50ai2

但是随着变量个数的增加,显然枚举推理会变得极其低效,因此又引入了近似推理的思想。

这里提了一种拒绝采样的方法,针对有观测变量的情况,即我们已经有了某些evidence,比如说此时下雨或者火车按时到站,我们进行采样,如果得到样本的值与我们观测到的情况相同,那么我们就接受这个样本,否则就要重新采样
这样做就会导致我们采样的效率很低,所以又引入了似然加权采样,在进行采样时,不再对观测变量采样,只对非观测变量采样,观测变量就直接赋我们的观测值,将这样得到的样本赋一个重要性权值

接下来又简要介绍了一下马尔科夫模型
马尔科夫假设是指,当前的状态只取决于有限固定数量的先前状态
而马尔科夫链指的是,一组随机变量的次序,其中每个变量的分布都遵循马尔科夫假设,也就是说链中每个事件发生的概率都取决于先前的事件,而要建立一个马尔科夫链,我们需要一个转移模型,根据当前事件的的可能值指定下一个事件的概率分布
cs50ai2
cs50ai2
隐藏马尔可夫模型是马尔可夫模型的一种,适用于具有隐藏状态的系统,该系统会生成一些观察到的事件,这意味着有时人工智能可以对世界进行一些观测,但无法了解世界的精确状态。 在这些情况下,世界的状态称为隐藏状态,人工智能可以访问的任何数据都是观察结果,我们可以建立一个感知模型来代表观测变量与状态的关系,再结合之前的转移模型,就可以建立隐藏马尔科夫链
cs50ai2

cs50ai2

课后题目

(1) pagerank
background:
这个题目主要是关于网页重要性(代表着该网页被访问的概率)的计算,我们可以采用迭代的方法来计算,令 PR(p) 为给定页面 p 的 PageRank:随机冲浪者最终访问该页面的概率,我们知道随机冲浪者可以通过两种方式进入该页面:

冲浪者以 1 - d 的概率随机选择一个页面并最终到达页面 p。
冲浪者以概率 d 跟随从页面 i 到页面 p 的链接。

第一个条件用数学方式表达起来相当简单:它是 1 - d 除以 N,其中 N 是总页数。 这是因为随机选择页面的一维概率在所有 N 个可能的页面之间平均分配。

对于第二个条件,我们需要考虑链接到页面 p 的每个可能的页面 i。 对于每个传入页面,令 NumLinks(i) 为页面 i 上的链接数。 链接到 p 的每个页面 i 都有自己的 PageRank,PR(i),表示我们在任何给定时间位于页面 i 上的概率。 由于从页面 i 开始,我们以相同的概率访问该页面的任何链接,因此我们将 PR(i) 除以链接数量 NumLinks(i),以获得我们位于页面 i 并选择指向页面 p 的链接的概率。

这为我们提供了页面 p 的 PageRank 的以下定义

cs50ai2

在此公式中,d 是阻尼因子,N 是页面总数,i 范围涵盖链接到页面 p 的所有页面,NumLinks(i) 是页面 i 上存在的链接数量。

那么我们如何计算每个页面的 PageRank 值呢? 我们可以通过迭代来做到这一点:首先假设每个页面的 PageRank 是 1 / N(即,在任何页面上的可能性相同)。 然后,根据之前的 PageRank 值,使用上述公式计算每个页面的新 PageRank 值。 如果我们不断重复这个过程,根据前一组 PageRank 值计算每个页面的一组新的 PageRank 值,最终 PageRank 值将收敛(即,每次迭代的变化不会超过一个小阈值)。

在此项目中,实现这两种计算 PageRank 的方法 - 通过从马尔可夫链随机冲浪者中采样页面并迭代应用 PageRank 公式来计算。

understanding:
打开 pagerank.py。 首先请注意文件顶部两个常量的定义: DAMPING 表示阻尼系数,最初设置为 0.85。 SAMPLES 表示我们将使用采样方法来估计 PageRank 的样本数量,最初设置为 10,000 个样本。

现在,看一下 main 函数。 它需要一个命令行参数,该参数是我们要计算 PageRank 的网页语料库的目录名称。 抓取函数获取该目录,解析该目录中的所有 HTML 文件,并返回表示语料库的字典。 该字典中的键代表页面(例如“2.html”),字典的值是由该键链接到的所有页面的集合(例如{“1.html”,“3.html”) })。

main函数然后调用sample_pagerank函数,其目的是通过采样来估计每个页面的PageRank。 该函数将crawl函数生成的页面语料库以及阻尼因子和要使用的样本数量作为参数。 最终,sample_pagerank 应返回一个字典,其中键是每个页面名称,值是每个页面的估计 PageRank(0 到 1 之间的数字)。

main函数还调用iterate_pagerank函数,该函数也会计算每个页面的PageRank,但使用迭代公式方法而不是采样。 返回值应采用相同的格式,并且我们希望在给定相同的语料库时这两个函数的输出应该相似

(2) Heredity
background:
每个孩子都会从父母那里继承一份 GJB2 基因。 如果父母有两个突变基因拷贝,那么他们会将突变基因遗传给孩子; 如果父母没有突变基因的拷贝,那么他们不会将突变基因遗传给孩子; 如果父母一方有一份突变基因,那么该基因遗传给孩子的概率为 0.5。 然而,基因传递后,它有可能会发生额外的突变:从导致听力障碍的基因版本变为不会造成听力障碍的基因版本,反之亦然。
我们可以尝试通过形成所有相关变量的贝叶斯网络来对所有这些关系进行建模,如下所示,它考虑了一个由两个父母和一个孩子组成的家庭。
cs50ai2
您在此项目中的任务是使用此模型对总体进行推断。 给定有关人的信息,他们的父母是谁,以及他们是否具有由给定基因引起的特定可观察特征(例如听力损失),您的人工智能将推断出每个人基因的概率分布,以及人是否会表现出相关的特征的概率分布。

understanding:
PROBS 是一个字典,包含许多表示各种不同事件的概率的常量。 所有这些事件都与一个人拥有多少个特定基因(以下简称“gene”)副本以及一个人是否表现出特定特征(以下简称“trait”)有关. 这里的数据大致基于 GJB2 基因的听力障碍版本和听力障碍特征的概率.

首先,PROBS[“gene”] 表示该基因的无条件概率分布(即如果我们对该人的父母一无所知

接下来,PROBS[“trait”] 表示一个人表现出某种特征(如听力障碍)的条件概率

最后,PROBS[“mutation”] 是基因从相关基因突变为非该基因的概率,反之亦然

最终,您计算的概率将基于 PROBS 中的这些值。

现在,看一下 main 函数。该函数首先将文件中的数据加载到 people 字典中。人们将每个人的名字映射到另一个包含有关他们的信息的字典:包括他们的名字、他们的母亲(如果在数据集中列出了)、他们的父亲(如果在数据集中列出了),以及他们是否被观察到有问题的特征(如果有则为 True,如果没有则为 False,如果我们不知道则为 None)。

接下来,main 定义一个概率字典,所有概率最初设置为 0。这就是您的项目最终将计算的内容:对于每个人,您的 AI 还将计算他们拥有多少基因副本的概率分布 就看他们是否有这个特质。 例如,概率[“Harry”][“gene”][1] 是哈利拥有 1 个基因副本的概率,概率[“Lily”][“trait”][False] 是莉莉没有表现出这种特征的概率。

最终,我们希望根据一些证据来计算这些概率:鉴于我们知道某些人具有或不表现出该特征,我们希望确定这些概率。 回想一下课程中的内容,我们可以通过将满足证据的所有联合概率相加来计算条件概率,然后对这些概率进行归一化,使它们的总和为 1。您在这个项目中的任务是实现三个函数来实现这一点 :joint_probability 计算联合概率,update以将新计算的联合概率添加到现有概率分布中,然后进行normalize以确保所有概率分布最终总和为 1。

specification:
在计算joint probability时,对于任何不在 one_gene 或two_genes 中的人,我们想计算他们没有该基因副本的概率; 对于任何不属于have_trait的人,我们想计算他们不具有该特质的概率。
例如,如果家庭由 Harry、James 和 Lily 组成,则调用此函数,其中 one_gene = {"Harry"}、two_genes = {"James"} 和 Trait = {"Harry", "James"} 应计算 莉莉有零个基因拷贝,哈利有一个基因拷贝,詹姆斯有两个基因拷贝,哈利表现出该特征,詹姆斯表现出该特征,而莉莉没有表现出该特征的概率。

在update函数中,对于概率中的每个人 person,该函数应通过将 p 添加到每个分布中的适当值来更新概率[person]["gene"] 分布和概率[person]["trait"] 分布。 所有其他值应保持不变。
例如,如果“Harry”同时出现在two_genes和have_trait中,则p将被添加到概率[“Harry”][“gene”][2]和概率[“Harry”][“trait”][True ]。

在normalize函数中,对于每个人的两种概率分布,此函数应对该分布进行归一化,以便分布中的值总和为 1,并且分布中的相对值相同。
例如,如果概率["Harry"]["trait"][True]等于0.1并且概率["Harry"]["trait"][False]等于0.3,那么你的函数应该更新前一个值 变为 0.25,后一个值为 0.75:现在数字之和为 1,并且后一个值仍然是前一个值的三倍。

代码实践

(1)PageRank:
首先是transition model:
着一部分主要根据前面提到的pagerank,根据当前页面,计算得到其它页面可能被访问的概率分布

def transition_model(corpus, page, damping_factor):
    """
    Return a probability distribution over which page to visit next,
    given a current page.

    With probability `damping_factor`, choose a link at random
    linked to by `page`. With probability `1 - damping_factor`, choose
    a link at random chosen from all pages in the corpus.
    """
    prop_dist = {}

    dict_len = len(corpus.keys())
    pages_len = len(corpus[page])

    if len(corpus[page]) == 0:
        for key in corpus.keys():
            prop_dist[key] = 1 / dict_len

    else:
        random_factor = (1 - damping_factor) / dict_len
        even_factor = damping_factor / pages_len
        for key in corpus.keys():
            if key not in corpus[page]:
                prop_dist[key] = random_factor
            else:
                prop_dist[key] = even_factor + random_factor

    return prop_dist

然后根据前面的transition model,使用马尔科夫采样来估计每个页面的pagerank
每次采样都利用random函数根据转移模型得到的概率,来选择页面,同时对应的页面计数加1,在采样结束之后,在除以采样数来得到各个页面的pagerank

def sample_pagerank(corpus, damping_factor, n):
    """
    Return PageRank values for each page by sampling `n` pages
    according to transition model, starting with a page at random.

    Return a dictionary where keys are page names, and values are
    their estimated PageRank value (a value between 0 and 1). All
    PageRank values should sum to 1.
    """
    samples_dict = corpus.copy()
    for i in samples_dict:
        samples_dict[i] = 0
    sample = random.choice(list(corpus.keys()))
    samples_dict[sample] += 1
    for _ in range(n):
        dist = transition_model(corpus, sample, damping_factor)
        dist_lst = list(dist.keys())
        dist_weights = [dist[i] for i in dist]
        sample = random.choices(dist_lst, dist_weights, k=1)[0]
        samples_dict[sample] += 1

    for item in samples_dict:
        samples_dict[item] /= n

    return samples_dict

这里是第二种计算pagerank的方法,通过之前的pagerank计算式进行迭代,当所有页面的pagerank变化都小于0.001时,认为pagerank收敛:

def iterate_pagerank(corpus, damping_factor):
    """
    Return PageRank values for each page by iteratively updating
    PageRank values until convergence.

    Return a dictionary where keys are page names, and values are
    their estimated PageRank value (a value between 0 and 1). All
    PageRank values should sum to 1.
    """
    num_pages = len(corpus)
    initial_rank = 1.0 / num_pages
    current_rank = {page: initial_rank for page in corpus}
    new_rank = {page: 0 for page in corpus}

    # 定义一个函数来计算给定页面的PageRank值
    def calculate_pagerank(page):
        rank = (1 - damping_factor) / num_pages
        rank += damping_factor * sum(current_rank[link] / len(corpus[link]) for link in corpus if page in corpus[link])
        return rank

    # 开始迭代计算PageRank值,直到收敛
    while True:
        # 遍历每个页面,计算新的PageRank值
        for page in corpus:
            new_rank[page] = calculate_pagerank(page)

        # 检查是否收敛,如果所有页面的PageRank值变化都小于0.001,则退出循环
        convergence = all(abs(new_rank[page] - current_rank[page]) < 0.001 for page in corpus)
        if convergence:
            break

        # 将新的PageRank值复制到current_rank以进行下一轮迭代
        current_rank = new_rank.copy()

    # 归一化PageRank值,使其总和为1
    total_rank = sum(new_rank.values())
    normalized_rank = {page: rank / total_rank for page, rank in new_rank.items()}

    return normalized_rank

(2)Heredity:
计算联合概率:
这里我们根据题目提示计算即可
先分为父母已知与父母未知的情况,父母未知的情况比较简单,直接将gene probability与trait probability相乘即可,
而父母已知时,基因概率就要分开考虑,要考虑到具体的遗传情况,以及遗传过程中的变异情况

def joint_probability(people, one_gene, two_genes, have_trait):
    """
    Compute and return a joint probability.

    The probability returned should be the probability that
        * everyone in set `one_gene` has one copy of the gene, and
        * everyone in set `two_genes` has two copies of the gene, and
        * everyone not in `one_gene` or `two_gene` does not have the gene, and
        * everyone in set `have_trait` has the trait, and
        * everyone not in set` have_trait` does not have the trait.
    """
    probability = 1

    for person in people:
        gene_number = 1 if person in one_gene else 2 if person in two_genes else 0
        trait = True if person in have_trait else False

        gene_numb_prop = PROBS['gene'][gene_number]
        trait_prop = PROBS['trait'][gene_number][trait]

        if people[person]['mother'] is None:
            probability *= gene_numb_prop * trait_prop
        else:
            mother = people[person]['mother']
            father = people[person]['father']
            percentages = {}
            # 计算得到遗传给后代目标基因的概率
            for ppl in [mother, father]:
                number = 1 if ppl in one_gene else 2 if ppl in two_genes else 0
                perc = 0 + PROBS['mutation'] if number == 0 else 0.5 if number == 1 else 1 - PROBS['mutation']
                percentages[ppl] = perc
           # 分为父母一个基因都不遗传,有一个人遗传了目标基因,两个人都遗传了目标基因
            if gene_number == 0:
                probability *= (1 - percentages[mother]) * (1 - percentages[father])
            elif gene_number == 1:
                probability *= (1 - percentages[mother]) * percentages[father] + percentages[mother] * (
                            1 - percentages[father])
            else:
                probability *= percentages[mother] * percentages[father]

            probability *= trait_prop

    return probability

更新概率以及归一化函数:

def update(probabilities, one_gene, two_genes, have_trait, p):
    """
    Add to `probabilities` a new joint probability `p`.
    Each person should have their "gene" and "trait" distributions updated.
    Which value for each distribution is updated depends on whether
    the person is in `have_gene` and `have_trait`, respectively.
    """
    for person in probabilities:
        gene_number = 1 if person in one_gene else 2 if person in two_genes else 0
        probabilities[person]["gene"][gene_number] += p
        probabilities[person]["trait"][person in have_trait] += p


def normalize(probabilities):
    """
    Update `probabilities` such that each probability distribution
    is normalized (i.e., sums to 1, with relative proportions the same).
    """
    for person in probabilities:
        # 获取基因分布
        gene_distribution = probabilities[person]["gene"]
        # 获取特征分布
        trait_distribution = probabilities[person]["trait"]
        # 计算基因分布的总和
        gene_sum = sum(gene_distribution.values())
        # 计算特征分布的总和
        trait_sum = sum(trait_distribution.values())
        # 归一化基因分布
        for gene in gene_distribution:
            gene_distribution[gene] /= gene_sum
        # 归一化特征分布
        for trait in trait_distribution:
            trait_distribution[trait] /= trait_sum

学习链接

参考代码链接:https://github.com/wbsth/cs50ai
https://github.com/PKUFlyingPig/cs50_ai
视频链接(b站中文机翻字幕): https://www.bilibili.com/video/BV1AQ4y1y7wy/?p=5&vd_source=23b9ed7e58fa7e510011caaf2e7e3320
课程官网(全套资源):https://cs50.harvard.edu/ai/2023/

总结

这次作业我感觉和课程结合的不是很好,不过也大致利用了马尔科夫与贝叶斯的一些思想,比较浅显文章来源地址https://www.toymoban.com/news/detail-709879.html

到了这里,关于cs50ai2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • cs50ai0----search

    cs50ai0-------Search 基础知识 课后题目 代码实践 学习链接 总结 (1) search problem 上图是搜索问题的一般形式 每个名词具体解释如下: initial state:state是agent与environment的一个配置或者说构造,initial state就是初始的state actions:在state下可以做出的所有action transition model: 对在任何

    2024年02月12日
    浏览(30)
  • 第二章:AI大模型基础知识 2.1 机器学习基础

    随着计算机技术的飞速发展,人工智能已经成为了当今科技领域的热门话题。在这个过程中,机器学习作为人工智能的一个重要分支,扮演着至关重要的角色。本文将从机器学习的基本概念、核心算法原理、具体操作步骤、实际应用场景等方面进行详细讲解,帮助读者更好地

    2024年02月21日
    浏览(57)
  • UE4的AI行为树基础知识

            在制作游戏时,会制作敌人、怪物、NPC等不被玩家所操作的对象,那么制作这些对象,就需要通过使用AI行为树来为他们编写各自的一些行为逻辑,比如敌人会寻找主角并攻击、怪物会在自己的领域巡逻等等。 NavMeshBoundsVolume:导航网格体边界体积,用作导航寻路,会

    2024年02月11日
    浏览(38)
  • AI模型部署基础知识(一):模型权重与参数精度

    一般情况来说,我们通过收集数据,训练深度学习模型,通过反向传播求导更新模型的参数,得到一个契合数据和任务的模型。这一阶段,通常使用pythonpytorch进行模型的训练得到pth等类型文件。AI模型部署就是将在python环境中训练的模型参数放到需要部署的硬件环境中去跑,

    2024年01月20日
    浏览(50)
  • AIGC内容分享(二十):「AI视频生成」技术核心基础知识和模型应用

    目录 何为AI视频? 一、技术发展概况 二、代表模型及应用​​​​​​​ 三、仍存在许多技术难点 「 AI 视频」 通常指的是由人工智能(AI)技术生成或处理的视频。这可能包括使用深度学习、计算机视觉和其他相关技术来改善视频的质量、内容或生成全新的视频内容。一

    2024年01月18日
    浏览(56)
  • 实时AI绘画模型SDXL Turbo核心基础知识详解 | 【算法兵器谱】

    Rocky Ding 公众号:WeThinkIn 【算法兵器谱】栏目专注分享AI行业中的前沿/经典/必备的模型论文,并对具备划时代意义的模型论文进行全方位系统的解析。也欢迎大家提出宝贵的优化建议,一起交流学习💪 大家好,我是Rocky。 如果说2022年,Stable Diffusion横空出世,成为AI行业从传

    2024年01月16日
    浏览(54)
  • 控制系统中的AI、AO、DI、DO是什么意思——控制系统基础知识

      控制系统中AI、AO、DI、DO是集散控制系统中模块上常见的一些基本标注,好处就是便于分清什么类型量的设备,方便前期的产品选型及后期的维修与保养。   同时将现场模拟量仪表和开关量设备等进行清晰分类,便于后期仪表和设备的弱电信号接线。 其实很简单,AI、

    2024年01月20日
    浏览(45)
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计

    github地址:https://github.com/Ahmednull/L2CS-Net L2CS-Net介绍: 眼睛注视(eye gaze) 是在各种应用中使用的基本线索之一。 它表示用户在人机交互和开放对话系统中的参与程度。此外,它还被用于增强现实,用于预测用户的注意力,从而提高设备的感知能力,降低功耗。 因此,研究人

    2024年01月16日
    浏览(40)
  • 【STM32】基础知识 第五课 C 语言基础知识

    stdint.h 是从 C99 中引进的一个标准 C 库的文件. 路径: “D:MDK5.34ARMARMCCinclude” 运算符 含义 运算符 含义 按位与 ~ 按位取反 | 按位或 左移 ^ 按位异或 右移 按位与: num1 运算符 num2 结果 0 0 0 1 0 0 0 1 0 1 1 1 按位或: num1 运算符 num2 结果 0 | 0 0 1 | 0 1 0 | 1 1 1 | 1 1 按位异或: num1 运算符

    2024年02月13日
    浏览(74)
  • 数字电路基础知识系列(六)之LC滤波器的基础知识

    LC滤波器,是指将电感(L)与电容器 ©进行组合设计构成的滤波电路,可去除或通过特定频率的无源器件。电容器具有隔直流通交流,且交流频率越高越容易通过的特性。而电感则具有隔交流通直流,且交流频率越高越不易通过的特性。因此,电容器和电感是特性完全相反的被

    2024年02月03日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包