作者|Angel Das
编译|VK
起源|Towards Datas Science
介绍
人工神经网络(ANNs)是机器学习技术的高级版本,是深度学习的外围。人工神经网络波及以下概念。输入输出层、暗藏层、暗藏层下的神经元、正向流传和反向流传。
简略地说,输出层是一组自变量,输入层代表最终的输入(因变量),暗藏层由神经元组成,在那里利用方程和激活函数。前向流传探讨方程的具体模式以取得最终输入,而反向流传则计算梯度降落以相应地更新参数。无关操作流程的更多信息,请参阅上面的文章。
https://towardsdatascience.co...
深层神经网络
当一个ANN蕴含一个很深的暗藏层时,它被称为深度神经网络(DNN)。DNN具备多个权重和偏差项,每一个都须要训练。反向流传能够确定如何调整所有神经元的每个权重和每个偏差项,以缩小误差。除非网络收敛到最小误差,否则该过程将反复。
算法步骤如下:
- 失去训练和测试数据以训练和验证模型的输入。所有波及相关性、离群值解决的统计假设依然无效,必须加以解决。
- 输出层由自变量及其各自的值组成。训练集分为多个batch。训练集残缺的训练完称为一个epoch。epoch越多,训练工夫越长
- 每个batch被传递到输出层,输出层将其发送到第一个暗藏层。计算该层中所有神经元的输入(对于每一个小批量)。后果被传递到下一层,这个过程反复,直到咱们失去最初一层的输入,即输入层。这是前向流传:就像做预测一样,除了所有两头后果都会被保留,因为它们是反向流传所须要的
- 而后应用损失函数测量网络的输入误差,该函数将冀望输入与网络的理论输入进行比拟
- 计算了每个参数对误差项的奉献
- 该算法依据学习速率(反向流传)执行梯度降落来调整权重和参数,并且该过程会反复进行
重要的是随机初始化所有暗藏层的权重,否则训练将失败。
例如,如果将所有权重和偏移初始化为零,则给定层中的所有神经元将完全相同,因而反向流传将以完全相同的形式影响它们,因而它们将放弃雷同。换句话说,只管每层有数百个神经元,但你的模型将体现得如同每层只有一个神经元:它不会太聪慧。相同,如果你随机初始化权重,你就突破了对称性,容许反向流传来训练不同的神经元
激活函数
激活函数是梯度降落的要害。梯度降落不能在立体上挪动,因而有一个定义良好的非零导数是很重要的,以使梯度降落在每一步都获得停顿。Sigmoid通常用于logistic回归问题,然而,也有其余风行的抉择。
双曲正切函数
这个函数是S形的,间断的,输入范畴在-1到+1之间。在训练开始时,每一层的输入或多或少都以0为核心,因而有助于更快地收敛。
整流线性单元
对于小于0的输出,它是不可微的。对于其余状况,它产生良好的输入,更重要的是具备更快的计算速度。函数没有最大输入,因而在梯度降落过程中可能呈现的一些问题失去了很好的解决。
为什么咱们须要激活函数?
假如f(x)=2x+5和g(x)=3x-1。两个输出项的权重是不同的。在链接这些函数时,咱们失去的是,f(g(x))=2(3x-1)+5=6x+3,这又是一个线性方程。非线性的缺失体现为深层神经网络中等价于一个线性方程。这种状况下的简单问题空间无奈解决。
损失函数
在解决回归问题时,咱们不须要为输入层应用任何激活函数。在训练回归问题时应用的损失函数是均方误差。然而,训练集中的异样值能够用均匀绝对误差来解决。Huber损失也是基于回归的工作中宽泛应用的误差函数。
当误差小于阈值t(大多为1)时,Huber损失是二次的,但当误差大于t时,Huber损失是线性的。与均方误差相比,线性局部使其对异样值不太敏感,并且二次局部比均匀绝对误差更快地收敛和更准确的数字。
分类问题通常应用二分类穿插熵、多分类穿插熵或稠密分类穿插熵。二分类穿插熵用于二分类,而多分类或稠密分类穿插熵用于多类分类问题。你能够在上面的链接中找到无关损失函数的更多详细信息。
注:分类穿插熵用于因变量的one-hot示意,当标签作为整数提供时,应用稠密分类穿插熵。
https://keras.io/api/losses/
用Python开发ANN
咱们将应用Kaggle的信用数据开发一个应用Jupyter Notebook的欺诈检测模型。同样的办法也能够在google colab中实现。
数据集蕴含2013年9月欧洲持卡人通过信用卡进行的交易。此数据集显示两天内产生的交易,其中284807笔交易中有492宗欺诈。数据集高度不均衡,正类(欺诈)占所有交易的0.172%。
https://www.kaggle.com/mlg-ul...
import tensorflow as tfprint(tf.__version__)import pandas as pdimport numpy as npfrom sklearn.model_selection import train_test_splitimport tensorflow as tffrom sklearn import preprocessingfrom tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense, Dropout, BatchNormalizationfrom sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_score, precision_recall_curve, aucimport matplotlib.pyplot as pltfrom tensorflow.keras import optimizersimport seaborn as snsfrom tensorflow import kerasimport random as rnimport osos.environ["CUDA_VISIBLE_DEVICES"] = "3"PYTHONHASHSEED=0tf.random.set_seed(1234)np.random.seed(1234)rn.seed(1254)
数据集由以下属性组成。工夫、次要成分、金额和类别。更多信息请拜访Kaggle网站。
file = tf.keras.utilsraw_df = pd.read_csv(‘https://storage.googleapis.com/download.tensorflow.org/data/creditcard.csv')raw_df.head()
因为大多数属性都是主成分,所以相关性总是0。惟一可能出现异常值的列是amount。上面简要介绍一下这方面的统计数据。
count 284807.00mean 88.35std 250.12min 0.0025% 5.6050% 22.0075% 77.16max 25691.16Name: Amount, dtype: float64
异样值对于检测欺诈行为至关重要,因为根本假如是,较高的交易量可能是欺诈流动的迹象。然而,箱线图并没有揭示任何具体的趋势来验证上述假如。
筹备输入输出和训练测试数据
X_data = credit_data.iloc[:, :-1]y_data = credit_data.iloc[:, -1]X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.2, random_state = 7)X_train = preprocessing.normalize(X_train)
数量和主成分剖析变量应用不同的尺度,因而数据集是标准化的。标准化在梯度降落中起着重要作用。标准化数据的收敛速度要快得多。
print(X_train.shape)print(X_test.shape)print(y_train.shape)print(y_test.shape)
输入:
(227845, 29) #记录数x列数(56962, 29)(227845,)(56962,)
开发神经网络层
下面的输入表明咱们有29个自变量要解决,因而输出层的形态是29。任何人工神经网络架构的个别构造概述如下。
+----------------------------+----------------------------+ | Hyper Parameter | Binary Classification | +----------------------------+----------------------------+ | # input neurons | One per input feature | | # hidden layers | Typically 1 to 5 | | # neurons per hidden layer | Typically 10 to 100 | | # output neurons | 1 per prediction dimension | | Hidden activation | ReLU, Tanh, sigmoid | | Output layer activation | Sigmoid | | Loss function | Binary Cross Entropy | +----------------------------+----------------------------++-----------------------------------+----------------------------+ | Hyper Parameter | Multiclass Classification | +-----------------------------------+----------------------------+ | # input neurons | One per input feature | | # hidden layers | Typically 1 to 5 | | # neurons per hidden layer | Typically 10 to 100 | | # output neurons | 1 per prediction dimension | | Hidden activation | ReLU, Tanh, sigmoid | | Output layer activation | Softmax | | Loss function | "Categorical Cross Entropy | | Sparse Categorical Cross Entropy" | | +-----------------------------------+----------------------------+
Dense函数的输出
- units — 输入尺寸
- activation — 激活函数,如果未指定,则不应用任何内容
- use_bias — 布尔值,如果应用偏置项
- kernel_initializer — 核权重的初始值设定项
- bias_initializer —偏置向量的初始值设定项。
model = Sequential(layers=None, name=None)model.add(Dense(10, input_shape = (29,), activation = 'tanh'))model.add(Dense(5, activation = 'tanh'))model.add(Dense(1, activation = 'sigmoid'))sgd = optimizers.Adam(lr = 0.001)model.compile(optimizer = sgd, loss = 'binary_crossentropy', metrics=['accuracy'])
体系结构摘要
model.summary()Model: "sequential"_________________________________________________________________Layer (type) Output Shape Param # =================================================================dense (Dense) (None, 10) 300 _________________________________________________________________dense_1 (Dense) (None, 5) 55 _________________________________________________________________dense_2 (Dense) (None, 1) 6 =================================================================Total params: 361Trainable params: 361Non-trainable params: 0_________________________________________________________________
让咱们试着了解下面的输入(输入阐明应用两个暗藏层提供):
- 咱们创立了一个具备一个输出、两个暗藏和一个输入层的神经网络
- 输出层有29个变量和10个神经元。所以权重矩阵的形态是10 x 29,而偏置矩阵的形态是10 x 1
- 第1层参数总数=10 x 29+10 x 1=300
- 第一层有10个输入值,应用tanh作为激活函数。第二层有5个神经元和10个输出,因而权重矩阵为5×10,偏置矩阵为5×1
- 第2层总参数=5 x 10+5 x 1=55
- 最初,输入层有一个神经元,然而它有5个不同于暗藏层2的输出,并且有一个偏置项,因而神经元的数量=5+1=6
model.fit(X_train, y_train.values, batch_size = 2000, epochs = 20, verbose = 1)Epoch 1/20114/114 [==============================] - 0s 2ms/step - loss: 0.3434 - accuracy: 0.9847Epoch 2/20114/114 [==============================] - 0s 2ms/step - loss: 0.1029 - accuracy: 0.9981Epoch 3/20114/114 [==============================] - 0s 2ms/step - loss: 0.0518 - accuracy: 0.9983Epoch 4/20114/114 [==============================] - 0s 2ms/step - loss: 0.0341 - accuracy: 0.9986Epoch 5/20114/114 [==============================] - 0s 2ms/step - loss: 0.0255 - accuracy: 0.9987Epoch 6/20114/114 [==============================] - 0s 1ms/step - loss: 0.0206 - accuracy: 0.9988Epoch 7/20114/114 [==============================] - 0s 1ms/step - loss: 0.0174 - accuracy: 0.9988Epoch 8/20114/114 [==============================] - 0s 1ms/step - loss: 0.0152 - accuracy: 0.9988Epoch 9/20114/114 [==============================] - 0s 1ms/step - loss: 0.0137 - accuracy: 0.9989Epoch 10/20114/114 [==============================] - 0s 1ms/step - loss: 0.0125 - accuracy: 0.9989Epoch 11/20114/114 [==============================] - 0s 2ms/step - loss: 0.0117 - accuracy: 0.9989Epoch 12/20114/114 [==============================] - 0s 2ms/step - loss: 0.0110 - accuracy: 0.9989Epoch 13/20114/114 [==============================] - 0s 1ms/step - loss: 0.0104 - accuracy: 0.9989Epoch 14/20114/114 [==============================] - 0s 1ms/step - loss: 0.0099 - accuracy: 0.9989Epoch 15/20114/114 [==============================] - 0s 1ms/step - loss: 0.0095 - accuracy: 0.9989Epoch 16/20114/114 [==============================] - 0s 1ms/step - loss: 0.0092 - accuracy: 0.9989Epoch 17/20114/114 [==============================] - 0s 1ms/step - loss: 0.0089 - accuracy: 0.9989Epoch 18/20114/114 [==============================] - 0s 1ms/step - loss: 0.0087 - accuracy: 0.9989Epoch 19/20114/114 [==============================] - 0s 1ms/step - loss: 0.0084 - accuracy: 0.9989Epoch 20/20114/114 [==============================] - 0s 1ms/step - loss: 0.0082 - accuracy: 0.9989
评估输入
X_test = preprocessing.normalize(X_test)results = model.evaluate(X_test, y_test.values)1781/1781 [==============================] - 1s 614us/step - loss: 0.0086 - accuracy: 0.9989
用Tensor Board剖析学习曲线
TensorBoard是一个很好的交互式可视化工具,可用于查看训练期间的学习曲线、比拟多个运行的学习曲线、剖析训练指标等。此工具随TensorFlow主动装置。
import osroot_logdir = os.path.join(os.curdir, “my_logs”)def get_run_logdir(): import time run_id = time.strftime(“run_%Y_%m_%d-%H_%M_%S”) return os.path.join(root_logdir, run_id) run_logdir = get_run_logdir()tensorboard_cb = keras.callbacks.TensorBoard(run_logdir)model.fit(X_train, y_train.values, batch_size = 2000, epochs = 20, verbose = 1, callbacks=[tensorboard_cb])%load_ext tensorboard%tensorboard --logdir=./my_logs --port=6006
超参调节
如前所述,对于一个问题空间,有多少暗藏层或多少神经元最适宜,并没有预约义的规定。咱们能够应用随机化searchcv或GridSearchCV来超调一些参数。可微调的参数概述如下:
- 暗藏层数
- 暗藏层神经元
- 优化器
- 学习率
- epoch
申明函数以开发模型
def build_model(n_hidden_layer=1, n_neurons=10, input_shape=29): # 创立模型 model = Sequential() model.add(Dense(10, input_shape = (29,), activation = 'tanh'))for layer in range(n_hidden_layer): model.add(Dense(n_neurons, activation="tanh"))model.add(Dense(1, activation = 'sigmoid')) # 编译模型model.compile(optimizer ='Adam', loss = 'binary_crossentropy', metrics=['accuracy']) return model
应用包装类克隆模型
from sklearn.base import clone keras_class = tf.keras.wrappers.scikit_learn.KerasClassifier(build_fn = build_model,nb_epoch = 100, batch_size=10)clone(keras_class)keras_class.fit(X_train, y_train.values)
创立随机搜寻网格
from scipy.stats import reciprocalfrom sklearn.model_selection import RandomizedSearchCVparam_distribs = { “n_hidden_layer”: [1, 2, 3], “n_neurons”: [20, 30],# “learning_rate”: reciprocal(3e-4, 3e-2),# “opt”:[‘Adam’]}rnd_search_cv = RandomizedSearchCV(keras_class, param_distribs, n_iter=10, cv=3)rnd_search_cv.fit(X_train, y_train.values, epochs=5)
查看最佳参数
rnd_search_cv.best_params_{'n_neurons': 30, 'n_hidden_layer': 3}rnd_search_cv.best_score_model = rnd_search_cv.best_estimator_.model
优化器也应该微调,因为它们影响梯度降落、收敛和学习速率的主动调整。
- Adadelta -Adadelta是Adagrad的一个更强壮的扩大,它基于梯度更新的挪动窗口来调整学习速率,而不是累积所有过来的梯度
- 随机梯度降落-罕用。须要应用搜寻网格微调学习率
- Adagrad-对于所有参数和其余优化器的每个周期,学习速率都是恒定的。然而,Adagrad在解决误差函数导数时,会扭转每个参数的学习速率“”,并在每个工夫步长“t”处扭转
- ADAM-ADAM(自适应矩预计)利用一阶和二阶动量来避免跳越部分极小值,放弃了过来梯度的指数衰减平均值
一般来说,通过减少层的数量而不是每层神经元的数量,能够取得更好的输入。
参考文献
Aurelien Geron (2017). Hands-on machine learning with Scikit-Learn and TensorFlow : concepts, tools, and techniques to build intelligent systems. Sebastopol, Ca: O’reilly Media
原文链接:https://towardsdatascience.co...
欢送关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官网文档:
http://sklearn123.com/
欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/