# Pytorch ML 코드 중심으로 알아보기 ### tensor dimension ![](https://i.imgur.com/ZLA7GZe.png) ### tensor initialization ```python ndarray = [[1,2],[3,4]] tensor_1 = torch.tensor(ndarray) # ndarray -> tensor nparray = np.array(ndarray) # ndarray -> numpy tensor_2 = torch.from_numpy(nparray) # numpy -> tensor tensor_3 = torch.ones_like(tensor_1) # tensor -> tensor (차원: 동일, 값: 1) tensor_3 = torch.rand_like(tensor_1) # tensor -> tensor (차원: 동일, 값: random) shape = (2,2) # 차원 모양 torch.rand(shape) # shape 모양의 random 값 tensor torch.ones(shape) # shape 모양의 모든값이 1인 tensor torch.zeros(shape) # shape 모양의 모든값이 random인 tensor ``` ### tensor 특성 - bridge: numpy와 tensor는 동일한 memory 공간을 공유 ```python tensor = torch.tensor([1,1]) tensor_np = tensor.numpy() tensor.add_(1) # = tensor([2,2]) print(tensor_np) # = [2,2] ``` - broadcasting: dimension이 다른 두 tensor간 연산이 가능하도록 조정 ```python m1 = torch.FloatTensor([[1, 2]]) m2 = torch.FloatTensor([3]) # m2: [3] -> [3,3] print(m1 + m2) # = tensor([[4., 5.]]) m1 = torch.FloatTensor([[1, 2]]) # m1: [[1,2]] -> [[1,2],[1,2]] m2 = torch.FloatTensor([[3], [4]]) # m2: [3],[4] -> [[3, 3],[4, 4]] print(m1 + m2) # = tensor([4., 5.],[5., 6.]]) ``` ### tensor 주요 함수 - tensor를 GPU로 옴기기 ```python if torch.cuda.is_available(): tensor = tensor.to('cuda') ``` - 행/열 값 변경 ```python tensor[:,0] = 0 # 1번째 column값 전부 0 tensor[0,:] = 0 # 1번째 row값 전부 0 tensor.add_(1) # 모든 element에 1을 더함 ``` - 합치기 ```python tensor_a, tensor_b # shape (3,2) tensors torch.cat([tensor_a, tensor_b)], dim=0) # result shape (6,4) torch.stack([tensor_a, tensor_b)], dim=0) # result shape (2,3,4) ``` - 덧샘 ```python tensor = torch.FloatTensor([[1, 2], [3, 4]]) tensor.sum() # = tensor(10.) tensor.sum(dim=0) # = tensor([4., 6.]) 밖에서 부터 첫번째 차원 tensor.sum(dim=1) # = tensor([3., 7.]) 밖에서 부터 두번째 차원 tensor.sum(dim=-1) # = tensor([3., 7.]) 안쪽에서 부터 첫번째 차원 tensor.sum(dim=-2) # = tensor([4., 6.]) 안쪽에서 부터 두번째 차원 ``` - 곱샘 ```python tensor = torch.tensor([1,1]) tensor.mul(tensor) # = tensor([1, 1]) element-wise product tensor * tensor # = tensor([1, 1]) element-wise product tensor.matmul(tensor.T) # = tensor(2) matrix multiplcation tensor @ tensor.T # = tensor(2) matrix multiplcation ``` - 평균 ```python tensor = torch.FloatTensor([[1, 2], [3, 4]]) tensor.mean() # = tensor(2.5000) t.mean(dim=0) # = tensor([2., 3.]) t.mean(dim=1) # = tensor([1.5000, 3.5000]) ``` - 최대값 ```python tensor = torch.FloatTensor([[1, 2], [3, 4]]) tensor.max() # = tensor(4.) tensor.max(dim=0) # = (tensor([3., 4.]), tensor([1, 1])) tensor.max(dim=0)[0] # = tensor([3., 4.]) dim=0 기준 max 값 tensor.max(dim=0)[1] # = tensor([1, 1]) dim=0 기준 argmax 값 (각 index) ``` - dimension 변경 ```python tensor_a.shape # = torch.Size([1, 2, 3]) tensor_a.view(-1,3).shape # = torch.Size([2,3]) 1 * 2 * 3 = ? * 3 tensor_a.view(-1,2,3).shape # = torch.Size([1,2,3]) 1 * 2 * 3 = ? * 2 * 3 tensor_b.shape # = torch.Size([1,2,1,2]) tensor_b.squeeze().shape # = torch.Size([2,2]) 값이 1인 차원을 제거 tensor_c.shape # = torch.Size([2,2]) tensor_c.unsqueeze(0).shape # = torch.Size([1,2,2]) 0번째 위치에 차원 추가 tensor_c.unsqueeze(1).shape # = torch.Size([2,1,2]) 1번째 위치에 차원 추가 ``` - type casting ```python lt = torch.LongTensor([1, 2, 3, 4]) lt.float() # = tensor([1., 2., 3., 4.]) bt = torch.BoolTensor([True, False, False, True]) bt.byte() # = tensor([1, 0, 0, 1], dtype=torch.uint8) ``` - 덮어쓰기 ```python x = torch.FloatTensor([[1, 2], [3, 4]]) x.mul(2.) # = tensor([[2, 4], [6, 8]]) x # = tensor([[1, 2], [3, 4]]) x 변수는 변하지 않음 x.mul_(2.) # = tensor([[2, 4], [6, 8]]) 함수 뒤에 _를 사용하면 변수 덮어쓰기 x # = tensor([[2, 4], [6, 8]]) ``` - 난수 발생 seed 설정 ```python torch.manual_seed(3) # 3번째 random seed for i in range(1,3): print(torch.rand(1)) # tensor([0.0043]) , tensor([0.1056]) ``` ### linear regression ```python x_train = torch.FloatTensor([[1], [2], [3]]) # 공부에 투자한 시간 1,2,3 시간 y_train = torch.FloatTensor([[2], [4], [6]]) # 시험 성적 2,4,6 점 # W의 차원은 x의 개수에 비례한다. x가 3개면 W는 (3,1)이 된다. # 지금 x의 개수는 시간이라는 변수 1개이며 총 3개의 데이터가 있으니 W의 차원은 1이 된다. W = torch.zeros(1, requires_grad=True) # requires_grad는 학습되는 값을 추적하기 위함 b = torch.zeros(1, requires_grad=True) optimizer = optim.SGD([W, b], lr=0.01) nb_epochs = 1999 # 원하는만큼 경사 하강법을 반복 for epoch in range(nb_epochs + 1): hypothesis = x_train.matmul(W) + b # H(x) = Wx + b x_train.matmul(W) + b cost = torch.mean((hypothesis - y_train) ** 2) # cost = avg((H(x) - y)^2) optimizer.zero_grad() # optimizer의 기울기는 누적되는 특징 때문에 0으로 초기화 cost.backward() # 비용함수 미분하여 gradient 계산 optimizer.step() # W와 b 업데이트 if epoch % 100 == 0: # 100번마다 로그 출력 print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format( epoch, nb_epochs, W.item(), b.item(), cost.item() )) ```