local to remote (보내기)

scp -P 1234 myfile user@192.168.0.10:/home/location

서버의 주소는 192.168.0.10, 포트는 1234일 때 user란 아이디로 connect하고 /home/location 에 myfile을 보내고싶을때

 

(파일 여러개 보내고 싶은경우는 myfile myfile1처럼 이어 붙이기만 하면 됩니다.)

(폴더를 보내고 싶을 땐 파일명 위치에 -r 옵션과 함께 폴더명을 적으면 됩니다!)

 


remote to local (받기)

scp -P 1234 user@192.168.0.10:/home/location/file1 /loc/

192.168.0.10:1234 의 서버에 user란 아이디로 연결하고, 서버의 /home/location/ 경로에 위치하고 있는 file1파일을 내컴퓨터의 /loc/ 경로에 받아오고 싶을 때


(보내기와 마찬가지로 여러파일 받아오고 싶을때, 파일경로를 띄어쓰기로 구분하여 모두 입력하고 쌍따옴표(")로 묶고, 다음위치에 저장하고싶은 경로를 작성하면 됩니다.)

(폴더를 받고 싶을 때, -r옵션을 user앞에 넣어준뒤 파일명 대신 폴더명을 적으면 됩니다!)

 

'short 팁' 카테고리의 다른 글

github "혼자 사용시" 로그인 정보 안풀리게 하기  (0) 2021.07.16
리눅스 링크파일 만들기  (0) 2021.07.15

git config credential.helper store

최초 주소, 패스워드 입력 후 다음번 푸시, 풀 할 때 안물어봅니다~

'short 팁' 카테고리의 다른 글

scp 우분투 파일전송  (0) 2021.07.18
리눅스 링크파일 만들기  (0) 2021.07.15

Total Relighting: Learning to Relight Portraits for Background Replacement [Total Relighting]

'paper' 카테고리의 다른 글

GAIL  (0) 2021.07.14
Distributional Reinforcement Learning Algorithm  (0) 2021.07.14
RL-GAN  (0) 2021.07.14

ln -s 원본위치 링크이름

=> 현재폴더에, 원본위치에 해당하는 바로가기를 링크이름으로 생성해준다.

'short 팁' 카테고리의 다른 글

scp 우분투 파일전송  (0) 2021.07.18
github "혼자 사용시" 로그인 정보 안풀리게 하기  (0) 2021.07.16

 우리가 단번에 떠올리는 인공지능은 이미지, 텍스트, agent와 같이 복잡한 문제를 해결하는 것으로 볼 수 있지만

갑자기 든 생각으로, 아주 기초적이고 간단한 문제를 딥러닝 모델을 활용해 풀어보려고 합니다.

 

 우선 아무 생각 없이 fc layer 몇 개 쌓고 했더니 답이 제대로 나오는 게 하나도 없어서 구글링을 통해 LSTM으로 구현해보았습니다.

 

 

먼저 계산 모델이 필요하겠죠? 풀코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from tensorflow.keras import layers
from tensorflow import keras
 
class Calc:
    def __init__(self):
        pass
 
    def build_model(self):
        n_numbers = 2
 
        model = keras.Sequential()
        model.add(layers.LSTM(6, input_shape=(n_numbers, 1), return_sequences=True))
        model.add(layers.LSTM(6))
        model.add(layers.Dense(1))
        model.compile(loss='mean_squared_error', optimizer='adam')
 
        return model    
cs

 

 

1
2
from tensorflow.keras import layers
from tensorflow import keras
cs

우선 model 시작을 위해 keras를 불러오고, layer를 쌓기 위해 layers를 import 합니다.

 

다음으로 계산 모델을 쉽게 관리하기 위해 클래스로 만들어 관리하였습니다.

1
2
3
4
5
6
7
8
def build_model(self):
    n_numbers = 2
 
    model = keras.Sequential()
    model.add(layers.LSTM(6, input_shape=(n_numbers, 1), return_sequences=True))
    model.add(layers.LSTM(6))
    model.add(layers.Dense(1))
    model.compile(loss='mean_squared_error', optimizer='adam')
cs

4번 줄을 시작으로 sequential을 생성하고

5,6,7번 줄과 같이 층을 add 합니다.

5번 줄의 인풋 사이즈가 2,1 인 이유는 우리가 알다시피 사칙연산할 때 숫자 두 개를 가지고 연산을 하기 때문에 2입니다!

6번 줄을 거쳐 7번 줄에선 아웃풋으로 1개를 뽑아줍니다. 이유는 당연하게도 사칙연산 후 결과는 한 개이기 때문입니다.

8번 줄을 통해 loss function과 optimizer을 정해줍니다. 로스로 mse를 선택했고 optim으로 adam을 정하였습니다.

 

1
return model
cs

모델을 리턴함으로써 학습을 진행할 수 있습니다.

 

 하지만 모델만 있다고 해서 학습이 되는 것은 아니고, 학습에 필요한 데이터가 필요합니다.

 우리가 필요한 데이터란 사칙연산에서 사용되는 입력 1, 입력 2, 기호, 결과 총 4개 컬럼이고, 보통 사칙연산 관련 데이터는  공유되어있는 게 없을 수밖에 없고, 따라서 직접 생성하는 게 더 빠르기 때문에 데이터를 생성하는 클래스를 다음과 같이 작성해보았습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import random
import numpy as np
 
class GetData:
    def __init__(self, sign):
        random.seed(1015)
        
        self.sign = sign
        self.res = list()
        self.label = list()
 
 
    def get_data(self):
        if self.sign == "+":
            for i in range(100):
                n1 = random.randrange(1100)
                n2 = random.randrange(1100)
                self.res.append([n1, n2])
                self.label.append(n1+n2)
            x, y = np.array(self.res), np.array(self.label)
            self.x = x.astype('float'/ float(100*2)
            self.y = y.astype('float'/ float(100*2)
            
            self.invert = lambda x : round(x*float(100*2))
 
            return self.x, self.y
cs

 사칙연산인 +, -, x, / 총 4개에 대하여 구해야 하기 때문에 클래스를 만들어 각 케이스마다 부가적으로 구현하였지만 설명은 + 메소드 하나만 해도 다른 기호들은 계산방식만 조금 다르기 때문에 +로 진행하겠습니다.

 

16.  n1 = random.randrange(1100)

17.  n2 = random.randrange(1100)

 16, 17라인에서 볼 수 있듯, 두 개의 무작위 수를 고르고 연산 결과까지 계산하여 데이터를 만들고 결과적으로 학습할 데이터와 레이블 두 묶음을 리턴해줍니다.

 

21.  self.x = x.astype('float'/ float(100*2)

22.  self.y = y.astype('float'/ float(100*2)

 21,22 라인의 의미는 학습을 진행할 때 정규화를 진행해주는 것과 의미가 동일합니다. 정확한 정규화 과정은 아니지만 어느 정도 데이터의 크기를 줄여 예측을 하는 데 있어 이점을 불러오게 됩니다.

 

24.  self.invert = lambda x : round(x*float(100*2))

 따라서 학습 완료 후 평가를 하기 위해 실제 값에 대하여 연산을 진행해야 하기 때문에 24라인의 self.invert 함수를 통해 원래 값으로 복원 후 mse를 계산하게 됩니다.

 

나머지 -,*,/ 기호에 관한 함수는 직접 만들어봐도 좋을 것 같습니다.

급하신 분은 아래 코드를 사용하시면 됩니다!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def get_data(self):
        if self.sign == "+":
            for i in range(100):
                n1 = random.randrange(1100)
                n2 = random.randrange(1100)
                self.res.append([n1, n2])
                self.label.append(n1+n2)
            x, y = np.array(self.res), np.array(self.label)
            self.x = x.astype('float'/ float(100*2)
            self.y = y.astype('float'/ float(100*2)
            
            self.invert = lambda x : round(x*float(100*2))
 
            return self.x, self.y
        elif self.sign == "-":
            for i in range(100):
                n1 = random.randrange(1100)
                n2 = random.randrange(1100)
                self.res.append([n1, n2])
                self.label.append(n1-n2)
            x, y = np.array(self.res), np.array(self.label)
            self.x = (x.astype('float')+float(100)) / float(100*2)
            self.y = (y.astype('float')+float(100)) / float(100*2)
            
            self.invert = lambda x : round(x*float(100*2)-float(100))
 
            return self.x, self.y
        elif self.sign == "/":
            for i in range(100):
                n1 = random.randrange(1100)
                n2 = random.randrange(1100)
                self.res.append([n1, n2])
                self.label.append(n1/n2)
            x, y = np.array(self.res), np.array(self.label)
            self.x = (x.astype('float')*float(100)) / float(100*2)
            self.y = (y.astype('float')*float(100)) / float(100*2)
 
            self.invert = lambda x : (x*float(100*2/ float(100)) # round x
 
            return self.x, self.y
        elif self.sign == "*":
            for i in range(100):
                n1 = random.randrange(1100)
                n2 = random.randrange(1100)
                self.res.append([n1, n2])
                self.label.append(n1*n2)
            x, y = np.array(self.res), np.array(self.label)
            self.x = (x.astype('float')/float(100)) / float(100*2)
            self.y = (y.astype('float')/float(100)) / float(100*2)
 
            self.invert = lambda x : round(x*float(100*2* float(100))
 
            return self.x, self.y
        else:
            import sys
            sys.exit(0)
cs

 

이제 데이터, 모델이 다 완성됐으니 학습하는 코드를 작성해보겠습니다.

1
2
3
4
from calc.calc_model import Calc
import random
import numpy as np
from calc.get_data import GetData
cs

먼저 모델과 데이터 불러오는 코드를 calc 폴더 안에 넣었기 때문에 1,4라인과 같이 작성하였습니다.

2번 라인은 왜 들어있는지 모르겠네요 필요 없습니다!

 

 

다음으로 모델을 불러오겠습니다.

1
2
3
4
5
num_epochs = 1000
 
model = Calc()
model = model.build_model()
#model.summary()
cs

학습시킬 에폭을 정하고, 

모델을 불러온 뒤, build_model 메소드를 통해 모델을 생성합니다.

5번 라인을 통해 모델의 구조를 확인해볼 수도 있습니다.

 

학습 코드는 생각 외로 너무 단순합니다. 데이터 불러오고, 학습시키고.

코드로 보여드리겠습니다~

1
2
3
4
5
6
7
8
for _ in range(num_epochs):
    customData = GetData(calc_sign)
    x, y = customData.get_data()
    x = x.reshape(10021)
 
    model.fit(x, y, epochs=30, batch_size=32, verbose=2)
 
print("Train Fin!")
cs

정말 짧게 학습 코드가 짜여지는 것을 볼 수 있습니다.

몇 에폭을 돌지 반복문 설정 후, 데이터를 생성하여 shape만 모델에 맞게 바꾼 뒤, 바로 모델에 넣어 학습을 진행합니다.

6번 라인의 model.fit의 인자로 epochs가 30인 이유는 해당 제일 바깥에 있는 반복문을 한 번씩 돌 때마다 새로운 데이터를 생성하여 학습을 진행하기 때문에 그 새로운 데이터를 한 번씩만 학습시키기엔 완전하지 않아서 30번 정도로 설정하였습니다.

 

학습결과를 평가하는 코드를 보여드리겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
testData = GetData(calc_sign)
test_data, test_label = testData.get_data()
test_data = test_data.reshape(100,2,1)
 
res = model.predict(test_data)
 
exp = [testData.invert(x) for x in test_label]
pred = [testData.invert(x) for x in res[:,0]]
 
from math import sqrt
rmse = sqrt(mean_squared_error(exp, pred))
print("RMSE :", rmse)
 
err_sum = 0
for i in range(len(exp)):
    err = exp[i] - pred[i]
    print("Real : {}, predicted : {}, err={}".format(exp[i], pred[i], (err)))
    err_sum += err
print("aver Err : {}".format(err_sum/len(exp)))
cs

테스트 데이터를 받아와 5번 라인과 같이 학습시킨 모델에 predict를 진행하여 결과를 담습니다.

7,8번 라인의 의미는 데이터 생성 메소드 설명할 때 작성해 놓았듯, mse계산을 위해 정규화 비스무리 처리해둔 것을 다시 원상복구 해놓는 것입니다.

15~18라인을 통해 모든 값의 에러를 측정하여 더한 뒤 결과로 내놓게 되면 다음과 같이 나옵니다!

 

많은 epoch으로 인해 오버피팅이 된것일까요?

 gpu를 통해 학습하면 금방 진행되는 것 같습니다. 제 결과를 보면 평균 에러가 0으로 나오네요 ㅋㅋ 보통 조금 차이 날 법도 한데 에러가 0으로 나왔습니다!

 학습 데이터와 테스트 데이터를 나누어 진행하였다 하더라도 데이터의 범위가 0부터 100 사이의 값이라 거의 모든 경우를 학습하여 오버 피팅이 된 것 같습니다.

 

모델을 저장해 나중에 사용하고 싶다면(그럴 일은 절대 없겠지만)

1
2
dic = {"+":"plus""-":"minus""*":"multiply""/":"divide"}
model.save('.pretrained/' + dic[calc_sign]+'_model.h5')
cs

위와 같이 작성해주시면 폴더 생성 후 모델을 세이브해두게 됩니다!

 

 곱셈 나눗셈도 진행해보면 재밌을 것 같네요!

곱셈 학습결과

 포스팅 마치고 곱셈도 돌려보았는데 엄청난 에러를 보이진 않네요. 어느정도 비슷한 값까진 가져오는 것을 볼 수 있습니다. 에러가 0인 결과도 몇몇 있긴 하네요.

 그래도 사칙연산하는 모델인데 정확도가 중요할 수도 있겠지만 여기서 정확도를 따지려면 그냥 계산기 돌리는게 낫겠죠? ㅋㅋ

 아무튼 재밌는 시간이었습니다!!

감사합니다!!

GAIL :Generative Adversarial Imitation Learning [GAIL]

'paper' 카테고리의 다른 글

Total Relighting  (0) 2021.07.15
Distributional Reinforcement Learning Algorithm  (0) 2021.07.14
RL-GAN  (0) 2021.07.14

C51 : A Distributional Perspective on Reinforcement Learning [C51]

 

QR-DQN : Distributional Reinforcement Learning with Quantile Regression [QR-DQN]

 

IQN : Implicit Quantile Networks for Distributional Reinforcement Learning [IQN]

'paper' 카테고리의 다른 글

Total Relighting  (0) 2021.07.15
GAIL  (0) 2021.07.14
RL-GAN  (0) 2021.07.14

RL-GAN-Net: A Reinforcement Learning Agent Controlled GAN Network for Real-Time Point Cloud Shape Completion

[RL-GAN]

'paper' 카테고리의 다른 글

Total Relighting  (0) 2021.07.15
GAIL  (0) 2021.07.14
Distributional Reinforcement Learning Algorithm  (0) 2021.07.14

몇 년 전, 공익근무 관련 업무 자동화로 이슈가 있었던 토픽입니다!

 

엄청난 스크린샷 업무를 파이썬 하나를 통해 몇 달 걸릴 일을 단숨에 끝냈다고 하네요.

마침 스크린샷 후 pdf파일 만들 일이 생겨, 상기 시나리오를 기반으로 구현을 해보려고 합니다.

 

 

우선 전체코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
import pyautogui
 
page = 250
for i in range(page):
    try:
        pyautogui.screenshot('filename'+str(i)+'.png', region=(200,300300,300))
    except:
        pass
    pyautogui.click(900,2000, button='left', clicks=1, interval=1)
cs

 

 

1
2
3
import pyautogui
 
page = 250
cs

 먼저, 우리가 사용할 라이브러리는 pyautogui 입니다.

 

 

 이 라이브러리를 통해 스크린샷과 원하는 위치를 클릭하는 기능을 구현할 것입니다.

 

 페이지는 원하시는 만큼 할당해 주시고,

 

 

1
2
3
4
5
for i in range(page):
    try:
        pyautogui.screenshot('filename'+str(i)+'.png', region=(200,300300,300))
    except:
        pass
cs

 반복문을 돌며 pyautogui.screenshot 함수를 통해 스크린샷을 찍게 되는데 먼저 저장 파일명이 인자로 들어가고,

위치를 지정해줘야 하는데 region에 차례로 시작할 x좌표, y좌표, x크기, y크기 가 들어가게 됩니다.

 

 try 문으로 감싸주는 것은 대용량 작업 시 뻑날 경우를 대비해서 추가해보았습니다

라고 하고 싶었지만, 사실은 코드 다 작성하고 오류가 나길래 귀찮아서 오류 읽지도 않고 오류 날 만한 곳 try로 묶었다가

계속 안되길래 확인해보니 Pillow라이브러리 설치가 안돼 있었습니다 ㅠㅠ

 설치 후 잘 동작하길래 안 지우고 놔두었습니다 ㅋㅋ!! 

 

 

1
pyautogui.click(900,2000, button='left', clicks=1, interval=1)
cs

 마지막으로, 클릭해서 페이지를 넘기거나 정보를 수정해야 하기 때문에, pyautogui.click함수를 활용하여 클릭을 하게 됩니다.

 인자를 차례로 보면, 클릭할 x좌표, y좌표, clicks에서 볼 수 있듯 몇 번 클릭할지, interval은 클릭 사이 간격을 몇 초로 둘 것인가를 설정하는 것입니다.

 이 interval로 인해 중간에 따로 sleep함수를 걸어주지 않아도 알아서 중간중간 실행을 기다릴 수 있습니다.

 

실행 후 생성된 스크린샷.png

 이로써 구현 완료입니다! 저는 여러 사진들을 캡쳐한 뒤 pdf로 묶어서 관리하려고 이 기능을 사용했네요.

 pyautogui 라이브러리에 좋은 기능들 입맛대로 수정해보면서 사용해보는 것도 재밌을 것 같아요!

 

감사합니다~

'Python' 카테고리의 다른 글

Python OS.PATH  (0) 2015.08.16
Python: SYS  (0) 2015.07.31
Python:FOR  (0) 2015.07.26

이번엔 switch  와 case, for, while, continue문을 볼거에요.




첫번째로 switch case 뭔가 감이 오시나요? 


switch 스위치 들어보셨죠.. 스위치 불 키고 끄고 할수 있는 스위치.


case 이런케이스 저런케이스, 경우를 뜻하는거 같구요!


소스 보고 가시죠!


public class test {

public static void main(String[] args) {

int n = 3;

switch(n)

{

case 1:

System.out.println("1");

break;

case 2:

System.out.println("2");

break;

case 3:

System.out.println("3");

break;

default:

System.out.println("not");

}

}

}


결과는 

3 입니다.


소스에서 switch 옆에 괄호 속에 n이 있죠?


그건 위에서 선언한 int 형 변수입니다.


그걸 이런케이스 저런케이스 그곳에 맞춰보는거죠.


n은 3이라고 선언이 되어있으니,


case 중에서 3이라는 경우로 가서 그걸 실행해주고 break문을 만나서 가장 가까운 중괄호를 빠져나오게 됩니다.




default는 케이스들이 아무것도 맞지 않다면 그때 실행되는 것입니다.


여기서 break들이 왜 나오냐 하면 case문은 맞는 조건을 찾게되면 그밑으로는 쭉 실행하게 됩니다. 직접해볼게요!


소스!


public class test {

public static void main(String[] args) {

int n = 1;

switch(n)

{

case 1:

System.out.println("1");

case 2:

System.out.println("2");

case 3:

System.out.println("3");

default:

System.out.println("not");

}

}

}


결과 : 

1

2

3

not


이렇군요 ㅋㅋ

break는 꼭 써주셔야 조건에 맞는 행동을 하고 빠져나온다는것 알고계세요!




이젠 for문과while문 보여드릴게요.


for = ~동안 while = ~동안 


의미가 둘이 비슷한 느낌이죠? 프로그래밍에서도 그렇습니다. 옆에 괄호가 들어갈때 들어가는 내용이 좀 다르긴 하지만요..ㅋㅋ


소스 보여드릴게요.


public class test {

public static void main(String[] args) {

int n=0;

for(int i=0;i<5;i++)

System.out.println(i);

while(n<5)

{

System.out.println(n);

n++;

}

}

}


결과 : 

0

1

2

3

4

0

1

2

3

4


01234 가 두번나와있죠?

이건 for문과 while문에서 똑같은 결과가 나온겁니다..

일단 보시면 for문 괄호 안에 int  i =0 이 있죠? 괄호 속에서 int 형 변수 i 를 생성한겁니다. 휘발성이에요. 

저 for 문이 끝나면 int i 는 찾을수 없게 됩니다.

세미콜론 옆을 보시면 i<5가 있죠? i<5일때 까지 실행하라는 겁니다.

그옆을 보시면 i++이 있죠? 밑의 소스를 한번 실행할때마다 i++도 같이 실행됩니다.

그래서 i가 증가하게 되고 i<5라는 조건에 맞지 않게 되어 for문을 벗어나게 되는겁니다.

그래서 i가 5가 되면 i<5 의 조건을 만족하지 못하기 때문에 튕겨져 나고오 while문으로 넘어가게 됩니다.



while문에선 괄호 안에 n<5가 있지않습니까? n<5일때까지 괄호속의 내용을 실행하는겁니다. for문하고 기능이 다를게 없지 않냐!

하지만 여기선 i++ 이런 걸 적어줄 필요가 없습니다. 그래서 코딩 실수 나오면 무한루프를 돌기도 합니다. ㅋㅋ

무한 루프의 뜻은 괄호속의 내용을 무한대로 실행한다는 뜻입니다.

강제로 무한루프를 돌고싶으시면


for(;;) 과 while(true) 을 하시면 됩니다. for문에 조건이 안들어가 있으면 무조건 참 while문에 조건이 true 면 무조건 참.


따라서 무한루프를 돌게 됩니다.




continue 문과 break문을 알려드릴게요.


아까 조금 설명해드렸는데 break문을 만나면 가장가까운 중괄호를 빠져나간다고 했죠? 가장가까운거라고 알고계시면 편하지만,


for,while,if이런 문구에 사용되는 중괄호만 빠져나오는 겁니다. 함수의 종료를 생각하시고 그 중괄호를 빠져나가려고 break를 하시면 뻘건줄이 


그어집니다..


함수를 빠져나가시려면 return; 이거만 붙여주시면 종료해버립니다.


여튼 break는 벗어나는 거죠?


하지만 continue는 중괄호의 맨위로 올라가서 다시 조건을 검사하게 됩니다. 아래의 소스들은 전부 무시하고 다시 위로 점프하게 되는겁니다.


쉽게 소스 보세요!


public class test {

public static void main(String[] args) {

int n=0;

while(n++<100)

{

if(n%5 == 0)

continue;

if(n == 13)

break;

System.out.println(n);

}

}

}


결과:

1

2

3

4

6

7

8

9

11

12


보시면 5의 배수경우는 없죠? 나머지 경우들은 있구..


if문에서 n을 5로 나눈 나머지가 0일땐 continue로 맨위로 올라가게 했거든여!


그리구 13은 없죠? 13을 만나면 break해서 끝내버리게 했거든요!


소스와 결과만 보시더라도 쉽게 이해가 가능하실꺼에요 ㅎㅎ



이번 포스팅은 여기서 마칠게요! 다음엔 c에서 배웠던  함수! 


java에선 메소드라고 불립니다. 이걸 공부해 볼게요! 다음포스팅에서 봐요~




안녕!

'JAVA' 카테고리의 다른 글

JAVA 5. 실행 흐름의 컨트롤  (0) 2018.04.04
JAVA 4. 형변환과 연산자  (0) 2018.04.03
JAVA 3. 변수, 자료형  (0) 2018.04.03
JAVA 2. system.out.println  (0) 2018.04.03
JAVA 1. 시작  (0) 2018.04.03

+ Recent posts