AI Cho Mọi Người

AI Cho Mọi Người

Dùng tf.keras cho bài toán regression

 

 

Trong bài này, chúng ta sẽ dùng tf.keras để huấn luyện các mô hình regression và classification. Ở bài trước, chúng ta đã biết cách đọc dữ liệu và xây dựng các mô hình trong Tensorflow. Các bước quan trọng khác như tính loss, tính đạo hàm và cập nhập giá trị trọng số dùng backpropagation và stochastic gradient descent chúng ta sẽ thảo luận trong bài học này.

Trong Tensorflow, thực hiện các bước trên chỉ bằng dòng lệnh sau

model.compile(optimizer=?, loss=?)

Hàm compile() khai báo loại optimizer muốn sử dụng và cách thức tính giá trị loss. Dấu ? ở code trên là chỗ để chúng ta xác đinh loại optimizer và các tính loss cụ thể nào đó. Các bạn vào 2 đường link sau để biết các loại optimizer và loss mà Tensorflow hỗ trợ.

https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/

https://www.tensorflow.org/api_docs/python/tf/keras/losses

Ví dụ chúng ta muốn dùng stochastic gradient descent và mean squared error, chúng ta khai báo như sau

model.compile(optimizer=tf.keras.optimizers.SGD(), loss=tf.keras.losses.MeanAbsoluteError())

Để huấn luyện một mô hình, chúng ta dùng hàm model.fit() nhận vào dữ liệu đặc trưngX, label y, và số epoch. Ví dụ, dòng code để huấn luyện mô hình với 100 epoch như sau

model.fit(X, y, epochs=100)

Ngoài ra, tham số verbose được dùng để xem thông tin loss và accuracy trong quá trình huấn luyện.

 

Áp dụng cho bài toán dự đoán doanh thu

Dữ liệu dự đoán doanh thu dựa vào số tiền cho quảng cáo được thể hiện ở bảng sau

 

TVRadioNewspaperSales
230.137.869.222.1
44.539.345.110.4
17.245.969.312
151.541.358.516.5
180.810.858.417.9
8.748.9757.2
57.532.823.511.8
120.219.611.613.2
8.62.114.8
199.82.621.215.6
66.15.824.212.6
214.724417.4
23.835.165.99.2
97.57.67.213.7
204.132.94619
195.447.752.922.4
67.836.611412.5
281.439.655.824.4
69.220.518.311.3
147.323.919.114.6
218.427.753.418
237.45.123.517.5
13.215.949.65.6
228.316.926.220.5
62.312.618.39.7
262.93.519.517
142.929.312.615
240.116.722.920.9
248.827.122.918.9
70.61640.810.5
292.928.343.221.4
112.917.438.611.9
97.21.53013.2
265.6200.317.4
95.71.47.411.9
290.74.18.517.8
266.943.8525.4
74.749.445.714.7
43.126.735.110.1
22837.73221.5
202.522.331.616.6
17733.438.717.1
293.627.71.820.7
206.98.426.417.9
25.125.743.38.5
175.122.531.516.1
89.79.935.710.6
239.941.518.523.2
227.215.849.919.8
66.911.736.89.7
199.83.134.616.4
100.49.63.610.7
216.441.739.622.6
182.646.258.721.2
262.728.815.920.2
198.949.46023.7
7.328.141.45.5
136.219.216.613.2
210.849.637.723.8
210.729.59.318.4
53.5221.48.1
261.342.754.724.2
239.315.527.320.7
102.729.68.414
131.142.828.916
699.30.911.3
31.524.62.211
139.314.510.213.4
237.427.51118.9
216.843.927.222.3
199.130.638.718.3
109.814.331.712.4
26.83319.38.8
129.45.731.311
213.424.613.117
16.943.789.48.7
27.51.620.76.9
120.528.514.214.2
5.429.99.45.3
1167.723.111
76.426.722.311.8
239.84.136.917.3
75.320.332.511.3
68.444.535.613.6
213.54333.821.7
193.218.465.720.2
76.327.51612
110.740.663.216
88.325.573.412.9
109.847.851.416.7
134.34.99.314
28.61.5337.3
217.733.55919.4
250.936.572.322.2
107.41410.911.5
163.331.652.916.9
197.63.55.916.7
184.9212220.5
289.742.351.225.4
135.241.745.917.2
222.44.349.816.7
296.436.3100.923.8
280.210.121.419.8
187.917.217.919.7
238.234.35.320.7
137.946.45915
251129.77.2
90.40.323.212
13.10.425.65.3
255.426.95.519.8
225.88.256.518.4
241.73823.221.8
175.715.42.417.1
209.620.610.720.9
78.246.834.514.6
75.13552.712.6
139.214.325.612.2
76.40.814.89.4
125.736.979.215.9
19.41622.36.6
141.326.846.215.5
18.821.750.47
2242.415.616.6
123.134.612.415.2
229.532.374.219.7
87.211.825.910.6
7.838.950.66.6
80.209.211.9
220.3493.224.7
59.61243.19.7
0.739.68.71.6
265.22.94317.7
8.427.22.15.7
219.833.545.119.6
36.938.665.610.8
48.3478.511.6
25.6399.39.5
273.728.959.720.8
4325.920.59.6
184.943.91.720.7
73.41712.910.9
193.735.475.619.2
220.533.237.920.1
104.65.734.410.4
96.214.838.912.3
140.31.9910.3
240.17.38.718.2
243.24944.325.4
3840.311.910.9
44.725.820.610.1
280.713.93716.1
1218.448.711.6
197.623.314.216.6
171.339.737.716
187.821.19.520.6
4.111.65.73.2
93.943.550.515.3
149.81.324.310.1
11.736.945.27.3
131.718.434.612.9
172.518.130.716.4
85.735.849.313.3
188.418.125.619.9
163.536.87.418
117.214.75.411.9
234.53.484.816.9
17.937.621.68
206.85.219.417.2
215.423.657.617.1
284.310.66.420
5011.618.48.4
164.520.947.417.5
19.620.1177.6
168.47.112.816.7
222.43.413.116.5
276.948.941.827
248.430.220.320.2
170.27.835.216.7
276.72.323.716.8
165.61017.617.6
156.62.68.315.5
218.55.427.417.2
56.25.729.78.7
287.64371.826.2
253.821.33017.6
20545.119.622.6
139.52.126.610.3
191.128.718.217.3
28613.93.720.9
18.712.123.46.7
39.541.15.810.8
75.510.8611.9
17.24.131.65.9
166.8423.619.6
149.735.6617.3
38.23.713.87.6
94.24.98.114
1779.36.414.8
283.64266.225.5
232.18.68.718.4

 

Ba cột đầu là đặc trưng và cột cuối là label. Đọc dữ liệu và chuẩn hóa được thực hiện như sau

# dataset
import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt

data = genfromtxt('advertising.csv', delimiter=',', skip_header=1)

m = data.shape[0]
X = data[:,:3]
y = data[:,3]

maxi = np.max(X)
mini = np.min(X)
avg = np.mean(X)
X = (X-avg) / (maxi-mini)

 

Thiết kế mô hình và khai báo optimizer và loss như sau

import tensorflow as tf

model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=1, input_shape=[3])
])
model.compile(optimizer=tf.keras.optimizers.SGD(0.05), loss=tf.keras.losses.MeanAbsoluteError())

# model
model.summary()

Ở đây, chúng ta sử dùng SGD với learning_rate = 0.05, và tính loss theo mean absolute error. Mọi thứ đã sẵn sàng cho việc huấn luyện mô hình. Chúng ta sẽ huấn luyện với số epoch=1000 và cho verbose=0 (không in gì ra trong quá trình huấn luyện) như sau

history = model.fit(X, y, epochs=1000, verbose=0)
print(type(history.history))
print(model.layers[0].weights)

import matplotlib.pyplot as plt
plt.plot(history.history['loss'], color="r")
plt.show()

Output của hàm model.fit() là đối tượng history, trong đó biến history.history là một dictionary có key là 'loss', chứa các giá trị loss trong quá trình huấn luyện. Ngoài ra, chúng ta có thể lấy ra được các giá trị trọng số của layer với dòng lệnh model.layers[0].weights.

Kết quả giá trị loss cho 1000 epoch như sau

 

Áp dụng cho bài toán dự đoán giá nhà

Bộ dữ liệu giá nhà Boston có 13 đặc trưng với 506 mẫu dữ liệu, được đọc từ hàm xây dựng sẵn trong Tensorflow như sau

import tensorflow as tf
from tensorflow import keras
import numpy as np

boston_housing = keras.datasets.boston_housing
(train_data, train_labels), (test_data, test_labels) = boston_housing.load_data()

# Shuffle the training set
order = np.argsort(np.random.random(train_labels.shape))
train_data = train_data[order]
train_labels = train_labels[order]

#Training set: (404, 13)
print("Training set: {}".format(train_data.shape))
#Testing set:  (102, 13)
print("Testing set:  {}".format(test_data.shape)) 


# calculating the mean and std.
mean = train_data.mean(axis=0)
std = train_data.std(axis=0)

# normalize data
train_data = (train_data - mean) / std
test_data = (test_data - mean) / std

Dữ liệu ban đầu được đọc từ hàm load_data(). Sau đó, các mẫu dữ liệu được hoán đổi vị trí một cách ngẫu nhiên và cuối cùng được chuẩn hóa.

Tiếp theo chúng ta cần xây dựng model cho bài toán dự đoán giá nhà. Đây là bài toán regression, nên layer cuối cùng không dùng thêm hàm sigmoid hay softmax. Ở phần này, chúng ta sẽ thiết kế một mô hình nhiều layer cho bài toán regression. Chúng sẽ sẽ tạo mô hình MLP với 2 hidden layer và mỗi hidden layer có 64 node. Hàm activation ReLU được dùng ở 2 hidden layer.  Code cho xây dựng model và hàm compile như sau

# model
model = keras.Sequential([
    keras.layers.Dense(64, activation=tf.nn.relu, input_shape=(train_data.shape[1],)),
    keras.layers.Dense(64, activation=tf.nn.relu),
    keras.layers.Dense(1)
])

# compile
loss = tf.keras.losses.MeanSquaredError()
optimizer=tf.keras.optimizers.RMSprop()
metric = tf.keras.losses.MeanAbsoluteError()

model.compile(loss=loss, optimizer=optimizer, metrics=[metric])    
model.summary()

Ở đây, hàm compile dùng thêm tham số metrics để xác định các tính độ chính xác của mô hình. Tham số metrics khác với loss, cái được dùng để tính đạo hàm trong backpropagation. Đôi khi loss và metrics cùng có chung cách tính, tùy thuộc vào bài toán regression hay classification. Optimizer RMSprop được dùng để cập nhật các trọng số trong quá trình huấn luyện.

Bài tập: Các bạn hãy tìm hiểu cách thức  hoạt động của RMSprop và điểm cải tiến so với SGD. Các bạn có thể tìm hiểu chi tiết hơn về RMSprop ở link sau https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/RMSprop

Bước kế tiếp là huấn luyện mô hình đã được xây dựng ở trên. Hàm model.fit() cho phép chúng ta chia dữ liệu training thành 2 phần (dữ liệu training và validation). Điều này giúp chúng ta hiểu sâu hơn quá trình huấn luyện mô hình. Chúng ta sẽ dùng 20% dữ liệu training cho phần validation như sau

# train model    
history = model.fit(train_data, train_labels, epochs=100,
                validation_split=0.2, verbose=0)

import matplotlib.pyplot as plt
plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Abs Error [1000$]')
plt.plot(history.epoch, np.array(history.history['loss']), label='Train Loss')
plt.plot(history.epoch, np.array(history.history['val_loss']), label = 'Val loss')
plt.legend()

Giá trị loss của dữ liệu training và validation trong quá trình huấn luyện được trình bày ở hình sau

Sau khi huấn luyện mô hình xong, chúng ta có thể dùng mô hình này để tính giá nhà dự đoán cho dữ liệu testing như sau

Biến test_predictions là mảng numpy, và bạn có thể dùng dữ liệu này để trình bày hay so sánh với label data.