pytorch练习
1、使用梯度下降法拟合y = sin(x)
import numpy as np import torch import torchvision import torch.optim as optim import torch.nn as nn import torch.nn.functional as F import time import os from skimage import io, transform import matplotlib.pyplot as plt from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils import pandas as pd import math import warnings plt.ion() np.random.seed(2) if __name__ == '__main__': # landmarks_frame = pd.read_csv('data/faces/face_landmarks.csv') # n = 65 # image_name = landmarks_frame.iloc[n, 0] # landmarks_frame = landmarks_frame.iloc[n, 1:].as_matrix() # landmarks_frame = landmarks_frame.astype('float').reshape(-1, 2) x = np.linspace(-math.pi, math.pi, 2000) y = np.sin(x) a = np.random.randn() b = np.random.randn() c = np.random.randn() d = np.random.randn() learning_rate = 1e-6 for t in range(10000): y_pred = a + b * x + c * x ** 2 +d * x ** 3 loss = np.square(y_pred - y).sum() if t % 100 == 99: print(t, loss) grad_y_pred = 2.0 * (y_pred - y) grad_a = grad_y_pred.sum() grad_b = (grad_y_pred * x).sum() grad_c = (grad_y_pred * x ** 2).sum() grad_d = (grad_y_pred * x ** 3).sum() a -= learning_rate * grad_a b -= learning_rate * grad_b c -= learning_rate * grad_c d -= learning_rate * grad_d print(f'Result: y = {a} + {b} x + {c} x^2 + {d} X ^ 3') # a = np.random.rand(2, 2) # print(a) # device = torch.device("cuda:0")
2、使用pytorch的自动求导:
import numpy as np import torch import torchvision import torch.optim as optim import torch.nn as nn import torch.nn.functional as F import time import os from skimage import io, transform import matplotlib.pyplot as plt from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils import pandas as pd import math import warnings plt.ion() np.random.seed(2) if __name__ == '__main__': dtype = torch.float # landmarks_frame = pd.read_csv('data/faces/face_landmarks.csv') # n = 65 # image_name = landmarks_frame.iloc[n, 0] # landmarks_frame = landmarks_frame.iloc[n, 1:].as_matrix() # landmarks_frame = landmarks_frame.astype('float').reshape(-1, 2) x = torch.linspace(-math.pi, math.pi, 2000, dtype=dtype) y = torch.sin(x) a = torch.randn((), dtype=dtype, requires_grad=True) b = torch.randn((), dtype=dtype, requires_grad=True) c = torch.randn((), dtype=dtype, requires_grad=True) d = torch.randn((), dtype=dtype, requires_grad=True) learning_rate = 1e-6 for t in range(10000): y_pred = a + b * x + c * x ** 2 + d * x ** 3 loss = (y_pred - y).pow(2).sum() if t % 100 == 99: print(t, loss.item()) loss.backward() # grad_y_pred = 2.0 * (y_pred - y) # grad_a = grad_y_pred.sum() # grad_b = (grad_y_pred * x).sum() # grad_c = (grad_y_pred * x ** 2).sum() # grad_d = (grad_y_pred * x ** 3).sum() with torch.no_grad(): a -= learning_rate * a.grad b -= learning_rate * b.grad c -= learning_rate * c.grad d -= learning_rate * d.grad a.grad = None b.grad = None c.grad = None d.grad = None print(f'Result: y = {a} + {b} x + {c} x^2 + {d} X ^ 3') # a = np.random.rand(2, 2) # print(a) # device = torch.device("cuda:0")
3、采用神经网络预测:
import numpy as np import torch import torchvision import torch.optim as optim import torch.nn as nn import torch.nn.functional as F import time import os from skimage import io, transform import matplotlib.pyplot as plt from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils import pandas as pd import math import warnings plt.ion() if __name__ == '__main__': device = 'cpu' dtype = torch.float x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype) print(x.shape) y = torch.sin(x) p = torch.tensor([1, 2, 3]) xx = x.unsqueeze(-1).pow(p) model = torch.nn.Sequential( torch.nn.Linear(3, 1), torch.nn.Flatten(0, 1) ) loss_fn = torch.nn.MSELoss(reduction='sum') learning_rate = 1e-6 for t in range(2000): y_pred = model(xx) loss = loss_fn(y_pred, y) if t % 100 == 99: print(t, loss.item()) model.zero_grad() loss.backward() with torch.no_grad(): for parameters in model.parameters(): parameters -= learning_rate * parameters.grad linear_layer = model[0] print( f'Result: y = {linear_layer.bias.item()} + {linear_layer.weight[:, 0].item()} x + {linear_layer.weight[:, 1].item()} x^2 + {linear_layer.weight[:, 2].item()} x^3') # a = np.random.rand(2, 2) # print(a) # device = torch.device("cuda:0")
4、采用自动计算loss和更新参数等:
import numpy as np import torch import torchvision import torch.optim as optim import torch.nn as nn import torch.nn.functional as F import time import os from skimage import io, transform import matplotlib.pyplot as plt from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils import pandas as pd import math import random import warnings plt.ion() class DynamicNet(torch.nn.Module): def __init__(self): super().__init__() self.a = torch.nn.Parameter(torch.randn(())) self.b = torch.nn.Parameter(torch.randn(())) self.c = torch.nn.Parameter(torch.randn(())) self.d = torch.nn.Parameter(torch.randn(())) self.e = torch.nn.Parameter(torch.randn(())) def forward(self, x): y = self.a + self.b * x + self.c * x ** 2 + self.d * x ** 3 for exp in range(4, random.randint(4, 6)): y = y + self.e * x ** exp return y def string(self): return f'y = {self.a.item()} + {self.b.item()} x + {self.c.item()} x^2 + {self.d.item()} x^3 + {self.e.item()} x^4 ? + {self.e.item()} x^5 ?' if __name__ == '__main__': device = 'cpu' dtype = torch.float x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype) y = torch.sin(x) p = torch.tensor([1, 2, 3]) model = DynamicNet() criterion = torch.nn.MSELoss(reduction='sum') learning_rate = 1e-8 optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9) for t in range(30000): y_pred = model(x) loss = criterion(y_pred, y) if t % 2000 == 1999: print(t, loss.item()) model.zero_grad() loss.backward() optimizer.step() print(f'Result: {model.string()}')