[모두를 위한 딥러닝2] #1주차

YSL·2021년 4월 4일
0
post-thumbnail

Lab-01-1

- Vector, Matrix, Tensor

cf> 스칼라 : 차원이 없는 경우
vector : 1차원
Matrix(행렬) : 2차원
Tensor : 3차원
2D Tensor : |t| = (batch size, dim) -> t가 batch size(세로) dimension(가로)의 크기를 가진다.
3D Tensor : |t| = (batch size, width,height) -> t가 batch size(세로)
너비(가로)*높이(깊이)의 크기를 가진다.

- Numpy

인덱스를 활용하여 슬라이싱, 수정이 쉬움
ex) 1D vector 선언하기 : np.array([0.,1.,2.,3.,4.,5.,6.])
2D array 선언하기 : np.array([[0.,1.,2.,3.],[4.,5.,6.],[7.,8.,9.],[10.,11.,12.]])
t.dim() : rank 반환
t.shape() : shape 반환

- PyTorch Tensor

Numpy와 유사함
ex) t = torch.FloatTensor[0.,1.,2.,3.,4.,5.,6.]) : 파이썬 리스트 -> torch의 float형 tensor
t.dim() : rank 반환
t.shape() = t.size() : shape 반환
+) 2차원도 numpy와 동일

- Broadcasting

: PyTorch에서 제공하는 기능
불가피하게 크기가 다른 행렬끼리 사칙연산을 해야 할 때, “자동으로” 행렬의 크기가 맞춰준다.
어떻게? 크기가 작은 행렬이 크기가 큰 행렬의 size와 같아지도록 원소를 반복

- Matrix Multiplication

  • 기존의 일반적인 곱셈(Multiplication) : 두 행렬의 크기가 같아야 함(다른 shape일 경우 자동으로 broadcasting)
  • 행렬곱(Matrix Multiplication) : [ 1 2 | 3 4 ](2 by 2) x [ 1 2 ](2 by 1)처럼 가운데 두 크기가 겹쳐야 계산 가능 => 결과값은 2 by 1 행렬

- Mean

: 평균값 리턴
ex) t = torch.FloatTensor([1., 2.])
t.mean() #1.5
t = torch.FloatTensor([[1., 2.], [3., 4.]])
t.mean() #1,2,3,4 전체 평균
t.mean(dim=0) #2 by 2 -> 1 by 2 => [2.(1,3의 평균), 3.(2,4의 평균)]
t.mean(dim=1) #2 by 2 -> 2 by 1 => [1.5(1,2의 평균), 3.5(3,4의 평균)]

- Sum

: 합 리턴(개수만큼 나누지 않은 mean과 동일함)
ex) t = torch.FloatTensor([[1., 2.], [3., 4.]])
t.sum() #10.
t.sum(dim=0) #2 by 2 -> 1 by 2 => [4., 6.]
t.sum(dim=1) #2 by 2 -> 2 by 1 => [3., 7.]

- Max와 Argmax

Max : tensor나 행렬에 대해 가장 큰 값 리턴
Argmax : max의 인덱스값 리턴
ex) t = torch.FloatTensor([[1., 2.], [3., 4.]])
t.max() #4.
t.max(dim=0) #2 by 2 -> 1 by 2 => [3.(1과 3 비교), 4.(2와 4 비교)]
t.max(dim=1) #2 by 2 -> 2 by 1 => [2.(1과 2 비교), 4.(3과 4 비교)]

Lab-01-2

- View(Numpy에서의 Reshape)

ex) t = np.array([[[0, 1, 2], [3, 4 5,]] | [6, 7, 8], [9, 10, 11]]))
ft = torch.FloatTensor(t)
ft.shape #torch.Size([2, 2, 3]) #가로, 세로, 깊이
ft.view([-1, 3]) #앞에는 모르겠고(-1) 뒤에 2개의 차원은 3으로 지정
#tensor([ [0, 1, 2], | [3, 4, 5] | [6, 7, 8], | [9, 10, 11] ]) #Size는 [4(세로), 3(가로)] = [2, 2, 3] -> [2*2, 3]

ft.view([-1, 1, 3]) #원래 크기 (2, 2, 3) -> (2*2, 1, 3) => (4, 1, 3)
 #tensor([ [ [ [0, 1, 2] ] | [ [3 , 4, 5] ] ] | [ [6, 7, 8] ] | [ [9, 10, 11] ] ] )

- Squeeze

: veiw함수와 유사하지만 dimension의 원소의 개수가 1인 경우 자동으로 그 dimension을 없애줌
ex) ft = torch.FloatTensor([ [0], [1], [2] ])
#tensor([ [0] | [1] | [2] ]) ; size는 [3, 1]
ft.squeeze() #두번째 dimension이 1이므로
#tensor([0, 1, 2]) ; size는 [3]
+) squeeze(dim = 원하는 dimension값) ; 해당 dimension값==1일 경우 작동
ex) ft.squeeze(dim = 0) #0번째 dim값이 3이므로 변화 없음
ft.squeeze(dim = 1) # ft.squeeze()와 같은 결과 리턴

- Unsqueeze

ex) ft = torch.Tensor([0, 1, 2]) #size : [3]
ft.unsqueeze(0) #ft 0번 dimension에 1을 넣어라 -> size : 1 by 3
view에서도 같은 결과를 리턴할 수 있음
ex) ft.view(1, -1) #뒤는 상관없이 앞에 1을 넣음
#tensor([ [0, 1, 2] ]) #shape : [1, 3]
ft.unsqueeze(1)
#tensor([ [0] | [1] | [2] ]) -> size : 3 by 1
ft.unsqueeze(-1) #dim = -1 ; 마지막 dimension을 나타내므로 dim=1과 같음
#tensor([ [0] | [1] | [2] ]) -> size : 3 by 1

- Type Casting

: Tensor의 타입을 바꿔주는 기능
ex) lt = torch.LongTensor([1, 2, 3, 4])
lt.float()
#tensor([1., 2., 3., 4.])
bt = torch.ByteTensor([True, False, False, True])
#tensor([1, 0, 0, 1])
bt.long()
#tensor([1, 0, 0, 1])
bt.float()
#tensor([1., 0., 0., 1.])

- Concatenate

: 이어붙이는 기능
ex) x = torch.FloatTensor([ [1, 2], [3, 4] ])
y = torch.FloatTensor([ [5, 6], [7, 8] ])
torch.cat([x, y], dim = 0) #가로로 이어붙이기
#tensor([ [1, 2] |3, 4] | [5, 6] | [7, 8] )) -> size : 4 by 2
torch.cat([x, y], dim = 1) #세로로 이어붙이기
#tensor([ [1, 2, 5, 6] | [3, 4, 7, 8] ]) -> size : 2 by 4

- Stacking

: Concatenation을 편리하게 사용할 수 있는 함수
ex) x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
torch.stack([x , y, z])
#tensor([ [1, 4] | [2, 5] | [3, 6] ]) -> size : 3 by 2
torch.stack([x , y, z], dim = 1) #위의 결과에 따라 (dim = 1) = 3
#tensor([ [1, 2, 3] | [4, 5, 6] ]) -> size : 2 by 3

+) Cat을 사용한 구현
  torch.cat([x.unsqueeze(0), y.unsqueeze(0), z.unsqueeze(0)], dim = 0)
   #unsqueeze한 x,y,z 모두 1 by 2
   #tensor([ [1, 4] | [2, 5] | [3, 6] ])

- Ones and Zeros

: 기존의 tensor와 같은 shape의 1 또는 0으로만 구성된 tensor 생성
ex) x = torch.FloatTensor([ [0, 1, 2], [2, 1, 0] ])
torch.ones_like(x)
#tensor([ [1, 1, 1] | [1, 1, 1] ])
torch.zeros_like(x)
#tensor([ [0, 0, 0] | [0, 0, 0] ])

- In-place Operation

: 메모리를 새로 선언하지 않고 결과값을 기존의 tensor에 할당하는 기능
ex) 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.) #In-place Operation
 #tensor([ [2., 4.] | [6., 8.] ])
x 
 #tensor([ [2., 4.] | [6., 8.] ]) -> x의 값이 바뀜
 
 
 

Lab-02

주어진 데이터로 최선의 예측을 하도록 학습시키는 방법

- Data definition

  • Training dataset : 모델을 학습시킬 때 사용하는 입력값
  • Test datset : 학습이 끝난 후 모델이 얼마나 잘 작동하는지 판별하기 위한 데이터

- Hypothesis

Linear regression : 학습데이터와 가장 잘 맞는 하나의 직선 찾기
Y = Wx + b (W: Weight, b: Bias)
W와 b는 각각 0으로 초기화 => 처음에 어떤 입력을 받아도 0을 예측
우리의 목적 : W와 b 학습시키기
=> Requires_grad = True ; PyTorch에게 W와 b 학습시킬 것을 명시

- Compute loss

  • 학습을 하려면, 우리의 모델이 얼마나 정답과 가까운지 알아야 함
    Cost 또는 loss(linear regression에는 MSE함수로 계산
    => 우리의 x값(예측값)과 실제 training dataset의 y값(출력값) 차이를 제곱해서 평균 낸 것

- Gradient descent

: loss를 이용해 모델 개선하기
torch.optim 라이브러리 사용 -> tensor와 적당한 learning rate를 지정해준다.

ex) 공부시간과 성적의 상관관계
x_train = torch.FloatTensor([ [1], [2], [3] ])
y_train = torch.FloatTensor([ [2], [4], [6] ])

W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)

optimizer = optim.SGD([W, b], lr = 0.01)

nb_epoches= 1000
for nb_epoch in range(1, nb_epochs+1):
	hypothesis = x_train * W + b
	cost = torch.mean((hypothesis – y_train) ** 2)

	항상 붙어다니는 3줄
	optimizer.zero_grad() #gradient 초기화
	cost.backward() #gradient 계산
	optimizer.step() #계산된 gradient를 방향대로 W와 b 계산

=> For문이 반복적으로 학습되면서 W와 b가 각각 하나의 숫자로 수렴하게 됨

Lab-03

Cost를 줄이는 Gradient Descent
Review> Hypothesis(Linear Regression) : H(x) = Wx + b
;인공신경망의 구조, 주어진 input x에 대해 어떤 output y를 예측할지 알려줌
( W : 하나의 matrix, x : input vector, b : Bais vector)
Simpler Hypothesis Function : H(x) = Wx ; W라는 상수 하나만 학습
어떻게 모델의 좋고 나쁨을 평가할 수 있을까?
=> Cost function

- Cost function

: 모델 예측값이 실제 데이터와 얼마나 다른지 나타내는 값
잘 학습된 모델일수록 cost값이 낮다

  • Mean Squared Error(MSE) : Linear Regression에서 쓰이는 cost function
    : 예측값과 실제값의 차이를 제곱한 평균을 구해줌

우리가 원하는 것 : cost function 최소화
=> 기울기(Gradient)가 음수일 때, W가 커져야 함
=> 기울기가 양수일 때, W가 작아져야 함

- Gradient Descent

: gradient를 이용해 cost를 줄인다
Cost를 줄이려면 W를 Grad W값에 일정 상수 알파(learing rate = lr)를 곱한 값을 뺌

시작할 때 optimizer 정의 -> optimizer.zero_grad()로 gradient를 0으로 초기화 -> 
cost.backward()로 gradient 계산 -> optimizer.step()으로 gradient 줄이기


 

0개의 댓글