机器学习算法mini版

来源:互联网 发布:会员返利系统源码 编辑:程序博客网 时间:2024/05/22 14:54

深度神经网络

  • 预训练(pre-training)的本质是参数(权值&&偏置)的初始化(careful initialization)。

  • 自动编码(autoencoder)的数学意义是寻找approximate identity functiong(x)=x

    dW1ijd~W1jid

判断学习的过程是否过慢

以神经网络、以梯度下降学习算法为例:
判断学习过程的变化情况,就是判断代价函数对模型所要学习的量,比如权重CwLjk的变化情况。

logistic regression

logistic regression是一个基于概率的(probabilistic ),线性分类器(classifier),注意逻辑斯特回归是一个分类模型,而不是回归模型。

tanh or sigmoid

用作激励函数的函数是选择tanh还是sigmoid

tanh(a)=eaeaea+easigmoid(a)=11+ea

一般选择tanh,因为更容易产生更快的学习效率(it typically yields to faster training and sometimes also to better local minima)

SGD(stochastic gradient descent)

SGD=S+GD

SGD要点有二:

  • 随机

    S:Stochastic的实现——shuffle

    np.random.shuffle(training_data)

    或者先随机地获得一次排列组合,再进行shuffle:

    r = np.random.permutation(training_data.shape[0])training_data[r, :]
  • 分块(batch)

    mini_batches = [training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)]

back propagation

backprog(x, y)

反向传播算法(监督学习)接收每一笔(单笔单笔接收)输入((x,y)),根据目前的weights以及biases进行对特征向量的预测(a=σ(wa+b)),也即y_pred = feedforward(x),最终根据真实值与预测值之间的误差(cost_derivative=y_predy)进行对权值及偏置的更新,这中间是一系列相对麻烦的过程,也是反向传播算法的精髓所在。也即,反向传播的最终目的是通过真实值与预测值的误差进行对权值以及偏置的更新。

wk=wkηmj=1Cxjwkmbl=blηmj=1Cxjblm

以上的梯度下降(GD:GradientDescent)公式中的,Cxjwj正是反向传播算法的工作。

mj=1Cxjwkm表达的是块的概念,将某一块当做一个整体进行权值以及偏置的更新,否则每传递进来一个样本都要进行一次前向进行预测,后向进行更新,会增大计算量。

面向对象版BP神经网络

神经网络的步骤:

  • 初始化全部权值和偏置

    这一步自然放在Network的构造函数的内部进行(一般的做法是使用np.random.randn())。因为初始化动作以及类的构造函数一样,只进行一次,也自然,Network类持有整个神经网络的全部权值以及偏置。

    class Network(object):    def __init__(self, topology):        self.topology = topology        self.num_layers = len(topology)        self.biases = [np.random.randn((y, 1)) for y in topology[1:]]        self.weights = [np.random.randn(y, x) for (x, y) in zip(topology[1:], topology[:-1])]

    注意这里每两层权重矩阵的size,W(j×i)j表示后一层(layer)的神经元(neuron)个数,i表示前一层(layer)的神经元(neuron)个数,这样做的目的是为了后面计算内积的方便,也即W(j×i)x(i×1),而前一层向后一层的偏置为b(j×1),这样根据前向(forward)计算(称之为链式计算吧),可获得下一层的输入也即:W(j×i)x(i×1)+b(j×1)

  • 根据输入(单样本,但特征向量),前向计算获得样本的预测类别

def feedword(self, a):    for w, b in zip(self.weights, self.biases):        a = sigmoid(np.dot(w, a)+b)    return a
  • 遍历训练集,对每一个(x,y),进行backpropagation,更新全部权值及偏置:

    1. 计算各层各个神经元的输入(zs)与输出(activations
      sll=iWljixl1ixlj=σ(slj)
    2. 根据(cost_derivative也即output_activationy)计算末尾一层的δ
      ensLi=(xLiy)xLisLi=(xLiy)σ(sLi)enWLji=ensLisLiWLji=ensLixL1i
    3. 后向计算每一层的权值更新

enWlji=enslisliWljiensli=k

def backprog(self, x, y):    nabla_b = [np.zeros(b.shape) for b in self.biases]     nabla_w = [np.zeros(w.shape) for w in self.weights]    activation = x    activations = [x]    zs = []    # step 1    for w, b in zip(self.weights, self.biases):        z = np.dot(w, activation) + b        zs.append(z)        activation = sigmoid(z)        activations.append(activation)    # step 2    delta = (activations[-1]-y)*sigmoid_prime(zs[-1])    nabla_b[-1] = delta    nabla_w[-1] = np.dot(delta, activations[-2].transpose())                    # 因为是两层之间的权值矩阵,delta表示的后一层的列                    # activations[-2]表示的前一层的列,作一转置    # step 3    for l  in range(2, self.num_layers):        z = zs[-l]        sp = sigmoid_prime(z)        delta = np.dot(self.wights[-l+1].transpose(), delta)*sp        nabla_b[-l] = delta        nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())

sigmoid_prime是对sigmoid函数的导数:

def sigmoid_prime(z):    return sigmoid(z)*(1-sigmoid(z))
0 0
原创粉丝点击