defcur_next(lis,cur_min,cur_pos,n,l):foriinrange(cur_pos+1,l):ifcur_min<lis[i]:returnlis[i],ireturn-1,l+1deffine_index(food_times,m,cur_min):forindex,Valueinenumerate(food_times):ifcur_min<=Value:ifm==0:returnindex+1else:m-=1defsolution(food_times,k):# 1
lis=food_times[:]lis.sort()# 2
cur_min=lis[0]diff=cur_mincur_pos=0# list 0부터 시작
n=len(lis)# 남은 음식 수
l=n# 처음 음식의 총 갯수
# 3
whilediff*n<=k:k=k-diff*ntemp,cur_pos=cur_next(lis,cur_min,cur_pos,n,l)iftemp==-1:return-1# k가 충분히 커, 음식을 다 먹었을 경우.
diff=temp-cur_mincur_min=tempn=l-cur_pos# 4
cur_min=lis[cur_pos]answer=fine_index(food_times,k%n,cur_min)returnanswerif__name__=="__main__":food_times=[3,1,2,2,3,2]k=13print(solution(food_times,k))
$ 수학적 수식(문장 사이에 적기 가능) $ \[수학적 수식( 무조건 가운데 정렬)\] \[x + y = z\]
17. Struct
ㅂ + 한자 를 사용해 찾을 수 있다.
```
├──
├──
├──
└──
```
적은 것 같지만 잘 사용하면 이것만으로 충분하고, 이게 전부이다.
더 필요한 내용은 추가적으로 직접 더 찾아서 공부하도록 하자.
Typora
하지만 typora에서도 더 많은 좋은 기능을 제공한다. typora도 추가적으로 공부해보도록 하자.
Visual studio code
마크다운을 활동하는 방법이 Typora도 있지만, Visual studio code를 활용하는 방법도 있다. ‘.md’ 파일을 만들고 ctrl+shift+v 를 눌러 previewer를 같이 띄어놓음으로써 마크다운을 쓰고 난 직후의 모습을 바로바로 확인할 수 있다. 아무리 그래도 VScode는 Typora보다는 실시간성이 떨어지지만 적절히 사용한다면 충분히 좋은 마크다운 편집기라고 할 수 있다.
---
layout: list
title: <아무거나 가능 But foler name with Capa>
slug: <new folder name>
menu: true
permalink: /<new folder name>/
order: 1
sitemap: false
description: >
지도학습 비지도학습 강화학습**^^**
# accent_color: rgb(38,139,210)
# accent_image:
# background: rgb(32,32,32)
# overlay: false
---
_config 수정하기
# Add links to the sidebar.
menu:
- title: <여기가 아무이름이나 다 됨>
url: /<New Folder Name>/
각 목차에 사용하는 게시물(md 파일)에 꼭 넣어야 하는 템플릿.
---
layout: post
title: Example Content III
description: >
A page showing Hydejack-specific markdown content.
image: /assets/img/blog/example-content-iii.jpg
---
20.08.22 블로그 재 정검
오랜만에 들어와서 블로그를 업그레이드 하고 싶었다. 그래서 이것저것 확인하는 중 다음의 과정을 거쳤다. 그 과정을 혹시 몰라 기록해 놓는다.
다음과 같이 gemfile을 수정했다.
bundle exec jekyll serve를 하기 전에 빌드를 하란다. $ bundle install
뭔가 버전이 엄청 안맞는다고 안된단다. 에러 메세지에 $ bundle update 를 하라고 해서 업데이트를 했다.
다시 bundle install 아주 잘된다.
$ bundle exec jekyll serve
_config.yml 파일에서 문제가 생긴다. 여기가 원래 주석이었는데 주석을 풀어놔서 그런가…..
"""
# nn 패키지를 사용한 신경망 생성
신경망의 학습 과정
1. 학습 가능한 매개변수(또는 가중치(weight))를 갖는 신경망을 정의합니다.
2. 데이터셋(dataset)을 이용해 아래의 과정을 반복한다.
3. 입력을 신경망에서 전파(process == forward)합니다.
4. 손실을 계산합니다.
5. 변화도(gradient)를 신경망의 매개변수들에 역으로 전파 -> d_Loss / d_parametar 를 구한다.
6. 신경망의 가중치를 갱신합니다. weight = weight - learning_rate * gradient
"""pass
importtorchimporttorch.nnasnnimporttorch.nn.functionalasF# F를 import하는 이유 : Implements forward and backward definitions of an autograd operation.
classNet(nn.Module):# nn.Module 클래스를 상속하여 Net 클래스를 생성한다.
def__init__(self):# para 없음
super(Net,self).__init__()# child class에서 parent class의 __init__ 내용들을 사용하고 싶다.
self.conv1=nn.Conv2d(1,6,kernel_size=3)self.conv2=nn.Conv2d(6,16,kernel_size=3)self.relu=nn.ReLU()self.maxP1=nn.MaxPool2d(kernel_size=2,stride=2)self.fc1=nn.Linear(16*6*6,120)self.fc2=nn.Linear(120,84)self.fc3=nn.Linear(84,10)defforward(self,x):# para에 x가 들어간다!
'''[홈페이지 방법]
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
print(x.size()) # 1*6*15*15
'''x=self.maxP1(self.relu(self.conv1(x)))# print(x.size()) # masP1의 stride가 1일 때. -> 1*6*29*29. // stride가 2일 때. -> 1*6*15*15
x=F.max_pool2d(F.relu(self.conv2(x)),2)# maxpool은 정사각형이기 때문에 2만 넣어도 (2,2)로 인식한다.
x=x.view(-1,self.num_flat_features(x))# torch.Size([1, 16, 6, 6]) -> num_flat_feature를 하고 난 후의 x의 torch.Size([1, 576])
# x = F.relu(self.fc1(x)) [홈페이지 방법]
# print("num_flat_feature를 하고 난 후의 x의" , x.shape)
x=self.relu(self.fc1(x))x=self.relu(self.fc2(x))x=self.fc3(x)returnxdefnum_flat_features(self,x):size=x.size()[1:]# all dimensions except the batch dimension (3차원이면 channel, 4차원이면 이미지 갯수)
num_features=1forsinsize:num_features*=s# 예를 들어 tensor sief (120, 6, 6) 라면, 6*6 = 36 을 return 한다.
returnnum_features
net=Net()print(net)# __init__ 에 정의한 내용이 나타난다. forward 아님!
"""
forward 함수만 정의하고 나면, (변화도를 계산하는) backward 함수는 autograd 를 사용하여 자동으로 정의된다.
모델의 학습가능한 매개변수들은 nn.Module 클래스의 parameters 매소드를 통해 확인할 수 있다.
"""pass
params=list(net.parameters())print(len(params))# 10개에는 conv filter의 parameter, FC의 parameter, bias 등이 포함되어 있다. 자세한 건 나중에 더 자세히 알아보기
print(params[0].size())# conv1's .weight
10
torch.Size([6, 1, 3, 3])
input=torch.randn(1,1,32,32)out=net(input)print(out)"""
*** NOTE 중요 ***
굳이 1*1*32*32의 이미지를 넣는 이유 :
torch.nn 은 미니-배치(mini-batch)만 지원합니다. torch.nn 패키지 전체는 하나의 샘플이 아닌, 샘플들의 미니-배치만을 입력으로 받습니다.
만약 하나의 샘플만 있다면, input.unsqueeze(0) 을 사용해서 가짜 차원을 추가합니다.
"""pass
num_flat_feature를 하기 전의 x의 torch.Size([1, 16, 6, 6])
num_flat_feature를 하고 난 후의 x의 torch.Size([1, 576])
tensor([[ 0.0136, 0.0084, 0.1542, -0.0920, -0.0778, 0.0385, -0.0898, 0.0524,
-0.0445, 0.0961]], grad_fn=<AddmmBackward>)
net.zero_grad()# 1. Sets gradients of all model parameters to zero.
out.backward(torch.randn(1,10))# # 2. Backpropa. 1*10 백터를 정규분포에서 랜덤한 값을 가져와 생성한 tensor.
# print(input.grad) -> None 이라고 나온다. 아직은 뭔지 모르겠으니 좀 더 공부해보자.
-> view -> linear -> relu -> linear -> relu -> linear
-> MSELoss
-> loss
# 다음과 같은 방법으로, 최근에 한 마지막 연산들을 찾아갈 수 있다.
# 아래의 grad_fn 과 next_function은 torch document에도 없고 여기에만 있다...
print(loss.grad_fn)# MSELoss // # 사용자가 마지막으로 이 변수를 만들 때 사용하는 Function을 참조한다. (기억해 놓는다.)
print(loss.grad_fn.next_functions[0][0])# Linear
print(loss.grad_fn.next_functions[0][0].next_functions)# ReLU
<MseLossBackward object at 0x000001915F1C0A88>
<AddmmBackward object at 0x000001915F1C0C88>
((<AccumulateGrad object at 0x000001915F1C0A88>, 0), (<ReluBackward0 object at 0x000001915F1C83C8>, 0), (<TBackward object at 0x000001915F1C8908>, 0))
오차(error)를 역전파하기 위해서는 loss.backward() 만 해주면 된다.
과거의 gradient를 없애는 작업이 필요한데( .zero_grad() ), 그렇지 않으면 gradient가 기존의 것과 누적되기 때문이다. ***
각 파라미터(가중치, 편향)에 대한 Loss 미분값을 알아내는 방밥
# 각 파라미터(가중치, 편향)에 대한 Loss 미분값을 알아내는 방밥
net.zero_grad()# zeroes the gradient buffers of all parameters
print('conv1.bias.grad before backward')print(net.conv1.bias.grad)# 이렇게 method를 사용하는 것도,
loss.backward()print('\nconv1.bias.grad after backward')# d_loss / d_bias_at-conv1
print(net.conv1.bias.grad)print("\n bias 들의 실제 값 = ",net.conv1.bias)
위에서 net.conv1.bias 는 그저 tensor이다. (https://pytorch.org/docs/stable/nn.html#conv2d 에서 확인가능 conv2d.weight도 사용 가능.)
그리고 grad는 torch.autograd.grad 를 이용한 것이다. (https://pytorch.org/docs/stable/autograd.html 에서 확인가능)
grad 함수 : xxx.grad에서 d_? / d_xxx 값을 tensor형태로 뱉어 준다.
가중치 갱신
확률적 경사하강법(SGD; Stochastic Gradient Descent)
# 아주 단순하게 가중치 갱신하는 방법
learning_rate=0.01# for를 돌아서, 내가 가진 모든 layers의 파라메터를 모두, 한번 갱신한다.
fori,finenumerate(net.parameters()):print("{}번째 parameters 갱신 완료: {}".format(i+1,f.size()))f.data.sub_(f.grad.data*learning_rate)# 굳이 data method를 사용하는 이유는 모르겠다.
# https://pytorch.org/docs/stable/tensors.html?highlight=sub_#torch.Tensor.sub_
# net.parameters를 이용해도 되고, 위에 처럼 net.conv1을 이용해도 좋다. print를 통해 알아보자.
print("\n",type(list(net.parameters())[0]),'\n',type(list(net.parameters())[0].grad),'\n',type(list(net.parameters())[0].grad.data),'\n',list(net.parameters())[1].grad,'\n',list(net.parameters())[1].grad.data)
# Optimizer를 사용해서 갱신하는 방법. https://pytorch.org/docs/stable/optim.html#algorithms -> 여기에 있는 가중치 갱신 알고리즘 사용할 것.
# 위의 과정이 optimizer.stop() 이라는 것 하나로 그대로 잘 동작한다.
importtorch.optimasoptim# Optimizer를 생성합니다.
optimizer=optim.SGD(net.parameters(),lr=0.01)# 학습 과정(training loop)에서는 다음과 같습니다:
optimizer.zero_grad()# zero the gradient buffers
output=net(input)loss=criterion(output,target)loss.backward()optimizer.step()# Does the update. 다양한 종류의 optimizer 들은 모두 자신만의 step method가 구현되어 있다.
객체를 생성한 후, 객체의 값을 수정 불가능, 변수는 해당 값을 가진 다른 객체를 가리키게됨.
=연산자를 사용해 copy한 것은 깊은 복사이다. (copy by value)
[그림은 이 사이트 참조 : https://ledgku.tistory.com/54]
2. float숫자끼리의 비교
다음과 같은 문제 때문에 함부로 비교하거나 빼면 안된다.
>> 0.2 * 3 == 0.6
False
>> 1.2 - 0.2 == 1.0
True
>> 1.2 - 0.1 == 1.1
False
이 문제를 해결하기 위해, unittest모듈의 assertAlomostEqual과 같은 메소드를 사용하는 방법도 있다.
하지만 이렇게 문제해결하는 것은 근본적 문제 해결이 아니므로 ‘최대공약수 찾기’와 같은 방법을 사용해야 할 것이다.
더 좋은 방법으로는 decimal 모듈을 사용하는 것이다. [from decimal import Decimal]
3. 숫자 연산에 필요한 메소드
divmod(x,y) : return (x//y, x%y)
rount(x,n) : return 소수점 n자리에서 반올림한 수 return
4. assert
assert 조건문 : 조건문의 결과가 True가 아니면 Error를 발생시킨다.
[https://wikidocs.net/21050]
5. 가장 기본적인 알고리즘 코드
\1. 진법 변환 :
\2. 최대공약수 :
\3. 소수 :
\4. numpy 패키지 :
공부를 위해 해당 페이지 참고 : [http://aikorea.org/cs231n/python-numpy-tutorial/#numpy]
**<이 책에="" 대한="" 나의="" 생각="">**이>
이 책은 코딩테스트를 위해 좋은 책은 아니다. 코딩 테스트를 준비하기 위해서는 차라리 고득점 킷을 풀어보고, 문제를 풀어보면서 ‘이러한 방법으로 풀면 좋다(완전탐석 DFS HEAP 등)’ 라는 것을 인터넷에서 찾아가며 공부하는 것이 훨씬 좋다.
대신 이 책은 면접을 위해 좋은 책이다. 그리고 파이썬을 통한 프로그램 개발자가 알아두면 좋은 책이다. 알고리즘을 개발하고 프로그램을 개발하는 사람이라면 기본적으로 알아두면 좋은 책이다.
하지만 웹 웹 개발자, 딥러닝 모델 개발자가 알아두면 좋은 책인가? 그건 아니다. 이러한 개발자들은 다른 사람들이 만들어 놓은 모듈을 잘 이용하는 것이 더 중요하다.
따라서 지금 이 책을 공부하는 것은 때가 아니다. 우선 코딩테스트 준비를 완벽하게 하고 난 후에, 어느 정도 여유가 생기고, 공부해야겠다는 생각이 들면, 공부하는 것이 좋을 듯 하다.
이 책에는 몇가지 중요한 메소드(맴버함수)들이 소개되지만, 어차피 책을 통해 공부한다고 한들 무조건 까먹고 나중에 당연히 검색을 해야한다. 따라서 지금 책을 읽어 메소드들을 머리속에 암기하려는 행동보다는 코딩테스트를 준비하면서 유용했던 메소드들을 차근차근 공부하고 기억해나가는 것이 더 좋을 듯 하다.
따라서 지금 이 책은 한 동안 읽지 않으려고 한다. 대략 4개월 정도 후에 공부할 필요성이 느껴진다면 그 때가서 공부를 해야겠다. 지금은 맨 위에서 말했던 대로, [1. 고득점 킷 2. 코딩테스트 기출을 풀면서 몰랐던 이론과 구현법 공부.] 를 해야겠다.