ニューラルネットワーク - フォワードアルゴリズム

ニューラルネットワーク - フォワードアルゴリズム

直感的に、ニューラルネットワークはZeyangで、波。

  • 複数の入力:最初に正規化
  • ニューロン:抽象的な概念、重み付けされた入力と、複数の

  • その「マップ」の「層」に関しては、各ニューロンの真ん中
  • 出力確率(ベクトル)

フォワードアルゴリズム

私たち最初の好奇心はそれで入力- >それを計算する方法への出力は、最も単純な三層のネットワークアーキテクチャの波を参照してください。

  • 入力層:左端、すなわち入力ノード3参照
  • ライン:重みは、図の各行は、重量を表し、
  • 隠れ層:および重み付け(ノード)+バイアス入力ノード(BIAS)

  • :そのようなロジックのような活性化関数(活性化機能)、一般的に使用される「S」型の機能、などTANH。

  • ソフトマックス:で総称関数のクラス、0-1の間のマッピングの出力値

  • 出力層:最終出力ベクトルは、各成分の値は1であります

チップ:

隠された層は、多層であってもよく、オフセット項バイアスは、ノードが0でないようにするためであります

活性化関数:F(X) - > 0-1との間の実際の値との間のマッピング0-1

Softmat:F([X1、X2、X3]) - > 0.5、0.3、0.2]ベクター、 "正規化" 感覚に

どのように隠された層ノードの値を計算するには?1.23例

\((1.23 = 0.5×0.1 + 0.8 * 0.1 + 1 * 0.7)+ 0.4 = 1.23 \)

1.23 - >活性化関数(1.23) - > 0.84

....

図から分かるように、ノードの最初の隠れ層の値は、重み付けされた前の層のすべてのノードの値とは、バイアスと相まって

そして、ソフトマックスによる活性化機能、そして...ついに確率ベクトルのスルー出力。

Activation Function 激活函数

作用: 将一个实数, 映射到 0-1 之间

比如常见的 双曲正切函数 tanh x

\(tanh\ x = \frac {sinh \ x}{cosh\ x} = \frac {e^{x} - e^{-x}} {e^{x} +e^{-x}} = \frac {e^{2x-1}} {e^{2x+1}}\)

>>> import math
>>> import numpy as np

>>> math.tanh(1.145)
0.8160909001379913

>>> np.tanh([1.66, -1.66])
array([ 0.93021718, -0.93021718])

>>> np.tanh([0.88, 1.23, 6.14, 10])
array([0.70641932, 0.84257933, 0.99999071, 1.000...])

感觉这玩意, 映射得有点猛, x 在 [-2, 2] 之间有点 "s"的波动, 超过 2就基本接近于 1了, 变化非常平缓. 像上边图中的 1.23的节点, 可以经过激活函数, 即 \(tanh\ (1.23) = 0.84\)... 以此类推.

隐含层节点, 通过激活函数的映射, 得到隐含层的输出节点. 这些节点跟 输出层的节点, 也是有 "连接, 线条(权重)"的关系的. 跟前面计算隐含层的节点是一样的计算方式.

图中2.08 是如何计算的

\((0.84 * 0.5 + 0.64 * 0.7 + 0.8 * 0.1 + 0.76 * 0.7) + 0.6 = 2.08\)

1.81 也是同样的算法

然后, 我们的目标, 是想输出一个概率值, 这里假设, 我们是一个分类问题

即如何将输出层的节点 \([2.08, 1.81]\) 变得像一个概率分布呢? 最常用的一种方式就是 Softmax. 这也是目前, 被应用得最多的方式.

Softmax 归一化指数函数

作用: f([1,2,3]) -> [0.2, 0.3, 0. 5], 即将输入向量, 归一化为一个概率分布, 写严格一点就是:

\(\sigma: R^k \rightarrow \{ z \in R^k | z_i > 0, \sum \limits_{i=1}^k z_i = 1\}\)

其中对于向量的一个分量:

\(\sigma(x)_i = \frac {e^{x_i}} {\sum \limits_{i=1}^k e^{x_i}}\)

import numpy as np 

def softmax(arr):
    """向量指数归一化输出"""
    return np.exp(arr) / np.sum(np.exp(arr))

>>> softmax([1, 3, 5])

array([0.01587624, 0.11731043, 0.86681333])

Softmax 的 Overflow (溢出)

>>> softmax([100, 200, 300])
array([1.38389653e-87, 3.72007598e-44, 1.00000000e+00])

>>> softmax([1000, 2000, 3000]
... )
__main__:3: RuntimeWarning: overflow encountered in exp
__main__:3: RuntimeWarning: invalid value encountered in true_divide
array([nan, nan, nan])
>>> softmax([1000, 2000, 3000])
array([nan, nan, nan])

就会发现, 数学推导和写代码实现, 根本就是两码事. 推导是非常完美和直观的, 但写成代码一跑, 当值一大的话, 就overflow 了. 为啥呢, 因为, 计算机存储值是有 "精度" 的呀. 因此, 为了避免这种 bug, 从数学上, 将每个值 减去 该向量中的最大值 即可.

\(\frac {e^{x_i}} {\sum \limits_{i=1}^k e^{x_i}} = \frac {e^{x_i}} {\sum \limits_{i=1}^k e^{x_i}} \frac {e^{-m}}{e^{-m}} = \frac {e^{x_i-m}} {\sum \limits_{i=1}^k e^{x_i-m}}\)

def softmax(arr):
    """向量指数归一化输出"""
    m = np.max(arr)
    return np.exp(arr - m) / np.sum(np.exp(arr - m))

# test
>>> softmax([3,4,5])
array([0.09003057, 0.24472847, 0.66524096])
>>> softmax([1000, 2000, 3000])
array([0., 0., 1.])   

把上图的 输出层节点 -> Softmax 得到了一个概率分布.

>>> softmax([2.08, 1.81])
array([0.5670929, 0.4329071])
>>>

即对于这样一个分类问题, 这个神经网络完成了:

  • 输入特征: [年龄, 收入, 性别] -> [ 0.5, 0.8, 1]
  • 输出概率: [ 买房, 不买房] -> [0.57, 0.43]

我的感觉是, 此处, 训练了网络结构的复杂函数, f, 完成了 \(R^{3} \rightarrow R^{2}\) 的一个非线性映射

小结

这个例子, 其实就是一个比较完整的 神经网络前向算法. 当然, 这里有个假设, 每个权值在已知的情况下.

首先, 有一个网络结构, 需要定义, 输入层有几个节点, 输出有几个节点,

然后, 每个隐含层, 有对应的偏置 bias, (为了防止输出为零的情况, 类似之前朴素贝叶斯中的平滑参数是一样的). 还有一个激活函数的选择, Softmax 的选择等.

接着, 要确定, 每个节点间的 "权值线条", 隐含层 到输出层的 "权值线条" 假设这些权值是已经训练好了的话,

最后, 给定一个输入, 则沿着网络结构, 往前走, 最后就输出了呀.

so, 现在的问题是, 如何通过样本来训练这些权值线条, 这就要用到 BP算法, 即咱常说的 误差向后传递. 下篇再整.

おすすめ

転載: www.cnblogs.com/chenjieyouge/p/12185352.html