深度学习入门:基于Python的理论与实现【笔记及理解】
第一章 python入门
-
- 数据类型:Python中的type()函数
-
-
列表(数组):
- >>> a = [1, 2, 3, 4, 5] # 生成列表
- >>> a[0:2] # 获取索引为0到2(不包括2!)的元素
- [1, 2]
- >>> a[1:] # 获取从索引为1的元素到最后一个元素
- [2, 3, 4, 5]
- >>> a[:3] # 获取从第一个元素到索引为3(不包括3!)的元素
- [1, 2, 3]
- >>> a[:-1] # 获取从第一个元素到最后一个元素的前一个元素之间的元素
- [1, 2, 3, 4]
- >>> a[:-2] # 获取从第一个元素到最后一个元素的前二个元素之间的元素
- [1, 2, 3]
-
列表(数组):
-
-
字典:
- >>> me = {'height':180} # 生成字典
- >>> me['height']# 访问元素
- 180
- >>> me['weight'] = 70 # 添加新元素
- >>> print(me)
- {'height': 180, 'weight': 70}
-
字典:
-
-
类:
- eg.
-
类:
-
-
NumPy:
-
numpy数组和python数组的区别
- Numpy是专门针对数组的操作和运算进行了设计
- 其数组的存储效率和输入输出性能远优于Python中的嵌套列表
-
numpy数组和python数组的区别
-
NumPy:
-
-
生成NumPy数组,需要使用np.array()方法。
- np.array()接收Python 列表作为参数,生成NumPy数组(numpy.ndarray)。
- >>> x = np.array([1.0, 2.0, 3.0])
- >>> print(x) [ 1. 2. 3.]
- >>> type(x)
- <class 'numpy.ndarray'>
-
生成NumPy数组,需要使用np.array()方法。
-
- 广播:
- 在NumPy数组的各个元素和标量之间进行运算。
- >>> x = np.array([1.0, 2.0, 3.0])
- >>> x / 2.0
- array([ 0.5, 1. , 1.5])
- 广播:
-
- N维数组:
- >>> A = np.array([[1, 2], [3, 4]])
- >>> A.shape (2, 2)
- >>> A.dtype #矩阵元素的数据类型可以通过dtype查看
- dtype('int64')
- 乘法:
- >>> B = np.array([[3, 0],[0, 6]])
- >>> A * B #各元素相乘
-
array([[ 3, 0],
- [ 0, 24]])
-
访问元素:【多维数组】
- N维数组:
-
-
使用数组访问各个元素:
- 获取满足一定条件的元素:【要从X中抽出 大于15的元素】
-
使用数组访问各个元素:
-
- argmax()
- p = np.argmax(y_batch, axis=1)
- 我们给定了参数axis=1。这指定了在100 × 10的数组中,沿着第1维方向(以 第1维为轴)找到值最大的元素的索引(第0维对应第1个维度)
-
Matplotlib:
- 使用Matplotlib可以轻松地绘制图形和实现数据的可视化。
-
pyplot模块绘制图形:
- 绘制sin(x)和cos(x):
- argmax()
-
- image模块的imread()方法读入图像:
- image模块的imread()方法读入图像:
-
第二章 感知机
-
- 神经网络(深度学习)的起源
- 使用单层感知机可以实现与门、与非门、或门三种逻辑电路,但是无法实现异或门。
- 感知机的绝妙之处在于它可以“叠加层”(通过叠加层来表示异或门是本节的要点)。
- 感知机通过叠加层能够进行非线性的表示,理论上还可以表示计算机进行的处理。
-
-
第三章 神经网络
-
- 我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层
- 依次称为第0层、第 1层、第2层。以下是一个“2层网络”:
- b是被称为偏置的参数,用于控制神经元被**的容易程度;
- 而w1 和w2是表示各个信号的权重的参数,用于控制各个信号的重要性。
-
- **函数(activation function):连接感知机和神经网络的桥梁。
- h(x)函数会将输入信号的总和转换为输出信号,**函数的 作用在于决定如何来**输入信号的总和。
-
- **函数(activation function):连接感知机和神经网络的桥梁。
-
- sigmoid函数:
- 神经网络中经常使用的一个**函数就是式(3.6)表示的sigmoid函数
- 神经网络中经常使用的一个**函数就是式(3.6)表示的sigmoid函数
- sigmoid函数:
-
-
def sigmoid(x):
- return 1 / (1 + np.exp(-x))
-
def sigmoid(x):
-
- sigmoid函数是一条平滑的曲线,输出随着输入发生连续性的变化。
- 而阶跃函数以0为界,输出发生急剧性的变化。
- sigmoid函数的平滑性对神经网络的学习具有重要意义。
-
- 神经网络中流动的是连续的实数值信号。
-
- 神经网络的**函数必须使用非线性函数
- 为什么不能使用线性函数呢?
- 因为使用线性函数的话,加深神经网络的层数就没有意义了。
- 线性函数的问题在于,不管如何加深层数,总是存在与之等效的“无隐藏层的神经网络”。
- ReLU函数:
- sigmoid函数很早就开始被使用了,而最近则主要使用ReLU(Rectified Linear Unit)函数。
- def relu(x):
return np.maximum(0, x)
-
- 多维数组的运算
- 数组的维数可以通过np.dim()函数获得:
- 注意,这里的A.shape的结果是个元组(tuple)。这是因为一维数组的情况下也要返回和多维数组的情况下一致的结果。例如,二维数组时返回的 是元组(4,3),三维数组时返回的是元组(4,3,2),因此一维数组时也同样以 元组的形式返回结果。下面我们来生成一个二维数组。
- 矩阵乘法:
- 数组的维数可以通过np.dim()函数获得:
- 多维数组的运算
>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([[3, 0],[0, 6]])
>>> A*B
array([[ 3, 0],
[ 0, 24]])
>>> np.dot(A,B) #多维数组的点积
array([[ 3, 12],
[ 9, 24]])
-
- 符号确认
- 符号确认
-
- 三层神经网络前向传递代码实现小结:
def identity_function(x):
return x
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def init_network():
network = {}
network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
network['b1'] = np.array([0.1, 0.2, 0.3])
network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
network['b2'] = np.array([0.1, 0.2])
network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
network['b3'] = np.array([0.1, 0.2])
return network
def forward(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = identity_function(a3)
return y
network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y) # [ 0.31682708 0.69627909]
-
- 输出层的设计
- 神经网络可以用在分类问题和回归问题上,不过需要根据情况改变输出层的**函数。一般而言,回归问题【预测连续数值】用恒等函数,分类问题用softmax函数。
- softmax函数:
- softmax函数 的输出通过箭头与所有的输入信号相连。这是因为,从式(3.10)可以看出, 输出层的各个神经元都受到所有输入信号的影响。
- 输出层的设计
-
- 实现softmax函数时的注意事项:
- 由于e^x计算存在指数爆炸,对于很多时候x很大的情况,容易出现错误。
- 但是分子分母的exp()中同加一个常数,不影响结果(推导如下)
- 所以,通过减去输入信号中的最大值,可以实现正确计算:
- 正确的softmax如下:
- softmax函数的输出是0.0到1.0之间的实数。并且,softmax 函数的输出值的总和是1。输出总和为1是softmax函数的一个重要性质。正因为有了这个性质,我们才可以把softmax函数的输出解释为“概率”。
- 但是:
- 实现softmax函数时的注意事项:
一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。
并且,即便使用softmax函数,输出值最大的神经元的位置也不会变。因此, 神经网络在进行分类时,输出层的softmax函数可以省略。在实际的问题中, 由于指数函数的运算需要一定的计算机运算量,因此输出层的softmax函数一般会被省略。
在输出层使用softmax函数是因为它和神经网络的学习有关系(详细内容请参考下一章)。
-
- MNIST数据集 手写数字识别
- 批处理
- 输入数据的形状为100 × 784,输出数据的形状为 100 × 10。这表示输入的100张图像的结果被一次性输出了。
比如,x[0]和y[0]中保存了第0张图像及其推理结果,x[1]和y[1]中保存了第1张图像及 其推理结果,等等。
这种打包式的输入数据称为批(batch)。批有“捆”的意思,图像就如同纸币一样扎成一捆。
- 批处理
- MNIST数据集 手写数字识别
第四章 神经网络的学习