1-1 o (squeeze() 함수는 차원이 1인 부분을 제거함)
1-2 o (unsqueeze(0)->batch width에 1 추가, 함수는 y.shape 함수로 확인 가능)
1-3 o (y.shape 함수로 확인 가능)
1-4 x (3차원 이상)
1-5 o

2-1 x
2-2 o
2-3
2-4 x (torch.size([2,2,3]))

3-1 
import torch
import numpy as np
x = np.random.rand(5,3)
print(x.shape)
print(x.ndim)

3-2
import torch
import numpy as np
x = np.random.rand(5,3)
y = x.reshape(15,) 
# y = x.view(-1)도 가능
print(y.shape)

3-3
import torch
import numpy as np
x = np.random.rand(5,3)
y = x.reshape(15,)
print(y)
mean_y = np.mean(y)
sum_y = np.sum(y)
max_y = np.max(y)
max_y_index = np.argmax(y)
print(mean_y,sum_y,max_y,max_y_index)

4-1
import torch
x = torch.ones(10, 5, 1, 3, 1)

# size가 1인 차원 전체 삭제해봅시당
x1 = torch.squeeze(x)
x1.shape # torch.Size([10, 5, 3]) 라는 결과가 출력 되어야 합니다! 

# size가 1인 차원 일부 삭제 : (A, B, 1, C) 차원 형태
x2 = x.squeeze(dim=2)
print(x2.shape) # torch.Size([10, 5, 3, 1]) 라는 결과가 출력 되어야 합니다! 

4-2
import torch
x = torch.ones(3, 5, 7)

# 1번과 2번 사이에 dimension 추가
x1 = x.unsqueeze(dim=1) 
print(x1.shape) # torch.Size([3, 1, 5, 7])라는 결과가 출력 되어야 합니다! 

# 마지막 자리에 dimension 추가
x2 = x.unsqueeze(dim=3)
print(x2.shape)