ubuntu에 mysql 설치

|

mysql 설치

기본 설치

sudo apt-get update
sudo apt-get install mysql-server
mysql_secure_installation

이후 적당히 봐가면서 y/n 해주자..


mysql 중지 및 db 경로 이전

여기서는 /data2/mysql/로 db 경로를 이전한다고 가정한다.

db 데이터 복사

sudo service mysql stop
sudo rsync -av /var/lib/mysql /data2/
sudo chown -R mysql:mysql /data2/mysql

datadir 경로 수정

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf로 열고 다음으로 수정한다.

datadir         = /data2/mysql

apparmor 설정

잘 모르는 내용이라 검색해봤는데, 우분투에서 앱의 resource 접근 제한등을 컨트롤하는 것이라 한다참고.

sudo vi /etc/apparmor.d/usr.sbin.mysqld 에서 다음 경로를 수정하자(/var/lib/mysql로 되어있었던 부분을… )

# Allow data dir access
  /data2/mysql/ r,
  /data2/mysql/** rwk,

sudo vi /etc/apparmor.d/abstractions/mysql에서 또 첫 줄의 /var/lib/mysql{,d}/mysql{,d}.sock rw,

/data2/mysql{,d}/mysql{,d}.sock rw,

로 바꿔주면 된다.

이제 마지막으로 apparmor를 재시작 후, mysql을 다시 시작

sudo /etc/init.d/apparmor reload
sudo service mysql start

동작 확인

mysql에서 현재 datadir을 보는 방법은 다음과 같다.

select @@datadir;

제대로 나오면 성공!


mysql 캐릭터셋 변경

역시 mysql service를 내리고 작업한다.(sudo service mysql stop)

/etc/mysql/mysql.conf.d/mysqld.cnf에서

[client]
default-character-set = utf8

[mysqld]
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8

/etc/mysql/conf.d/mysql.cnf에서

[mysql]
default-character-set = utf8

/etc/mysql/conf.d/mysqldump.cnf에서

[mysqldump]
quick
quote-names
max_allowed_packet = 16M
default-character-set = utf8

이제 다시 mysql을 키고 확인한다. (sudo service mysql start)

show variables like 'char%';로 확인했을 때,

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

요렇게 나오면 성공!

마지막 삽질기 (제대로 덤프가 안될 때)

mysqldump로 dump를 하면, utf8 데이터가 제대로 덤프가 안되는 경우가 있다. 이때 latin1으로 dump를 뜬 후 mysqldump -u eval -p EVAL –default-character-set=latin1 > 20171219.sql 해당 파일의 latin1을 utf8로 바꿔치고 데이터를 넣으면 된다….;;

Population Based Training of Neural Networks 정리

|
  • Sequential optimization
    • 종류
      • hand tuning
      • bayesian optimization
    • 장점 : best solution을 제공한다. 이전 노드의 정보를 fully utilize
    • 단점 : parallelize하기 힘들고, sequential하게 여러번 training을 해야한다.
  • Parallel optimization
    • 종류
      • grid search
      • random search
    • 장점 : parallelize
    • 단점 : 같이 돌고있는 다른 노드들의 정보를 쓰지 않는다.

요 두가지의 장점을 가져오기 위해 Genetic algorithm을 들고옴

1g

  • population을 만들어서
    • 어느 정도 학습을 하고
    • evaluation한 후
    • 잘 안된 녀석은
      • 잘 된 녀석으로 hparams, params를 엎어친다!(exploit)
      • 그리고 hparams를 새로 만드는데 (explore)
        • 기존꺼에서 살짝 perturbing
        • prior distribution에서 hyperparameter를 resampling

2.png

toy example에서 explore는 살짝 도움만 주고 사실상 exploit이 훨씬 더 중요했다고 한다.

실험에서는 algorithm 설명과는 달리 explore시에 hyperparameter만 바꾼다.

대체로 explore시 perturbation을 0.8~1.2로 주며, GAN의 경우 0.5~2.0으로 많이 크게 주었다.

간단한 실험중인데 잘되는 것 같다.

pytorch image loader

|

data folder 구조

먼저 data folder의 구조를 살펴보자.

!tree images
images
├── class1
│   ├── 1.png
│   ├── 2.png
│   ├── 3.png
│   ├── 4.png
│   ├── 5.png
│   └── 6.png
└── class2
    ├── 1.png
    ├── 2.png
    ├── 3.png
    └── 4.png

2 directories, 10 files

class가 2개 있으며, 각각 6개, 4개의 image가 있다.

이제 이것을 뽑아보자!

ImageFolder dataset을 이용해서 image batcher를 만들기

import torchvision.datasets as dset
import torchvision.transforms as transforms
import torch

dataset = dset.ImageFolder(root="images/",
                           transform=transforms.Compose([
                               transforms.Scale(128),       # 한 축을 128로 조절하고
                               transforms.CenterCrop(128),  # square를 한 후,
                               transforms.ToTensor(),       # Tensor로 바꾸고 (0~1로 자동으로 normalize)
                               transforms.Normalize((0.5, 0.5, 0.5),  # -1 ~ 1 사이로 normalize
                                                    (0.5, 0.5, 0.5)), # (c - m)/s 니까...
                           ]))
dataloader = torch.utils.data.DataLoader(dataset,
                                         batch_size=2,
                                         shuffle=True,
                                         num_workers=8)
for i, data in enumerate(dataloader):
    print(data[0].size())  # input image
    print(data[1])         # class label
torch.Size([2, 3, 128, 128])

 1
 1
[torch.LongTensor of size 2]

torch.Size([2, 3, 128, 128])

 0
 1
[torch.LongTensor of size 2]

torch.Size([2, 3, 128, 128])

 0
 0
[torch.LongTensor of size 2]

torch.Size([2, 3, 128, 128])

 1
 0
[torch.LongTensor of size 2]

torch.Size([2, 3, 128, 128])

 0
 0
[torch.LongTensor of size 2]

0이 6개, 1이 4개 나왔다. 이는 각 클래스의 label로 쓰일 수 있다. 나온 이미지를 한번 확인해보자!

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from torchvision.transforms import ToPILImage
to_img = ToPILImage()

for i, data in enumerate(dataloader):
    img = data[0][0,:]
    break
print(img.size())
print("max: {}, min: {}".format(np.max(img.numpy()), np.min(img.numpy())))
plt.imshow(to_img(img))
torch.Size([3, 128, 128])
max: 1.0, min: -1.0

<matplotlib.image.AxesImage at 0x1144d71d0>

output_5_2.png

변환 몇개 빼고 해보면 다음처럼 보인다.

dataset = dset.ImageFolder(root="images/",
                           transform=transforms.Compose([
                               transforms.Scale(128),       # 한 축을 128로 조절하고
                               transforms.ToTensor(),       # Tensor로 바꾸고 (0~1로 자동으로 normalize)
                           ]))
dataloader = torch.utils.data.DataLoader(dataset,
                                         batch_size=2,
                                         shuffle=True,
                                         num_workers=8)

for i, data in enumerate(dataloader):
    img = data[0][0,:]
    break
print("max: {}, min: {}".format(np.max(img.numpy()), np.min(img.numpy())))
plt.imshow(to_img(img))
max: 1.0, min: 0.0

<matplotlib.image.AxesImage at 0x114027f28>

output_7_2.png

Reparametrization Trick 정리

|

참고 0: 요걸 기본으로 해서 이 포스트를 작성!

참고 1: Eric jang의 블로그

Motivation

deep learning에서, 보통 우리는 $x \sim p_\theta(x)$에서 draw한 sample들을 통해 gradient를 backpropagation을 하게 된다.

  • 물론 여기서 $p_\theta(x)$는 learned parametric distribution

예를 들어 variational autoencoder(VAE)를 학습한다면, input x에 대해서, latent representation z는 $q_\phi(z \vert x)$에서 오고, 보통 이는

  • $q_\phi(z \vert x) = \cal{N}(\mu_\phi(x), \Sigma_\phi(x))(z)$

가 되며, 이 때 $\phi$또한 neural network의 parameter가 된다.

이제 학습을 진행하면 loss의 parameter $\phi$에 대한 backpropagation이 필요하다.

간단하게 얘기를 했는데 VAE 정리를 예전에 해놔서.. 여기에 있음!

Goal

다시 정리하자면 우리는 cost의 기대값을 minimize하는 것이 골인데, 그 cost의 기대값은 다음처럼 표현된다.

gradient descent를 사용해서 이를 달성할건데, 그러려면

  • $\nabla_\theta L(\theta,\phi)$
  • $\nabla_\phi L(\theta,\phi)$

두가지를 구해야한다.

계산

이건 항상 하는 일로 굉장히 쉬운데

이며 따라서 샘플링으로 쉽게 끝낼 수 있다.

$\nabla_{\theta} L(\theta, \phi) \approx \frac{1}{|S|} \sum_{s=1}^S \nabla_{\theta} f_{\theta}(x_s)$

요렇게….

계산

요거는 이제 어려워지는데… 수식을 전개해보면

이 되어서 sampling으로 할 수가 없게된다.

요걸 기억하라고한다.

  • $p_\phi(x)$가 $\phi$에 대해 미분 가능해야함
  • $f_\theta(x)$는 굳이 x에 대해 미분가능할 필요 없음

이제 이 어려운 일을 어떤식으로 파헤쳐나가는지 알아보는 것이 이 포스팅의 목적!

여기까지 한줄 요약: sampling하는 distribution에 대해서 backpropagation(BP)을 하지 않으면 쉽고, sampling하는 distribution에 대해서 BP를 하면 골치아파짐. 그래서 sampling하는 dist.에 대해 어떻게 대처하는지 여러 방법을 알아보려 함.

Score function estimator(SF)

Policy gradient에서 보던 방법이다. integral을 어떻게든 expectation으로 만들어서 sampling가능하게 만들어주는 것이 목적!

고등학교에서 나오던 이 미분식 하나로 모든게 끝난다. 요걸 다시 써보면

위의 식을 이용해서 전개하면

요렇게하면 $p_\phi(x)$에 대해서 expectation꼴이 되므로 아까와 같이 sampling하면 된다.

Reparameterization trick

VAE에서 보던 trick인데, 굉장히 단순하며 잘 작동한다. stochastic node를 stochastic한 부분과 deterministic한 부분으로 분해시켜서 deterministic한 부분으로 backpropagation을 흐르게하자는게 핵심! 즉, $x = g(\phi, \epsilon)$로 deterministic, stochastic의 함수로 본다.

예를 들어보면 $x \sim \cal{N}(\mu_\phi,\sigma^2_\phi)$인 녀석은

  • $\epsilon \sim \cal{N}(0, 1)$을 이용하면
  • $x = \mu_\phi + \sigma^2_\phi*\epsilon$으로 나타낼 수 있다.

위처럼 stochastic과 deterministic으로 나누면 gradient를 다음처럼 구할 수 있다.

근데 요구조건이 존재한다.

  • $f_\theta(x)$가 $x$에 대해 미분가능해야한다.
    • 이 조건은 쉽다. 맨날 하는 일이니…
  • $g(\phi, \epsilon)$이 존재해야하며, $\phi$에 대해 미분가능해야한다.
    • 그렇다면 continuous해야하는데, 이는 categorical variable에 대해서는 불가능한가?
    • 그렇진 않다. 이를 가능하게하려면 Gumbel-max trick과 Gumbel-softmax trick을 사용하면 된다.

사실 이 부분을 가장 알고싶어서 시작한 일인데 이제야 Gumbel까지 왔다..

Gumbel-max trick(stochastic을 따로 뺌)

categorical한 variable을 reparametrization함. 요걸 쓰면 categorical에서 sample한 것과 비슷한 효과를 낸다고한다.

$x \sim \cal{Cat}(\pi_\phi)$를 discrete categorical variable이라 해보자.

$\epsilon_k \sim \mathcal{Gumbel}(0,1)$를 가지고 Reparametrization하면

로 쓸 수 있다. 요것이 Gumbel-max trick

  • 하지만 아직도 $\phi$에 대해 discrete하며 미분이 불가능하다.

Gumbel-softmax(continuous)

Gumbel-max의 argmax를 softmax로 바꾼 녀석. 이제 미분이 가능해진다.

특성들

  • 여기서 $\tau$는 temporature parameter인데
    • 0에 가까워지면 one-hot
    • 무한대로가면 uniform distribution을 갖는다.
  • $p(x_k = \underset{i}{max}\ x_i) = \pi_k$

참고 1: Eric jang의 블로그를 보면 MNIST VAE를 Gumbel softmax로 구현한 코드도 존재한다. 이를 보면 좀 더 쉬울 것이다.

참고 구현

잘 안와닿으니까 코드로 보자

import math
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt


def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

def sample_gumbel(eps=1e-20):
    u = np.random.uniform(0,1)
    return -math.log(-math.log(u+eps)+eps)


def gumbel_softmax(logits, tau=0.01):
    g = [sample_gumbel() for _ in range(logits.shape[0])]
    y = logits + g
    return softmax(y/tau)

x = np.array([0 ,1, 2, 3])
p = np.array([0.0, 0.2, 0.9, 0.1])
plt.plot(x,softmax(p))

output_2_1.png

sum_ = np.zeros_like(p)
for i in range(10000):
    sum_ += gumbel_softmax(p)
plt.plot(x,sum_/np.sum(sum_))

output_4_1.png

굉장히 비슷함을 알 수 있다!

plt.plot(gumbel_softmax(p))

output_5_1.png

각각의 샘플은 이렇다.

BEGAN

|

참조(여기는 v1논문, 내가 본건 v4논문… condition이 좀 많이 다르다.)

W-distance 설명!! 요걸 기반으로 좀 더 공부해야할 듯..함!

W-gan의 세줄다섯줄 요약!

  • distance metric을 통해 probability를 최소화시키고싶음
  • KL-divergence를 보통 썼는데… 얘는 불연속에 불편함이 많아서 w_dist를 써보자!
  • 얘는 1-lipschitz함수로 sup을 찾는것과 같다.
  • 그래서 $\theta$ 그대로 놓고 f를 업데이트하고(여러번) 그 f로 $\theta$ 업데이트
  • Improving W-gan에서는 이것자체도 loss에 넣어버림

Introduction

  • GAN의 단점
    • 학습이 어려움
      • Hyper parameter 잘골라야…
      • training을 위한 trick도 많아…
      • D, G사이의 밸런스도 맞추기 힘들어…
    • Model collapse
      • discriminator를 속이는 한 예제만 죽어라 파는 것..
  • 이 논문의 contribution
    • 간단하고, 강인한 구조로 빠르고 stable한 수렴을 이룸
    • Discriminator와 Generator간의 밸런스를 맞추는 equilibrium concept를 제안함 -> $\gamma$
      • image의 diversity와 quality간의 trade-off를 조정하는 방법을 제시
    • convergence에 대한 approximate measure를 제안함.

Related Work

  • DCGAN - CNN으로 트레이닝하는 방법을 제안
  • EBGAN - Discriminator를 AutoEncoder(AE)로 제안(사실 Energy based라는데… 그냥 AE가 맞는 듯)
  • WGAN - JSD->wasserstein dist로 바꿔서 구현 간소화
    • 사실 잘 모르겠다…

Proposed Method(Equilibrium 없이..)

먼저 Equilibrium이 없이 설명한다. 이 이후에 나오니까 걱정 ㄴㄴ

  • 기존 GAN은 sample들의 distribution이 잘 matching되도록 트레이닝
  • 이를 sample들의 AE-loss의 distribution을 matching하도록 바꿈
  • 그리고는 이 loss의 Wasserstein distance의 lower bound를 계산하고,
  • 이를 최대화하는 것이 D의 역할
  • 반대가 G의 역할

AE-loss 정의

  • $ \cal{L}:\mathbb{R}^{N_x}\mapsto \mathbb{R}^+ $
  • AE-loss.png 그냥 단순히 AE를 거친 input과 output의 pixel별 로스를 구해서 l-1,l-2 norm중에 하나를 취한다.

W-distance

먼저 $\mu_1$을 real-image에서의 AE-loss의 distribution, $\mu_2$를 generation한 image의 AE-loss의 distribution이라 하자.

  • $\Gamma(\mu_1, \mu2)$: marginal distribution이 $\mu_1, \mu2$인 모든 joint distribution. (어떤 녀석인지 직감적으로 안와닿는다.. 다음 섹션 참조!)

위 수식이 W-distance라는데 먼저 $\gamma$에 대해서 생각해보자.

  • $\gamma(x_1, x_2) \in \Gamma$: transportaion plan
    • $x_1$ 에서 $x_2$로 얼마나 옮겨야 $p_{u_1}$에서 $p_{u_2}$가 되는지..
    • 그 가능한 셋 중에서 한 계획이라 보면 된다.
    • 다음 섹션의 첫번째 table을 참조해서 보자. $x_1 = 0$인 부분에서 0으로 1/6, 1로 2/6을 이동시키고, $x_1 = 1$인 부분에서 0으로 1/6, 1로 2/6을 이동시키면 최종적으로 $p_{\mu_2}$가 된다.

이제 w-distance를 쉽게 정의할 수 있다.

  • $x_1$에서 $x_2$로 옮기는 데, 거리를 $\vert x_1 - x_2\vert$로 생각한거지..
    • mass * distance를 cost로 보아서..
    • 즉 $p_{\mu_1}$에서 $p_{\mu_2}$로 distance를 만드는데 필요한 가장 적은 cost를 구한 것!

여기에 jensen’s inequality를 쓰면 lower bound를 구할 수 있다.

거창하게 말고… $\sum \vert a \vert \ge \vert \sum a \vert $요렇게만 봐도 쉽지.

  • $m_n$: $\mu_n$의 mean

이제 이후에는 이 W-distance의 lower bound를 최적화한다


marginal distribution은 같지만 다른 joint distribution의 예

  • $\mu_1,\mu_2$가 평균이 1/2, 2/3인 bernoulli distribution을 따른다고 가정해보자
  • $\Gamma(\mu_1, \mu_2)$에는 이런 녀석들이 가능
  0 1 $p_{\mu_1}(x_1)$
0 $\frac{1}{6}$ $\frac{2}{6}$ $\frac{1}{2}$
1 $\frac{1}{6}$ $\frac{2}{6}$ $\frac{1}{2}$
$p_{\mu_2}(x_2)$ $\frac{1}{3}$ $\frac{2}{3}$  
  0 1 $p_{\mu_1}(x_1)$
0 $\frac{2}{9}$ $\frac{5}{18}$ $\frac{1}{2}$
1 $\frac{1}{9}$ $\frac{7}{18}$ $\frac{1}{2}$
$p_{\mu_2}(x_2)$ $\frac{1}{3}$ $\frac{2}{3}$  

GAN objective

드디어 GAN을 어떻게 만들까가 나온다..

  • $z \in [-1, 1]^{N_z}$: uniform random samples
  • $G:\textbf{R}^{N_z} \rightarrow \textbf{R}^{N_x}$ generator
  • Discriminator는 (1)번 식을 maximize해야한다.
    • $\vert m_1 - m_2\vert$를 maximize
    • $W_1(\mu_1, \mu_2) \ge m_2-m_1$
    • $m_1 \rightarrow 0$
    • $m_2 \rightarrow \infty$

위 내용을 파라미터를 넣은 수식으로 다시쓰면

  • $\theta_D$: Discriminator의 파라미터
  • $\theta_G$: Generator의 파라미터

일 때

  • $\cal{L}_D = \cal{L}(x;\theta_D) - \cal{L}(G(z_D;\theta_G);\theta_D)$
    • Discriminator의 loss는 작게, Generator의 loss는 크게..(GAN이 맨날 그렇지..)
  • $\cal{L}_G = -\cal{L}_D$

이렇게 만들어서 WGAN에서의 한계인 K-Lipschitz 컨디션이 필요없다고 하는데 이건 나중에 시간나면 알아보자.

그리고, 요렇게 만들었는데 여느때와 같이 D가 G를 압도해버리는 문제가 생겼다. 그래서 Equilibrium을 도입한다.


Proposed Method(Final)

위의 식이 평형상태라고 본다. 당연히… fake data나 real data나 AE의 loss가 비슷하면 평형이다. 근데 좀 더 condition을 relax해보자.

BEGAN에서 Discriminator는 두가지 목적을 가진다.

  1. 진짜 이미지를 잘 AE로 loss 적게 만들기
  2. G에서 나온 것은 loss를 크게 구분해주기

$\gamma$를 작게 세팅하면 진짜 이미지를 잘 decoding하는 것이 목적이며, 따라서 이를 diversity ratio라고 명명했다.

이제 Equilibrium을 넣은 BEGAN의 objective는

가 된다.

  • 맨 처음식
    • $k_t$는 0부터 시작한다.
    • generator의 loss를 얼마나 discriminator에 반영할지 정한다.
  • 두번째 식
    • Generator가 처음에 뱉는 것이 더 reconstruction이 잘됨 -> loss 적음
  • 세번째 식
    • $\lambda_k$ : 0.001부터 시작
    • proportional control theory에서 왔단다.
    • 두려워하지말고 차근차근 뜯어보다…
      • 먼저 처음식에서 k가 커지면 discriminator는 generator가 loss를 크게하도록 최적화하는데 가중치를 둔다.
      • 이제 세번째 식을 보면 실제 이미지의 loss의 감마배보다 fake 이미지의 loss가 크다면
        • 즉 Generator가 잘 못할 것 같으면 -> k값을 줄여서 discriminator가 자기 loss 줄이는데 더 초점을 두도록..
        • fake image의 loss가 작으면, (G가 잘하면) -> k값을 늘려서 g를 견제하도록 해준다.

training을 D와 G에 대해 병렬로 수행할 수 있었으며, pretrained된 D에 대해서도 잘 학습이 됐다!(EQ가 잘됨)


Convergence measure

GAN이 학습이 잘됐는지 끝난건지 measure가 없어서 만들어봄!

  • 앞에꺼
    • real-image를 얼마나 잘 decoding 하나
  • 뒤에꺼
    • proportional control error라는데…

요걸 loss처럼 사용해보면 이렇게 잘 된다고 함 gs.png


마지막으로 모델 사진

Model.png

나의 생각

  • EBGAN에서 AE를 써서 generator의 gradient를 좀 더 세부적으로 조정이 가능했을 것이다.
  • loss의 distriution 매칭을 강조했는데 이건 EBGAN을 봐야 알겠다..
  • WGAN의 w-distance를 좀 더 파봐야함.
  • 다음엔 unrolled-gan을 볼까 생각이 든다. (이유는 아래 코드 구현에…)

code

  • 내 깃헙에 BEGAN 코드를 만들어 올렸다.
  • mode collapse 문제를 제대로 해결 못했는데 celebA가 다 얼굴이라 피해간 것으로 보이지 않을까 싶다.
  • 그래서 fashion-mnist를 가지고 실험했는데 신발만 학습하거나, 옷만 학습하더라…
  • update: celebA의 데이터는 얼굴 사이사이의 data가 존재(data distribution이 훨씬 더 continuous)하기 때문에 더 잘되는 것으로 결론냄
    • 그렇다면 mnist같이 여러개의 class를 가지고 실험하는 경우는 class별로 separable하니까 하나만 학습될 가능성이 높아짐