吴恩达深度学习-L1 神经网络和深度学习总结

作业地址:吴恩达《深度学习》作业线上版 - 知乎 (zhihu.com)

写的很好的笔记:吴恩达《深度学习》笔记汇总 - 知乎 (zhihu.com)        我的「吴恩达深度学习笔记」汇总帖(附 18 个代码实战项目) - 知乎 (zhihu.com)

此处只记录需要注意的点,若想看原笔记请移步。

1.1 深度学习入门

我们只需要管理神经网络的输入和输出,而不用指定中间的特征,也不用理解它们究竟有没有实际意义。

1.2 简单的神经网络——逻辑回归

所有输入数据的集合构成一个矩阵(其中每个输入样本用列向量的形式表示,这是为了方便计算机的计算):

吴恩达深度学习-L1 神经网络和深度学习总结_第1张图片

需要注意X矩阵的行表示特征数量nx,列表示m个样本。

Y矩阵表示m个样本,每个样本标签为0或1。

注意区别误差函数和损失函数,误差函数是定义在每个样本上的,而损失函数是定义在整个样本上的。

向量化计算前向和反向传播中,1/m怎么来的?

吴恩达深度学习-L1 神经网络和深度学习总结_第2张图片

1.3 “浅度”神经网络

这段代码有一点需要注意:

db2=np.sum(dZ2, axis=1, keepdims=True)
db1=np.sum(dZ1, axis=1, keepdims=True)

这个keepdims=True 是必不可少的。使用np.sum, np.mean这种会导致维度变少的计算时,如果加了keepdims=True ,会让变少的那一个维度保持长度1。比如一个[4, 3]的矩阵,我们对第二维做求和,理论上得到的是一个[4]的向量。但如果用了keepdims=True,就会得到一个[4, 1]的矩阵。

保持向量的维度,可以让某些广播运算正确进行。比如我要用[4, 3]的矩阵减去[4]的矩阵就会报错,而减去[4, 1]的矩阵就不会报错。

1.4 深层神经网络

注意:输入层并不计入层数,但可以用第“0”层称呼输入层

我们要记住,全体样本是把每个样本以列向量的形式横向堆叠起来,堆成了一个矩阵。我们心中对X, Y的矩阵形状要有数。

为什么在前向传播中要缓存?

吴恩达深度学习-L1 神经网络和深度学习总结_第3张图片

记不住公式没关系,编程的时候对着翻译就行。

超参数则包括:

  • 学习率 \alpha
  • 训练迭代次数
  • 网络层数 L

我们直接从超参数的作用来给超参数下定义。超参数的取值会决定参数 W,b 的取值,它们往往只参与训练,而不参与最后的推理计算。可以说,除了网络中要学习的参数外,网络中剩下的可以变动的数值,都是超参数。

一个简单区别超参数的方法是:超参数一般是我们手动调的。我们常说“调参”,说的是超参数。

self.W: List[np.ndarray] = []    //表示W是一个矩阵

两个新的numpy API

第一个API是

np.savez(filename, a_name=a, b_name=b, ...)

它可以把ndarray类型的数据a, b, ...以键值对的形式记录进一个.npz文件中,其中键值对的键是数据的名称,值是数据的值。

第二个API是np.load(filename)。它可以从.npz里读取出一个词典。词典中存储的键值对就是我们刚刚保存的键值对。

比如,我们可以用如下方法存取W, b 两个ndarray :

W = np.zeros((1, 1))
b = np.zeros((1, 1))
np.savez('a.npz', W=W, b=b)
params = np.load('a.npz')
assert W == params['W']
assert b == params['b']

学会了这两个API的用法后,我们来看看该怎么存取神经网络的参数:

def save(self, filename: str):
    save_dict = {}
    for i in range(len(self.W)):
        save_dict['W' + str(i)] = self.W[i]
    for i in range(len(self.b)):
        save_dict['b' + str(i)] = self.b[i]
    np.savez(filename, **save_dict)

def load(self, filename: str):
    params = np.load(filename)
    for i in range(len(self.W)):
        self.W[i] = params['W' + str(i)]
    for i in range(len(self.b)):
        self.b[i] = params['b' + str(i)]

和刚刚介绍的用法一样,这里我们要给神经网络中每一个参数取一个独一无二的名字,再把所有名字和值合并成键值对。保存和读取,就是对键值对的写和读。

这里我使用了**save_dict这种传参方式。在Python中,func(**dict)的作用是把一个词典的值当作函数的键值对参数。比如我要写func(a=a, b=b) ,我可以定义一个词典d={'a':a, 'b':b} ,再用func(**d) 把词典传入函数的键值对参数。

总结

吴恩达《深度学习专项》第一阶段总结与第二阶段预览 - 知乎 (zhihu.com)

自我感觉达到文章里Level3的水平了,对于计算中的某些细节还有些不清楚,比如导数的计算,\frac{1}{m}怎么来的,反向传播的过程中的cache存储等。

你可能感兴趣的:(深度学习,人工智能)