Trong bài viết ngày hôm nay, mình sẽ trình bày về các toán tử trong Tensorflow, bao gồm các nội dung sau:
Quay lại bài học trước, đây là một đồ thị đơn giản được xây dựng bởi thư viện TF.
0
1
2
3
4
5
6
7
|
import tensorflow as tf
a = tf.constant(2)
b = tf.constant(3)
x = tf.add(a, b)
with tf.Session() as sess:
print(sess.run(x))
|
Khi thực hiện chạy đoạn lệnh này, bạn sẽ nhận được một Warning:
The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
Để loại bỏ những Warning như này, bạn chỉ cần set log level sang chỉ hiện thị ERROR bằng cách thêm đoạn lệnh sau vào đầu chương trình
0
1
2
3
|
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2' # 0: ALL, 1: WARNING + ERR, 2: ERR, 3: NOTHING
|
Như trong bài trước mình có cho các bạn xem TensorBoard trình bày đồ thị của chúng ta. Nhưng làm sao có thể làm được điều đó?
0
1
2
3
4
5
6
7
8
9
10
11
12
|
import tensorflow as tf
a = tf.constant(2)
b = tf.constant(3)
x = tf.add(a, b)
# Write before session run
writer = tf.summary.FileWriter('./graphs', tf.get_default_graph())
with tf.Session() as sess:
# Or write inside session
# writer = tf.summary.FileWriter('./graphs', sess.graph)
print(sess.run(x))
writer.close() # close the writer when you’re done using it
|
Và việc tiếp theo bạn phải làm là run đoạn code này
0
1
2
3
|
$ python3 [yourprogram].py
$ tensorboard --logdir="./graphs" --port 6006 # Hoặc bất kỳ port nào khác
|
Sau đó truy cập vào đường dẫn
http://localhost:6006/
trên trình duyệt
Và đây là cái mà bạn sẽ nhìn thấy
Constants
Trong các ví dụ ở bài trước và ngay ở ví dụ phía trên, bạn có thể đã thấy chúng ta sử dụng
tf.constant
để thể hiện một giá trị hằng trong TF. Và đó cũng là cách để thêm một hằng vào đồ thị.
Cú pháp đầy đủ của
constant
0
1
2
3
4
5
6
7
8
|
tf.constant(
value,
dtype=None,
shape=None,
name='Const',
verify_shape=False
)
|
Ví dụ:
0
1
2
3
4
5
6
7
8
9
10
|
import tensorflow as tf
a = tf.constant([2, 2], name='a')
b = tf.constant([[0, 1], [2, 3]], name='b')
x = tf.multiply(a, b, name='mul')
with tf.Session() as sess:
print(sess.run(x))
# >> [[0 2]
# [4 6]]
|
Tạo các Tensor với các giá trị đặc biệt
tf.zeros(shape, dtype=tf.float32, name=None)
Tạo một tensor có kích thước là shape, và tất cả các phần tử đều có giá trị 0.
0
1
2
|
tf.zeros([2, 3], tf.int32) ==> [[0, 0, 0], [0, 0, 0]]
|
tf.zeros_like(input_tensor, dtype=None, name=None, optimize=True)
Tạo một tensor có kích thước và kiểu dữ liệu giống với
input_tensor
(trừ khi kiểu dữ liệu được chỉ định) và tất cả các phần tử đều có giá trị 0.
0
1
2
3
|
# input_tensor is [[0, 1], [2, 3], [4, 5]]
tf.zeros_like(input_tensor) ==> [[0, 0], [0, 0], [0, 0]]
|
Tương tự như 2 hàm trên, nhưng 2 hàm dưới đây sẽ tạo ra các tensor mà mọi phần tử đều có giá trị 1
tf.ones(shape, dtype=tf.float32, name=None)
tf.ones_like(input_tensor, dtype=None, name=None, optimize=True)
Variables
Có hằng thì phải có biến đúng không nào? Vậy làm sao tạo một biến trong TF?
0
1
2
3
4
5
6
7
8
9
|
s = tf.Variable(2, name="scalar")
m = tf.Variable([[0, 1], [2, 3]], name="matrix")
W = tf.Variable(tf.zeros([784,10]))
# create variables with tf.get_variable
s = tf.get_variable("scalar", initializer=tf.constant(2))
m = tf.get_variable("matrix", initializer=tf.constant([[0, 1], [2, 3]]))
W = tf.get_variable("big_matrix", shape=(784, 10), initializer=tf.zeros_initializer())
|
Bạn có 2 cách để tạo biến trong TF, cả hai đều phải cung cấp giá trị khởi tạo ban đầu.
Có 1 lưu ý nữa: Các biến này bạn đã cung cấp giá trị khởi tạo, nhưng vẫn mới chỉ là định nghĩa. Bạn cần khởi tạo chúng trước khi chạy trong session.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Cách đơn giản nhất là khởi tạo tất cả các biến trong 1 lần:
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
Khởi tạo một số biến nhất định:
with tf.Session() as sess:
sess.run(tf.variables_initializer([a, b]))
Khởi tạo 1 biến:
W = tf.Variable(tf.zeros([784,10]))
with tf.Session() as sess:
sess.run(W.initializer)
|
Placeholder
Ngoài constant và Variable, TF còn đưa ra một khái niệm là Placeholder. Tại sao lại cần thêm Placeholder?
Hãy nhớ lại rằng một chương trình TF gồm 2 quá trình: Xây dựng graph và thực thi tính toán trên graph đó. Như vậy, tại bước xây dựng graph thì chúng ta chưa cần biết.
Thí dụ:
Chúng ta cần định nghĩa một hàm f(x,y) = 2 * x + y mà không biết trước giá trị của x và y. Trong trường hợp này, x và y nên là Placeholder. Hay ví dụ sử dụng Placeholder thực tế nhất là input và nhãn của dữ liệu trong các mô hình học giám sát.
Việc sử dụng Placeholder giúp cho chúng ta có thể truyền dữ liệu khác nhau vào đồ thị khi training. Điều này giúp chúng ta có thể sử dụng linh động với nhiều mẫu dữ liệu khác nhau thay vì truyền cứng nhắc.
tf.placeholder(dtype, shape=None, name=None)
0
1
2
3
4
5
6
7
8
9
10
11
|
# create a placeholder for a vector of 3 elements, type tf.float32
a = tf.placeholder(tf.float32, shape=[3])
b = tf.constant([5, 5, 5], tf.float32)
# use the placeholder as you would a constant or a variable
c = a + b # short for tf.add(a, b)
with tf.Session() as sess:
print(sess.run(c)) # >> InvalidArgumentError: a doesn’t an actual value
|
Trong ví dụ trên, do a và b là
placeholder
nên để có thể chạy được. ta cần truyền giá trị vào trước khi chạy. Các biến kiểu placeholder sẽ nhận giá trị thông qua tham số feed_dict
là một kiểu dữ liệu dictionary trong python.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# create a placeholder for a vector of 3 elements, type tf.float32
a = tf.placeholder(tf.float32, shape=[3])
b = tf.constant([5, 5, 5], tf.float32)
# use the placeholder as you would a constant or a variable
c = a + b # short for tf.add(a, b)
with tf.Session() as sess:
print(sess.run(c, feed_dict={a: [1, 2, 3]})) # the tensor a is the key, not the string ‘a’
# >> [6, 7, 8]
|
Lazy loading trong Tensorflow
Lazy loading là khái niệm mô tả việc chỉ tạo đối tượng khi cần và tạo nó ngay trong session thay vì phải định nghĩa và thêm vào graph trước khi chạy.
Một chương trình TF thông thường
0
1
2
3
4
5
6
7
8
9
10
11
|
= tf.Variable(10, name='x')
y = tf.Variable(20, name='y')
z = tf.add(x, y) # create the node before executing the graph
writer = tf.summary.FileWriter('./graphs/normal_loading', tf.get_default_graph())
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(10):
sess.run(z)
writer.close()
|
Còn đây là chương trình TF sử dụng lazy loading
0
1
2
3
4
5
6
7
8
9
10
|
x = tf.Variable(10, name='x')
y = tf.Variable(20, name='y')
writer = tf.summary.FileWriter('./graphs/normal_loading', tf.get_default_graph())
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(10):
sess.run(tf.add(x, y)) # someone decides to be clever to save one line of code
writer.close()
|
Cả 2 đoạn code trên đều cho cùng một output. Tuy nhiên, nếu bạn định nghĩa trước thì hàm init đối tượng đó chỉ cần chạy một lần. Nhưng nếu sử dụng lazy loading, hàm init sẽ được gọi mỗi khi bạn sử dụng nó. Nếu bạn dùng lazy loading nhiều lần, chương trình của bạn sẽ chậm và tốn chi phí để thực thi. Bạn có thể xem biểu diễn của 2 chương trình trên TensorBoard
Kết luận: Hạn chế sử dụng lazy loading.
Trong bài tiếp theo mình sẽ cùng các bạn đi giải quyết một vài bài toán đơn giản sử dụng tensoflow