MiniFlow -- 6.Cost

我们已经知道了什么是激活函数,但是怎么评判我们的模型的好坏的标准呢,这里我们引出损失函数。
有很多技术来定义模型的精确度,都是为了产生能够尽量接近真实值,人们使用不同的名称来定义这个精准度的度量方法,可以叫做loss或者cost,这里会使用cost多些
接下来我们看一个均方误差的损失公式(mean squared error(MSE)).
在这里插入图片描述
这里的w表示神经网络里的要学习的权重,b是偏量,m是一个批次总共训练样本,可以将a看作真实值,y(x)为网络输出,我们的目的是将y(x) 和 a 尽最大程度的相似,这里y(x) 和a是相同长度的向量
我们认为的权重其实就是一些行列式
比如

# 2 by 2 matrices
w1  = np.array([[1, 2], [3, 4]])
w2  = np.array([[5, 6], [7, 8]])

# flatten
w1_flat = np.reshape(w1, -1)
w2_flat = np.reshape(w2, -1)

w = np.concatenate((w1_flat, w2_flat))
# array([1, 2, 3, 4, 5, 6, 7, 8])

当目前位置我们的网络的输出其实就是胡乱猜测的,即使添加了激活函数,因为没有对比cost
接下来我们来实现MES

nn.py


from miniflow import *
import numpy as np

if __name__ == "__main__":
    y, a = Input(), Input()
    cost = MSE(y, a)

    y_ = np.array([1, 2, 3])
    a_ = np.array([4.5, 5, 10])

    feed_dict = {y: y_, a: a_}
    graph = topological_sort(feed_dict)
    # forward pass
    forward_pass(graph)

    """
    Expected output

    23.4166666667
    """
    print(cost.value)

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):
        pass

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


class Sigmoid(Node):
    def __init__(self, node):
        Node.__init__(self, [node])

    def _sigmoid(self, x):
        return 1./(1+np.exp(-x))

    def forward(self):
        x = self.inbound_nodes[0].value

        self.value = self._sigmoid(x)


class MSE(Node):
    def __init__(self, y, a):
        Node.__init__(self, [y, a])

    def forward(self):
        y = self.inbound_nodes[0].value.reshape(-1, 1)
        a = self.inbound_nodes[1].value.reshape(-1, 1)
        m = self.inbound_nodes[0].value.shape[0]
        diff = y - a
        self.value = np.mean(diff**2)



"""
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)
            nodes.append(m)

    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"] 为空的时候说明输入都添加完了,将输出添加到最后
            # 比如一个节点有多个输入,当将这几个输入都添加到L后,在添加其输出节点,以此类推
            if len(G[m]["in"]) == 0:
                S.add(m)
    return L


def forward_pass(graph):
    """
    Performs a forward pass through a list of sorted Nodes.

    Arguments:

        `graph`: The result of calling `topological_sort`.
    """
    # Forward pass
    for n in graph:
        n.forward()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合
首先,建议使用 INNER JOIN 来连接两个表,而不是使用逗号分隔的 FROM 子句。这会使 SQL 语句更易于阅读和理解。 其次,可以使用视图(View)来简化 SQL 语句,将复杂的逻辑转移到视图中,从而使 SQL 语句更简洁和易读。 此外,对于 SUM 函数的多次调用,可以使用 WITH 语句或者临时表(Temporary Table)来避免多次计算,从而提高 SQL 查询的性能。 最后,建议使用索引来优化查询,特别是在大型数据集的情况下,这可以显著提高查询性能。 下面是优化后的 SQL 语句: WITH ssb_summary AS ( SELECT partner_id, SUM(actual_amount) AS 销售额, SUM(refund_amount) AS 退货金额, SUM(refund_good_cost) AS 退货成本, SUM(refund_good_cost)*0.4 AS 退货损耗, SUM(cooperation_fee) AS 合作费用, SUM(point_fee) AS 扣点费用, SUM(receivable) AS 应收款, (SUM(amount)-SUM(point_fee))*0.06 AS 提成金额, SUM(settlement_amount) AS 结算金额, (SUM(amount)-SUM(point_fee)-SUM(refund_amount))-(SUM(cost)-SUM(refund_good_cost))-SUM(refund_good_cost)*0.4-SUM(cooperation_fee)-(SUM(amount)-SUM(point_fee))*0.06 AS 毛利润, ((SUM(amount)-SUM(point_fee)-SUM(refund_amount))-(SUM(cost)-SUM(refund_good_cost))-SUM(refund_good_cost)*0.4-SUM(cooperation_fee)-(SUM(amount)-SUM(point_fee))*0.06)/(SUM(amount)-SUM(refund_amount)-SUM(point_fee)) AS 毛利率 FROM saas_bill WHERE bill_month BETWEEN '2023-06' AND '2023-07' GROUP BY partner_id ) SELECT sp.company_name, ssb_summary.销售额, ssb_summary.退货金额, ssb_summary.退货成本, ssb_summary.退货损耗, ssb_summary.合作费用, ssb_summary.扣点费用, ssb_summary.应收款, ssb_summary.提成金额, ssb_summary.结算金额, ssb_summary.毛利润, ssb_summary.毛利率, sp.cooperate_status, sp.id, SUM(wipe_zero) FROM saas_partner sp INNER JOIN ssb_summary ON sp.id = ssb_summary.partner_id WHERE sp.company_type = '门店' AND sp.cooperate_status='合作中' GROUP BY sp.id, sp.company_name, ssb_summary.销售额, ssb_summary.退货金额, ssb_summary.退货成本, ssb_summary.退货损耗, ssb_summary.合作费用, ssb_summary.扣点费用, ssb_summary.应收款, ssb_summary.提成金额, ssb_summary.结算金额, ssb_summary.毛利润, ssb_summary.毛利率 ORDER BY ssb_summary.毛利润 DESC 这样,SQL 查询就会更快,更易于维护和理解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值