2025年3月30日 星期日 甲辰(龙)年 月廿九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

深度学习:基于python,函数总和运用

时间:11-11来源:作者:点击数:55

误差反向传播法的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

神经网络学习的全貌图

在这里插入图片描述

对应误差反向传播法的神经网络的实现

在这里插入图片描述
在这里插入图片描述

使用的一个类:计算图层,第五章:这里神经网络层:y=xw+b

  • class Affine:
  • def __init__(self, W, b):
  • self.W =W
  • self.b = b
  • self.x = None
  • self.original_x_shape = None
  • # 权重和偏置参数的导数
  • self.dW = None
  • self.db = None
  • def forward(self, x):
  • # 对应张量
  • self.original_x_shape = x.shape
  • x = x.reshape(x.shape[0], -1)
  • self.x = x
  • out = np.dot(self.x, self.W) + self.b #这里神经网络层:y=xw+b
  • return out
  • def backward(self, dout):
  • dx = np.dot(dout, self.W.T)
  • self.dW = np.dot(self.x.T, dout)
  • self.db = np.sum(dout, axis=0)
  • dx = dx.reshape(*self.original_x_shape) # 还原输入数据的形状(对应张量)
  • return dx

激活函数层的实现

  • class Relu:
  • def __init__(self):
  • self.mask = None
  • def forward(self, x):
  • self.mask = (x <= 0)
  • out = x.copy()
  • out[self.mask] = 0
  • return out
  • def backward(self, dout):
  • dout[self.mask] = 0
  • dx = dout
  • return dx
  • def softmax(a):
  • exp_a = np.exp(a)
  • sum_exp_a = np.sum(exp_a)
  • y = exp_a / sum_exp_a
  • return y
  • class SoftmaxWithLoss:
  • def __init__(self):
  • self.loss = None
  • self.y = None # softmax的输出
  • self.t = None # 监督数据
  • def forward(self, x, t):
  • self.t = t
  • self.y = softmax(x)
  • self.loss = cross_entropy_error(self.y, self.t) #交叉熵误差,输出的越小,表明越精确
  • return self.loss
  • def backward(self, dout=1):
  • batch_size = self.t.shape[0]
  • if self.t.size == self.y.size: # 监督数据是one-hot-vector的情况
  • dx = (self.y - self.t) / batch_size
  • else:
  • dx = self.y.copy()
  • dx[np.arange(batch_size), self.t] -= 1
  • dx = dx / batch_size
  • return dx

传统的梯度的计算方法

  • def numerical_gradient(f, x):
  • h = 1e-4 # 0.0001
  • grad = np.zeros_like(x)
  • it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
  • while not it.finished:
  • idx = it.multi_index
  • tmp_val = x[idx]
  • x[idx] = float(tmp_val) + h
  • fxh1 = f(x) # f(x+h)
  • x[idx] = tmp_val - h
  • fxh2 = f(x) # f(x-h)
  • grad[idx] = (fxh1 - fxh2) / (2*h)
  • x[idx] = tmp_val # 还原值
  • it.iternext()
  • return grad

两层神经网络

  • # coding: utf-8
  • import sys, os
  • sys.path.append(os.pardir) # 为了导入父目录的文件而进行的设定
  • import numpy as np
  • from common.layers import *
  • from common.gradient import numerical_gradient
  • from collections import OrderedDict
  • class TwoLayerNet:
  • def __init__(self, input_size, hidden_size, output_size, weight_init_std = 0.01):
  • #input_size:输入层大小,hidden_size隐藏层大小,output_size输出层大小
  • # #weight_init_std:初始化权重时的高斯分布的规模
  • # 初始化权重
  • #随机生成w,b,慢慢做测试
  • self.params = {} #生成空字典
  • self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
  • self.params['b1'] = np.zeros(hidden_size)
  • self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
  • self.params['b2'] = np.zeros(output_size)
  • # 生成层
  • self.layers = OrderedDict() #
  • # Affine1是一个类,里面是这里神经网络层:y=xw+b的forward和backward,误向反差
  • self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
  • # 激活函数层的实现相当于relu和Sigmoid,都是在隐藏层处理h()函数
  • self.layers['Relu1'] = Relu()
  • self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
  • #显示Affine1 经过 Relu1 的处理到Affine2
  • self.lastLayer = SoftmaxWithLoss()
  • #前向通道,遍历
  • def predict(self, x):
  • for layer in self.layers.values():
  • x = layer.forward(x)
  • return x
  • # x:输入数据, t:监督数据 ,计算损失值
  • def loss(self, x, t):
  • y = self.predict(x)
  • return self.lastLayer.forward(y, t)
  • #计算识别精度
  • def accuracy(self, x, t):
  • y = self.predict(x)
  • y = np.argmax(y, axis=1)
  • if t.ndim != 1 :
  • t = np.argmax(t, axis=1)
  • accuracy = np.sum(y == t) / float(x.shape[0])
  • return accuracy
  • # x:输入数据, t:监督数据
  • #传统的梯度的计算方法
  • def numerical_gradient(self, x, t):
  • loss_W = lambda W: self.loss(x, t)
  • grads = {}
  • grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
  • grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
  • grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
  • grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
  • return grads
  • # 反向传播的梯度的计算方法
  • def gradient(self, x, t):
  • # forward
  • self.loss(x, t)
  • # backward
  • dout = 1
  • dout = self.lastLayer.backward(dout)
  • layers = list(self.layers.values()) #把字典转换成列表形式
  • layers.reverse() #列表翻转
  • for layer in layers:
  • dout = layer.backward(dout)
  • # 设定
  • grads = {}
  • grads['W1'], grads['b1'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
  • grads['W2'], grads['b2'] = self.layers['Affine2'].dW, self.layers['Affine2'].db
  • return grads

函数执行

取三张照片做测试

没有循环测试,只坐了一遍,没有减小误差

  • import sys, os
  • sys.path.append(os.pardir) # 为了导入父目录的文件而进行的设定
  • import numpy as np
  • from dataset.mnist import load_mnist
  • from two_layer_net import TwoLayerNet
  • # 读入数据 #x_train(60000, 784) t_train(60000, 10)
  • (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
  • network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
  • x_batch = x_train[:3] #(3, 784)
  • t_batch = t_train[:3] #(3, 10)
  • #传统的梯度的计算方法
  • grad_numerical = network.numerical_gradient(x_batch, t_batch)
  • # 反向传播的梯度的计算方法
  • grad_backprop = network.gradient(x_batch, t_batch)
  • for key in grad_numerical.keys():
  • diff = np.average( np.abs(grad_backprop[key] - grad_numerical[key]) )
  • print(key + ":" + str(diff))
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门