Học sâu Python - Triển khai

Trong quá trình triển khai Deep learning này, mục tiêu của chúng tôi là dự đoán mức độ tiêu thụ hoặc xáo trộn dữ liệu của khách hàng đối với một ngân hàng nhất định - những khách hàng có khả năng rời bỏ dịch vụ ngân hàng này. Tập dữ liệu được sử dụng tương đối nhỏ và chứa 10000 hàng với 14 cột. Chúng tôi đang sử dụng phân phối Anaconda và các khuôn khổ như Theano, TensorFlow và Keras. Keras được xây dựng dựa trên Tensorflow và Theano có chức năng như các phụ trợ của nó.

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

# Installing Tensorflow
pip install –upgrade tensorflow

# Installing Keras
pip install --upgrade keras

Bước 1: Xử lý trước dữ liệu

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')

Bước 2

Chúng tôi tạo ma trận các tính năng của tập dữ liệu và biến mục tiêu, là cột 14, được gắn nhãn là “Đã thoát”.

Giao diện ban đầu của dữ liệu như hình dưới đây:

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

Đầu ra

Bước 3

Y

Đầu ra

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

Bước 4

Chúng tôi làm cho phân tích đơn giản hơn bằng cách mã hóa các biến chuỗi. Chúng tôi đang sử dụng chức năng ScikitLearn 'LabelEncoder' để tự động mã hóa các nhãn khác nhau trong các cột có giá trị từ 0 đến 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

Đầu ra

Trong kết quả trên, tên quốc gia được thay thế bằng 0, 1 và 2; trong khi nam và nữ được thay thế bằng 0 và 1.

Bước 5

Labelling Encoded Data

Chúng tôi sử dụng cùng một ScikitLearn thư viện và một chức năng khác được gọi là OneHotEncoder để chỉ cần chuyển số cột tạo ra một biến giả.

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

Bây giờ, 2 cột đầu tiên đại diện cho quốc gia và cột thứ 4 đại diện cho giới tính.

Đầu ra

Chúng tôi luôn chia dữ liệu của mình thành phần đào tạo và kiểm tra; chúng tôi đào tạo mô hình của mình trên dữ liệu đào tạo và sau đó chúng tôi kiểm tra độ chính xác của một mô hình trên dữ liệu thử nghiệm, giúp đánh giá hiệu quả của mô hình.

Bước 6

Chúng tôi đang sử dụng ScikitLearn's train_test_splitchức năng chia dữ liệu của chúng tôi thành tập huấn luyện và tập kiểm tra. Chúng tôi giữ tỷ lệ phân chia giữa chuyến tàu và bài kiểm tra là 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)

Một số biến có giá trị hàng nghìn trong khi một số biến có giá trị hàng chục hoặc đơn vị. Chúng tôi chia tỷ lệ dữ liệu để chúng mang tính đại diện hơn.

Bước 7

Trong mã này, chúng tôi đang điều chỉnh và chuyển đổi dữ liệu đào tạo bằng cách sử dụng StandardScalerchức năng. Chúng tôi chuẩn hóa quy mô của mình để chúng tôi sử dụng cùng một phương pháp phù hợp để chuyển đổi / chia tỷ lệ dữ liệu thử nghiệm.

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

Đầu ra

Dữ liệu hiện đã được chia tỷ lệ thích hợp. Cuối cùng, chúng tôi đã hoàn tất việc xử lý trước dữ liệu của mình. Bây giờ, chúng ta sẽ bắt đầu với mô hình của mình.

Bước 8

Chúng tôi nhập các Mô-đun cần thiết tại đây. Chúng ta cần mô-đun Tuần tự để khởi tạo mạng nơ-ron và mô-đun dày đặc để thêm các lớp ẩn.

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

Bước 9

Chúng tôi sẽ đặt tên cho mô hình là Bộ phân loại vì mục đích của chúng tôi là phân loại thời gian nghỉ của khách hàng. Sau đó, chúng tôi sử dụng mô-đun Tuần tự để khởi tạo.

#Initializing Neural Network 
classifier = Sequential()

Bước 10

Chúng tôi thêm từng lớp ẩn một bằng cách sử dụng hàm dày đặc. Trong đoạn mã dưới đây, chúng ta sẽ thấy nhiều đối số.

Tham số đầu tiên của chúng tôi là output_dim. Đó là số lượng nút mà chúng tôi thêm vào lớp này.initlà sự khởi tạo của Stochastic Gradient Decent. Trong mạng Neural, chúng tôi gán trọng số cho mỗi nút. Khi khởi tạo, trọng số phải gần bằng 0 và chúng tôi khởi tạo ngẫu nhiên các trọng số bằng cách sử dụng hàm thống nhất. Cácinput_dimchỉ cần tham số cho lớp đầu tiên, vì mô hình không biết số lượng biến đầu vào của chúng ta. Ở đây tổng số biến đầu vào là 11. Trong lớp thứ hai, mô hình tự động biết số lượng biến đầu vào từ lớp ẩn đầu tiên.

Thực thi dòng mã sau để thêm lớp đầu vào và lớp ẩn đầu tiên -

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

Thực thi dòng mã sau để thêm lớp ẩn thứ hai:

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

Thực thi dòng mã sau để thêm lớp đầu ra -

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

Bước 11

Compiling the ANN

Chúng tôi đã thêm nhiều lớp vào trình phân loại của mình cho đến bây giờ. Bây giờ chúng tôi sẽ biên dịch chúng bằng cách sử dụngcompilephương pháp. Các đối số được thêm vào trong điều khiển biên dịch cuối cùng sẽ hoàn thành mạng nơ-ron. Vì vậy, chúng ta cần cẩn thận trong bước này.

Đây là một giải thích ngắn gọn về các đối số.

Đối số đầu tiên là OptimizerĐây là một thuật toán dùng để tìm tập trọng số tối ưu. Thuật toán này được gọi làStochastic Gradient Descent (SGD). Ở đây chúng tôi đang sử dụng một trong số nhiều loại, được gọi là 'Trình tối ưu hóa Adam'. SGD phụ thuộc vào tổn thất, vì vậy tham số thứ hai của chúng ta là tổn thất. Nếu biến phụ thuộc của chúng ta là nhị phân, chúng ta sử dụng hàm mất logarit được gọi là‘binary_crossentropy’và nếu biến phụ thuộc của chúng tôi có nhiều hơn hai danh mục ở đầu ra, thì chúng tôi sử dụng ‘categorical_crossentropy’. Chúng tôi muốn cải thiện hiệu suất của mạng nơ-ron của mình dựa trênaccuracy, vì vậy chúng tôi thêm metrics như độ chính xác.

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

Bước 12

Một số mã cần được thực hiện trong bước này.

Lắp ANN vào Bộ đào tạo

Bây giờ chúng tôi đào tạo mô hình của chúng tôi trên dữ liệu đào tạo. Chúng tôi sử dụngfitphương pháp để phù hợp với mô hình của chúng tôi. Chúng tôi cũng tối ưu hóa trọng số để cải thiện hiệu quả của mô hình. Đối với điều này, chúng tôi phải cập nhật trọng số.Batch size là số lần quan sát mà sau đó chúng tôi cập nhật trọng số. Epochlà tổng số lần lặp. Các giá trị của kích thước lô và kỷ nguyên được chọn bằng phương pháp thử và sai.

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

Đưa ra dự đoán và đánh giá mô hình

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

Dự đoán một quan sát mới

# 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

Bước 13

Predicting the test set result

Kết quả dự đoán sẽ cho bạn xác suất khách hàng rời bỏ công ty. Chúng tôi sẽ chuyển xác suất đó thành nhị phân 0 và 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)

Bước 14

Đây là bước cuối cùng mà chúng tôi đánh giá hiệu suất mô hình của mình. Chúng tôi đã có kết quả ban đầu và do đó chúng tôi có thể xây dựng ma trận nhầm lẫn để kiểm tra độ chính xác của mô hình của chúng tôi.

Making the Confusion Matrix

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

Đầu ra

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

Từ ma trận nhầm lẫn, Độ chính xác của mô hình của chúng tôi có thể được tính như sau:

Accuracy = 1541+175/2000=0.858

We achieved 85.8% accuracy, cái nào tốt.

Thuật toán lan truyền chuyển tiếp

Trong phần này, chúng ta sẽ học cách viết mã để truyền tiến (dự đoán) cho một mạng nơ-ron đơn giản -

Mỗi điểm dữ liệu là một khách hàng. Đầu vào đầu tiên là họ có bao nhiêu tài khoản và đầu vào thứ hai là họ có bao nhiêu con. Mô hình sẽ dự đoán người dùng thực hiện bao nhiêu giao dịch trong năm tới.

Dữ liệu đầu vào được tải trước dưới dạng dữ liệu đầu vào và các trọng số nằm trong một từ điển được gọi là trọng số. Mảng trọng số của nút đầu tiên trong lớp ẩn có trọng số là ['node_0'] và đối với nút thứ hai trong lớp ẩn có trọng số tương ứng là ['node_1'].

Các trọng lượng cấp vào nút đầu ra có sẵn trong các trọng số.

Chức năng kích hoạt tuyến tính chỉnh lưu

Một "chức năng kích hoạt" là một chức năng hoạt động tại mỗi nút. Nó chuyển đổi đầu vào của nút thành một số đầu ra.

Chức năng kích hoạt tuyến tính được chỉnh lưu (được gọi là ReLU ) được sử dụng rộng rãi trong các mạng hiệu suất rất cao. Hàm này nhận một số duy nhất làm đầu vào, trả về 0 nếu đầu vào là số âm và đầu vào là đầu ra nếu đầu vào là số dương.

Dưới đây là một số ví dụ -

  • relu (4) = 4
  • relu (-2) = 0

Chúng ta điền vào định nghĩa của hàm relu ()−

  • Chúng tôi sử dụng hàm max () để tính toán giá trị cho đầu ra của relu ().
  • Chúng tôi áp dụng hàm relu () cho node_0_input để tính toán node_0_output.
  • Chúng tôi áp dụng hàm relu () cho node_1_input để tính toán 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

Đầu ra

0.9950547536867305
-3

Áp dụng mạng cho nhiều Quan sát / hàng dữ liệu

Trong phần này, chúng ta sẽ tìm hiểu cách định nghĩa một hàm được gọi là dự đoán_with_network (). Hàm này sẽ tạo ra các dự đoán cho nhiều quan sát dữ liệu, được lấy từ mạng ở trên được lấy làm dữ liệu đầu vào. Các trọng số cho trong mạng trên đang được sử dụng. Định nghĩa hàm relu () cũng đang được sử dụng.

Hãy để chúng tôi định nghĩa một hàm được gọi là dự đoán_with_network () chấp nhận hai đối số - input_data_row và weights - và trả về một dự đoán từ mạng làm đầu ra.

Chúng tôi tính toán các giá trị đầu vào và đầu ra cho mỗi nút, lưu trữ chúng dưới dạng: node_0_input, node_0_output, node_1_input và node_1_output.

Để tính toán giá trị đầu vào của một nút, chúng ta nhân các mảng có liên quan với nhau và tính tổng của chúng.

Để tính toán giá trị đầu ra của một nút, chúng ta áp dụng hàm relu () cho giá trị đầu vào của nút. Chúng tôi sử dụng 'vòng lặp for' để lặp qua input_data -

Chúng tôi cũng sử dụng dự đoán_with_network () để tạo dự đoán cho mỗi hàng của dữ liệu đầu vào - input_data_row. Chúng tôi cũng thêm mỗi dự đoán vào kết quả.

# 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

Đầu ra

[0, 12]

Ở đây chúng ta đã sử dụng hàm relu trong đó relu (26) = 26 và relu (-13) = 0, v.v.

Mạng nơ-ron nhiều lớp sâu

Ở đây chúng tôi đang viết mã để thực hiện truyền chuyển tiếp cho một mạng nơ-ron có hai lớp ẩn. Mỗi lớp ẩn có hai nút. Dữ liệu đầu vào đã được tải trước dưới dạnginput_data. Các nút trong lớp ẩn đầu tiên được gọi là node_0_0 và node_0_1.

Trọng số của chúng được tải trước dưới dạng trọng số ['node_0_0'] và trọng số ['node_0_1'] tương ứng.

Các nút trong lớp ẩn thứ hai được gọi là node_1_0 and node_1_1. Trọng lượng của chúng được tải trước dưới dạngweights['node_1_0']weights['node_1_1'] tương ứng.

Sau đó, chúng tôi tạo đầu ra mô hình từ các nút ẩn bằng cách sử dụng các trọng số được tải trước dưới dạng weights['output'].

Chúng tôi tính toán node_0_0_input bằng cách sử dụng các trọng số của nó ['node_0_0'] và input_data đã cho. Sau đó áp dụng hàm relu () để lấy node_0_0_output.

Chúng ta làm tương tự như trên đối với node_0_1_input để lấy node_0_1_output.

Chúng tôi tính toán node_1_0_input bằng cách sử dụng các trọng số của nó ['node_1_0'] và kết quả đầu ra từ lớp ẩn đầu tiên - hidden_0_outputs. Sau đó, chúng tôi áp dụng hàm relu () để lấy node_1_0_output.

Chúng ta làm tương tự như trên đối với node_1_1_input để lấy node_1_1_output.

Chúng tôi tính toán model_output bằng cách sử dụng weights ['output'] và các kết quả đầu ra từ mảng hidden_1_outputs lớp ẩn thứ hai. Chúng tôi không áp dụng hàm relu () cho đầu ra này.

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)

Đầu ra

364