728x90

Pytorch data_loader에서 num_worker를 세팅하는 부분이 있다.

 

num_worker를 공식문서에서 설명하는 것은 다음과 같다.

 

num_workers (int, optional) – how many subprocesses to use for data loading. 
      0 means that the data will be loaded in the main process. (default: 0)

 

( default 값은 0 이며, 이는 main process만 사용하는 것을 의미한다. 이때, 다른 값을 입력하는 경우 sub process를 추가적으로 얼마나 사용할지를 정하는 것이다.)

 

먼저 우리가 GPU를 사용하는 이유는 딥러닝에서 많이 사용되는 행렬 연산을 병렬처리하여 빠르게 연산하기 위함이다.

그러기 위해서는 CPU에 loading되어 있는 data를 GPU로 넘겨주는 작업의 속도도 중요하다. 이때, 넘겨주는 속도가 느리게 되면 전체적인 작업속도가 느려지는 것이고, 이를 빠르게 하기 위해서 멀티프로세싱 방법을 사용할 수 있다.

이에 대한 그림은 아래와 같이 표현된다.

(빨간색은 넘겨주는 속도가 느린경우, 보라색은 이 속도가 최적화되어 빨라진 경우이다.)

 

가장 좋은 예시는 아래와 같이 GPU 사용률을 100%로 만드는 것이다. ( GPU-Util ) 

 

그러면 이러한 의문이 생길 수 있다.

 

"무조건 많은 CPU코어를 data proceccing에 할당해 주면 좋은거 아닌가?"

 

이 질문에 대한 대답은 

 

"꼭 그렇지는 않다" 이다.

 

CPU 코어의 수는 한정되어 있으므로 적당한 수를 지정해주는 것이 좋고, 

(CPU 코어는 데이터 로딩 이외에도 다른 일을 해야 되므로..) 

 

코어의 절반 정도를 사용하면 적당하다고 이야기 하고 있다.

 

자세한 내용은 아래 링크 참고.

 

https://jybaek.tistory.com/799

 

DataLoader num_workers에 대한 고찰

Pytorch에서 학습 데이터를 읽어오는 용도로 사용되는 DataLoader는 torch 라이브러리를 import만 하면 쉽게 사용할 수 있어서 흔히 공식처럼 잘 쓰고 있습니다. 다음과 같이 같이 사용할 수 있겠네요. fr

jybaek.tistory.com

 

 

 

728x90

'Pytorch' 카테고리의 다른 글

Pytorch : Variable() 클래스 사용용도 및 의미 (현재는 필요없음)  (0) 2021.09.09
Deep learning model code basic structure  (0) 2021.04.28
THOP: PyTorch-OpCounter  (0) 2021.04.01
visualization  (0) 2020.08.05
torch.utils.data.DataLoader  (0) 2020.06.20
728x90

디리클레 분포(Dirichlet Distribution)는 Beta distribution을 다항분포 형태로 확장시킨 분포이다.

디리클레 분포의 수식은 아래과 같이 표현되며 α는 디리클레 분포의 하이퍼 파라메터 벡터이다.

 

 

예시는 아래와 같다.

 

가위/바위/보는 3가지 경우가 나타나는 사건이므로 다항분포(카테고리 분포)에 속합니다. 따라서 관측 사건이 다항분포이므로, 사전확률을 다항분포의 켤레 분포인 디리클레 분포를 사용하면 손쉽게 사후확률 분포를 계산할 수 있겠죠.

 

  1. 그러므로 친구가 가위/바위/보를 내는 확률 X는 디리클레 분포를 따른다고 가정하고 시작합시다. 관측된 값이 없으므로 하이퍼 파라미터 3개는 모두 1로 주었습니다.
    사전 확률 분포: X ~ Dir(1, 1, 1)
  2. 가위바위보 5판을 했는데, 친구가 (가위, 바위, 보) = (2, 2, 1) 번을 냈습니다. 
    관측값: (2, 2, 1)
  3. 관측값을 바탕으로 사후 확률분포를 계산합니다. 디리클레 분포의 하이퍼 파라미터를 각각 (2, 2, 1) 씩 키워주면 되겠죠.
    사후 확률 분포: X' ~ Dir(3, 3, 2)
  4. 가위바위보 3판을 더했는데, 친구가 (가위, 바위, 보) = (0, 1, 2)번을 냈습니다.
    관측값: (0, 1, 2)
  5. 관측값을 바탕으로 사후 확률분포를 또 업데이트합시다.
    새로운 사후 확률 분포: X'' ~ Dir(3, 4, 4)

처음 단계에서 친구가 가위/바위/보를 낼 확률이 (0.25, 0.25, 0.5)일 가능도는 다음과 같겠죠.

 

3번에 이르렀을 때, 친구가 가위/바위/보를 낼 확률이 (0.25, 0.25, 0.5)일 가능도를 계산하고자 하면 다음과 같이 됩니다.

 

5번에 이르렀을 때, 마찬가지로 (0.25, 0.25, 0.5)일 가능도를 계산하면 다음과 같이 되겠죠. (실제 계산방법은 생략했습니다. 컴퓨터가 알아서 해줄테니깐 계산식에 집착할 필요는 없다고 생각합니다.)

 

관측 과정을 통해 가능도가 바뀌어나가는 것을 확인할 수 있죠. 따라서 베이즈 추론과 디리클레 분포를 이용하면 친구가 가위/바위/보를 낼 확률값이 어느 정도인지 추정해볼 수 있습니다.

 

 

 

이러한 디리클레 분포는 토픽 모델링에 사용된다.

 

 

728x90
728x90

베이지안 추론의 경우, 사건(event)의 확률을 계산할 때, 사전 확률 (prior probability)를 함께 고려한다는 점이 핵심이다.

이를 통해, 단순히 관측만으로는 편향되어 추론되는 확률을 좀 더 정밀하게 조절할 수 있다.

 

 

문제는 사전확률을 정의하고 사후확률 (poterior probability)를 구했을 때, 사후 확률이 실제로 분석하기 굉장히 복잡해진다는 단점이 있다는 것이다. (적분 계산이 필요한데, 적분이 매우 복잡해짐)

 

이때, 사전확률을 특정 사전확률분포를 사용하면, 이와 같은 적분 계산이 쉬워짐을 발견하였고, 이를 conjugate prior라고 부른다.

(conjugate prior는 likelihood, p(X|0)과 비슷한 형태를 띄고 있다는 것이 특징이다. 덕분에 곱해도 수학적 형태가 많이 바뀌지 않고는다. 이 덕분에 적분이 간단해 진다.)

 

이때, 이항분포의 conjugate prior는 Bata distribution으로 다음과 같이 표현된다.

이때, 알파 베타는 각각 (A사건이 일어난 횟수 +1) , (B사건이 일어난 횟수 +1) 을 의미한다.

이때, B~(1,1)은 A사건, B사건이 둘다 일어난 횟수가 0인 경우로, '앞으로 사건이 발생할 확률의 분포'는 편향되지 않고 일정해야 된다.

 

그러나 만약 2번 앞면이 나오고 1번 뒷면이 나왔다고 가정하면, 이전의 경험을 통해 앞면이 나올 확률이 (2/3)으로 판단되는 상황이고, 이를 Beta distribution으로 표현하면 B~(3,2), 즉 다음과 같이 사전확률이 표현된다.

( 앞면이 나올 확률 2/3 인 부분이 가장 높음)

 

 

이때, 사건의 가짓수가 2가지이면 이항분포와 Beta distribution을 사용하고,

사건의 가짓수가 2가지 이상인 경우, Multinomial distribution과 Dirichlet 분포를 함께 사용한다.

 

 

 

https://bab2min.tistory.com/567

 

[잠재 디리클레 할당 파헤치기] 1. 베이즈 추론

작년에 토픽 모델링이라는 개념을 접하고 깜짝 놀랐어요. 그냥 적당한 크기의 문헌들을 넣어주면 거기에서 적절하게 컴퓨터가 연관된 단어들을 묶어서 주제 분포를 만들어주고, 문헌별로 주제

bab2min.tistory.com

 

728x90
728x90

- "proto"로 시작하는 .py파일을 삭제할 때,

find . -name "*proto.py" -delete

 

 

 

-"proto"로 끝나는 .py파일을 삭제할 때,

find . -name "proto*.py" -delete

 

 

-"proto"가 포함되는 .py 파일을 삭제할 때,

find . -name "*proto*.py" -delete

 

 

https://itholic.github.io/linux-find-rm/

 

728x90

'Terminal' 카테고리의 다른 글

Point pip command to python 3.8 from 3.6 on ubuntu  (0) 2021.06.14
chown : 권한 변경 명령어  (0) 2021.06.08
윈도우 to 리눅스 파일전송  (0) 2021.05.18
VIM 문자 치환 방법  (0) 2021.05.17
scp 서버 파일 전송  (0) 2021.05.07
728x90

Paper

https://arxiv.org/abs/1806.05236

 

Manifold Mixup: Better Representations by Interpolating Hidden States

Deep neural networks excel at learning the training data, but often provide incorrect and confident predictions when evaluated on slightly different test examples. This includes distribution shifts, outliers, and adversarial examples. To address these issu

arxiv.org

Code (unofficial)

https://github.com/DaikiTanak/manifold_mixup

 

DaikiTanak/manifold_mixup

pytorch implementation of manifold-mixup. Contribute to DaikiTanak/manifold_mixup development by creating an account on GitHub.

github.com

 

 

Introduction

 

- 기존 딥러닝 네트워크의 문제 중 하나는 over-confident하다는 문제가 있다.

- manifold-mixup은 기존 image-level에서 mix를 한 mix-up 논문과 달리 hidden-representation을  mix한 논문이다.

- 이러한 manifold-mixup을 활용하면 regulaizer 역할을 하기 때문에 over-confident 문제를 완화하는 효과가 있다고 주장한다.

- 또한 mix된 hidden representation부분에서 학습이 이루어지기 때문에 smoothing된 decision boundary를 얻을 수 있다고 한다.

- 이러한 결과들이 일어나는 이유로 class-representation을 flatten하기 때문이라고 이야기하고 있다.

- 이때 , flatten의 의미는 class마다 해당하는 feature의 variance의 방향이 줄어든다는 것이다.

- 본 논문에서는 flatten이 왜 일어나는지 증명하고 이를 통해서 어떠한 효과가 있는지 설명하고 있다.

( over-confident 완화 & smoother decision boundary)

 

 

아래 그림은 위의 내용을 담고 있다.

- (a)는 기존 딥러닝 네트워크의 decision boundary를 보여주고 있다. 

- (b)는 manifold mixup를 적용한 딥러닝 네트워크의 decision boundary를 보여주고 있다. (smoothing 되었음)

- (d)는 기존 딥러닝 네트워크의 Confidence 값을 나타내고 있다. -> high confidence에 집중하고 있는것을 보여줌.

- (e)는 manifold mixup을 적용하는 경우 confidece 값이 적절히 분포하게 됨을 알 수 있다.

 

 

 

Manifold Mixup Flattens Representations

 

 

저자는 왜 Manifold-Mixup이 feature representation을 flatten하는 효과를 가져오는지 설명한다.

수학적으로 설명하는 부분은 논문에 있고, 직관적으로 설명하는 부분은 Appendix F에 있다. 

 

위의 왼쪽 그림을 보면 A1과 B2의 mixup 결과는 회색과 같다. 그리고 A1와 B2와 mixup과의 거리를 볼 때, 50% red, 50% blue로 soft label을 정할 수 있다.

 

위의 중간 그림을 보면 A1과 B2의 mixup 결과는 회색과 같다. 그리고 A1와 B2와 mixup과의 거리를 볼 때, 5% red, 95% blue로 soft label을 정할 수 있다.

 

이때, 왼쪽과 중간 그림의 mixup 결과는 둘다 매우 비슷하다. 그러나 soft-label 결과는 매우 다른 상황이다. 

 

network를 mixup 결과와 softlabel 결과가 비슷하게 되도록 optimization이 되게 되고 결과적으로 위의 오른쪽그림과 같이 A2를 이동시킨다. 이러한 작업의 결과로 feature representaion이 flatten 되게 된다. 

 

728x90
728x90

객체가 클래스의 하위 인스턴스 인지 여부를 확인하는 Method.

 

ex)

 

isinstance(1, int)  -> True 반환 ( 1은 int 클래스의 인스턴스이므로)

 

isinstance(1.4 , string) -> False 반환 (1.4는 string 클래스의 인스턴스가 아니므로)

 

마찬가지로 

 

test=Test()

 

isinstance(test, Test) -> True

 

https://sonseungha.tistory.com/509

 

[python] isinstance

isinstance() 의 설명은 아래와 같습니다. Return whether an object is an instance of a class or of a subclass thereof. A tuple, as in isinstance(x, (A, B, ...)), may be given as the target to check ag..

sonseungha.tistory.com

 

 

728x90
728x90

Paper

https://arxiv.org/abs/2103.15086

 

Learning Placeholders for Open-Set Recognition

Traditional classifiers are deployed under closed-set setting, with both training and test classes belong to the same set. However, real-world applications probably face the input of unknown categories, and the model will recognize them as known ones. Unde

arxiv.org

 

 

Code

 

없음

 

 

Introduction

 

기존 openset recognition 방법의 경우, logit 또는 softmax output 확률 값을 이용한 openset 방식을 사용하였다. 

그러나 이러한 방법의 경우 위 그림 왼쪽과 같이 기존 클래스와 확연히 다른 경우 logit or softmax 값이 낮게 나와 openset 분류가 가능하지만, 위 그림 오른쪽과 같이 기존 클래스와 비슷한 클래스의 경우 기존 thresholding 방법으로는 구분이 어렵다.

(기존 closed set output과 비슷한 logit이 나옴)

 

이러한 문제를 해결하기 위해서 본 논문에서는 Novel Class 를 위한 Placeholder를 만든다.

먼저 기존의 closed-set 만을 표현하는 Classifier를 확장시킨다. (Augmented)

이때 추가된 Classifier를 classifier placeholder라고 표현한다.

이를 통해 각 클래스 마다 known과 unknown을 구분하는 class-specific threshold를 만든다.

 (원래는 class마다 동일한 threshold로 known과 unknown를 구분하였음)

 

 또한 novel class의 distribution을 학습하기 위해서 'data placeholder'를 이용한다. data placeholder는 manifold mixup을 활용하여 open class의 instance를 생성하며 이를 openset training data로 활용하여 training에 활용한다.

 

Method

 

- Learning Classifier Placeholders

 

Classifier Placeholder는 dummy classififer를 만들어주는 방법이다.

수식으로 표현하면 다음과 같다.

 

왼쪽의 경우 기존의 classifier이고 오른쪽의 경우 추가로 Augmented(추가된, 확장된) classifier weight이다.

이때, embedding network, phi는 둘다 같다.

 

그리고 dummy classifer는 일단 dummy class 하나만을 표현한다. 

 

이러한 dummy classifier는 class마다 threshold를 지정하기 위해 사용되며, 따라서 특정 target class에 가깝게 embedding 되도록 유도한다. 따라서 아래와 같은 식으로 optimization 한다.

 

왼쪽의 loss식은 augmented된 classfier의 logit을 target class y에 optimization하는 것이고, (일반적인 classification loss와 같다고 보면 된다.) 오른쪽의 식은 augmented된 classifier에서 target class y를 제거하고, 이를 open-class, K+1 에 optimization하는 것이다. 이를 통해서 dummy classifier의 weight는 target classifier의 weight와 가까운 위치에 optimization이 된다. (target-class와 non-target class의 사이) 이때 하나의 class만이 아닌 모든 class y에 대해서 이를 행하게 되면 결국 dummy classifier를 중앙을 나타내는 weight가 된다.

 

이렇게 하는 이유는 따로 openset sample이 일단 없는 상황에서도 중앙 부분의 decision boundary를 형성하는 classifier를 만들기 위해서 이다.

 

이때 첫번째 loss term을 통해서 classification 성능을 유지하며, 두번째 loss term을 통해서 dummy classifier가 다른 class center (classifier weight) 보다 더 가깝게 위치하도록 유도된다. 

 

이는 특정 instance가 기존에는 closed set으로만 prediction되도록 한정되어 있었다면, class 마다 closed-set 혹은 dummy classifier (open-class)로도 prediction 될 수 있도록 optimization하는 것이다.

 

 

-Learning multiple dummy classifiers

 

이러한 dummy classifier는 여러개를 사용할 수 있다. C개 만큼 사용하면 다음과 같이 표현이 가능하다.

이렇게 여러개의 dummy classifier를 사용하는 경우 dummy logit은 max값 하나만 이용한다.

(가장 가까운 dummy classifier만 업데이트, 나머지 다 하면 나머지도 그쪽 Class로 당겨짐.. 그럴 필요 없음)

이를 통해 openset class의 경계를 좀 더 디테일하게 설정이 가능하다. (경계가 여러개 벡터로 형성..)

 

 

 

-Learning Data Placeholders

 

논문에서는 openset boundary를 설정하기 위한  classifier placeholder 뿐만아니라 openset instance를 생성하여 learning에 활용한다. 이때 openset instance를 data placeholder라고 지칭한다.

 

openset instance를 생성하기 위해 manifold mixip을 사용한다. 먼저 layer를 다음과 같이 표현한다.

이때 manifold mixup를 pre-layer를 통과한 middle-level feature를 통해서 수행하며 수식으로 표현하면 다음과 같다.

이때 람다는 Beta distribution에서 sampling하며 결정한다. (Mixup, Manifold Mixup에서 사용한것과 동일함)

 

manifold mixup을 사용하는 이유는 이를 통해서 low-confidence를 만들 수 있기 때문이다. 

(이 부분은 manifold mixup 논문을 읽어봐야 할듯 함)

 

이러한 mix-up 과정은  mini-batch 내에서만 이루어진다.

 

이를 통해 생성된 x_pre를 openset instance로 분류하며 아래와 같이 openset으로 분류하도록 트레이닝한다.

 

이를 그림으로 나타내면 아래와 같다.

 

 

 

Discussion about vanilla mixup

 

왜 vailla mixup이 아니라 manifold mixup을 활용했는가?

 

본 논문의 저자는 다음과 같이 주장한다. (솔직히 뭔소린지 모르겠음)

 

- vanilla mixup을 활용할 경우 다음과 같이 mix한 결과가 openset instance가 아닌 another class k instance와 유사할 수 있음

 

-> 근거없는 주장인듯

 

그러나 manifold mixup의 경우 can move the decision boundary away from the data in all directions

-> manifold mixup 논문을 봐야될듯..

 

 

Calibration and Guideline for Implementation

 

Closeset의 경우에 high-confidence가 나오지만, openset의 경우 open-class instance및 dummy classifier 또한 embedding space의 중앙에 위치하기 때문에 confidence 값 자체가 기본적으로 낮게 나온다. 

 

때문에 dummy classifier를 이용해 openset을 분류할 경우, logit값의 크기를 맞춰주는 Calibration  작업이 필요하다.

 

Calibration 작업을 수행하기 위해 val dataset을 사용한다.

 

val dataset 을 이용해 다음을 계산한다.

 

 

결과적으로 다음과 같이 bias를 추가하여 calibtration을 한다.

이때 bias의 값은 val dataset의 95% 이상이 known으로 예측되는 값을 이용한다.

(val dataset이 known data로만 이루어져 있기 때문)

 

 

 

Training process of PROSER

 

 

Experiment

 

openess 정의

 

이때 N_train은 train class의 개수를 의미하며, N_test는 test때 class의 개수를 의미한다.

 

예를 들어 cifar10의 경우 train class는 6개이며, test  class 개수는 10개가 된다.

 

계산을 하면, 1- root ( 6/10)  = 22.54%가 된다.

 

이런식으로 계산을 하면 각 데이터셋 마다 다음과 같은 Openness score가 나온다.

 

mnist, svhn, cifar10 : 22.54%

cifar+10 , cifar+50 : 46.55% , 72.78%

Tiny-imageNet : 68.37%

 

 

backbone : GdFR과 같은 backbone

 

결과는 다음과 같음 (AUROC)

 

 

- Plain CNN과 Closed-set acc 비교

 

 

Openset Recognition Test

- GdFR metric 그대로 사용하였음

- MNIST와 Cifar10 데이터셋으로 학습시킨 후 ImageNet-crop, resize & LSUN-crop , resize Test dataset을 openset으로 test

- macro-averaged F1-scores로 측정한다.

 

- Mnist 같은 경우 known과 unknown dataset을 1:1로 구성한다.

 

-Cifar-10 같은 경우, Imagenet과 LSUN dataset으로 test를 하는데, Cifar-10과의 이미지 resolution을 맞추기위해서 32x32로 resize하거나 crop하여 test한다.  

 

 

 

 

Ablation study

 

본 논문에서는 Cifar100 dataset에서 ablation study를 수행했으며, 100개의 Class 중에서 15개의 class는 known, unknown class는 다음과 같이 조절하면서 실험하였다.  (randomly selected) 이에 따른 openness는 29.29% ~ 61.28%로 변한다.

 

위와 같은 setting으로 macro F1-score를 측정했으며, 결과는 아래와 같다.

 

 

이때 Mixup은 data placeholder 만을 사용한 것이며,

Dummy는  classifier placeholder만을 사용한 것이다.

 

 

Visualization of Decision Boundaries

 

위는 decision boundary를 visualization한 것이다. 첫번째와 두번째 그림은 일반적인 thresholding method를 사용했을 때, decision boundary를 나타낸 것으로, 4번 Class가 openset으로 들어왔을 때는 어느정도 openset으로 잘구분을 하지만, 5번 Class가 openset으로 들어왔을 때는, closed set과 상당히 많이 겹치는 것을 확인할 수 있다. (하늘색 부분 확인)

 

그러나 PROSER의 경우, Class마다 적절한 decision boundary를 결정할 수 있고 따라서 class 5도 잘 구분할 수 있게 된다.

(이 부분에 대해 좀 더 생각해 봐야 될 듯)

 

 

 

 

Pros

 

- open class 에 대한 logit을 따로 설정하였기 때문에, 고정된 threshold (특정 Logit 값)으로 openset을 분류하는 것이 아니라

  adaptive하게 (open class의 Logit이 특정값이 아니라 다른 클래스에 대한 logit보다 높은 값이면 openset) openset으로 분류가 가능하다.

 

- Manifold mixup을 활용하여 decision boundary를 smoothing하고, 또한 low confidence sample을 openset instance로 활용한 것이 도움이 되었음

 

Cons

 

- 여전히 feature가 유사한 클래스를 처리하는 방법은 없지않나.. 생각해봄.

 

 

 

Comparison with another papars

 

- RPL과 비교하면 유사한점은 openset을 featrue space의 중앙으로 mapping 시키도록 유도한다는 점이다.

- 차이점은 openset만을 위한 logit을 따로 두어 adaptive한 openset threshold를 설정한다는 장점이 있다.

- 또한 Manifold Mixup을 활용하여 openset training을 한다는 장점이 있다.

(RPL도 openset training 형태가 들어가 있기는 하지만 본 논문이 좀 더 적합해 보임)

(RPL은 Meta learning 형태로 기존의 closed-set을 openset으로 가정하여 trainig하기 때문에 실질적으로 openset이라고 보기 힘듬)

(그러나 manifold mixup은 실질적으로 low-confidence sample을 생성한 것이기 때문에  좀 더 적합한 openset sample이라고 생각함.)

-RPL의 경우는 open space의 크기를 줄인다는 장점이 더 있음.

 

728x90
728x90

여러가지 방법이 있으나

 

크게 2가지 방법이 있다.

 

1) sftp

2) scp

 

sftp는  secure ftp의 줄임말로서, 원래 암호화 없이 전송을 하던 ftp 전송방식을 암호화 한 방법이다.

sftp 명령어 및 계정@서버주소를 통해서 접속하고, 'get' , 'put' 명령어를 통해 파일을 주고 받을 수 있다.

 

그러나 한글이 깨지고 tap명령어를 통해 파일명이 자동완성이 안된다는 단점들이 있다.

 

그래서 scp를 사용하는 방법이 있는데, scp의 경우 ip가 존재해야 전송이 가능하기 때문에

와이파이로 연결되어 있는 경우, 전송이 어렵다는 단점이 있다.

 

결론 -> winscp를 쓰자.

 

자세한 사항은 아래 사이트 참고.

https://whitewing4139.tistory.com/105

 

20. Linux - 윈도우와 리눅스 사이 파일 이동 시키기(SCP, SFTP)

지난 포스팅에서 공개키를 이용하여 리눅스에 비밀번호 입력 없이 SSH 접속하는 방법에 대해 알아보았다. 그런데, 해당포스팅만 보신 분들이라면, 도대체 어떻게 윈도우의 파일을 리눅스로 옮겼

whitewing4139.tistory.com

 

728x90

'Terminal' 카테고리의 다른 글

chown : 권한 변경 명령어  (0) 2021.06.08
Terminal 특정 이름 포함 파일 삭제  (0) 2021.05.27
VIM 문자 치환 방법  (0) 2021.05.17
scp 서버 파일 전송  (0) 2021.05.07
서버 재실행 : sudo reboot  (0) 2021.01.14

+ Recent posts