MiniFlow -- 4.Linear Transform

还记得以前的要给公式
在这里插入图片描述
上面的表述方式可以理解为和公式的方式,接下来我们使用矩阵的方式,将所有的x表示为矩阵X,所有的w为矩阵W,当然b也可以理解为一个向量

如果我们认为 Linear 节点是一个1个输入,就是对应上面公式i=1,但是要对应k个输出,上面的公司就不能用了,接下来我们就得用矩阵的方式表示
我们使用X表示一个 1x1矩阵
在这里插入图片描述
W就变成了1xk矩阵
在这里插入图片描述
根据行列式乘法规则,1x1 * 1xk -->1xk 因为mxn * nxk --> mxk

那我们怎么将n个输入,对应到k个输出呢
X是一个1xn矩阵,W是一个nxk矩阵,我们想要得到一个1xk的矩阵,b仍然是要一个1xk矩阵

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里n是输入特征数量,k是输出特征数量,经过计算,我们得到一个矩阵,这个矩阵与k个特征,这就将输入n个特征映射到输出k个特征
根据行列式规则,我们不能用XW表示,得到一个1xk矩阵,然后根据矩阵加法,加上b,得到一个1xk矩阵

但是在实践,在每一次前向运算中我们使用一个批次喂入网络,而不是上面的1xk,这个时候输入就是 m x n,m表示批次
在这里插入图片描述
根据行列式规则,我们会得到一个mxk矩阵,m是批次,k是输出特征数量,b就得用广播来计算了

因此可以用公式表示为
在这里插入图片描述

代码

nn.py


from miniflow import *
import numpy as np


if __name__ == "__main__":
    X, W, b = Input(), Input(), Input()
    f = Linear(X, W, b)
    # 2*2 行批次,列特征
    X_ = np.array([[-1., -2.], [-1, -2]])
    # 行特征,列输出特征数量
    W_ = np.array([[2., -3], [2., -3]])
    b_ = np.array([-3., -5])
    feed_dict = {X: X_, W: W_, b: b_}
    graph = topological_sort(feed_dict)
    output = forward_pass(f, graph)

    print(output)

miniflow.py

import numpy as np

class Node(object):
    def __init__(self, inbound_nodes=[]):
        # 输入节点列表 用户前向计算
        self.inbound_nodes = inbound_nodes
        # 输出节点列表 用户反向传播
        self.outbound_nodes = []
        # A calculated value 本节点的计算值
        self.value = 0
        # Add this node as an outbound node on its inputs.
        # 将本节点作为输入节点的输出节点
        for n in self.inbound_nodes:
            n.outbound_nodes.append(self)

    def forward(self):
        """
        Forward propagation 虚函数
        前向运算 基于 inbound_nodes 输入节点列表的 value 计算输入节点列表的输出值
        存储在 self.value
        :return:
        """
        raise NotImplemented


class Input(Node):
    def __init__(self):
        """
        Input node 没有 inbound nodes ,他是整个神经网络的开始
        因此不需要进行任何操作
        """
        # 输入节点列表为空
        Node.__init__(self)

    def forward(self, value=None):
        if value is not None:
            self.value = value



class Linear(Node):
    def __init__(self, X, W, b):
        # Notice the ordering of the inputs passed to the
        # Node constructor.
        Node.__init__(self, [X, W, b])

    def forward(self):
        X = self.inbound_nodes[0].value
        W = self.inbound_nodes[1].value
        b = self.inbound_nodes[2].value
        self.value = np.dot(X, W) + b



"""
Can you augment the Add class so that it accepts
any number of nodes as input?

Hint: this may be useful:
https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists
"""


class Add(Node):
    def __init__(self, *inputs):
        """
        You could access x and y in forward with
        self.inbound_nodes[0] (x) and self.inbound_nodes[1](y)
        这里我们要计算x和y的和,那么输入节点就是x,y,那么x,y 就是本届点的输入节点,也就是self.inbound_nodes[0]
        :param x: Node input
        :param y: Node input
        """
        Node.__init__(self, inputs)

    def forward(self):
        for n in self.inbound_nodes:
            self.value += n.value


def topological_sort(feed_dict):
    """
    我们将所有节点构成一个graphs,一个计算图
    :param feed_dict: 这个一个输入节点的字典,key 是Input node value 是初始化的值
    :return: 返回一个序列化的节点列表
    """
    # 提取所有输入节点
    input_nodes = [n for n in feed_dict.keys()]
    G = {}
    # 所有输入节点列表
    nodes = [n for n in input_nodes]
    # 这里将所有输入节点和输出节点作为G的key node, value也是一个字典,in记录key node的所有输入节点列表,out记录key node 的所有输出节点列表
    # 其中一个G的一个元素如下,node 可以是Input 也可以是Add, 如果node是Input 那么in为空,如果node是末尾节点,out为空
    # 如果node是中间节点,name in是输入节点列表, out就是输出节点
    #       |-in list         |-in list
    # node1 |           node2 |
    #       |-out list        |-out list

    while len(nodes) > 0:
        # 从头部弹出一个节点 node
        n = nodes.pop(0)
        if n not in G:
            G[n] = {"in": set(), "out": set()}
        for m in n.outbound_nodes:
            if m not in G:
                G[m] = {"in": set(), "out": set()}
            G[n]["out"].add(m)
            G[m]["in"].add(n)

    L = []
    # 无序不重复
    S = set(input_nodes)
    # 这里序列化L,L为 input input out
    while len(S) > 0:
        n = S.pop()
        # 给输入节点赋值,如果n节点是输入节点,就将赋值
        if isinstance(n, Input):
            n.value = feed_dict[n]
        # 将节点n加到L中
        L.append(n)
        # 检查当前的节点的输出节点,n 可能是 Input Add,或者隐藏层 最后一层的节点没有outbound_nodes
        for m in n.outbound_nodes:
            # 删除当前节点中的输出
            G[n]["out"].remove(m)
            # 删除输出节点中的输入
            G[m]['in'].remove(n)
            # 如果 G[m]["in"] 为空的时候说明输入都添加完了,将输出添加到最后
            if len(G[m]["in"]) == 0:
                S.add(m)
    return L


def forward_pass(output_node, sorted_nodes):
    """
    Performs a forward pass through a list of sorted nodes.
    :param output_node: A node in the graph, should be the output node(have no outgoing edges)
    :param sorted_nodes: A topologically sorted list of nodes.
    :return: the out
    """
    for n in sorted_nodes:
        n.forward()

    return output_node.value
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值