关键词:
实现深层神经网络
本章我们将编码完成全连接神经网络,并使用CIFAR-10数据集进行测试,在本章练习中我们将完成:
- 1.仿射层传播
- 2.ReLU层传播
- 3.组合单层神经元
- 4.实现浅层全连接神经网络
- 5.实现深层全连接神经网络
# -*- coding: utf-8 -*-
import time
import numpy as np
import matplotlib.pyplot as plt
from classifiers.chapter3 import *
from utils import *
%matplotlib inline
plt.rcParams['figure.figsize'] =(10.0, 8.0) # 设置默认绘图尺寸
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
%load_ext autoreload
%autoreload 2
def rel_error(x, y):
#计算相对错误
return np.max(np.abs(x - y) /(np.maximum(1e-8, np.abs(x) + np.abs(y))))
# 将CIFAR10数据集的导入,切片,预处理操作进行封装
data = get_CIFAR10_data() #获取数据
# 训练数据
X_train =data['X_train']
y_train =data['y_train']
# 验证数据
X_val = data['X_val']
y_val = data['y_val']
# 测试数据
X_test = data['X_test']
y_test = data['y_test']
for k, v in data.items():
print('%s: ' % k, v.shape)
X_train: (49000, 3, 32, 32)
y_train: (49000,)
X_val: (1000, 3, 32, 32)
y_val: (1000,)
X_test: (1000, 3, 32, 32)
y_test: (1000,)
仿射层前向传播
仿射(affine)传播就是将各个输入特征进行加权求和,如果下一层有m个神经元,那就相当于线性代数中的m组线性方程式。
进行测试:
# 测试affine_forward 函数
# np.linspaces,规定起点、终点(包含)、返回array的长度,返回一个两端点间数值平均分布的array。
num_inputs = 2
input_shape =(4, 5, 6)
output_dim = 3 #输出维度
# 2*4*5*6
input_size = num_inputs * np.prod(input_shape)
# 3*4*5*6
weight_size = output_dim * np.prod(input_shape)
# 初始化输入参数
x = np.linspace(-0.1, 0.5, num=input_size).reshape(num_inputs, *input_shape)
w = np.linspace(-0.2, 0.3, num=weight_size).reshape(np.prod(input_shape), output_dim)
b = np.linspace(-0.3, 0.1, num=output_dim)
# 测试affine_forward函数
out, _ = affine_forward(x, w, b)
correct_out = np.array([[ 1.49834967, 1.70660132, 1.91485297],
[ 3.25553199, 3.5141327, 3.77273342]])
# 比较你的实现结果和正确结果。该误差应该小于1e-9。
print('测试 affine_forward 函数:')
print('误差: ', rel_error(out, correct_out))
测试 affine_forward 函数:
误差: 9.769847728806635e-10
仿射层反向传播
在前向传播中,实现的启示就是out=x1w1+x2w2+b这个函数,那仿射层的反向传播,其实就是将x,w,b各自对应的梯度求出即可。需要注意的是,在缓存中我们存储的是原始数据的四维图像数据。因此,同前向传播一样,首先将数据转换为二维数据后,再进行求解。
# 测试 affine_backward 函数
from utils.gradient_check import *
x = np.random.randn(10, 2, 3)
w = np.random.randn(6, 5)
b = np.random.randn(5)
dout = np.random.randn(10, 5)
dx_num = eval_numerical_gradient_array(lambda x: affine_forward(x, w, b)[0], x, dout)
dw_num = eval_numerical_gradient_array(lambda w: affine_forward(x, w, b)[0], w, dout)
db_num = eval_numerical_gradient_array(lambda b: affine_forward(x, w, b)[0], b, dout)
_, cache = affine_forward(x, w, b)
dx, dw, db = affine_backward(dout, cache)
# 相对误差应该小于1e-10
print('测试 affine_backward 函数:')
print('dx 误差: ', rel_error(dx_num, dx))
print('dw 误差: ', rel_error(dw_num, dw))
print('db 误差: ', rel_error(db_num, db))
测试 affine_backward 函数:
dx 误差: 2.6581417320273106e-08
dw 误差: 2.2266239834308258e-11
db 误差: 3.035949501360111e-11
ReLU层前向传播
ReLU激活函数的公式为max(0, x),我们直接使用NumPy提供的内置公式即可。实现 relu_forward 激活函数的前向传播,并使用下列代码进行测试:
# 测试relu_forward 函数
x = np.linspace(-0.5, 0.5, num=12).reshape(3, 4)
out, _ = relu_forward(x)
correct_out = np.array([[ 0., 0., 0., 0., ],
[ 0., 0., 0.04545455, 0.13636364,],
[ 0.22727273, 0.31818182, 0.40909091, 0.5, ]])
# 比较输出结果. 其误差大约为 1e-8
print('测试 relu_forward 函数:')
print('误差: ', rel_error(out, correct_out))
测试 relu_forward 函数:
误差: 4.999999798022158e-08
ReLU层反向传播
实现 relu_backward函数并使用数值梯度进行检验:
x = np.random.randn(10, 10)
dout = np.random.randn(*x.shape)
dx_num = eval_numerical_gradient_array(lambda x: relu_forward(x)[0], x, dout)
_, cache = relu_forward(x)
dx = relu_backward(dout, cache)
# 其相对误差大约为1e-12
print('测试 relu_backward 函数:')
print('dx 误差: ', rel_error(dx_num, dx))
测试 relu_backward 函数:
dx 误差: 3.2756356627391068e-12
完整的神经元层
接下来我们将上述的affine传播,和ReLU传播组合在一起,形成一层完整的神经元层。
在你实现affine_relu_forward和affine_relu_backward函数之后,运行下面的代码进行梯度检验:
#初始化。
x = np.random.randn(2, 3, 4)
w = np.random.randn(12, 10)
b = np.random.randn(10)
dout = np.random.randn(2, 10)
#执行ReLU,获取分析梯度。
out, cache = affine_relu_forward(x, w, b)
dx, dw, db = affine_relu_backward(dout, cache)
#获取数值梯度。
dx_num = eval_numerical_gradient_array(lambda x: affine_relu_forward(x, w, b)[0], x, dout)
dw_num = eval_numerical_gradient_array(lambda w: affine_relu_forward(x, w, b)[0], w, dout)
db_num = eval_numerical_gradient_array(lambda b: affine_relu_forward(x, w, b)[0], b, dout)
#比较相对误差。
print('测试 ReLU神经元相对误差:')
print('dx 误差: ', rel_error(dx_num, dx))
print('dw 误差: ', rel_error(dw_num, dw))
print('db 误差: ', rel_error(db_num, db))
测试 ReLU神经元相对误差:
dx 误差: 6.029307341263184e-11
dw 误差: 4.873523095375596e-10
db 误差: 4.284094461510698e-11
输出层:Softmax
运行下列代码以确认我们的实现是正确的:
num_classes, num_inputs = 10, 50
x = 0.001 * np.random.randn(num_inputs, num_classes)
y = np.random.randint(num_classes, size=num_inputs)
dx_num = eval_numerical_gradient(lambda x: softmax_loss(x, y)[0], x, verbose=False)
loss, dx = softmax_loss(x, y)
# 测试 softmax_loss 函数. 损失值大约为 2.3 dx 误差大约为 1e-8
print('\\n测试 softmax_loss:')
print('loss: ', loss)
print('dx error: ', rel_error(dx_num, dx))
测试 softmax_loss:
loss: 2.3026391824439414
dx error: 9.528882883490555e-09
浅层神经网络
现在我们将实现浅层全连接神经网络,打开chapter3\\shallow_layer_net.py文件,阅读内容完成相应任务后,执行下面代码进行验证。
N, D, H, C = 3, 5, 50, 7
X = np.random.randn(N, D)
y = np.random.randint(C, size=N)
std = 1e-2
model = ShallowLayerNet(input_dim=D, hidden_dim=H, num_classes=C, weight_scale=std)
print('测试初始化 ... ')
W1_std = abs(model.params['W1'].std() - std)
b1 = model.params['b1']
W2_std = abs(model.params['W2'].std() - std)
b2 = model.params['b2']
# assert(W1_std < std / 10, '第一层权重初始化有问题')
# assert(np.all(b1 == 0), '第一层偏置初始化有问题')
# assert(W2_std < std / 10, '第二层权重初始化有问题')
# assert(np.all(b2 == 0), '第二层偏置初始化有问题')
print('测试前向传播过程 ... ')
model.params['W1'] = np.linspace(-0.7, 0.3, num=D*H).reshape(D, H)
model.params['b1'] = np.linspace(-0.1, 0.9, num=H)
model.params['W2'] = np.linspace(-0.3, 0.4, num=H*C).reshape(H, C)
model.params['b2'] = np.linspace(-0.9, 0.1, num=C)
X = np.linspace(-5.5, 4.5, num=N*D).reshape(D, N).T
scores = model.loss(X)
correct_scores = np.asarray(
[[11.53165108, 12.2917344, 13.05181771, 13.81190102, 14.57198434, 15.33206765, 16.09215096],
[12.05769098, 12.74614105, 13.43459113, 14.1230412, 14.81149128, 15.49994135, 16.18839143],
[12.58373087, 13.20054771, 13.81736455, 14.43418138, 15.05099822, 15.66781506, 16.2846319 ]])
scores_diff = np.abs(scores - correct_scores).sum()
# assert(scores_diff < 1e-6, '前向传播有问题')
# print('测试训练损失(无正则化)')
y = np.asarray([0, 5, 1])
loss, grads = model.loss(X, y)
correct_loss = 3.4702243556
# assert(abs(loss - correct_loss) < 1e-10, '训练阶段的损失值(无正则化)有问题')
print('测试训练损失(正则化0.1)')
model.reg = 1.0
loss, grads = model.loss(X, y)
correct_loss = 26.5948426952
# assert(abs(loss - correct_loss) < 1e-10, '训练阶段的损失值(有正则化)有问题')
for reg in [0.0, 0.7]:
print('梯度检验,正则化系数 = ', reg)
model.reg = reg
loss, grads = model.loss(X, y)
for name in sorted(grads):
f = lambda _: model.loss(X, y)[0]
grad_num = eval_numerical_gradient(f, model.params[name], verbose=False)
print('%s 相对误差: %.2e' %(name, rel_error(grad_num, grads[name])) )
测试初始化 ...
测试前向传播过程 ...
测试训练损失(正则化0.1)
梯度检验,正则化系数 = 0.0
W1 相对误差: 1.52e-08
W2 相对误差: 3.48e-10
b1 相对误差: 6.55e-09
b2 相对误差: 4.33e-10
梯度检验,正则化系数 = 0.7
W1 相对误差: 8.18e-07
W2 相对误差: 2.85e-08
b1 相对误差: 1.09e-09
b2 相对误差: 9.09e-10
训练浅层全连接网络
阅读 ShallowLayerNet.train()以及predict()函数,确保自己了解整个流程
input_size = 32 * 32 * 3
hidden_size = 100
num_classes = 10
net = ShallowLayerNet(input_size, hidden_size, num_classes)
# 训练网络
stats = net.train(X_train, y_train, X_val, y_val,
num_iters=2000, batch_size=500,
learning_rate=1e-3, learning_rate_decay=0.95,
reg=0.6, verbose=True)
# 验证结果
val_acc =(net.predict(X_val) == y_val).mean()
print('最终验证正确率: ', val_acc)
print('历史最佳验证正确率: ', stats['best_val_acc'])
迭代次数 0 / 2000: 损失值 2.394240
迭代次数 100 / 2000: 损失值 1.933027
迭代次数 200 / 2000: 损失值 1.765465
迭代次数 300 / 2000: 损失值 1.647589
迭代次数 400 / 2000: 损失值 1.582696
迭代次数 500 / 2000: 损失值 1.606909
迭代次数 600 / 2000: 损失值 1.512944
迭代次数 700 / 2000: 损失值 1.545821
迭代次数 800 / 2000: 损失值 1.487011
迭代次数 900 / 2000: 损失值 1.611031
迭代次数 1000 / 2000: 损失值 1.502333
迭代次数 1100 / 2000: 损失值 1.413480
迭代次数 1200 / 2000: 损失值 1.604284
迭代次数 1300 / 2000: 损失值 1.431850
迭代次数 1400 / 2000: 损失值 1.334827
迭代次数 1500 / 2000: 损失值 1.464982
迭代次数 1600 / 2000: 损失值 1.335481
迭代次数 1700 / 2000: 损失值 1.418904
迭代次数 1800 / 2000: 损失值 1.367120
迭代次数 1900 / 2000: 损失值 1.418279
最终验证正确率: 0.512
历史最佳验证正确率: 0.512
# 绘制损失函数变化曲线
plt.subplot(2, 1, 1)
plt.plot(stats['loss_history'])
plt.title('Loss history')
plt.xlabel('Iteration')
plt.ylabel('Loss')
plt.subplot(2, 1, 2)
plt.plot(stats['train_acc_history'], label='train')
plt.plot(stats['val_acc_history'], label='val')
plt.plot([0.5] * len(stats['val_acc_history']), 'k--')
plt.title('Classification accuracy history')
plt.xlabel('Epoch')
plt.ylabel('Clasification accuracy')
# 添加图标
plt.legend()
# 控制布局
plt.tight_layout()
plt.show()
深层全连接网络
接下来我们将实现深层的全连接网络,由于我们以及实现了浅层网络,深层网络的实现将变得很简单。
深层神经网络相比于浅层神经网络,虽然仅仅是隐藏层数量变多而已,但它却具有了浅层网络没有的强大能力。由于我们已经实现了浅层网络,深层网络的实现将变得非常简单。现在要做的仅仅是将浅层网络中固定的单隐藏层变成任意多层即可。在深层全连接神经网络,隐藏层使用ReLU作为激活函数,输出层使用Softmax作为分类器。
N, D, H1, H2,H3, C = 2, 15, 20, 30, 20, 10
X = np.random.randn(N, D)
y = np.random.randint(C, size=(N,))
for reg in [0, 0.11, 3.14]:
print('权重衰减系数= ', reg)
model = FullyConnectedNet(input_dim=D,hidden_dims=[H1, H2,H3],num_classes=C,reg=reg, weight_scale=5e-2)
loss, grads = model.loss(X, y)
print('初始化化损失值: ', loss)
for name in sorted(grads):
f = lambda _: model.loss(X, y)[0]
grad_num = eval_numerical_gradient(f, model.params[name], verbose=False, h=1e-5)
print('%s 相对误差: %.2e' %(name, rel_error(grad_num, grads[name])))
权重衰减系数= 0
初始化化损失值: 2.302395002878659
W1 相对误差: 7.33e-06
W2 相对误差: 2.52e-07
W3 相对误差: 1.21e-06
W4 相对误差: 3.73e-07
b1 相对误差: 5.57e-07
b2 相对误差: 1.47e-08
b3 相对误差: 1.74e-06
b4 相对误差: 1.38e-10
权重衰减系数= 0.11
初始化化损失值: 2.5387725473271425
W1 相对误差: 1.22e-07
W2 相对误差: 8.56e-07
W3 相对误差: 1.27e-07
W4 相对误差: 7.80e-08
b1 相对误差: 7.76e-08
b2 相对误差: 4.06e-07
b3 相对误差: 3.10e-09
b4 相对误差: 9.36e-11
权重衰减系数= 3.14
初始化化损失值: 8.877932640499402
W1 相对误差: 1.11e-08
W2 相对误差: 9.18e-08
W3 相对误差: 5.11e-08
W4 相对误差: 4.26e-08
b1 相对误差: 3.60e-07
b2 相对误差: 9.61e-08
b3 相对误差: 2.56e-08
b4 相对误差: 3.55e-10
# 在小数据集上测试训练效果,正常情况下应该出现严重过拟合现象
input_size = 32 * 32 * 3
num_classes = 10
num_train = 50
X_train_small= X_train[:num_train]
y_train_small= y_train[:num_train]
w= 1e-1
l = 1e-3
net = FullyConnectedNet(input_size ,[100,查看详情
tensorflow实战-tensorflow和其他深度学习框架的对比-第2章
...wTensorFlow是相对高阶的机器学习库,用户?方便地用它设计神经网络结构,而不必为了追求高效率的实现亲自写C++或者CUDA代码。TensorFlow另外一个特点是灵活的移植性。TensorFlow还提供了TensorBoard,TensorBoard是TensorF 查看详情
神经网络与深度学习摘要第1章绪论
【神经网络与深度学习摘要】第1章绪论文章目录【神经网络与深度学习摘要】第1章绪论1.人工智能1.1图灵测试1.2人工智能的主要领域1.3人工智能的发展历史1.4人工智能的流派2.机器学习2.1机器学习定义2.2使用机器学习模型步骤3.... 查看详情
tensorflow实战google深度学习框架(代码片段)
第3章TensorFlow入门3.1TensorFlow计算模型-计算图3.1.1计算图的概念Tensorflow中所有计算都会被转化成计算图的一个节点,计算图上的边表示了他们之间的相互依赖关系。3.1.2计算图的使用Tensorflow的程序可以分成两个阶段:定义计算、... 查看详情
第3章神经网络《深度学习入门基于python的理论与实现》
第3章神经网络《深度学习入门基于Python的理论与实现》3.1从感知机到神经网络3.2激活函数3.1从感知机到神经网络 查看详情
深度学习:基于python:第7章卷积神经网络(代码片段)
第7章卷积神经网络第7章卷积神经网络7.1整体结构7.2卷积层7.2.1 全连接层存在的问题7.2.2 卷积运算7.2.3 填充7.2.4 步幅7.2.5 3维数据的卷积运算7.2.6 结合方块思考7.2.7 批处理7.3池化层7.4卷积层和池化层的实现7.4.1 4维数组7... 查看详情
2023.5.7《动手学深度学习》第78章(代码片段)
今天继续学习《动手学习深度学习》第7章:现代卷积神经网络、第8章:循环神经网络,今天学到的内容主要有这两章的概念。一、理论部分:1、LeNet和AlexNet的网络结构LeNet的激活函数是Sigmoid,AlexNet的激活函数是ReLU。2、AlexNet... 查看详情
[人工智能-深度学习-59]:生成对抗网络gnn-基本原理(图解详解通俗易懂)(代码片段)
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121878299目录第1章生成对抗网络GAN概述与主要应用第2章生成对抗网络GAN... 查看详情
keras深度学习实战——卷积神经网络详解与实现(代码片段)
Keras深度学习实战(7)——卷积神经网络详解与实现0.前言1.传统神经网络的缺陷1.1构建传统神经网络1.2传统神经网络的缺陷2.使用Python从零开始构建CNN2.1卷积神经网络的基本概念2.2卷积和池化相比全连接网络的优势3.使用... 查看详情
深度学习100例|第43天:文本卷积神经网络(textcnn)新闻文本分类实战(代码片段)
🚩本文作者:微学AI、K同学啊🥇精选专栏:《深度学习100例》🔥推荐专栏:《新手入门深度学习》📚选自专栏:《Matplotlib教程》🧿优秀专栏:《Python入门100题》大家好,我是K同学啊&... 查看详情
keras深度学习实战——卷积神经网络的局限性(代码片段)
Keras深度学习实战(9)——卷积神经网络的局限性0.前言1.卷积神经网络的局限性2.情景1——训练数据集图像尺寸较大3.情景2——训练数据集图像尺寸较小4.情景3——在训练尺寸较大的图像时使用更大池化小结系列链接0.... 查看详情
tensorflow实战-tensorflow实现卷积神经网络cnn-第5章
第5章-TensorFlow实现卷积神经网络CNN5.1卷积神经网络简介卷积神经网络CNN最初是为了解决图像识别等问题设计的,当然现在的应用已经不限于图像和视频,也可以用于时间序列信号,比如音频信号、文本数据等。在深度学习出现之... 查看详情
2023.5.6《动手学深度学习》第34章(代码片段)
...动手学习深度学习》第5章:深度学习计算、第6章:卷积神经网络,今天学到的内容主要有这两章的概念。以及实现LeNet对FashionMNIST进行分类。一、理论部分:1、概念解释:1×1卷积的作用:卷积通常用于识别相邻元素间相互作用... 查看详情
keras深度学习实战(20)——神经风格迁移详解(代码片段)
...m图像生成算法的学习中,我们通过修改像素值试图使神经网络中卷积核的激活最大化。但是,这并不具备灵活生成指定风格图像的功能,因此,本节我们继续学习神经风格迁 查看详情
keras深度学习实战(29)——长短时记忆网络详解与实现(代码片段)
...TermMemory,LSTM),顾名思义是具有记忆长短期信息能力的神经网络 查看详情
keras深度学习实战(29)——长短时记忆网络详解与实现(代码片段)
...TermMemory,LSTM),顾名思义是具有记忆长短期信息能力的神经网络 查看详情
keras深度学习实战(26)——文档向量详解(代码片段)
...实战(26)——文档向量详解0.前言1.文档向量基本概念2.神经网络模型与数据集分析2.1模型分析2.2数据集介绍3.利用Keras构建神经网络模型生成文档向量小结系列链接0.前言在《从零开始构建单词向量》一节中,我们学习了单词向... 查看详情
keras深度学习实战(22)——生成对抗网络详解与实现(代码片段)
...链接0.前言生成对抗网络(GenerativeAdversarialNetworks,GAN)使用神经网络生成与原始图像集非常相似的新图像,它在图像生成中应用广泛,且GAN的相关研究正在迅速发展ÿ 查看详情