Bibliothèque d'apprentissage automatique open source de Python.
PyTorch définit une classe appelée ** Tensor ** (torch.Tensor
), qui est utilisée pour sauvegarder et calculer des tableaux multidimensionnels. Il est similaire au tableau Array de Numpy, mais il permet également les opérations Nvidia activées par CUDA sur les GPU.
[Source] -> PyTorch --Wikipedia
Les bibliothèques d'apprentissage automatique sont à peu près divisées en deux types: ** Définir par exécution ** et ** Définir et exécuter **.
Define by Run Définissez le réseau pendant l'exécution. Étant donné que le réseau peut être modifié de manière dynamique, une conception flexible est possible. Par exemple, il est possible de changer de réseau en fonction de la taille des données et de modifier la conception à chaque itération. Les bibliothèques bien connues incluent PyTorch et Chainer.
Define and Run Définissez d'abord le réseau, puis exécutez. Vous pouvez facilement configurer un réseau simplement en combinant des parties comme un bloc lego. Concis et facile à comprendre. Les bibliothèques bien connues incluent Keras et Tensorflow.
PyTorch appartient à la bibliothèque d'apprentissage automatique Define by Run qui construit un réseau lors de l'exécution. En raison de ces différences, il semble préférable d'utiliser ces bibliothèques au bon endroit. Keras de Define and Run est-il simple dans le travail d'analyse de données normal, et PyTorch de Define by Run est-il supérieur dans la recherche et les tâches difficiles qui nécessitent une conception détaillée?
[Source de référence] -> "Introduction à PyTorch" Comment utiliser et quelle est la différence avec Tensorflow, Keras, etc.? --Proclassiste
La plus grande différence entre PyTorch et Chainer est que PyTorch est largement utilisé dans les communautés d'outre-mer, tandis que Chainer se trouve principalement au Japon. En effet, Chainer a été développé par une société japonaise appelée Preferred Networks (PFN). Cependant, en décembre 2019, PFN a annoncé qu'il mettrait fin à la mise à jour majeure de Chainer et passerait à la recherche et au développement de PyTorch, ce qui a changé la relation entre les deux bibliothèques. Pour plus de détails, voir ici. Par conséquent, si vous souhaitez utiliser la bibliothèque d'apprentissage automatique Define by Run à l'avenir, vous pouvez sélectionner PyTorch en toute sécurité.
Vérifiez les spécifications de PyTorch en citant le tutoriel officiel de PyTorch.
What is PyTorch? -- PyTorch Tutorials 1.4.0 documentation
Le «Tensor» utilisé dans PyTorch est similaire au «ndarray» de Numpy, mais le «Tensor» peut être calculé en utilisant le GPU pour un calcul plus rapide.
Ce qui suit est un résumé de la façon d'utiliser le Tensor
de PyTorch par rapport à Numpy.
import torch
import numpy as np
Un tableau avec tous les zéros.
# Tensor
x_t = torch.zeros(2, 3)
# Numpy
x_n = np.zeros((2,3))
print('Tensor:\n',x_t,'\n')
print('Numpy:\n',x_n)
# ---Output---
#Tensor:
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
#Numpy:
# [[0. 0. 0.]
# [0. 0. 0.]]
Un tableau avec tous les éléments 1.
# Tensor
x_t = torch.ones(2,3)
# Numpy
x_n = np.ones((2,3))
print('Tensor:\n',x_t,'\n')
print('Numpy:\n',x_n)
# ---Output---
#Tensor:
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
#Numpy:
# [[1. 1. 1.]
# [1. 1. 1.]]
Un tableau qui spécifie les valeurs des éléments.
# Tensor
x_t = torch.tensor([[5,3],[10,6]])
# Numpy
x_n = np.array([[5,3],[10,6]])
print('Tensor:\n',x_t,'\n')
print('Numpy:\n',x_n)
# ---Output---
#Tensor:
# tensor([[ 5, 3],
# [10, 6]])
#Numpy:
# [[ 5 3]
# [10 6]]
Un tableau dans lequel les valeurs des éléments sont spécifiées par des nombres aléatoires.
# Tensor
x_t = torch.rand(2,3)
# Numpy
x_n = np.random.rand(2,3)
print('Tensor:\n',x_t,'\n',x12_t,'\n')
print('Numpy:\n',x_n,'\n',x12_n)
# ---Output---
#Tensor:
# tensor([[0.5266, 0.1276, 0.6704],
# [0.0412, 0.5800, 0.0312]])
# tensor(0.3370)
#Numpy:
# [[0.08877971 0.51718009 0.99738679]
# [0.35288525 0.68630145 0.73313903]]
# 0.1799177580940461
L'accès à chaque élément du tableau peut se faire comme x [0,1]
(cela obtiendra les éléments de la 1ère ligne et de la 2ème colonne du tableau x
).
# Tensor
x12_t = x_t[0,1]
# Numpy
x12_n = x_n[0,1]
print('Tensor:\n',x12_t,'\n')
print('Numpy:\n',x12_n)
# ---Output---
#Tensor:
# tensor(0.1276)
#Numpy:
# 0.5171800941956144
Il convient de noter ici que Numpy obtient une valeur numérique lors de l'obtention d'un élément d'un tableau, mais PyTorch obtient un Tensor au lieu d'une valeur numérique. Par conséquent, PyTorch ne peut pas traiter les éléments du tableau extraits de cette manière car ils le sont comme une quantité scalaire. Si vous voulez récupérer une valeur numérique comme Numpy, vous devez exécuter Tensor.item ()
.
x12_value = x12_t.item()
print(x12_t)
print(x12_value)
# ---Output---
# tensor(0.1276)
# 0.12760692834854126
Avec PyTorch, vous pouvez effectuer des opérations à quatre règles avec le même sentiment que Numpy.
# Tensor
x_t = torch.Tensor([1,2,3])
y_t = torch.Tensor([2,2,2])
add_t = x_t + y_t
sub_t = x_t - y_t
mul_t = x_t * y_t
div_t = x_t / y_t
print('Tensor:\nAddition:\n',add_t,'\nSubtraction:\n',sub_t,
'\nMultiplication:\n',mul_t,'\nDivision:\n',div_t,'\n')
# Numpy
x_n = np.array([1,2,3])
y_n = np.array([2,2,2])
add_n = x_n + y_n
sub_n = x_n - y_n
mul_n = x_n * y_n
div_n = x_n / y_n
print('Numpy:\nAddition:\n',add_n,'\nSubtraction:\n',sub_n,
'\nMultiplication:\n',mul_n,'\nDivision:\n',div_n)
# ---Output---
#Tensor:
#Addition:
# tensor([3., 4., 5.])
#Subtraction:
# tensor([-1., 0., 1.])
#Multiplication:
# tensor([2., 4., 6.])
#Division:
# tensor([0.5000, 1.0000, 1.5000])
#
#Numpy:
#Addition:
# [3 4 5]
#Subtraction:
# [-1 0 1]
#Multiplication:
# [2 4 6]
#Division:
# [0.5 1. 1.5]
Autograd: Automatic Differentiation -- PyTorch Tutorials 1.4.0 documentation
Les informations de forme (nombre de lignes, nombre de colonnes) du tableau peuvent être obtenues par la méthode «shape». Il se comporte comme Numpy.
# Tensor
x_t = torch.rand(4,3)
row_t = x_t.shape[0]
column_t = x_t.shape[1]
print('Tensor:\n','row: ',row_t,'column: ',column_t)
# Numpy
x_n = np.random.rand(4,3)
row_n = x_n.shape[0]
column_n = x_n.shape[1]
print('Numpy:\n','row: ',row_n,'column: ',column_n)
# ---Output---
#Tensor:
# row: 4 column: 3
#Numpy:
# row: 4 column: 3
Si vous voulez changer la forme du tableau, vous utilisez souvent «.view ()» dans PyTorch et «.reshape ()» dans Numpy. Cependant, vous pouvez utiliser .reshape ()
pour le Tensor de PyTorch ainsi que pour Numpy.
# Tensor
x_t = torch.rand(4,3)
y_t = x_t.view(12)
z_t = x_t.view(2,-1)
print('Tensor:\n',x_t,'\n',y_t,'\n',z_t,'\n')
# Numpy
x_n = np.random.rand(4,3)
y_n = x_n.reshape(12)
z_n = x_n.reshape([2,-1])
print('Numpy:\n',x_n,'\n',y_n,'\n',z_n)
# ---Output---
#Tensor:
# tensor([[0.5357, 0.2716, 0.2651],
# [0.6570, 0.0844, 0.9729],
# [0.4436, 0.9271, 0.4013],
# [0.8725, 0.2952, 0.1330]])
# tensor([0.5357, 0.2716, 0.2651, 0.6570, 0.0844, 0.9729, 0.4436, 0.9271, 0.4013,
# 0.8725, 0.2952, 0.1330])
# tensor([[0.5357, 0.2716, 0.2651, 0.6570, 0.0844, 0.9729],
# [0.4436, 0.9271, 0.4013, 0.8725, 0.2952, 0.1330]])
#
#Numpy:
# [[0.02711389 0.24172801 0.01202486]
# [0.59552453 0.49906154 0.81377212]
# [0.24744639 0.58570244 0.26464142]
# [0.14519645 0.03607043 0.46616757]]
# [0.02711389 0.24172801 0.01202486 0.59552453 0.49906154 0.81377212
# 0.24744639 0.58570244 0.26464142 0.14519645 0.03607043 0.46616757]
# [[0.02711389 0.24172801 0.01202486 0.59552453 0.49906154 0.81377212]
# [0.24744639 0.58570244 0.26464142 0.14519645 0.03607043 0.46616757]]
Lorsque vous utilisez .reshape ()
.
# Tensor
x_t = torch.rand(4,3)
y_t = x_t.reshape(2,-1)
#y_t = torch.reshape(x_t,[2,-1]) <-- Also works
print('Tensor:\n',y_t,'\n')
# Numpy
x_n = np.random.rand(4,3)
y_n = x_n.reshape(2,-1)
#y_n = np.reshape(x_n,[2,-1]) <-- Also works
print('Numpy:\n',y_n)
# ---Output---
#Tensor:
#tensor([[0.0617, 0.4898, 0.4745, 0.8218, 0.3760, 0.1556],
# [0.3192, 0.5886, 0.8385, 0.5321, 0.9758, 0.8254]])
#
#Numpy:
#[[0.60080911 0.55132561 0.75930606 0.03275005 0.83148483 0.48780054]
# [0.10971541 0.02317271 0.22571149 0.95286975 0.93045979 0.82358474]]
La translocation de tableau se fait avec .transpose ()
ou .t ()
dans PyTorch et avec .transpose ()
ou .T
dans Numpy.
# Tensor
x_t = torch.rand(3,2)
xt_t = x_t.transpose(0,1)
#xt_t = torch.transpose(x_t,0,1)
#xt_t = x_t.t()
print('Tensor:\n',x_t,'\n',xt_t)
# Numpy
x_n = np.random.rand(3,2)
xt_n = x_n.transpose()
#xt_n = np.transpose(x_n)
#xt_n = x_n.T
print('Numpy:\n',x_n,'\n',xt_n)
# ---Output---
#Tensor:
# tensor([[0.8743, 0.8418],
# [0.6551, 0.2240],
# [0.9447, 0.2824]])
# tensor([[0.8743, 0.6551, 0.9447],
# [0.8418, 0.2240, 0.2824]])
#Numpy:
# [[0.80380702 0.81511741]
# [0.29398279 0.78025418]
# [0.19421487 0.43054298]]
# [[0.80380702 0.29398279 0.19421487]
# [0.81511741 0.78025418 0.43054298]]
Tensor
--> ndarray
Pour convertir de «Tensor» en «ndarray», utilisez «Tensor.numpy ()».
Le "ndarray" converti n'est pas affecté par le changement de la source de référence "Tensor". (ndarrya
est une copie de Tensor
.) Si vous voulez créer un lien, vous devez utiliser une opération sur place (ajoutez _
à la fin de chaque fonction. Par exemple, ʻadd_ () `.) y a-t-il.
a = torch.ones(5)
b = a.numpy()
a = a + 1
print('a = ',a)
print('b = ',b)
# ---Output---
# a = tensor([2., 2., 2., 2., 2.])
# b = [1. 1. 1. 1. 1.]
a = torch.ones(5)
b = a.numpy()
a.add_(1)
#torch.add(a,1,out=a) <-- Same operation
print('a = ',a)
print('b = ',b)
# ---Output---
# a = tensor([2., 2., 2., 2., 2.])
# b = [2. 2. 2. 2. 2.]
Tensor
<-- ndarray
Lors de la conversion de ndarray
en Tensor
, utiliseztorch.from_numpy (ndarray)
.
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print('a = ',a)
print('b = ',b)
# ---Output---
# a = [2. 2. 2. 2. 2.]
# b = tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
CUDA Tensor
Tensor
peut déplacer la zone de calcul en utilisant la méthode .to ()
.
Cela vous permet de déplacer Tensor
de la mémoire CPU vers la mémoire GPU et d'effectuer des calculs.
x = torch.rand(2,3)
if torch.cuda.is_available():
device = torch.device("cuda") # a CUDA device object
y = torch.ones_like(x, device=device) # directly create a tensor on GPU
x = x.to(device) # or just use strings ``.to("cuda")``
z = x + y
print(z)
print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
# ---Output---
#tensor([[1.1181, 1.1125, 1.3122],
# [1.1282, 1.5595, 1.4443]], device='cuda:0')
#tensor([[1.1181, 1.1125, 1.3122],
# [1.1282, 1.5595, 1.4443]], dtype=torch.float64)
En définissant l'attribut requires_grad
de torch.Tensor
sur True
, tout l'historique des calculs peut être suivi. En appelant la méthode backward ()
lorsque le calcul est terminé, toute différenciation est automatiquement exécutée. Le coefficient différentiel est stocké dans l'attribut «grad».
Si vous souhaitez arrêter le suivi de l'historique des calculs, vous pouvez appeler la méthode detach ()
pour le séparer du suivi de l'historique des calculs.
Chaque Tensor
a un attribut grad_fn
. Cet attribut fait référence à la classe «Function» qui crée le «Tensor». (Strictement parlant, le Tensor
défini par l'utilisateur n'a pas l'attribut grad_fn
, et le Tensor
dans le résultat du calcul reçoit l'attribut grad_fn
.)
x = torch.ones(2, 2, requires_grad=True)
print(x)
# ---Output---
#tensor([[1., 1.],
# [1., 1.]], requires_grad=True)
y = x + 2
print(y)
# ---Output---
#tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
print(x.grad_fn)
print(y.grad_fn)
# ---Output---
# None
# <AddBackward0 object at 0x7f2285d93940>]
z = y * y * 3
out = z.mean()
print(z)
print(out)
# ---Output---
#tensor([[27., 27.],
# [27., 27.]], grad_fn=<MulBackward0>)
#tensor(27., grad_fn=<MeanBackward0>)
print(z.grad_fn)
# ---Output---
#<MulBackward0 object at 0x7f2285d93ac8>
out.backward()
print(x.grad)
# ---Output---
#tensor([[4.5000, 4.5000],
# [4.5000, 4.5000]])
Quand j'ai calculé le résultat final,
out = \frac{1}{4} \sum_{i} z_i \\
z_i = y_i \cdot y_i \cdot 3 = 3 \cdot (x_i+2)^2
Donc,
\frac{\partial out}{\partial x_i} = \frac{1}{4} \cdot 3 \cdot 2 \cdot (x_i+2) = 4.5
Il est confirmé que
Les principaux points de cet article sont résumés ci-dessous.
--PyTorch est une bibliothèque d'apprentissage automatique Define by Run.
--Utilisez un tableau appelé torch.Tensor
qui permet un calcul à grande vitesse et une différenciation automatique. Cela peut être utilisé (défini / calculé) de la même manière que numpy.ndaray de Numpy, et peut être facilement converti l'un à l'autre.
requires_grad
de torch.Tensor
sur True
, l'historique du calcul peut être retracé, et en appelant la méthode backward ()
à la fin du calcul, une différenciation automatique est effectuée. Ceci est très utile pour mettre à jour les paramètres par la méthode de propagation de retour d'erreur du réseau neuronal.Recommended Posts