Python Deep Learning 简明教程

Python Deep Learning - Implementations

在这个深度学习的实现中,我们的目标是为一家特定的银行预测客户流失或流失数据,即可能离开这家银行服务的客户。使用的数据集相对较小,包含 10000 行,14 列。我们使用 Anaconda 发行版和 Theano、TensorFlow 和 Keras 等框架。Keras 构建在以 Tensorflow 和 Theano 为后端的代码之上。

# Artificial Neural Network
# Installing Theano
pip install --upgrade theano

# Installing Tensorflow
pip install –upgrade tensorflow

# Installing Keras
pip install --upgrade keras

Step 1: Data preprocessing

In[]:

# Importing the libraries
   import numpy as np
   import matplotlib.pyplot as plt
   import pandas as pd

# Importing the database
   dataset = pd.read_csv('Churn_Modelling.csv')

Step 2

我们创建了数据集的特征矩阵和目标变量,即第 14 列,标记为“Exited”。

数据的初始外观如下所示 −

In[]:
X = dataset.iloc[:, 3:13].values
Y = dataset.iloc[:, 13].values
X

Output

step output

Step 3

Y

Output

array([1, 0, 1, ..., 1, 1, 0], dtype = int64)

Step 4

通过对字符串变量进行编码简化分析。我们使用 ScikitLearn 函数“LabelEncoder”自动对列中的不同标签进行编码,值介于 0 到 n_classes-1 之间。

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_X_1 = LabelEncoder()
X[:,1] = labelencoder_X_1.fit_transform(X[:,1])
labelencoder_X_2 = LabelEncoder()
X[:, 2] = labelencoder_X_2.fit_transform(X[:, 2])
X

Output

step4 output

在上面的结果中,国家名称已替换为 0、1 和 2;而男性和女性已替换为 0 和 1。

Step 5

Labelling Encoded Data

我们使用相同的 ScikitLearn 库和另一个名为 OneHotEncoder 的函数,只是为了传递列号,以创建一个哑变量。

onehotencoder = OneHotEncoder(categorical features = [1])
X = onehotencoder.fit_transform(X).toarray()
X = X[:, 1:]
X

现在,前 2 列表示国家,第 4 列表示性别。

Output

step5 output

我们总是将我们的数据分为训练和测试部分;我们在训练数据上训练我们的模型,然后我们检查模型在测试数据上的准确性,这有助于评估模型的效率。

Step 6

我们使用 ScikitLearn 的 train_test_split 函数将我们的数据拆分为训练集和测试集。我们将训练与测试的拆分比例保持为 80:20。

#Splitting the dataset into the Training set and the Test Set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

一些变量的值为数千,而另一些变量的值为十或一。我们对数据进行缩放,以便它们更具代表性。

Step 7

在这个代码中,我们使用 StandardScaler 函数对训练数据进行拟合和转换。我们对缩放进行标准化,以便使用相同拟合的方法来转换/缩放测试数据。

# Feature Scaling
fromsklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

Output

step7 output

现在数据已正确缩放。最后,我们完成了数据预处理。现在,我们将从我们的模型开始。

Step 8

我们在这里导入所需的模块。我们需要顺序模块来初始化神经网络,需要密集模块来添加隐藏层。

# Importing the Keras libraries and packages
import keras
from keras.models import Sequential
from keras.layers import Dense

Step 9

我们将模型命名为 Classifier,因为我们的目标是对客户流失进行分类。然后我们使用 Sequential 模块进行初始化。

#Initializing Neural Network
classifier = Sequential()

Step 10

我们使用 dense 函数逐个添加隐藏层。在下面的代码中,我们将看到许多参数。

我们的第一个参数是 output_dim 。它是我们添加到此层的节点数。 init 是随机梯度下降的初始化。在神经网络中,我们为每个节点分配权重。在初始化时,权重应接近于零,并且我们使用均匀函数随机初始化权重。只为第一层需要 input_dim 参数,因为模型不知道我们输入变量的数量。在此,输入变量的总数为 11。在第二层,模型自动从第一隐藏层了解输入变量的数量。

执行以下代码行以添加输入层和第一隐藏层 −

classifier.add(Dense(units = 6, kernel_initializer = 'uniform',
activation = 'relu', input_dim = 11))

执行以下代码行以添加第二隐藏层 −

classifier.add(Dense(units = 6, kernel_initializer = 'uniform',
activation = 'relu'))

执行以下代码行以添加输出层 −

classifier.add(Dense(units = 1, kernel_initializer = 'uniform',
activation = 'sigmoid'))

Step 11

Compiling the ANN

我们现在已向分类器添加了多层。我们现在将使用 compile 方法编译它们。在最终编译中添加的参数控制完成神经网络。所以,我们在这一步中需要小心。

以下是参数的简要说明。

第一个参数是 Optimizer 。它是一种用于找到最佳权重设置的算法。这个算法称为 Stochastic Gradient Descent (SGD) 。我们会从多种类型中使用一种,即“Adam 优化器”。SGD 取决于损失,所以我们的第二个参数是损失。如果我们的因变量是二元的,我们使用称为 ‘binary_crossentropy’ 的对数损失函数。如果我们的因变量在输出中有多于两类,我们使用 ‘categorical_crossentropy’ 。我们希望基于 accuracy 改善神经网络的性能,所以我们添加 metrics 作为一个准确度。

# Compiling Neural Network
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

Step 12

此步骤需要执行一些代码。

Fitting the ANN to the Training Set

现在,我们对训练数据训练我们的模型。我们使用 fit 方法来拟合我们的模型。我们还优化权重以提高模型效率。为此,我们必须更新权重。 Batch size 是我们在更新权重后的观察次数。 Epoch 是迭代总数。我们会通过实验法选择批次大小和轮次的值。

classifier.fit(X_train, y_train, batch_size = 10, epochs = 50)

Making predictions and evaluating the model

# Predicting the Test set results
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)

Predicting a single new observation

# Predicting a single new observation
"""Our goal is to predict if the customer with the following data will leave the bank:
Geography: Spain
Credit Score: 500
Gender: Female
Age: 40
Tenure: 3
Balance: 50000
Number of Products: 2
Has Credit Card: Yes
Is Active Member: Yes

Step 13

Predicting the test set result

预测结果会告诉你客户离开公司的可能性。我们会将该可能性转换为二进制 0 和 1。

# Predicting the Test set results
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)
new_prediction = classifier.predict(sc.transform
(np.array([[0.0, 0, 500, 1, 40, 3, 50000, 2, 1, 1, 40000]])))
new_prediction = (new_prediction > 0.5)

Step 14

这是最后一步,我们将评估模型性能。我们已经有了原始结果,因此我们可以构建混淆矩阵来检查我们模型的准确度。

Making the Confusion Matrix

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print (cm)

Output

loss: 0.3384 acc: 0.8605
[ [1541 54]
[230 175] ]

从混淆矩阵来看,我们模型的准确率可以计算为 −

Accuracy = 1541+175/2000=0.858

We achieved 85.8% accuracy ,这是好的。

The Forward Propagation Algorithm

在本节中,我们将会学习如何编写代码来对简单的神经网络进行正向传播(预测) −

forward propagation algorithm

每个数据点都是客户。第一个输入是他们有多少个帐户,第二个输入是他们有多少个孩子。该模型会预测用户明年会进行多少交易。

输入数据已作为输入数据预加载,权重都在一个称为 weights 的字典中。隐藏层中第一个节点的权重数组在 weights['node_0'] 中,隐藏层中第二个节点的权重数组则在 weights['node_1'] 中。

输入输出节点的权重在 weights 中可用。

The Rectified Linear Activation Function

“激活函数”是在每个节点中工作的函数。它将节点的输入转换为某些输出。

修正线性激活函数 (简称 ReLU) 广泛用于超高性能网络。该函数采用单个数字作为输入,如果输入为负数,则返回 0;如果输入为正数,则将其作为输出返回。

这里列出一些示例 −

  1. relu(4) = 4

  2. relu(-2) = 0

我们填写 relu() 函数的定义−

  1. 我们使用 max() 函数计算 relu() 的输出值。

  2. 我们对 node_0_input 应用 relu() 函数,计算 node_0_output。

  3. 我们将 relu() 函数应用于 node_1_input 以计算 node_1_output。

import numpy as np
input_data = np.array([-1, 2])
weights = {
   'node_0': np.array([3, 3]),
   'node_1': np.array([1, 5]),
   'output': np.array([2, -1])
}
node_0_input = (input_data * weights['node_0']).sum()
node_0_output = np.tanh(node_0_input)
node_1_input = (input_data * weights['node_1']).sum()
node_1_output = np.tanh(node_1_input)
hidden_layer_output = np.array(node_0_output, node_1_output)
output =(hidden_layer_output * weights['output']).sum()
print(output)

def relu(input):
   '''Define your relu activation function here'''
   # Calculate the value for the output of the relu function: output
   output = max(input,0)
      # Return the value just calculated
   return(output)
# Calculate node 0 value: node_0_output
node_0_input = (input_data * weights['node_0']).sum()
node_0_output = relu(node_0_input)

# Calculate node 1 value: node_1_output
node_1_input = (input_data * weights['node_1']).sum()
node_1_output = relu(node_1_input)

# Put node values into array: hidden_layer_outputs
hidden_layer_outputs = np.array([node_0_output, node_1_output])

# Calculate model output (do not apply relu)
odel_output = (hidden_layer_outputs * weights['output']).sum()
print(model_output)# Print model output

Output

0.9950547536867305
-3

Applying the network to many Observations/rows of data

在本节中,我们将学习如何定义一个名为 predict_with_network() 的函数。此函数将生成对多个数据观测的预测,这些观测取自以上网络,作为 input_data。使用以上网络中给出的权重。relu() 函数定义也正在使用中。

让我们定义一个名为 predict_with_network() 的函数,该函数接受两个参数 - input_data_row 和 weights - 并返回来自网络的预测作为输出。

我们计算每个节点的输入和输出值,将它们存储为:node_0_input、node_0_output、node_1_input 和 node_1_output。

要计算节点的输入值,我们将相关数组相乘并计算它们的和。

要计算节点的输出值,我们将 relu() 函数应用于节点的输入值。我们使用“for 循环”来迭代 input_data -

我们还使用 predict_with_network() 为 input_data 中的每一行(input_data_row)生成预测。我们还将每个预测附加到 results 中。

# Define predict_with_network()
def predict_with_network(input_data_row, weights):
   # Calculate node 0 value
   node_0_input = (input_data_row * weights['node_0']).sum()
   node_0_output = relu(node_0_input)

   # Calculate node 1 value
   node_1_input = (input_data_row * weights['node_1']).sum()
   node_1_output = relu(node_1_input)

   # Put node values into array: hidden_layer_outputs
   hidden_layer_outputs = np.array([node_0_output, node_1_output])

   # Calculate model output
   input_to_final_layer = (hidden_layer_outputs*weights['output']).sum()
   model_output = relu(input_to_final_layer)
# Return model output
   return(model_output)

# Create empty list to store prediction results
results = []
for input_data_row in input_data:
   # Append prediction to results
   results.append(predict_with_network(input_data_row, weights))
print(results)# Print results

Output

[0, 12]

这里我们使用了 relu 函数,其中 relu(26) = 26,而 relu(-13) = 0,以此类推。

Deep multi-layer neural networks

这里我们正在编写代码来对具有两个隐藏层的神经网络进行前向传播。每个隐藏层有两个节点。输入数据已预加载为 input_data 。第一个隐藏层中的节点称为 node_0_0 和 node_0_1。

它们的权重分别预加载为 weights['node_0_0'] 和 weights['node_0_1']。

第二个隐藏层中的节点称为 node_1_0 and node_1_1 。它们的权重分别预加载为 weights['node_1_0']weights['node_1_1']

然后我们使用预加载为 weights['output'] 的权重从隐藏节点创建模型输出。

deep multi layer

我们使用其权重 weights['node_0_0'] 和给定的 input_data 计算 node_0_0_input。然后应用 relu() 函数以获得 node_0_0_output。

我们对 node_0_1_input 做与上面相同的事,以获得 node_0_1_output。

我们使用其权重 weights['node_1_0'] 和来自第一个隐藏层输出 hidden_0_outputs 计算 node_1_0_input。然后我们应用 relu() 函数以获得 node_1_0_output。

我们对 node_1_1_input 做与上面相同的事,以获得 node_1_1_output。

我们使用 weights['output'] 和来自第二个隐藏层 hidden_1_outputs 数组的输出计算 model_output。我们不对此输出应用 relu() 函数。

multi hidden layer
import numpy as np
input_data = np.array([3, 5])
weights = {
   'node_0_0': np.array([2, 4]),
   'node_0_1': np.array([4, -5]),
   'node_1_0': np.array([-1, 1]),
   'node_1_1': np.array([2, 2]),
   'output': np.array([2, 7])
}
def predict_with_network(input_data):
   # Calculate node 0 in the first hidden layer
   node_0_0_input = (input_data * weights['node_0_0']).sum()
   node_0_0_output = relu(node_0_0_input)

   # Calculate node 1 in the first hidden layer
   node_0_1_input = (input_data*weights['node_0_1']).sum()
   node_0_1_output = relu(node_0_1_input)

   # Put node values into array: hidden_0_outputs
   hidden_0_outputs = np.array([node_0_0_output, node_0_1_output])

   # Calculate node 0 in the second hidden layer
   node_1_0_input = (hidden_0_outputs*weights['node_1_0']).sum()
   node_1_0_output = relu(node_1_0_input)

   # Calculate node 1 in the second hidden layer
   node_1_1_input = (hidden_0_outputs*weights['node_1_1']).sum()
   node_1_1_output = relu(node_1_1_input)

   # Put node values into array: hidden_1_outputs
   hidden_1_outputs = np.array([node_1_0_output, node_1_1_output])

   # Calculate model output: model_output
   model_output = (hidden_1_outputs*weights['output']).sum()
      # Return model_output
   return(model_output)
output = predict_with_network(input_data)
print(output)

Output

364