深度学习:tensorflow 的整体实现,numpy实现深度学习(三)

tensorflow 的整体实现需要的变量:

首先我们需要记录所有层,已经所有的权重信息,需要两个优化器,添加层时当前层的神经元个数

class NaiveNN:
    def __init__(self):
        # 记录所有的layer
        self._layers = []
        # 记录所有的权值矩阵,偏置量
        self._weights = []
        self._bias = []
        # 记录着所有权值矩阵的和偏置量的优化器
        self._w_optimizer = self._b_optimizer = None
        # 记录着当前最后一个Layer所含的神经元个数
        self._current_dimension = 0

添加层的处理:

    def add(self, layer):
        if not self._layers:
            # 如果是第一次加入layer、则初始化相应的属性
            self._layers = [layer]
            self._current_dimension = layer.shape[1]
            # 调用初始化权值矩阵和偏置量的方法
            self._add_params(layer.shape)
        
        else:
            _next = layer.shape[0]
            layer.shape = (self._current_dimension, _next)
            # 调用进一步处理Layer的方法
            self._add_layer(layer, self._current_dimension, _next)
            
    def _add_params(self, shape):
        self._weights.append(np.random.randn(*shape))
        self._bias.append(np.zeros((1, shape[1])))
        
    def _add_layer(self, layer, *args):
        _current, _next = args
        self._add_params((_current, _next))
        self._current_dimension = _next
        self._layers.append(layer)
        

优化器的处理:

训练时需要初始化优化器,选择哪个优化器以及初始参数。

    def _init_optimizers(self, optimizer, lr, epoch):
        # 利用定义好的优化器工厂来初始化优化器
        # 注意由于最后一层是CostLayer对应的占位符、所以无需把它输进优化器
        _opt_fac = OptFactory()
        self._w_optimizer = _opt_fac.get_optimizer_by_name(
                optimizer, self._weights[:-1], lr, epoch)
        self._b_optimizer = _opt_fac.get_optimizer_by_name(
                optimizer, self._bias[:-1], lr, epoch)  

前向传播的处理:

遍历每一层前向传播计算结果。

    # 前向传播求各层的结果    
    def _get_activations(self, x):
        _activations = [self._layers[0].activate(x, self._weights[0], self._bias[0])]
        for i, layer in enumerate(self._layers[1:]):
            _activations.append(layer.activate(_activations[-1], self._weights[i+1], self._bias[i+1]))
    
        return _activations

更新权重:

根据梯度更新每一层的权重

    # 求对应层优化后的权重矩阵
    def _opt(self, i, _activation, _delta):
        self._weights[i] += self._w_optimizer.run(i, _activation.T.dot(_delta))
        self._bias[i] += self._b_optimizer.run(i, np.sum(_delta, axis=0, keepdims=True))
    
 

训练:

训练过程:准备好优化器,计算每一层前向传播结果,反向传播计算每一层梯度,根据梯度更新每一层权重,重复epoch。

    # 训练
    def fit(self, x, y, lr=0.001, optimizer="Adam", epoch=10):
        # 初始化优化器
        self._init_optimizers(optimizer, lr, epoch)
        layer_width = len(self._layers)
        
        for counter in range(epoch):
            # 更新学习率
            self._w_optimizer.update()
            self._b_optimizer.update()
            # 前向传播计算每一层的结果
            _activations = self._get_activations(x)
            # costlayer单独计算梯度,delta
            _deltas = [self._layers[-1].bp_first(y, _activations[-1])]
            # 计算其它层的梯度,delta
            for i in range(-1, -len(_activations), -1):
                _deltas.append(self._layers[i-1].bp(_activations[i-1], self._weights[i], _deltas[-1]))
                
            # 根据梯度更新权重
            for i in range(layer_width -1, 0, -1):
                self._opt(i, _activations[i-1], _deltas[layer_width -i -1])
            self._opt(0, x, _deltas[-1])

预测:

根据得到的权重直接预测结果

    def predict(self, x, get_raw_results=False):
        y_pred = self._get_prediction(np.atleast_2d(x))
        if get_raw_results:
            return y_pred
        return np.argmax(y_pred, axis=1)
    def _get_prediction(self, x):
        # 直接取前向传导算法得到的最后一个激活值即可
        return self._get_activations(x)[-1]

猜你喜欢

转载自blog.csdn.net/weixin_40759186/article/details/86442219