如何从0-1构建自己的”pytorch“(自己专属的深度学习框架)——part02

今日份学习目标

  1. 掌握激活函数
  2. 学习激活函数的意义
  3. 激活函数和线性变化之间能产生的作用
  4. 链式求导
  5. 反向传播
  6. 传播的顺序由拓扑排序来决定
  7. 拓扑排序的原理和实现过程

激活函数

世界中的很多真实关系都不是简单的线性关系,我们是否可以构建一些基本的模块,然后来组成复杂的函数

其实早期的神经网络 只有线性变化+激活函数 深度网路最重要的是多了一个CNN

理论上所有的函数都可以用多层的线性函数+非线性变化来进行拟合。但是我们之所以又有了CNN,RNN这些模型,就是因为一个问题维数灾难,就是当参数每上升一个维度,我们所需要的数据就要10倍增长,所以我们不能无节制的使用多层线性函数,因为会增加参数,这也是我们为什么使用CNN,RNN因为会减少参数。

常用的激活函数:sigmoid,relu,tanh

def sigmoid(x): # basic sub-model : Transfer :Activation Function : 激活函数
    return 1 / (1 + np.exp(-x))

def relu(x):
    return x * (x > 0)

def tanh(x):
#     return np.tanh(x)
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))

def leaky_relu(x):
    return 0.1*x*(x<0)+x*(x>0)

x=np.linspace(-10,10,100)
plt.plot(tanh(x))

构建神经网络拓扑图

首先我们要构建神经网络拓扑图,可视化需要用到一个工具包networkx

NetworkX是一款Python的软件包,用于创造、操作复杂网络,以及学习复杂网络的结构、动力学及其功能。 
有了NetworkX你就可以用标准或者不标准的数据格式加载或者存储网络,它可以产生许多种类的随机网络或经典网络,也可以分析网络结构,建立网络模型,设计新的网络算法,绘制网络等等。

#搭建神经网络
import networkx as nx
#代表着网络的结构
computing_graph = {
    'x1': ['linear-01'], 
    'k1': ['linear-01'],
    'b1': ['linear-01'],
    'linear-01': ['sigmoid'], 
    'sigmoid': ['linear_2'],
    'k2': ['linear_2'],
    'b2': ['linear_2'],
    'linear_2': ['loss']
}

#此处直接输入字典表示节点和边,当然可以使用其他的形式
graph=nx.DiGraph(computing_graph)#建立一个有向图
# nx.draw(graph,with_labels=True)
layout=nx.layout.spring_layout(graph)# 一种布局方式,用Fruchterman-Reingold算法排列节点(这个算法我不了解,样子类似多中心放射状)
nx.draw(graph,layout,with_labels=True,node_color='green')#显示标签,并设置颜色

 显示图如下,还是比较清晰的

以上就是一个简单的展示,接下来,我们就正式开始

第一步:需要进行拓扑排序,确定节点遍历的顺序

第二步:前向传播

第三步:反向传播

首先进行第一步代码展示:

import random
#拓扑排序,来决定节点前向传播和反向传播的顺序
def topologic(graph):
    sorted_node=[]
    
    while len(graph)>0:
        all_inputs=[]
        all_outputs=[]
        
        for n in graph:
            all_inputs+=graph[n]
            all_outputs.append(n)
        
        all_inputs=set(all_inputs)
        all_outputs=set(all_outputs)
        
        need_remove=all_outputs-all_inputs#需要删除的节点,也就是只有输出没有输入的点
        
        if len(need_remove)>0:
            node=random.choice(list(need_remove))
            visited_next=[node]
            
            #如果是最后一个节点,比如linear2-loss
            if len(graph)==1: 
                visited_next+=graph[node]
            
            graph.pop(node)
            
            sorted_node+=visited_next
            
        else:
            break    
    return sorted_node
#图中的所有节点
computing_graph = {
    'x1': ['linear-01'], 
    'k1': ['linear-01'],
    'b1': ['linear-01'],
    'linear-01': ['sigmoid'], 
    'sigmoid': ['linear_2'],
    'k2': ['linear_2'],
    'b2': ['linear_2'],
    'linear_2': ['loss']
}
visit_order_by_algorithm=topologic(computing_graph)

第二步,前向传播如下:

#首先建立图
import networkx as nx
computing_graph = {
    'x1': ['linear-01'], 
    'k1': ['linear-01'],
    'b1': ['linear-01'],
    'linear-01': ['sigmoid'], 
    'sigmoid': ['linear_2'],
    'k2': ['linear_2'],
    'b2': ['linear_2'],
    'linear_2': ['loss']
}
graph=nx.DiGraph(computing_graph)
layout=nx.layout.spring_layout(graph)

#该函数用来给每一步前向传播画图
def visited_procedure(graph, postion, visited_order, step, sub_plot_index=None, colors=('red', 'green')):

    changed = visited_order[:step] if step is not None else visited_order
    
    before, after = colors
    
    color_map = [after if c in changed else before for c in graph]
    
    nx.draw(graph, postion, node_color=color_map, with_labels=True, ax=sub_plot_index)

#构建前向传播
import matplotlib.pyplot as plt
import numpy as np

dimension = int(len(visit_order_by_algorithm)**0.5)

fig, ax = plt.subplots(dimension, dimension+1, figsize=(15,15))

for i in range(len(visit_order_by_algorithm)+1):
    ix = np.unravel_index(i, ax.shape)#索引按照ax.shape进行排序
    plt.sca(ax[ix])#选择(0,0)这个曲线,开始绘制
    ax[ix].title.set_text('Feed Forward Step: {}'.format(i))
    visited_procedure(graph, layout, visit_order_by_algorithm, step=i, sub_plot_index=ax[ix])

第三步,反向传播:

#反向传播代码基本一样,只需将,遍历顺序颠倒即可
dimension = int(len(visit_order_by_algorithm)**0.5)

fig, ax = plt.subplots(dimension, dimension+1, figsize=(15,15))
for i in range(len(visit_order_by_algorithm)+1):
    ix = np.unravel_index(i, ax.shape)#索引按照ax.shape进行排序
    plt.sca(ax[ix])#选择(0,0)这个曲线,开始绘制
    ax[ix].title.set_text('Feed Forward Step: {}'.format(i))
    visited_procedure(graph, layout, visit_order_by_algorithm[::-1], step=i, sub_plot_index=ax[ix],colors=['green','red'])

很感谢大家的观看,有什么问题欢迎随时留言交流。
 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值