零基础深度学学习:反向传播算法及全连接层实现

在已知目标函数的基础上,用随机梯度下降算法对目标函数进行优化,不断更新权重

神经网络要计算每个节点误差项来进行权重更新。显然,计算一个节点的误差项,需要先计算每个与其相连的下一层节点的误差项。这就要求误差项的计算顺序必须是从输出层开始,然后反向依次计算每个隐藏层的误差项,直到与输入层相连的那个隐藏层。这就是反向传播算法的名字的含义。

import numpy as np
class FullConnectedLayer(object):
    def __init__(self, input_size, output_size, activator):
        '''
        构造函数
        :param input_size: 本层输入向量的维度
        :param output_size:本层输出向量的维度
        :param activator:激活函数
        '''
        self.input_size = input_size
        self.output_size = output_size
        self.activator = activator
        #权重矩阵w:output_size * input_size
        self.w = np.random.uniform(-0.1, 0.1, (output_size, input_size))
        #偏置项
        self.b = np.zeros((output_size, 1))
        #输出向量
        self.output = np.zeros((output_size, 1))

    def forward(self, input_array):
        self.input = input_array
        self.output = self.activator.forward(
            np.dot(self.w, input_array)+self.b
        )

    def backward(self, delta_array):####该层的反向传播算法
        ####self.activartor.backward是激活函数类的backward
        self.delta = self.avtivator.backward(self.input)*np.dot(self.w.T,delta_array)
        self.w_grad = np.dot(delta_array,self.input.T)
        self.b_grad = delta_array

    def update(self,learning_rate):
        self.W+=learning_rate*self.W_grad
        self.b+=learning_rate*self.b_grad


####sigmoid激活函数类
class SigmoidActivator(object):
    def forward(self, weighted_input):
        return 1.0/(1.0+np.exp(-weighted_input))

    def backward(self, output):
        return output*(1-output)


####神经网络类
class Network(object):
    def __init__(self, layers):
        '''
        构造函数
        :param layers:
        '''
        self.layers = []
        for i in range(len(layers) - 1):
            self.layers.append(
                FullConnectedLayer(layers[i],layers[i+1], SigmoidActivator())
            )
    def predict(self, sample):
        output = sample
        for layer in self.layers:
            layer.forward(output)
            output = layer.output
        return output

    def train(self, labels, data_set, rate, epoch):
        for i in range(epoch):
            for d in range(len(data_set)):
                self.train_one_sample(labels[d], data_set[d], rate)

    def train_one_sample(self, label, sample, rate):
        self.predict(sample)
        self.calc_gradient(label)
        self.update_weight(rate)

    def calc_gradient(self, label):
        #输出层节点
        delta = self.layers[-1].activator.backward(
            self.layers[-1].output
        )*(label -self.layers[-1].output)
        #隐藏层节点
        for layer in self.layers[::-1]:
            layer.backward(delta)
            delta = layer.delta
        return delta
    def update_weight(self, rate):
        for layer in self.layers:
            layer.update(rate)

 

你可能感兴趣的:(零基础深度学学习:反向传播算法及全连接层实现)