- vừa được xem lúc

Pytorch Fundamentals

0 0 18

Người đăng: Trần Quang Hiệp

Theo Viblo Asia

Khởi tạo một tensor

Tensors là kiểu dữ liệu phổ biến trong các bài toán về Trí tuệ nhân tạo. Ngoài việc sử dụng chúng làm cấu trúc dữ liệu cơ sở cho hình ảnh, một công dụng nổi bật hơn của tensor là được tận dụng để khởi tạo weight kết nối các layer của mạng nơ-ron. Trong phần này, ta sẽ thực hành các cách khác nhau để khởi tạo một đối tượng tensor:

  1. Import Pytorch và khởi tạo tensor bằng cách gọi torch.tensor như sau
import torch
x = torch.tensor([[1,2]])
y = torch.tensor([[1],[2]])
  1. In ra shape và kiểu dữ liệu của tensor
print(x.shape) # torch.Size([1,2]) # one entity of two items
print(y.shape) # torch.Size([2,1]) # two entities of one item each
print(x.dtype) # torch.int64

Kiểu dữ liệu của tất cả phần tử trong một tensor là giống nhau. Điểu đó có nghĩa là nếu một tensor mà bao gồm các kiểu dữ liệu khác nhau (ví dụ như một phần tử kiểu boolean, một phần tử là số nguyên, một phần tử là số thập phân) thì toàn bộ tensor bị ép vào kiểu dữ liệu chung (generic) nhất.

x = torch.tensor([False, 1, 2.0])
print(x)
# tensor([0., 1., 2.])
  1. Sinh một tensor với 3 hàng 4 cột gồm các phần tử 0
torch.zeros((3,4))
  1. Sinh một tensor với 3 hàng 4 cột gồm các phần tử 1
torch.ones((3,4))
  1. Sinh một tensor gồm 3 hàng 4 cột chứa các phần tử ngẫu nhiên trong nửa đoạn [0,10)
torch.randint(low = 0, high = 10, size = (3,4))
  1. Sinh một tensor gồm 3 hàng 4 cột chứa các phần tử ngẫu nhiên có giá trị nằm giữa 0 và 1
torch.rand(3,4)
  1. Sinh một tensor gồm 3 hàng 4 cột với giá trị các phần tử theo một phân phối chuẩn
torch.randn((3,4))
  1. Ta có thể convert một Numpy array thành một Torch tensor sử dụng torch.tensor(<numpy-array>)
x = np.array([10,20,30],[2,3,4]])
y = torch.tensor(x)
print(type(x), type(y))
# <class 'numpy.ndarray'> <class 'torch.Tensor'>

Các thao tác trên tensor

Tương tự như Numpy, bạn có thể thực hiện các thao tác cơ bản trên tensor.

  1. Nhân tất cả phần tử trong x với 10
import torch
x = torch.tensor([[1,2,3,4], [5,6,7,8]])
print(x * 10)
# tensor([[10, 20, 30, 40],
# [50, 60, 70, 80]])
  1. Cộng 10 và các phần tử trong x và lưu kết quả vào biến y
x = torch.tensor([[1,2,3,4], [5,6,7,8]])
y = x.add(10)
print(y)
# tensor([[11, 12, 13, 14],
# [15, 16, 17, 18]])
  1. Reshape tensor
y = torch.tensor([2, 3, 1, 0])
# y.shape == (4)
y = y.view(4,1)
# y.shape == (4, 1)
  1. Một cách khác để reshape tensor là sử dụng phương thức squeeeze trong đó ta thêm axis index mà ta muốn xóa. Chú ý rằng điều này chỉ được áp dụng chỉ khi axis mà ta muốn xóa chỉ có một phần tử
x = torch.randn(10,1,10)
z1 = torch.squeeze(x, 1) # similar to np.squeeze()
# The same operation can be directly performed on
# x by calling squeeze and the dimension to squeeze out
z2 = x.squeeze(1)
assert torch.all(z1 == z2)
# all the elements in both tensors are equal
print('Squeeze:\n', x.shape, z1.shape)
# Squeeze: torch.Size([10, 1, 10]) torch.Size([10, 10])
  1. Ngược lại với squeezeunsqueeze nghĩa là ta thêm chiều (dimension) vào ma trận
x = torch.randn(10,10)
print(x.shape)
# torch.size(10,10)
z1 = x.unsqueeze(0)
print(z1.shape)
# torch.size(1,10,10)
# The same can be achieved using [None] indexing
# Adding None will auto create a fake dim
# at the specified axis
x = torch.randn(10,10)
z2, z3, z4 = x[None], x[:,None], x[:,:,None]
print(z2.shape, z3.shape, z4.shape)
# torch.Size([1, 10, 10])
# torch.Size([10, 1, 10])
# torch.Size([10, 10, 1])

Việc sử dụng None là một cách khá hay nếu chúng ta muốn fake channel hoặc batch dimension.

Các thao tác trên tensor

  1. Nhân 2 tensor khác nhau
tensor1 = torch.randn(3)
tensor2 = torch.randn(3)
torch.matmul(tensor1, tensor2).size()
torch.Size([])
tensor1 = torch.randn(3, 4)
tensor2 = torch.randn(4)
torch.matmul(tensor1, tensor2).size()
torch.Size([3])
  1. Tương tự như concatenate trong Numpy, ta có thể concat tensor sử dụng phương thức cat
import torch
x = torch.randn(10,10,10)
z = torch.cat([x,x], axis=0) # np.concatenate()
print('Cat axis 0:', x.shape, z.shape)
# Cat axis 0: torch.Size([10, 10, 10])
# torch.Size([20, 10, 10])
z = torch.cat([x,x], axis=1) # np.concatenate()
print('Cat axis 1:', x.shape, z.shape)
# Cat axis 1: torch.Size([10, 10, 10])
# torch.Size([10, 20, 10])
  1. Lấy giá trị lớn nhất trong tensor
x = torch.arange(25).reshape(5,5)
print('Max:', x.shape, x.max())
# Max: torch.Size([5, 5]) tensor(24)
  1. Ta có thể lấy giá trị lớn nhất theo hàng và chỉ số của các giá trị đó
x.max(dim=0)
# torch.return_types.max(values=tensor([20, 21, 22, 23, 24]),
# indices=tensor([4, 4, 4, 4, 4]))

Tương tự theo cột

m, argm = x.max(dim=1)
print('Max in axis 1:\n', m, argm)
# Max in axis 1: tensor([ 4, 9, 14, 19, 24])
# tensor([4, 4, 4, 4, 4])
  1. Hoán vị chiều của tensor
x = torch.randn(10,20,30)
z = x.permute(2,0,1) # np.permute()
print('Permute dimensions:', x.shape, z.shape)
# Permute dimensions: torch.Size([10, 20, 30])
# torch.Size([30, 10, 20])

Lưu ý rằng không nên reshape một tensor sử dụng tensor.view. Mặc dù Torch không báo lỗi nhưng nó sẽ ra kết quả sai mà ta không nhìn thấy được trong quá trình training. Nếu muốn swap dimension, bạn nên sử dụng permute.

Ngoài ra còn rất nhiều method khác như abs, add, argsort, ceil, floor, sin, cos, tan, cumsum, cumprod, diag, eig, exp, log, log2, log10, mean, median, mode, resize, round, sigmoid, softmax, square, sqrt, svd cách gọi các method này giống như các method đã trình bày.

Auto gradient

Vi phân và tính toán đạo hàm đóng vai trò rất quan trọng đối với việc cập nhật trọng số trong mạng neural network. Pytorch tensor cung cấp một hàm built in để tính toán đạo hàm.

  1. Định nghĩa một tensor và yêu gradient được tính toán
import torch
x = torch.tensor([[2., -1.], [1., 1.]], requires_grad=True)
print(x)
  1. Tiếp theo, định nghĩa cách tính toán ra output, ví dụ như sau alt text
out = x.pow(2).sum()

Ta đều biết rằng đạo hàm của hàm trên là 2*x hãy thử kiểm chứng bằng hàm của Pytorch.

  1. Giá trị của một đạo hàm được tính bằng cách gọi phương thức backward()
out.backward()
  1. Okay! Giờ ta sẽ xác định giá trị đạo hàm tương ứng với đầu vào là x
x.grad

Lợi ích của của Pytorch tensor so với Numpy array

Tensor Torch được tối ưu hóa để hoạt động với GPU so với NumPy. Để hiểu thêm điều này, hãy thực hiện một thử nghiệm nhỏ, trong đó ta thực hiện phép nhân ma trận bằng cách sử dụng NumPy trong một kịch bản và tensor trong một kịch bản khác và so sánh thời gian thực hiện phép nhân ma trận trong cả hai tình huống:

  1. Sinh 2 torch object
import torch
x = torch.rand(1, 6400)
y = torch.rand(6400, 5000)
  1. Xác định device sử dụng để lưu trữ tensor object
device = 'cuda' if torch.cuda.is_available() else 'cpu'

Lưu ý rằng nếu không có GPU thì device sẽ là CPU

  1. Lưu 2 tensor vào device
x, y = x.to(device), y.to(device)
  1. Thực hiện nhân ma trận sử dụng Torch object
%timeit z=(_@.com)
# It takes 0.515 milli seconds on an average to
# perform matrix multiplication
  1. Thực hiện nhân ma trận trên sử dụng cpu
x, y = x.cpu(), y.cpu()
%timeit z=(_@.com)
# It takes 9 milli seconds on an average to
# perform matrix multiplication
  1. Thực hiện nhân ma trận sử dụng Numpy array
import numpy as np
x = np.random.random((1, 6400))
y = np.random.random((6400, 5000))
%timeit z = np.matmul(x,y)
# It takes 19 milli seconds on an average to
# perform matrix multiplication

Ta thấy rằng nhân ma trận sử dụng Torch trên GPU nhanh ~18 lần so với Torch trên CPU và ~40 lần so với sử dụng Numpy array. Do đó nếu không có GPU, bạn có thể sử dụng Google Colab cho các thao tác tính toán trên tensor để tăng tốc độ tính toán 😃))

Bình luận

Bài viết tương tự

- vừa được xem lúc

Các thuật toán cơ bản trong AI - Phân biệt Best First Search và Uniform Cost Search (UCS)

Nếu bạn từng đọc các thuật toán trong AI (Artificial Intelligence - Trí tuệ nhân tạo), rất có thể bạn từng nghe qua về các thuật toán tìm kiếm cơ bản: UCS (thuộc chiến lược tìm kiếm mù) và Best First Search (thuộc chiến lược tìm kiếm kinh nghiệm). Khác nhau rõ từ khâu phân loại rồi, thế nhưng hai th

0 0 152

- vừa được xem lúc

Con đường AI của tôi

Gần đây, khá nhiều bạn nhắn tin hỏi mình những câu hỏi đại loại như: có nên học AI, bắt đầu học AI như nào, làm sao tự học cho đúng, cho nhanh, học không bị nản, lộ trình học AI như nào... Sau nhiều lần trả lời, mình nghĩ rằng nên viết hẳn một bài để trả lời chi tiết hơn, cũng như để các bạn sau này

0 0 137

- vừa được xem lúc

[ChatterBot] Thư viện chatbot hay ho dành cho Python| phần 3

Trong bài trước mình đã trình bày về Training data cho chatbot và tiền xử lý dữ liệu. Trong phần này sẽ trình bày với các bạn về logic adapter.

0 0 47

- vừa được xem lúc

[Deep Learning] Kỹ thuật Dropout (Bỏ học) trong Deep Learning

. Trong bài viết này, mình xin phép giới thiệu về Dropout (Bỏ học) trong mạng Neural, sau đó là mình sẽ có 1 số đoạn code để xem Dropout ảnh hưởng thế nào đến hiệu suất của mạng Neural. 1.1. Dropout trong mạng Neural là gì.

0 0 36

- vừa được xem lúc

Kỹ thuật Dropout (Bỏ học) trong Deep Learning

Trong bài viết này, mình xin phép giới thiệu về Dropout (Bỏ học) trong mạng Neural, sau đó là mình sẽ có 1 số đoạn code để xem Dropout ảnh hưởng thế nào đến hiệu suất của mạng Neural. 1.

0 1 66

- vừa được xem lúc

Blockchain dưới con mắt làng Vũ Đại 4.0

Mở bài. Hey nhô các bạn, lại là mình đây .

0 0 38