Loading src/apren/basics/ml_tensors.md +26 −24 Changes for src/apren/basics/ml_tensors.md: 26 added lines, 24 removed lines. Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ from torch import nn ```python punts = [[0.5, 1.0], [2.0, -1.0], [0.0, 3.0], [1.5, 0.5]] # 4 punts, 2 coordenades X = torch.tensor(punts) print(X) print('shape:', X.shape, '| ndim:', X.ndim, '| dtype:', X.dtype) X_t = torch.tensor(punts) print(X_t) print('shape:', X_t.shape, '| ndim:', X_t.ndim, '| dtype:', X_t.dtype) ``` ```text Loading @@ -38,13 +38,15 @@ shape: torch.Size([4, 2]) | ndim: 2 | dtype: torch.float32 ``` Les dades solen arribar en un array de NumPy, que `torch.tensor` també accepta. `dtype` en tria el tipus, i `.numpy()` fa el camí invers: el tipus, i `.numpy()` fa el camí invers. Quan tens les mateixes dades en tots dos formats, el tensor porta el nom de l'array amb **`_t`** al final (`y` i `y_t`): així el nom diu sempre amb quina biblioteca treballes. ```python y_np = np.array([1, 0, 1, 0]) y = torch.tensor(y_np, dtype=torch.float32) print(y_np.dtype, '→', y.dtype) print(y.numpy()) # i de tornada a NumPy y = np.array([1, 0, 1, 0]) y_t = torch.tensor(y, dtype=torch.float32) print(y.dtype, '→', y_t.dtype) print(y_t.numpy()) # i de tornada a NumPy ``` ```text Loading @@ -58,9 +60,9 @@ Els pesos d'una capa de PyTorch són `float32`, i NumPy crea els decimals en `fl dius el tipus en convertir, la capa no accepta les dades: ```python X_np = np.array(punts) # NumPy: float64 per defecte X = np.array(punts) # NumPy: float64 per defecte neurona = nn.Linear(2, 1) # els pesos de PyTorch: float32 neurona(torch.tensor(X_np)) # float64 contra float32 neurona(torch.tensor(X)) # float64 contra float32 ``` ```text Loading @@ -71,8 +73,8 @@ RuntimeError: mat1 and mat2 must have the same dtype, but got Double and Float sempre amb `dtype=torch.float32`, etiquetes incloses: ```python X = torch.tensor(X_np, dtype=torch.float32) print(X.dtype) X_t = torch.tensor(X, dtype=torch.float32) print(X_t.dtype) ``` ```text Loading @@ -87,9 +89,9 @@ Les operacions element a element, la indexació i les agregacions funcionen com agregacions, l'eix es diu `dim` en lloc d'`axis`: ```python print(X * 2) # element a element print(X[:, 0]) # la columna 0: totes les files print(X.mean(dim=0)) # la mitjana de cada columna: dim fa el paper d'axis print(X_t * 2) # element a element print(X_t[:, 0]) # la columna 0: totes les files print(X_t.mean(dim=0)) # la mitjana de cada columna: dim fa el paper d'axis ``` ```text Loading @@ -110,7 +112,7 @@ punts i un vector de pesos, és la **suma ponderada** d'una neurona, ```python w = torch.tensor([2.0, -1.0]) # un pes per coordenada b = 0.5 z = X @ w + b # la suma ponderada de la neurona, per als 4 punts alhora z = X_t @ w + b # la suma ponderada de la neurona, per als 4 punts alhora print(z) print(torch.sigmoid(z)) # les probabilitats ``` Loading @@ -133,11 +135,11 @@ Les etiquetes, en canvi, solen arribar en fila. `.reshape(-1, 1)` les posa en co els eixos de mida 1. ```python print(y.shape) # una etiqueta per punt print(y.reshape(-1, 1).shape) # en columna: 4 files i 1 columna print(y_t.shape) # una etiqueta per punt print(y_t.reshape(-1, 1).shape) # en columna: 4 files i 1 columna torch.manual_seed(0) neurona = nn.Linear(2, 1) sortida = neurona(X) sortida = neurona(X_t) print(sortida.shape) # la sortida d'una xarxa: sempre en columna print(sortida.squeeze().shape) # squeeze treu els eixos de mida 1 ``` Loading @@ -153,7 +155,7 @@ La funció de pèrdua compara la sortida i les etiquetes posició a posició, i ```python loss_fn = nn.BCEWithLogitsLoss() loss_fn(sortida, y) # etiquetes en fila, sortida en columna loss_fn(sortida, y_t) # etiquetes en fila, sortida en columna ``` ```text Loading @@ -161,7 +163,7 @@ ValueError: Target size (torch.Size([4])) must be the same as input size (torch. ``` ```python y_col = y.reshape(-1, 1) y_col = y_t.reshape(-1, 1) print(loss_fn(sortida, y_col)) ``` Loading Loading @@ -218,8 +220,8 @@ que entrena les xarxes: ```python w = torch.tensor([2.0, -1.0], requires_grad=True) # PyTorch en seguirà les operacions z = X @ w + 0.5 perdua = loss_fn(z, y) z = X_t @ w + 0.5 perdua = loss_fn(z, y_t) perdua.backward() # calcula la derivada de la pèrdua respecte de w print(w.grad) ``` Loading Loading @@ -250,7 +252,7 @@ seguir les operacions, i en sortir-ne tot torna a ser com abans: ```python with torch.no_grad(): z = X @ w + 0.5 # dins del bloc, PyTorch no segueix res z = X_t @ w + 0.5 # dins del bloc, PyTorch no segueix res print(z.requires_grad) ``` Loading Loading
src/apren/basics/ml_tensors.md +26 −24 Changes for src/apren/basics/ml_tensors.md: 26 added lines, 24 removed lines. Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ from torch import nn ```python punts = [[0.5, 1.0], [2.0, -1.0], [0.0, 3.0], [1.5, 0.5]] # 4 punts, 2 coordenades X = torch.tensor(punts) print(X) print('shape:', X.shape, '| ndim:', X.ndim, '| dtype:', X.dtype) X_t = torch.tensor(punts) print(X_t) print('shape:', X_t.shape, '| ndim:', X_t.ndim, '| dtype:', X_t.dtype) ``` ```text Loading @@ -38,13 +38,15 @@ shape: torch.Size([4, 2]) | ndim: 2 | dtype: torch.float32 ``` Les dades solen arribar en un array de NumPy, que `torch.tensor` també accepta. `dtype` en tria el tipus, i `.numpy()` fa el camí invers: el tipus, i `.numpy()` fa el camí invers. Quan tens les mateixes dades en tots dos formats, el tensor porta el nom de l'array amb **`_t`** al final (`y` i `y_t`): així el nom diu sempre amb quina biblioteca treballes. ```python y_np = np.array([1, 0, 1, 0]) y = torch.tensor(y_np, dtype=torch.float32) print(y_np.dtype, '→', y.dtype) print(y.numpy()) # i de tornada a NumPy y = np.array([1, 0, 1, 0]) y_t = torch.tensor(y, dtype=torch.float32) print(y.dtype, '→', y_t.dtype) print(y_t.numpy()) # i de tornada a NumPy ``` ```text Loading @@ -58,9 +60,9 @@ Els pesos d'una capa de PyTorch són `float32`, i NumPy crea els decimals en `fl dius el tipus en convertir, la capa no accepta les dades: ```python X_np = np.array(punts) # NumPy: float64 per defecte X = np.array(punts) # NumPy: float64 per defecte neurona = nn.Linear(2, 1) # els pesos de PyTorch: float32 neurona(torch.tensor(X_np)) # float64 contra float32 neurona(torch.tensor(X)) # float64 contra float32 ``` ```text Loading @@ -71,8 +73,8 @@ RuntimeError: mat1 and mat2 must have the same dtype, but got Double and Float sempre amb `dtype=torch.float32`, etiquetes incloses: ```python X = torch.tensor(X_np, dtype=torch.float32) print(X.dtype) X_t = torch.tensor(X, dtype=torch.float32) print(X_t.dtype) ``` ```text Loading @@ -87,9 +89,9 @@ Les operacions element a element, la indexació i les agregacions funcionen com agregacions, l'eix es diu `dim` en lloc d'`axis`: ```python print(X * 2) # element a element print(X[:, 0]) # la columna 0: totes les files print(X.mean(dim=0)) # la mitjana de cada columna: dim fa el paper d'axis print(X_t * 2) # element a element print(X_t[:, 0]) # la columna 0: totes les files print(X_t.mean(dim=0)) # la mitjana de cada columna: dim fa el paper d'axis ``` ```text Loading @@ -110,7 +112,7 @@ punts i un vector de pesos, és la **suma ponderada** d'una neurona, ```python w = torch.tensor([2.0, -1.0]) # un pes per coordenada b = 0.5 z = X @ w + b # la suma ponderada de la neurona, per als 4 punts alhora z = X_t @ w + b # la suma ponderada de la neurona, per als 4 punts alhora print(z) print(torch.sigmoid(z)) # les probabilitats ``` Loading @@ -133,11 +135,11 @@ Les etiquetes, en canvi, solen arribar en fila. `.reshape(-1, 1)` les posa en co els eixos de mida 1. ```python print(y.shape) # una etiqueta per punt print(y.reshape(-1, 1).shape) # en columna: 4 files i 1 columna print(y_t.shape) # una etiqueta per punt print(y_t.reshape(-1, 1).shape) # en columna: 4 files i 1 columna torch.manual_seed(0) neurona = nn.Linear(2, 1) sortida = neurona(X) sortida = neurona(X_t) print(sortida.shape) # la sortida d'una xarxa: sempre en columna print(sortida.squeeze().shape) # squeeze treu els eixos de mida 1 ``` Loading @@ -153,7 +155,7 @@ La funció de pèrdua compara la sortida i les etiquetes posició a posició, i ```python loss_fn = nn.BCEWithLogitsLoss() loss_fn(sortida, y) # etiquetes en fila, sortida en columna loss_fn(sortida, y_t) # etiquetes en fila, sortida en columna ``` ```text Loading @@ -161,7 +163,7 @@ ValueError: Target size (torch.Size([4])) must be the same as input size (torch. ``` ```python y_col = y.reshape(-1, 1) y_col = y_t.reshape(-1, 1) print(loss_fn(sortida, y_col)) ``` Loading Loading @@ -218,8 +220,8 @@ que entrena les xarxes: ```python w = torch.tensor([2.0, -1.0], requires_grad=True) # PyTorch en seguirà les operacions z = X @ w + 0.5 perdua = loss_fn(z, y) z = X_t @ w + 0.5 perdua = loss_fn(z, y_t) perdua.backward() # calcula la derivada de la pèrdua respecte de w print(w.grad) ``` Loading Loading @@ -250,7 +252,7 @@ seguir les operacions, i en sortir-ne tot torna a ser com abans: ```python with torch.no_grad(): z = X @ w + 0.5 # dins del bloc, PyTorch no segueix res z = X_t @ w + 0.5 # dins del bloc, PyTorch no segueix res print(z.requires_grad) ``` Loading