카테고리 보관물: Personal projects

Lightshail Ubuntu 배포판 업그레이드 후 ssh 접속이 안된다.

망했다! Litghtsail의 Ubuntu 배포판이 너무 오래전 것이라 콘솔에 접근해서 조심스럽게 screen session도 새로 만들어 가면서 업그레이드를 했는데 끝나고 나니 SSH가 안된다. 아마도 중간에 SSH관련 환경설정을 파일을 변경할 것인지 묻는 선택메뉴가 나왔는데, 현재 설정을 그냥 쓰겠다고 했던게 문제인것 같다. 다행히 blogging service는 잘돌아 가고 있지만 SSH가 안되면 서버관리를 할 방법이 없는데…

Workaound

다행히 세상은 생각보다 넓고 인간은 같은 실수를 반복하기에 이전에 같은 실수를 한 사람의 비슷한 경험을 정보의 바다에서 찾을 수 있었다 (SSH stops working after upgrade to Ubuntu 18.04 on AWS Lightsail). 대충 Ubuntu 18.04 LTS로 올라가면서 SSH 환경설정 파일에 변경이 있었는데 메인테이너 버전을 적용하지 않으면 문제가 되는가 보다. 이 포스팅은 위의 링크에 있는 내용을 기준으로 정리한 것이다. (Lightsail 한정이고 EC2를 사용하고 있다면 아래와 같이 번거로운 작업을 할 필요가 없다고 한다)

순서 요약

  1. SSH접속이 안되는 instance로 부터 스냅샷을 하나 만든다.
  2. 스냅샷의 시작 스크립트에 ssh 환경설정을 수정하는 명령어를 넣고 새로운 인스턴스를 만든다.
  3. 잘 되면 새로운 인스턴스를 고정 IP에 연결하고 이전 인스턴스를 지운다.

스냅샷 생성

SSH 접속이 안되는 인스턴스로 부터 스냅샷을 하나 만든다. 관리 -> 스냅샷 수동 스냅샷 아래의 ‘+ 스냅샷 생성’을 클릭.

생성이 완료될 때까지 조금 기다렸다가 이 스냅샷으로 부터 새로운 인스턴스를 하나 만든다.

시작 스크립트를 추가하고 인스턴스를 실행

새 인스턴스 생성 메뉴에 보면 “시작 스크립트”를 넣는 곳이 있는데 이곳을 선택하고 ssh config를 변경해 줄 다음의 sed 명령어를 입력한다.

그리고 나서 인스턴스를 실행하면 처음에는 여전히 SSH 접속이 되지 않는데, 꽤 오랜 시간 (10~20분)이 지나고 나서야 가능해 진다.

고정 IP 변경과 정리

네트워킹 -> Static IP에서 고정 IP를 분리하고 새로운 인스턴스에 새로 연결해 준다.

새로운 인스턴스를 고정 IP에 할당 한 후 기존 서버를 끄고 도메인에 접속해서 잘 돌아가는 지 확인한 후 스냅샷과 기존 인스턴스를 지워준다. 스냅샷 생성 기능은 예전에 한 번 백업용으로 좋겠다 싶어서 만들어 봤다가 추가 요금이 나온적이 있다. 🙁

결론

다음 부터는 이미지를 업데이트 하고 싶을 땐 먼저 백업을 만들어서 작업 및 확인하고 최종으로 IP를 변경 하도록 하자.

TensorFlow에서 CUBLAS_STATUS_NOT_INITIALIZED 오류 문제

failed to create cublas handle: CUBLAS_STATUS_NOT_INITIALIZED

이 문제는 TensorFlow의 GPU memory growth 설정과 관련이 있다. 이 경우 GPU의 allow_grouth option을 True로 설정하면 문제를 해결할 수 있는데, Use a GPU 페이지에 따르면 tf.config.experimental.set_memory_growth()를 통해 True로 설정하거나 혹은 환경변수 TF_FORCE_GPU_ALLOW_GROWTH를 설정해서 해결 할 수 있다.

코드에 다음과 같이 환경 변수를 설정해 줄 수도 있지만,

실행 환경에 따라 문제가 발생하지 않을 수도 있어서, 나는 주로 command line에서 다음과 같이 script를 실행할 때 이 값을 함께 설정한다.

Transpose convolution의 출력 크기

Keras의 transpose convolution 2D (Conv2DTranspose) 레이어로 DCGAN을 실습해보고 있었는데 gemrator가 생성해야 하는 image가 나누다 보면 소수(prime number)가 나오는 직사각형 크기의 178×218 였다.

많은 예제 코드들에서 transpose convolution 2D의 padding을 “same”으로 지정하기 때문에 Conv2DTranspose의 출력 크기는 stride의 배수여야 한다고 오해 했었는데, 실은 padding을 “same”으로 설정하느냐 혹은 “valid”로 설정하느냐에 따라 출력의 크기가 다음과 같이 달라진다.

# padding을 ‘same’으로 설정 했을 때
Output = Input \times stride

# padding을 ‘valid’로 설정 했을 때
Output = (Input - 1) \times stride+ filter

예를 들어 다음 layer를 선언하고 (44, 54, 3) tensor를 주면 소수 값의 (89, 109, 64) tensor가 출력된다.

한글 텍스트 추출을 위한 Python PDF module

이 내용은 2020년 3월에 작성된 것으로 참조하는 시점에 따라 변경된 사항들이 있을 수도 있습니다.

PyPDF2

PyPDF2는 PDF file의 metadata 정보를 가져오거나 페이지 단위로 나누거나 합치는 등의 여러가지 편리한 기능들을 제공한다. 하지만 한글을 제대로 추출하지 못하는 문제가 있어서(한글 뿐 아니라 CJK 모두 라고 함) 목적에는 적합하지 않았다.

PDFMiner

한글 처리는 문제 없다. 그런데 페이지 단위로 나누어서 처리하는 것을 따로 지원하지 않아서 원하는 페이지에 접근하려면 순차적으로 처음부터 해당 페이지를 찾아가는 trick을 사용해야 하는데, 이 코드로 순차적 접근을 하면 시간 복잡도가 O(N^2)가 되어 파일의 크기가 조금만 커도 성능이 매우 떨어진다.

Tika

많은 곳에서 쓰이는 꽤나 유명한 프로젝트인데 Python module로도 proting 되어 있다(tika-python). 한글 추출에는 문제가 없고, 이 모듈 자체에서는 페이지 단위의 텍스트 추출을 지원하지 않으나, 그대신 PDF를 XML로 추출한 다음에 BeautifulSoupe로 <div page=””> 태그를 찾아 페이지 단위로 접근하는 신박한 트릭이 있다(StackOverflow). 나는 BeautifulSoup의 paser로 lxml을 사용했다.

주의. 명시적으로 표시 되지는 않지만 JRE(Java Runtime Environment)에 의존하므로 동작시 오류가 발생하면 JRE가 제대로 설치 되어 있고 접근 가능한지 확인해 볼 것. Ubuntu 18.04 default-jre package (OpenJDK 11)로 동작 확인.

결론

PDF 문서 자체에 대한 합치기/나누기/정보 가져오기 등은 PyPDF2가 무척 편하다. 한글 텍스트 추출을 위해서는 Tika, 페이지 단위 접근이 필요하다면 Tika + BS를 고려해 볼 만하다. PDFMiner는 뭐랄까.. 쫌 별로..

Back propgation에서의 전치행렬(transpose matrix) – 2편

1편이 너무 길어 져서 \frac{\partial L}{\partial W} = X^T \cdot \frac{\partial L}{\partial Y}에 대한 유도는 여기로 나누었다.

이제 \frac{\partial Y}{\partial W}를 보면, 얘들도 모두 matrix이니 \frac {\partial Y}{\partial W}는 다음과 같이 생겼다.

\frac{\partial Y}{\partial W} = \begin{bmatrix}\frac{\partial Y}{\partial w_{1,1}} & \frac{\partial Y}{\partial w_{1,2}} & \frac{\partial Y}{\partial w_{1,3}} \\\\ \frac{\partial Y}{\partial w_{2,1}} & \frac{\partial Y}{\partial w_{2,2}} & \frac{\partial Y}{\partial w_{2,3}} \end{bmatrix}

첫번째 원소인 \frac{\partial Y}{\partial w_{1,1}}을 구하기 위해 이전 처럼, W에 대해 Y로 편미분하면 다음과 같이된다.

\frac{\partial Y}{\partial w_{1,1}}=\begin{bmatrix}x_{1,1} & 0 & 0 \\\\ x_{2,1} & 0 & 0\end{bmatrix} \\\\ \frac{\partial Y}{\partial w_{1,2}}=\begin{bmatrix}0 & x_{1,1} & 0 \\\\ 0 & x_{2,1} & 0\end{bmatrix} \\\\ \frac{\partial Y}{\partial w_{1,3}}=\begin{bmatrix}0 & 0 & x_{1,1} \\\\ 0 & 0 & x_{2,1}\end{bmatrix} \\\\ \frac{\partial Y}{\partial w_{2,1}}=\begin{bmatrix}x_{1,2} & 0 & 0 \\\\ x_{2,2} & 0 & 0\end{bmatrix} \\\\ \frac{\partial Y}{\partial w_{2,2}}=\begin{bmatrix}0 & x_{1,2} & 0 \\\\ 0 & x_{2,2} & 0\end{bmatrix} \\\\ \frac{\partial Y}{\partial w_{2,3}}=\begin{bmatrix}0 & 0 & x_{1,2} \\\\ 0 & 0 & x_{2,2}\end{bmatrix}

Matrix W의 각 원소들 역시 scalar이므로 1편에서 X의 경우 처럼, 다음과 같이 나타낼 수 있다.

\frac{\partial L}{\partial w_{1,1}} = \sum_{i=1}{N} \sum_{j=1}{M}\frac{\partial L}{\partial y_{i,j}} \cdot \frac{\partial y_{i,j}}{\partial w_{1,1}}

\frac{\partial L}{\partial w_{1,1}} = (\frac{\partial L}{\partial y_{1,1}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,1}} \times x_{2,1}) \\\\ \frac{\partial L}{\partial w_{1,2}} = (\frac{\partial L}{\partial y_{1,2}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,2}} \times x_{2,1}) \\\\ \frac{\partial L}{\partial w_{1,3}} = (\frac{\partial L}{\partial y_{1,3}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,3}} \times x_{2,1}) \\\\ \frac{\partial L}{\partial w_{2,1}} = (\frac{\partial L}{\partial y_{1,1}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,1}} \times x_{2,2}) \\\\ \frac{\partial L}{\partial w_{2,2}} = (\frac{\partial L}{\partial y_{1,2}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,2}} \times x_{2,2}) \\\\ \frac{\partial L}{\partial w_{2,3}} = (\frac{\partial L}{\partial y_{1,3}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,3}} \times x_{2,2})

이것을 2X3인 matrix로 나타내면

\frac{\partial L}{\partial W} = \begin{bmatrix}(\frac{\partial L}{\partial y_{1,1}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,1}} \times x_{2,1}) & (\frac{\partial L}{\partial y_{1,2}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,2}} \times x_{2,1}) & (\frac{\partial L}{\partial y_{1,3}} \times x_{1,1}) + (\frac{\partial L}{\partial y_{2,3}} \times x_{2,1}) \\\\ (\frac{\partial L}{\partial y_{1,1}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,1}} \times x_{2,2}) & (\frac{\partial L}{\partial y_{1,2}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,2}} \times x_{2,2}) & (\frac{\partial L}{\partial y_{1,3}} \times x_{1,2}) + (\frac{\partial L}{\partial y_{2,3}} \times x_{2,2}) \end{bmatrix}

Matrix X와 W원소의 위치를 바꿔서 나타내면

\frac{\partial L}{\partial W} = \begin{bmatrix}(x_{1,1} \times \frac{\partial L}{\partial y_{1,1}}) + (x_{2,1} \times \frac{\partial L}{\partial y_{2,1}}) & (x_{1,1} \times \frac{\partial L}{\partial y_{1,2}}) + (x_{2,1} \times \frac{\partial L}{\partial y_{2,2}}) & (x_{2,1} \times \frac{\partial L}{\partial y_{1,3}}) + (x_{1,1} \times \frac{\partial L}{\partial y_{2,3}})  \\\\ (x_{1,2} \times \frac{\partial L}{\partial y_{1,1}}) + (x_{2,2} \times \frac{\partial L}{\partial y_{2,1}}) & (x_{1,2} \times \frac{\partial L}{\partial y_{1,2}}) + (x_{2,2} \times \frac{\partial L}{\partial y_{2,2}}) & (x_{1,2} \times \frac{\partial L}{\partial y_{1,3}}) + (x_{2,2} \times \frac{\partial L}{\partial y_{2,3}}) \end{bmatrix}

Matrix X와 Y로 구분하면

\frac{\partial L}{\partial W} = \begin{bmatrix}x_{1,1} & x_{2,1} \\\\ x_{1,2} & x_{2,2}\end{bmatrix} \cdot \begin{bmatrix}\frac{\partial L}{\partial y_{1,1}}  & \frac{\partial L}{\partial y_{1,2}} & \frac{\partial L}{\partial y_{1,3}} \\\\ \frac{\partial L}{\partial y_{2,1}} & \frac{\partial L}{\partial y_{2,2}} & \frac{\partial L}{\partial y_{2,3}}\end{bmatrix} = X^T \cdot \frac{\partial L}{\partial Y}이 성립한다.