import math

num = int(input())

# 분해가 전부 될때까지 loop 돌립니다.
while num != 1:
    for i in range(2, num + 1):
        # 나눠지면 출력하고,
        # 다음을 위해 해당 수로 num을 나눠줍니다.
        if(num % i == 0):
            print(i)
            num = num // i
            break

'# 코딩 문제 관련 > 파이썬' 카테고리의 다른 글

백준 1037번(python)  (0) 2020.04.09
백준 5086번(python)  (0) 2020.04.09
백준 5598번(python)  (0) 2020.04.01
백준 1541번(python)  (0) 2020.01.07
백준 11399번(python)  (0) 2020.01.07


# A: 65
# Z: 90
transformed = input()
result = ''

# number % 26 을 수행하면 0 ~ 25 사이의 숫자를 얻을 수 있습니다.
for cha in transformed:
    # 먼저 0 ~ 25 범위로 변경하기 위해 65를 빼주고,
    cha = ord(cha) - 65
    # 3번 옮겼으니 변환전으로 돌리기 위해 3을 빼주고,
    # A, B 같은 경우 음수가 생길 수 있으니, 다시 값의 범위 26을 더해줍니다.
    cha = cha - 3 + 26
    # % 26을 수행하면 음수였던 수는 X, Y, Z가 존재하는 뒤로 돌아가게 될 겁니다.
    cha = cha % 26
    # 본모습으로 돌아가기 위해 65를 더해줍니다.
    cha = cha + 65
    
    result += chr(cha)
    
print(result)

'# 코딩 문제 관련 > 파이썬' 카테고리의 다른 글

백준 5086번(python)  (0) 2020.04.09
백준 11653번(python)  (0) 2020.04.01
백준 1541번(python)  (0) 2020.01.07
백준 11399번(python)  (0) 2020.01.07
백준 1931번(python)  (0) 2020.01.03

https://www.youtube.com/watch?v=n7byMbl2VUQ&list=PLQY2H8rRoyvzuJw20FG82Lgm2SZjTdIXU&index=8


머신러닝 프로세스는 크게 두 가지로 설명할 수 있습니다.

  1. 데이터 전처리
  2. 모델을 통한 연산

전처리 과정에서 우리는 CPU를 활용해서 이미지를 cropping한다던지, 기타 video 영상을 위한 처리 등을 수행합니다.
만약 전체 트레이닝 속도가 느리다면, 위 두 가지 과정 중 하나가 bottleneck일 것입니다.

GPU나 TPU는 계속해서 엄청나게 발전해왔습니다.
이들은 Matrix, linear algebra 등의 연산을 매우 빠르게 수행함으로써 ML의 속도를 향상시켰습니다.
하지만 CPU는 GPU에 비해 상대적으로 그렇게 향상되지 못했습니다.
만약 데이터 전처리 과정에서 병목 현상이 발생한다면 전체 과정이 매우 느려질 것입니다.

그래서 이번 영상에서는 tf.data를 활용하여 속도를 개선시키는 방법을 살펴볼 것입니다.
먼저, tf.data는 다들 알다시피 데이터 전처리를 위한 쉽고, 유용한 프레임워크입니다. 아래 코드에서 tf.data의 대략적인 프로세스를 볼 수 있습니다.

import tensorflow as tf

def expensive_preprocessing(record):
	pass
    
dataset = tf.data.TFRecordDataset('.../*.tfrecord')
dataset = dataset.map(expensive_preprocessing)
dataset = dataset.shuffle(buffer_size = 1024)
dataset = dataset.batch(batch_size = 128)

dataset = dataset.prefetch()

model = tf.keras.Mpdel(...)
model.fit(dataset)
  • Dataset 객체를 생성하고,
  • 일련의 preprocessing 함수를 적용하고,
  • shuffle과 batch를 결정하고,
  • prefetch() 옵션을 넣어줍니다. prefetch()는 데이터의 입력 과정에서 다음 큐에 들어갈 데이터의 전처리를 미리 병렬적으로 수행하는 함수입니다.
  • 마지막으로 모델을 학습시킵니다.

 

그렇다면 데이터 전처리의 병목 현상을 해결할 수 있는 방법은 무엇이 있을까요?

첫 번째 아이디어는 reuse computation입니다.
이 방법은 우리가 수행하는 전처리 과정에서의 연산을 한번만 사용하지 말고, 저장해두었다가 다음 연산에서도 다시 사용하는 것을 의미합니다.(약간 캐시와 비슷한 느낌?)

이 방법을 수행할 수 있도록 tf.data snapshot을 소개합니다. 데이터 전처리 과정을 저장해두었다가 사용할 수만 있다면, 모델 아키텍처를 실험하거나 여러 가지 하이퍼파라미터를 실험하는 데에 있어서 매우 유용할 것입니다.
snapshot 기능은 다음과 같이 사용할 수 있습니다.

import tensorflow as tf

def expensive_preprocessing(record):
	pass
    
dataset = tf.data.TFRecordDataset('.../*.tfrecord')
dataset = dataset.map(expensive_preprocessing)
dataset = dataset.snapshot("/path/to/snapshot_dir/") # add
dataset = dataset.shuffle(buffer_size = 1024)
dataset = dataset.batch(batch_size = 128)

dataset = dataset.prefetch()

model = tf.keras.Mpdel(...)
model.fit(dataset)
  • snapshot 기능을 사용하면 일단 한번은 전체 디스크를 활용하지만, 다음 연산부터는 이를 참고하여 연산을 수행할 수 있습니다.
  • 그리고 snapshot은 shuffle 기능을 사용하기 전에 추가해두어야 합니다. 셔플 후에 사용하면 모든 작업이 frozen되기 때문에 주의해야 합니다. 랜덤하게 입력하는 장점을 사용할 수 없죠.
    또, 이 기능은 TF 2.3부터 이용가능하다는군요.

두 번째 아이디어는 distribute computation입니다.
이 방법은 Host CPU를 만들어 worker들에게 작업을 할당한 뒤 병렬적으로 처리하고 결과는 Host CPU에서 종합하도록 합니다.
이를 tf.data serveice로 제공합니다.

사용 방법은 코드로 확인할 수 있습니다.

import tensorflow as tf

def randomized_preprocessing(record):
    pass
    
dataset = tf.data.TFRecordDataset('.../*.tfrecord')
dataset = dataset.map(randomized_preprocessing)

dataset = dataset.shuffle(buffer_size = 1024)
dataset = dataset.batch(batch_size = 32)
dataset = dataset.distribute("<master_address>") # add
dataset = dataset.prefetch()

model = tf.keras.Model(...)
model.fit(dataset)
  • distribute 이전의 코드는 cluster에서 셋팅한 worker들이 병렬적으로 수행합니다.

 

아래 코드로 내용을 대체합니다.

더 많은 층의 output을 보고 싶으면, feature_maps를 for-loop로 구현하면 됩니다.

# 신경망 시각화(조휘용)
import tensorflow as tf

get_layer_name = [layer.name for layer in model.layers]
get_output = [layer.output for layer in model.layers]

# 모델 전체에서 output을 가져올 수 있습니다.
visual_model = tf.keras.models.Model(inputs = model.input, outputs = get_output)

test_img = np.expand_dims(testX[0], axis = 0)
feature_maps = visual_model.predict(test_img)

# 첫 번째 컨볼루션 층의 특징맵을 시각화합니다.
conv_featuremap = feature_maps[0]
conv_name = get_layer_name[0]

img_size = conv_featuremap.shape[1]
img_features = conv_featuremap.shape[-1]

display_grid = np.zeros((img_size, img_size * img_features))

for i in range(img_features):
    x = conv_featuremap[:, :, :, i]
    x -= x.mean(); x /= x.std()
    x *= 64
    x += 128
    x = np.clip(x, 0, 255).astype('uint8')
    display_grid[:, i * img_size : (i + 1) * img_size] = x
    
plt.figure(figsize = (20,20))
plt.title(conv_name)
plt.grid(False)
plt.imshow(display_grid, cmap = 'viridis')

 

DataFrame과 같은 테이블을 결합할 때, pd.concat 함수를 사용해서 축 방향으로 결합할 수도 있지만,

이 방법외에도 결합을 위해 자주 사용하는 방법은 pd.merge 함수를 활용하는 것입니다.

간단한 예제를 통해 네 가지의 Join 방법을 살펴봅니다.

  • Inner Join
  • Outer Join
  • Left Join
  • Right Join

먼저 테이블은 다음과 같이 정의합니다.

import pandas as pd

A = pd.DataFrame({'ID' : [1, 2, 3], 
                  '이름' : ['김우주', '오수아', '박새로이']})
B = pd.DataFrame({'ID' : [2, 3, 4], '주소' : ['서울', '장가', '이태원']})

 

Inner Join

Inner Join은 두 테이블의 키가 일치하는 데이터만 추출해서 반환합니다. 우리는 'ID'를 키로 활용할 것입니다.
두 테이블에서 일치하는 아이디는 [2, 3]이기 때문에, 2행을 가지는 테이블을 만들 수 있습니다.

pd.merge(A, B, on = 'ID', how = 'inner')

Outer Join

Outer Join은 키를 기준으로 두 테이블에 존재하는 모든 데이터를 활용해서 결합하는 방법입니다. 따라서 A 테이블에서는 ID=4가 없으므로 NaN 값으로 채워질 것이고, B 테이블에서는 ID=1이 없으므로 NaN 값으로 채워질 것입니다.
쉽게 생각하면 조건은 잘 모르겠고, Null 값으로 채워서라도 다 사용하겠다~ 라는 의미입니다.

pd.merge(A, B, on = 'ID', how = 'outer')

 

Left Join

Left Join은 left에 위치하는 테이블의 키만 사용하여 데이터를 반환합니다. A 테이블이 보유하고 있는 키를 right 테이블은 B가 보유하고 있지 않으면 무시됩니다. 밑의 결과에서 ID=4가 반환되지 않는 것을 볼 수 있습니다.

pd.merge(left = A, right = B, on = 'ID', how = 'left')

 

Right Join

Right JoinLeft Join의 반대입니다. B 테이블의 키만 반환합니다.

pd.merge(left = A, right = B, on = 'ID', how = 'right')