블로그
전체 32#태그
- 현대
- 카카오
- 유니콘
- 스타트업
2021. 08. 19.
0
210820 TIL
Docker에서 java 실행할 때, 앱에 대한 변수가 담긴 application.properties를 추가로 넣고 싶을때 FROM openjdk:8 VOLUME /tmp WORKDIR / ADD target/springboot-docker-mysql.jar springboot-docker-mysql.jar ENTRYPOINT ["java","-jar","springboot-docker-mysql.jar","--spring.config.additional-location=application.properties"] 위처럼 additional-location으로 지정해줘야한다. location으로 지정하면 기존에 되어 있던거 날라간다 훠우.. 여러 컨테이너를 각기 다른 네트워크로 띄웠을때... 같은 localhost여도 포트가 허용이 안되어 있으면 api로 서로 데이터를 주고 받을 수가 없다. 즉, 인터넷 브라우져로 서비스를 되는 것을 확인했는데 각자 컨테이너에서 데이터를 끌어오는게 안된다. 이때에는 포트를 오픈시켜줘야함. netstat으로 확인했을때 도커로 인해 tcp로 해당 포트가 열려있는 것 처럼 보이지만 iptables로 확인해보면 열려있지 않다면 오픈 시켜줘야한다. iptables -I INPUT 1 -p tcp --dport 12345 -j ACCEPT 위 명령어를 써서 원하는 포트를 열어주고 다시 통신이 되는지 확인하면 잘 돌아가는 것을 확인할 수 있다. 휴... 오늘도 일하면서 많이 배워간다.. 삽질도 많이 하고
2021. 08. 13.
0
20210812 TIL
저번에 하던 shinyproxy 관련된 내용이다. shinyproxy의 configure file에 해당하는 application.yml 파일에 필요한 정보들을 좀 적어볼까 한다. yaml 파일 또는 yml 파일이라고 부르는 이 파일은 간단하게 생긴 json이라고 보면 될거 같다. https://shinyproxy.io/documentation/configuration/ 이 사이트에 잘(?) 나와있긴 한데 대충 오늘 고생한 부분만 얘기하자면.. specs: - id: app_name container-volumes: ["/host/path:/container/path"] 이 부분에 관한 내용이다. 지금 작업하는 환경은 windows 10에서 wsl2를 이용하여 작업하고 있고, 왜인지는 모르겠지만 도커 컴포즈로 빌드할때 에러가 자꾸 나서 빌드만큼은 wsl2에서 하고 있다.. 그리고 wsl에서 빌드하니 도로 windows로 나가기 귀찮아서 거기서 그냥 docker-compose로 실행했다. 문제는 여기서... 발생. container-volumes의 /host/path를 윈도우 기준으로 했더니 계속 오류가 났다... wsl 기준으로는 wsl의 주소를 넣고, windows10이라면 그 기준으로 넣어야된다... 휴.. 이걸 간과해서 시간을 얼마나 잡아먹었는지 모르겠다..
2021. 08. 10.
0
20210810 TIL
docker compose를 이용해서 r-shiny app을 구동하는 proxy 서버를 띄우는 작업을 해야하는데 r로 이런걸 하는건 처음이라 좀 오래 걸렸다. 반나절을 다 써버렸네... 시간 아깝구로.. 그리고 공식 홈페이지 설명은 개떡같다. 도커고 도커 컴포즈고 네트워크고 잘 모르는 사람이 했다면 시간 엄청 잡아먹었을듯... 역시 프레임워크 선정은 사람이 많이 쓰는걸 해야 에러 잡기가 쉽다. 레퍼런스가 많으니... 아무튼 감사의 의미와 잊지 않겠다는 의미로 아래에 해당 내용을 정리한 것을 붙여넣었다. How to use Download a template: # Download a template git clone git@github.com:kassambara/shinyproxy-config.git cd shinyproxy-config/docker-compose-example Template folder structure: docker-compose-example ├── docker-compose.yml ├── shinyapps │ └── euler-docker │ ├── Dockerfile │ ├── Rprofile.site │ └── euler │ ├── server.R │ └── ui.R └── shinyproxy ├── Dockerfile └── application.yml Content of the docker-compose.yml: version: "3.6" services: shinyproxy: image: datanovia/shinyproxy container_name: dnv_shinyproxy restart: on-failure build: ./shinyproxy networks: - dnv-net ports: - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock - ./shinyproxy-logs/server:/log - ./shinyproxy-logs/container:/container-logs - ./shinyproxy/application.yml:/opt/shinyproxy/application.yml euler: image: euler-docker container_name: dnv_euler build: ./shinyapps/euler-docker networks: - dnv-net networks: dnv-net: name: dnv-net Content of the ShinyProxy application.yaml: proxy: title: ShinyProxy port: 8080 authentication: simple admin-groups: admins users: - name: jack password: password groups: admins - name: jeff password: password docker: internal-networking: true container-network: dnv-net # change this route to your work directory, use absolute path # work-directory: /Users/kassambara/Documents/shinyproxy-docker-compose-example specs: - id: 01_hello display-name: Hello Application description: Application which demonstrates the basics of a Shiny app container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"] container-image: openanalytics/shinyproxy-demo container-network: "${proxy.docker.container-network}" # container-volumes: ["${proxy.work-directory}/apps:/apps"] - id: euler display-name: Euler's number container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"] container-image: euler-docker container-network: "${proxy.docker.container-network}" logging: file: /log/shinyproxy.log Docker uses networks to enable communication between containers. For ShinyProxy to communicate properly with the Shiny App, the network specified in docker-compose.yml must be the same as the same as that listed in application.yml. (Tip, if you’re using a docker-compose file to launch the app, don’t set up the docker network manually, see here for why). Each container listed in services: is named in container_name, with the Dockerfile being pointed to via. the context and Dockerfile variables. If the container was terminated with an error code, the restart line instructs Docker what action is to be taken . The networks variables lists the Docker network that the container has access to. The network used by all applications in this docker-compose must match the network specified in the ShinyProxy application.yml. Building and running # Go into your project folder cd shinyproxy-config/docker-compose-example # Build all docker images docker-compose build # Run shinyproxy docker-compose up -d shinyproxy Visit: http://localhost:8080 To stop shinyproxy use docker-compose down. 이 자료를 공유해주신 분께 무한한 감사를 드린다... So much Thank you. https://github.com/kassambara/shinyproxy-config
2021. 08. 05.
0
20218404 TIL
python 프로세스와 스레드 공부하면서 정리한 것. (1).프로세스 - 운영체제 -> 할당 받는 자원 단위(실행 중인 프로그램) - CPU동작 시간, 주소공간(독립적) - Code, Data, Stack, Heap -> 독립적 - 최소 1개의 메인스레드 보유 - 파이프, 파일, 소켓등을 사용해서 프로세스간 통신(Cost 높음)-> Context Switching 하나의 프로세스 내에서 여러개의 스레드 작동 (2).스레드 - 프로세스 내에 실행 흐름 단위 - 프로세스 자원 사용 - Stack만 별도 할당 나머지는 공유(Code, Data, Heap) - 스레드끼리 메모리 공유(변수 공유) 가능 - 한 스레드의 결과가 다른 스레드에 영향 끼침 - 동기화 문제는 정말 주의(디버깅 어려움) (3).멀티 스레드 - 한 개의 단일 어플리케이션(응용프로그램) -> 여러 스레드로 구성 후 작업 처리 - 시스템 자원 소모 감소(효율성), 처리량 증가(Cost 감소) - 통신 부담 감소, 디버깅 어려움, 단일 프로세스에는 효과 미약, 자원 공유 문제(교착상태), 프로세스 영향준다. (4).멀티 프로세스 - 한 개의 단일 어플리케이션(응용프로그램) -> 여러 프로세스로 구성 후 작업 처리 - 한 개의 프로세스 문제 발생은 확산 없음(프로세스 Kill) - 캐시 체인지, Cost 비용 매우 높음(오버헤드 상승 가능성 높음), 복잡한 통신 방식 사용
2021. 08. 02.
0
20210802 TIL
SQL DISTINCT : 중복을 제거하여 보여줌 A, B, C 컬럼을 SELECT 할때 `SELECT DISTINCT A, B, C ...`으로 한다면 A, B, C의 모두 내용이 똑같은 중복만 제거하여 보여줌. GROUP BY 하나의 컬럼에 대해서 그룹화함. python pandas에서도 dataframe에 group_by가 있는데 꽤 유용하게 썼었고, SQL에도 이와 같은 역할을 하는 것이 있다. GROUP BY를 사용할 때는 두가지를 기억해야 합니다. 특정 컬럼을 그룹화 하는 GROUP BY 특정 컬럼을 그룹화한 결과에 조건을 거는 HAVING * WHERE랑 HAVING을 헷깔리는 경우가 많은데 WHERE는 그룹화 하기 전이고, HAVING은 그룹화 후에 조건입니다. 출처: https://extbrain.tistory.com/56 [확장형 뇌 저장소] 컬럼 그룹화 SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼; 조건 처리 후에 컬럼 그룹화 SELECT 컬럼 FROM 테이블 WHERE 조건식 GROUP BY 그룹화할 컬럼; 컬럼 그룹화 후에 조건 처리 SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼 HAVING 조건식; 조건 처리 후에 컬럼 그룹화 후에 조건 처리 SELECT 컬럼 FROM 테이블 WHERE 조건식 GROUP BY 그룹화할 컬럼 HAVING 조건식; ORDER BY가 존재하는 경우 SELECT 컬럼 FROM 테이블 [WHERE 조건식] GROUP BY 그룹화할 컬럼 [HAVING 조건식] ORDER BY 컬럼1 [, 컬럼2, 컬럼3 ...]; 출처: https://extbrain.tistory.com/56 [확장형 뇌 저장소] GROUP BY에 대해서 잘 정리해주신 블로그 글을 찾아서 공유함.
2021. 08. 01.
0
20210801 TIL
pytorch의 nn.Module을 사용해서 linear layer 구현 방법 import torch.nn as nn # nn.Module 이라고 하는 추상 클래스를 불러와서 하나의 클래스로 구현하여 계산에 이용한다. class MyLinear(nn.Module): def __init__(self, input_dim=3, output_dim=2): self.input_dim = input_dim self.output_dim = output_dim super().__init__() self.W = nn.Parameter(torch.FloatTensor(input_dim, output_dim)) self.b = nn.Parameter(torch.FloatTensor(output_dim)) def forward(self, x): y = torch.matmul(x, self.W) + self.b return y linear = MyLinear(3, 2) # parameters라는 함수를 통해 trainable한 값들을 iterate 해줌. for p in linear.parameters(): print(p) 사실 위에 처럼 복잡하게 안함ㅋ # 사실 위와 같이 low level에서 실행하지 않아도 된다. # 미리 구현되어 있는 아래와 같은 코드로 단순하게 돌려도 된다. # 다만 위와는 다르게 W 가 transpose되어 있다. linear = nn.Linear(3, 2) y = linear(x) 위 처럼 간단하게 linear layer 하나를 생성하고 그 것들이 여러 개 들어있는 multi-linear layer를 아래와 같이 구현한다. class MyLinear(nn.Module): def __init__(self, input_dim=3, output_dim=2): self.input_dim = input_dim self.output_dim = output_dim super().__init__() # 위에서 처럼 low lever에서 parameter를 등록하는 것이 아니라 # 아래와 같이 nn.Linear로 등록해주면 된다. # 여러개의 linear들로 구성된 뉴럴 넷웤을 구성할 수 있다. self.linear = nn.Linear(input_dim, output_dim) def forward(self, x): # |x| = (batch_size, input_dim) y = self.linear(x) # |y| = (batch_size, output_dim) return y 오호링.
2021. 07. 31.
0
20210731 TIL
matrix_multiplication x = torch.FloatTensor([[1, 2], [3, 4], [5, 6]]) y = torch.FloatTensor([[1, 2], [1, 2]]) xx = torch.FloatTensor([1,2]) x * xx x * xx를 계산하면 broadcasting이 되어 계산된다. 수학적인 행렬의 곱을 하려면 단순하게 곱하기가 아니라, torch.mm(x, y) 를 해야한다. 정말 수학에서 처럼 행렬의 사이즈가 맞아야만 하는데 이를 편하게 내부적으로 곱셉을 하게 만들어 주는 함수가 matmul() 이다. 다만, 행렬의 사이즈가 곱셈하기에 맞는 것이 아니더라도 알아서 잘 바꾸어서 계산해주기 때문에, 내가 어떤 형태의 행렬 또는 텐서를 넣어서 계산하는지 파악이 잘 안될 수 있다는 단점이 있다. z = torch.matmul(x, y) xxx = torch.FloatTensor([[1],[2]]) print(x.size()) print(xx.size()) print(xxx.size()) print(torch.matmul(x, xx)) print(torch.matmul(x, xxx)) torch.Size([3, 2]) torch.Size([2]) torch.Size([2, 1]) tensor([ 5., 11., 17.]) tensor([[ 5.], [11.], [17.]]) bmm x = torch.FloatTensor([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]], [[13, 14], [15, 16], [17, 18]]]) y = torch.FloatTensor([[[1, 2, 2], [1, 2, 2]], [[1, 3, 3], [1, 3, 3]], [[1, 4, 4], [1, 4, 4]]]) (3, 3, 2) * (3, 2, 3) 을 계산하는 예제인데, (3, 2) 행렬, (2, 3) 행렬를 각 3개씩 batch 로 계산한다는 의미 이다. mm 처럼 수학에서의 행렬 곱셈 처럼 짝이 딱 맞아야만 실행된다. (batch, p, n) * (batch, n, m) 형태여야 계산 가능. 결과는 (batch, p, m) 형태 위의 상황과 마찬가지로 matmul로 계산하느냐 mm 혹은 bmm으로 계산하느냐의 차이가 있으므로 거기서 기인하는 문제는 인식하면서 사용을 해야된다. z = torch.bmm(x, y) (3, 3, 2)와 (3, 2, 3)의 결과이므로 (3, 3, 3)의 형태를 얻게 된다.
2021. 07. 28.
0
20210728 TIL
pytorch x = torch.FloatTensor([[[1, 2]], [[3, 4]]]) print(x.size()) y = x.expand(*[2, 3, 2]) print(y) print(y.size()) print() yy = x.expand(*[2, 4, 2]) # 차원 중에 1인 것만 expand가 가능하다. print(yy) print(yy.size()) y = torch.cat([x, x, x], dim=1) print(y) print(y.size()) x = torch.randperm(3**3).reshape(3, 3, -1) # 27개(3,3,3) 랜덤하게 0부터 26까지 print(x) print(x.size()) y = x.argmax(dim=-1) # 마지막 dim을 기준으로 가장 큰 값이 있는 인덱스 반환 # 3,3 으로 차원 축소됨. print(y) print(y.size()) print() print() yy = x.argmax(dim=1) # 마지막 dim을 기준으로 가장 큰 값이 있는 인덱스 반환 # 3,3 으로 차원 축소됨. print(yy) print(yy.size()) values, indices = torch.topk(x, k=1, dim=-1) # top k개 뽑아달라! # sort가 된다 # value와 index를 return print(values) print(values.size()) print(indices) print(indices.size()) # 차원 축소가 되지는 않고 k로 바뀜 # k가 1이었으니까 3,3,1 values2, indices2 = torch.topk(x, k=2, dim=-1) # sort가 된다 # value와 index를 return print(values2) print(values2.size()) print(indices2) print(indices2.size()) # 얘는 k가 2 였으니까 3,3,2 로 return됨. print(x[1:3, :, :].size()) print(x[:, :1, :].size()) # 사이즈는 3,2가 아니라 3,1,2 이다. 이렇게 range로 들고 오면 해당 dim은 사라지지 않음. print(x[:, :-1, :].size()) print(x[:, 0, :]) # 사이즈는 3,2 # range로 들고 온게 아니고 하나로 정해서 들고온거라 차원축소가 된다.
2021. 07. 27.
1
20210727 TIL
pytorch broadcasting 각 tensor는 최소 1개 이상의 dimension을 갖고 있어야한다. dimension size를 iterate 할때에 dimension의 size가 같거나 둘 중 하나는 1 혹은 없어야 한다. (3, 2, 4)와 (1, 4)는 broadcastable 하다. 3 - 2 - 4 0 - 1 - 4 뒤에서 부터 확인하면 되는데, 4와 4 동일(오케이), 2와 1 둘 중 하나는 없거나 1(오케이), 3과 없음은 둘 중 하나는 없거나 1 (오케이) (3, 1, 2)와 (1,3)은 non-broadcastable하다. 3 - 1 - 2 0 - 1- 3 뒤에서부터 확인. 2와 3 : 같거나(노노) 둘 중 하나는 1 혹은 없음 (노노) = 브로드캐스팅 안된다. print(x.unsqueeze(2)) print(x.unsqueeze(2).size()) print(x.unsqueeze(1)) print(x.unsqueeze(1).size()) # print(x.unsqueeze(3)) # print(x.unsqueeze(3).size()) # 3을 넣으면 에러남 # 그러면 unsqueeze(2) 하고 나서 3을 넣으면 에러날까? print(x.unsqueeze(2).unsqueeze(3)) print(x.unsqueeze(2).unsqueeze(3).size()) # 오,, 에러는 안나고 맨 마지막 차원이 추가가 됐넹 print(x.unsqueeze(-1)) print(x.unsqueeze(-1).size()) print(x.reshape(2, 2, -1)) print(x.reshape(2, 2, -1).size()) 차원을 늘리기 어떤 차원을 늘려줄지는 반드시 명시를 해줘야함. 줄이기(sum, mean) # dim을 명시 == 없어질 차원을 명시 print(x.sum(dim=0)) # y 축(첫번째 차원)에 대해서 차원 축소 print(x.sum(dim=-1)) # x 축(맨 마지막 차원)에 대해서 축소 dim을 명시해서 축소, (2, 2)였다면 각각 (1,2) (2,1)으로 축소 된다고 생각하고 계산하면 됨. 직접 계산하는 것이 아니지만 어느 방향으로 계산될지를 생각할 수 있어야함. view와 reshape은 같은 기능을 하지만 미묘하게 다름. view가 조금 더 low-level에서 동작한다는 것. contiguous + view = reshape
2021. 07. 25.
0
20210725 TIL
python conda env settings anaconda 와 miniconda conda env 생성 conda create --name 가상환경명 설치할패키지및파이썬버전 conda create -n test_env python=3.6 scipy=0.15.0 이것저것 깔리는게 싫다면 --no-default-packages 원래 있던 가상환경을 복제한 뒤 사용하고 싶다면 conda create -n myenv --clone base yaml이 있다면 conda env create -f environment.yml 가상환경 목록 보기 conda env list env 변경 conda activate 가상환경명 env에서 설치한 것들 확인 가상환경 삭제하기 conda env remove -n 가상환경명 env를 써주지 않으면 실행이 안된다. 안쓰고 지우고 싶다면 아래의 방법으로 conda remove --name myenv --all windown용 가상환경 설치 FOR /F "delims=~" %f in (requirements.txt) DO conda install --yes "%f" || pip install "%f" 리눅스용 가상환경 설치 with while read requirement; do conda install --yes $requirement; done error.log conda install로 안되는 것들이 있는 경우(pip로만 설치 가능한 경우) while read requirement; do conda install --yes $requirement || pip install $requirement; done error.log conda list 하면 설치된 패키지 목록을 볼 수 잇다. 설치된 패키지 목록을 yaml 형식으로 저장 conda env export > environment.yml 특정 환경 안의 특정 패키지를 업데이트 conda update -n 가상환경명 패키지명 특정 환경의 모든 패키지를 업데이트 conda update --all ((현재환경)) conda update -n 가상환경명 --all pip freeze > requirements.txt conda list --expert > packagelist.txt 설치 pip install -r requirements.txt conda install --file packagelist.txt