Introduction to Artificial Neural Networks with Keras
From Biological to Artificial Neurons
神经元逻辑计算
感知器
最常用的阶跃函数是heaviside阶跃函数,有的时候也会用sign函数
TLU(threshold logic unit)阈值逻辑单元
感知器由单层TLU组成,比如一个2输入3输出的感知器
全连接层的输出计算
ϕ函数被称为激活函数,在使用TLU时,它是阶跃函数
感知器的训练算法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191016161142662.png
wi, j是第i个输入和第j个输出的连接权重
如果训练实例线性可分,那么感知机必能收敛
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron
iris = load_iris()
X = iris.data[:, (2, 3)] # petal length, petal width
y = (iris.target == 0).astype(np.int)
per_clf = Perceptron(max_iter=1000, tol=1e-3, random_state=42)
per_clf.fit(X, y)
y_pred = per_clf.predict([[2, 0.5]])
y_pred
与Logistic Regession分类相比,感知机不输出分类概率,而是根据阈值直接给出分类,所以LR有时候更好用一些。
感知机不能解决XOR问题,所以需要用多层感知机(MLP)
多层感知机和反向传播
图为前馈神经网络,因为signal只有一个流向(从输入到输出)。
反向传播
反向传播算法用于训练MLP,反向传播算法可以计算出关于每个单个模型参数的网络错误的梯度,从而找出应该如何调节每个连接权重和每个偏执以减小error, 一旦得到这些梯度,它便会执行常规的Gradient Descent步骤,然后重复整个过程,直到网络收敛到解。
- 它一次处理一个小批量(例如,每个包含32个实例),并且多次经历整个训练集。每次通过都称为一个epoch。
- 每个batch都传递到网络的输入层,然后将其发送到第一个隐藏层。然后,该算法将计算该层中所有神经元的输出(对于batch中的每个实例)。结果传递到下一层,计算其输出并传递到下一层,依此类推,直到获得最后一层的输出,即输出层,这就是前向遍历。除此之外,还保留了所有中间结果,因为之后的后向遍历仍需要这些中间结果。
- 接下来,该算法将测量网络的error(即该算法使用损失函数,将期望的输出与网络的实际输出进行比较,并返回error)。
- 然后,它计算每个输出连接对错误的贡献程度。这是通过应用链式规则(可能是微积分中最基本的规则)来分析完成的,这使此步骤变得快速而精确。
- 然后,算法再次使用链式规则来测量这些错误贡献中有多少是来自下面层中每个连接的错误贡献,一直进行到算法到达输入层为止。如前所述,这种反向传递通过在网络中向后传播误差梯度,从而有效地测量了网络中所有连接权重上的误差梯度
- 最后,该算法执行梯度下降步骤,以使用刚刚计算的误差梯度来调整网络中的所有连接权重。
- 该算法非常重要,值得再次总结:对于每个训练实例,反向传播算法首先进行预测(正向传递)并测量误差,然后反向遍历每一层以测量来自每个连接的误差贡献(反向 通过),最后调整连接权重以减少错误(渐变下降步骤)。
为了使反向传播算法起作用,阶跃函数被替换为sigmoid函数
σ(z) = 1 / (1 + exp(–z))
除此之外,反向传播算法还可以和其他的激活函数一起工作,比如:
- 双曲正切函数
tanh(z) = 2σ(2z) – 1 - ReLU函数
ReLU(z) = max(0, z)
为什么需要激活函数?
如果在层和层之间没有非线性函数的话,多个线性层的堆叠其效果和单个线性层是相同的,一个带有非线性成分的足够大的DNN在理论上是可以近似任何函数的。
Regression MLPS
Classification MLPS
Exercise1
Tensorflow PlayGround
Implementing MLPs with Keras
使用 Sequential API构建图片分类器
加载数据集
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
#The training set contains 60,000 grayscale images, each 28x28 pixels:
X_train_full.shape #(60000,28,28)
数据集已经分为了训练集和测试集,但是还没有验证集,需要在创建一个,因为需要使用梯度下降训练神经网络,需要对特征进行缩放,(除以255.0),使之便成为0到1之间的浮点数。
X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test / 255.
查看是什么东西(28X28的灰度值图片)
plt.imshow(X_train[0], cmap="binary")
#plt.axis('off')
plt.show()
y值对应的东西名称:
y_train#array([4, 0, 7, ..., 3, 0, 5], dtype=uint8)
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat","Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
class_names[y_train[0]]#'Coat'
看看数据集中的其他东西都长什么样子:
n_rows = 4
n_cols = 10
plt.figure(figsize=(n_cols * 1.2, n_rows * 1.2))
for row in range(n_rows):
for col in range(n_cols):
index = n_cols * row + col
plt.subplot(n_rows, n_cols, index + 1)
plt.imshow(X_train[index], cmap="binary", interpolation="nearest")
plt.axis('off')
plt.title(class_names[y_train[index]], fontsize=12)
plt.subplots_adjust(wspace=0.2, hspace=0.5)
save_fig('fashion_mnist_plot', tight_layout=False)
plt.show()
Creating the model using the Sequential API
使用keras的API构建神经网络:
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
- 第一行创建一个顺序模型。 这是用于神经网络的最简单的Keras模型,它仅由顺序连接的一堆单层组成。 这称为顺序API。
- 接下来,我们构建第一层并将其添加到模型中。 它是Flatten层,其作用是将每个输入图像转换为一维数组:如果接收到输入数据X,则计算X.reshape(-1,1)。 该层没有任何参数。 它只是在那里做一些简单的预处理。 由于它是模型中的第一层,因此您应该指定input_shape,其中不包括批次大小,而仅包括实例的形状。
- 然后添加一个具有300个神经元的dense层,使用ReLU激活函数,每个dense层都维护自己的权重矩阵,其中包括所有输入和神经元之间的连接权重,它还管理一个偏置项的权重的向量(每个神经元一个)
- 然后,我们还使用ReLU激活功能添加第二个具有100个神经元的密集隐藏层。
- 最后,我们使用softmax激活函数添加一个包含10个神经元的密集输出层(每个类一个)(因为这些类是互斥的)。
可以统一写为:
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(300, activation="relu"),
keras.layers.Dense(100, activation=