NPU ?

  • 지금 개발된 고도화된 AI 기술 구현에는 GPU(그래픽처리장치)의 공이 크다.
  • GPU의 원래 목적은 컴퓨터 그래픽 처리다. AI용으로 GPU를 쓰는 이유는 그래픽 처리와 AI 연산이 비슷한 방법으로 이뤄지기 때문.
  • 그러나, GPU의 원래 목적이 AI 연산은 아니기 때문에 비용이나 전력소모 등 비효율적인 부분이 발생. 
  • 이를 극복하기 위해 최근에는 FPGA를 사용하거나 NPU, TPU 등 새로운 프로세서를 개발해 사용하고 있다.
  • 한마디로 NPU 는 인공지능을 위해 만든 프로세서
  • TPU 도 구글에서 인공지능을 위해 만든 NPU이다.


FPGA ?

  • FPGA(field programmable gate array)는 CPU나 GPU 등 회로 변경이 불가능한 다른 프로세서와 달리 프로그래밍이 가능한 프로세서로 용도에 맞게 회로를 변경할 수 있다. 
  • FPGA는 인공지능에 중요하게 쓰인다. 병렬연산 등 새로운 설계가 가능하기 때문에 머신러닝(ML)에 적합한 프로세서 설계에 적합하다.
  • 짧은 대기 시간과 높은 처리량은 FPGA의 가장 큰 장점. 
  • FPGA는 GPU보다 전력효율이 높다
  • BING 검색엔진에 FPGA 를 활용

 

 

아래글  읽어보면 FPGA ,NPU 가 뭘 의미하는지 대충감이옴

http://www.aitimes.com/news/articleView.html?idxno=137640 

http://www.aitimes.com/news/articleView.html?idxno=134014 

 

chmod +x a.sh
chmod +x b.sh
nohup ./a.sh >nohup.out & nohup ./b.sh >nohup2.out &

 

일단 nohup 시작하기전에 chmod +x a.sh 로 permission을 줘야 에러가 안남.

그리고 동시에 실행할땐 &, 차례차례 실행할거면 &&, ; 

 

  • ; - 앞의 명령어가 실패해도 다음 명령어가 실행
  • && - 앞의 명령어가 성공했을 때 다음 명령어가 실행
  • & - 앞의 명령어를 백그라운드로 돌리고 동시에 뒤의 명령어를 실행

 

>nohup.out 이거는 출력을 여기에 저장하겠다는 의미. 예를들어 print("hello") 라는 파이썬 파일을 실행하면 nohup.out 을 열어보면 hello 출력이 되어있을것.

잘 실행되고있는지 궁금하면 nohup.out 파일열어보면 된다.

 

- 종료하기

ps -ef
kill -9 [PID]

ps -ef | grep 쉘스크립트파일명



 

 

푸리에 변환이란??

  • 시간을 기준으로 그린 그래프에서 → 주파수 기준 그래프로 변환해줌.
  • 한마디로 주어진 신호를 다양한 주파수를 가지는 주기함수들의 합으로 나타내는 것이다.
  • 여기서 주기함수란? 우리가 일반적으로 알고 있는 사인(sin), 코사인(cos) 함수를 의미.

 

 

 

시간기준 -> 주파수 그래프 바뀌는 원리만 정확히 이해하면  감이온다. 

아래그림처럼 해당 주파수가 sin,cos그래프들이 몇개 모여 이루어졌나 보는것이다. 

 

 

 

 

푸리에 변환도 여러가지가 있는데 그중에서 FFT 를 사용한 초간단 예제. (빠르다!)

'<개념> > 기타' 카테고리의 다른 글

벡터 유사도 (vector similiarity)  (0) 2022.06.05
FPGA, NPU 초간단 개념  (0) 2022.02.28
SHIFT 개념 이해하기 예제 with SIN/COS/TAN  (0) 2021.12.30
자주나오는 이산수학관련 내용  (0) 2021.11.28
RestfulAPI 개념정리  (0) 2021.08.14

 

# 실행중인 gpu 죽이기 (pid 는 nvidia-smi로)
kill -9 PID
import tensorflow
tensorflow .__version__
tensorflow.config.list_physical_devices(device_type='GPU')
tensorflow.test.is_gpu_available()
# nvidia-version 확인하기
cat /proc/driver/nidia/version

# cuda 버전확인하기
nvcc -V

# pip3, python 버전확인
pip3 --version
python3 --version
pip3 show 

# 커널버전확인
uname -a
# 폴더개수
ls -l | grep ^d | wc -l
# 파일개수
ls -l | grep ^- | wc -l
# 하위폴더개수
find . -type f | wc -l
# 현재경로 확인하기
pwd
# 파일전체삭제
rm -r 파일이름

# 중간경로없이 찾기
cd ~/.ssh

 

새로운 세션을 시작:

| tmux

세션 이름을 지정해서 시작

| tmux new -s name

마지막 세션 열기 (attach):

| tmux a

‘namename’이라는 이름의 세션 열기:

| tmux a -t namename

돌고 있는 세션 리스트 보기:

| tmux ls

세션 끝내기:

| tmux kill-session -t namename

| tmux kill-session -t session_number

세션 다시 불러오기

| tmux attach -t namename

| mux attach -t session_number

세션 종료하기

| exit

 

 

< ctrl+b 누르고 손땐다음 그다음 또 누르는거임, 동시에 누르는거 아님>

세션이름 rename

ctrl+b, $ 

tmux 창에서 빠져나오기 (중지아님) 

ctrl+b, d 

창 쪼개기 (좌우로 생김)

ctrl+b , %

커서 위아래로 이동하기

ctrl+b , [

 

 

tmux 로 돌리고 ctrl+b, d 로 나온다음, 콘솔창 꺼버리면된다.

tmux-a로 다시 접속하면 그대로 실행중인창이 나와서 문제없는걸 확인할수 있다.

자꾸 에러날때 직빵인 방법

pip3 show tensorflow

이걸로 tensorflow 위치를 를 복사해준다. 

 

결과로 나온  /usr/local/lib/python3.6/dist-packages 파일에 있는  tensorboard 파일로 이동해준다. 

그리고 main.py 를 실행시키고 logdir 뒤에는 로그파일이 있는 주소를 가르키면 된다.

(리눅스 : pwd 로 경로위치 복사) 

cd /usr/local/lib/python3.6/dist-packages/tensorboard
python3.6 main.py --logdir="/root/data_generation/logs"

 

 

 알고리즘 풀이코드는 제외

 

 

1. Rupture

import os
import pandas as pd
import glob
import datetime
import matplotlib.pyplot as plt
import statsmodels.api as sm
import seaborn as sns
import statsmodels.api as sm
from scipy import stats
from sklearn.preprocessing import LabelEncoder
import numpy as np
#pd.options.display.float_format = '{:.10f}'.format #표 전체 다보이
# 안잘리게 설정
pd.set_option('display.max_row', 3000)
pd.set_option('display.max_columns', 1000)

breaks_rpt = []
for i in breaks:
    breaks_rpt.append(Data_F.index[i-1])
#breaks_rpt = pd.to_datetime(breaks_rpt)
breaks_rpt




plt.plot(y, label='data')
print_legend = True
for i in breaks_rpt:
    if print_legend:
        plt.axvline(i, color='red',linestyle='dashed', label='breaks')
        print_legend = False
    else:
        plt.axvline(i, color='red',linestyle='dashed')
plt.grid()
plt.legend()
plt.show()

 

 

 

2. jenkspy

https://github.com/mthh/jenkspy

 

GitHub - mthh/jenkspy: Compute Natural Breaks in Python (Fisher-Jenks algorithm)

Compute Natural Breaks in Python (Fisher-Jenks algorithm) - GitHub - mthh/jenkspy: Compute Natural Breaks in Python (Fisher-Jenks algorithm)

github.com

 

 

 

- Rupture 은 이상치 value 를 뽑아내고

- jenkspy 는 이상치 key 를 뽑아준다.

참조1 :https://github.com/linkedin/luminol

참조2 : https://www.kaggle.com/caesarlupum/anomaly-detection-time-series-linkedin-luminol/notebook

 

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import os
import gc
import warnings

from scipy.stats import norm
warnings.filterwarnings('ignore')
pd.set_option('max_columns', 150)
pd.set_option('max_rows', 150)

import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
from scipy import stats
#To plot figs on jupyter
%matplotlib inline
# figure size in inches
rcParams['figure.figsize'] = 14,6

import plotly.offline as py
py.init_notebook_mode(connected=True)
import plotly.graph_objs as go
import plotly.tools as tls
import warnings
warnings.filterwarnings('ignore')
pd.set_option('max_columns', 200)
pd.set_option('max_rows', 200)
pd.options.display.float_format = '{:.5f}'.format
## DATASET 1 (ent1, ds1)------------------------------------------------------------------------
mu, sigma = 0.0, 1.0
ent1 = np.zeros((10000))
for i in range(10):
#     print(mu)
    for j in range(1000):
        ent1[1000*i+j] = np.random.normal(mu, sigma)
    mu = mu + 9 - i

a1 = 0.6
a2 = -0.5
ds1 = np.zeros((10000))
ds1[0] = ent1[0]
ds1[1] = ent1[1]
for i in range(2,10000):
    ds1[i] = a1*ds1[i-1] + a2*ds1[i-2] + ent1[i]
## DATASET 2 (ent2 ds2 )------------------------------------------------------------------------
mu = 0.0
ent2 = np.zeros((10000))
for i in range(10):
#     print(mu)
    for j in range(1000):
        sigma = 0.1/(0.01 + (10000 - (i*1000 + j))/10000)
        ent2[1000*i+j] = np.random.normal(mu, sigma)
    mu = mu + 1

a1 = 0.6
a2 = -0.5
ds2 = np.zeros((10000))
ds2[0] = ent1[0]
ds2[1] = ent1[1]
for i in range(2,10000):
    ds2[i] = a1*ds2[i-1] + a2*ds2[i-2] + ent2[i]

## DATASET 3 (ds3) ------------------------------------------------------------------------
mu, sigma1, sigma3 = 0.0, 1.0, 3.0
ds3 = np.zeros((10000))
for i in range(10):
    if i in {0,2,4,6,8}:
        for j in range(1000):
            ds3[1000*i+j] = np.random.normal(mu, sigma1)
    else:
        for j in range(1000):
            ds3[1000*i+j] = np.random.normal(mu, sigma3)
plt.figure(figsize=(16,4))
plt.plot(ent1)
plt.title('Dataset 1  ent1')
plt.ylabel('Values')
plt.xlabel('Count')
plt.legend()

plt.figure(figsize=(16,4))
plt.plot(ent2)
plt.title('Dataset 2  ent2')
plt.ylabel('Values')
plt.xlabel('Count')
plt.legend()

plt.figure(figsize=(16,4))
plt.plot(ds1)
plt.title('Dataset 3  ds1')
plt.ylabel('Values')
plt.xlabel('Count')
plt.legend()

plt.figure(figsize=(16,4))
plt.plot(ds2)
plt.title('Dataset 4  ds2')
plt.ylabel('Values')
plt.xlabel('Count')
plt.legend()

plt.figure(figsize=(16,4))
plt.plot(ds3)
plt.title('Dataset 5  ds3')
plt.ylabel('Values')
plt.xlabel('Count')
plt.legend()

plt.show()

 

import luminol
from luminol import anomaly_detector,correlator
from luminol.anomaly_detector import AnomalyDetector
from luminol.correlator import Correlator

#Luminol - only if module 'luminol was installed'
#data preprocessing for the framework

data = np.array(ent1)
ts_s = pd.Series(data)
ts_dict = ts_s.to_dict()

data2 = np.array(ent2)
ts_s2 = pd.Series(data)
ts_dict2 = ts_s.to_dict()


detector = anomaly_detector.AnomalyDetector(ts_dict)
anomalies = detector.get_anomalies()
anomalies
if anomalies:
    time_period = anomalies[0].get_time_window()
    correlator = correlator.Correlator(ts_dict, ts_dict2, time_period)
    
    
 print(correlator.get_correlation_result().coefficient)
 
 def scoreLuminolALLData(ts_dict):    
    data = np.array(ts_dict)
    ts_s = pd.Series(data)
    ts_dict = ts_s.to_dict()

    detector = anomaly_detector.AnomalyDetector(ts_dict)
    score = detector.get_all_scores()
    score_v = []
    for timestamp, value in score.iteritems():
        score_v.append(value)
#         print(timestamp, value)
    return score_v
dataplot1 = scoreLuminolALLData(ent1)    
dataplot2 = scoreLuminolALLData(ent2) 
dataplot3 = scoreLuminolALLData(ds1)    
dataplot4 = scoreLuminolALLData(ds2)        
dataplot5 = scoreLuminolALLData(ds3) 

dataplot1

더보기
더보기
더보기

dataLUMINOL_dataset1 = np.array(dataplot1)
from scipy import stats
dataLUMINOL_dataset1 = stats.describe(dataplot1)
dataLUMINOL_dataset1

 

qt25_ds1 = np.percentile(dataplot1, 25)  # Q1 백분위 25퍼센트
qt50_ds1 = np.percentile(dataplot1, 50)  # Q2 백분위 25퍼센트
qt75_ds1 = np.percentile(dataplot1, 75)  # Q3 백분위 25퍼센트
qt25_ds1, qt50_ds1, qt75_ds1

 

dfLUMINOL_dataset1 = pd.DataFrame(dataplot1, columns=['Score'])
dfLUMINOL_dataset1.value_counts()
# 이건 퍼센테이지가 왜저렇게 나왔는지 분석하기 위해서 보여준것임. 

 

 

def plot_anomaly_score_low_higt(datascore, data):
    datascore_ = np.array(datascore)
    from scipy import stats
    datascore_ = stats.describe(datascore)
    
    datascore_ = pd.DataFrame(datascore, columns=['Score'])

    delta = np.percentile(datascore, 75)
    print('Threashold ',delta)

    plt.figure(figsize=(16,6))
    plt.plot(data)
    plt.title("data count")        

    plt.figure(figsize=(16,6))
    plt.plot(datascore)
    plt.title("data count")        

    
    plt.figure(figsize=(16,6))
    df_high_data_ = datascore_[datascore_ <= delta]
    df_high_score_ = datascore_[datascore_ > delta]
    
    plt.plot(datascore_.index, datascore_.Score.fillna(1), c='gray', alpha=0.4)
    plt.scatter(df_high_data_.index, df_high_data_.values, label='Inline', s=10)
    plt.scatter(df_high_score_.index, df_high_score_.values, label='Outlier', c='red', s=10)
    plt.margins(x=0.01,y=0.2)
    plt.title('Anomaly Score ')
    plt.ylabel('Score')
    plt.xlabel('Data Count')
    plt.legend()
    plt.show()

 

dataLUMINOL_dataset2 = np.array(dataplot2)
from scipy import stats
dataLUMINOL_dataset2 = stats.describe(dataplot2)
dataLUMINOL_dataset2

qt25_ds2 = np.percentile(dataplot2, 25)  # Q1
qt50_ds2 = np.percentile(dataplot2, 50)  # Q2
qt75_ds2 = np.percentile(dataplot2, 75)  # Q3
qt25_ds2,qt50_ds2, qt75_ds2


dfLUMINOL_dataset2 = pd.DataFrame(dataplot2, columns=['Score'])
plot_anomaly_score_low_higt(dfLUMINOL_dataset2, ent2)

 

dataLUMINOL_dataset4 = np.array(dataplot4)
from scipy import stats
dataLUMINOL_dataset4 = stats.describe(dataplot4)
dataLUMINOL_dataset4


qt25_ds4 = np.percentile(dataplot4, 25)  # Q1
qt50_ds4 = np.percentile(dataplot4, 50)  # Q2
qt75_ds4 = np.percentile(dataplot4, 75)  # Q3
qt25_ds4, qt50_ds4, qt75_ds4

dfLUMINOL_dataset4 = pd.DataFrame(dataplot4, columns=['Score'])
plot_anomaly_score_low_higt(dfLUMINOL_dataset4, ds2)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from synthetic_tests_lib import crosscorr, compute_shift
from scipy import signal
# 완전다른 그래프랑 어케 나타나는지 
x = [0,1,2,3,4,5,6,7,8,9]
g1 = [1,2,3,4,5,6,7,8,9,10]
g2 = [10,9,8,7,6,5,4,3,2,1]
shift = compute_shift(g1,g2)
plt.plot(x,g1,label='g1')
plt.plot(x,g2,label='g2')
plt.legend(loc='upper right')
plt.title("compute_shift(g1,g2)")
print('shift : '+ str(shift))
print('shift 가 의미하는바 =  g1 그래프가 얼마만큼 움직여야 g2 그래프와 동일해는가')

from synthetic_tests_lib import crosscorr, compute_shift

# 완전다른 그래프랑 어케 나타나는지 
g1 = np.sin(x)
g2 = np.cos(x)
g3 = np.tan(x)
x1=[3,4,5,6,7,8,9,10,11,12]
g4 = np.sin(x1)
g5 = np.sin(x)*2
x2=[0,0.2,0.4,0.6,0.8,1.0,1.2,1.4,1.6,1.8]
g6 = np.sin(x2)

shift = compute_shift(g1,g2)
shift2 = compute_shift(g1,g3)
shift3 = compute_shift(g1,g5)
shift4 = compute_shift(g1,g6)

shift5 = compute_shift(g3,g5)
shift6 = compute_shift(g2,g4)

plt.plot(x,g1,label='g1 : sin(x)')
plt.plot(x,g2,label='g2 : cos(x)')
plt.plot(x,g3,label='g3 : tan(x)')
plt.plot(x,g4,label='g4 : sin(x+3)')
plt.plot(x,g5,label='g5 : sin(x)*2')
plt.plot(x,g6,label='g6 : sin(1/5*x)')



plt.legend(loc='upper right')
plt.title("compute_shift")
print('shift(sin,cos) : '+ str(shift))
print('shift2(sin,tan) : '+ str(shift2))
print('shift3(sin,sin*2) : '+ str(shift3))
print('shift4(sin,sin(1/5*x) : '+ str(shift4))
print('shift5(tan,sin*2) : '+ str(shift5))
print('shift6(cos,sin(x+3) : '+ str(shift6))

d1, d2 ,d3 = pd.Series(g1), pd.Series(g2),pd.Series(g3)
lags = np.arange(-(5), (5), 1)
rs = np.nan_to_num([crosscorr(d1, d2, lag) for lag in lags])
rs2 = np.nan_to_num([crosscorr(d1, d3, lag) for lag in lags])
#print('rs'+str(rs))
#print('rs2'+str(rs2))
#print(np.corrcoef(g1,g2))

# 높이는 상관없다.(sinx,sinx*2) shift=0

# 완전다른 그래프랑 어케 나타나는지 
x = [0,1,2,3,4,5,6,7,8,9]
g1 = [1,0,0,1,1,0,0,1,1,0]
g2 = [10,9,8,7,6,5,4,3,2,1]
shift = compute_shift(g1,g2)
plt.plot(x,g1,label='g1')
plt.plot(x,g2,label='g2')
plt.legend(loc='upper right')
plt.title("compute_shift(g1,g2)")
print('shift : '+ str(shift))
print('shift 가 의미하는바 =  g1 그래프가 얼마만큼 움직여야 g2 그래프와 동일해는가')

d1, d2 = pd.Series(g1), pd.Series(g2)
lags = np.arange(-(5), (5), 1)
rs = np.nan_to_num([crosscorr(d1, d2, lag) for lag in lags])
print('rs'+str(rs))
print(np.corrcoef(g1,g2))

'<개념> > 기타' 카테고리의 다른 글

FPGA, NPU 초간단 개념  (0) 2022.02.28
푸리에 변환 초간단 정리  (0) 2022.01.30
자주나오는 이산수학관련 내용  (0) 2021.11.28
RestfulAPI 개념정리  (0) 2021.08.14
AJAX,JSON 개념메모  (0) 2021.08.14

- kaggle luminol https://www.kaggle.com/caesarlupum/anomaly-detection-time-series-linkedin-luminol

- 위랑 똑같은데 알고리즘만 다름 https://www.kaggle.com/caesarlupum/anomaly-detection-time-series-changefinder#Glipse-Data

- 위에두개 작성한 사람이 cpd 알고리즘만 모아둔거 https://www.kaggle.com/general/128356

- pilly  - 

- rupture https://github.com/deepcharles/ruptures

ㄴ 이건 이상치 value 를 잡아줌 

- jenkspy  https://pypi.org/project/jenkspy/

ㄴ이건 이상치 key 를 잡아줌

 

'<개념> > 기타' 카테고리의 다른 글

푸리에 변환 초간단 정리  (0) 2022.01.30
SHIFT 개념 이해하기 예제 with SIN/COS/TAN  (0) 2021.12.30
RestfulAPI 개념정리  (0) 2021.08.14
AJAX,JSON 개념메모  (0) 2021.08.14
도커 초간단 개념정리  (0) 2021.05.09
  • 추세 (Trend) : 증가하는지 감소하는지
  • 계절성 (Seasonality) : 일정한 빈도로 주기적으로 반복되는 패턴( 𝑚 )
  • 잔차(Residual) : 데이터 - 추세(trend) - 계절성(seasonal)

그렇다면 잔차가 불규칙적인 값으로 seaonal 한 값(계절성) 이 유의미한 값이 되기위해서는 잔차(residual)이 다음과 같이 2가지 조건을 모두 만족해야합니다.

 

 

  1. 잔차는 (1) 정규분포이고 ,평균0과 일정한 분산을 가져야함

2. 잔차에 (1) 특정한 흐름이 있으면 안됨, 규칙성이 보이면안됨

 

위에 서술한 잔차의 2가지 조건을 만족하기위해서 총 4가지 방법으로 잔차진단을 수행합니다

잔차진단 ! (4가지)

 

 

pdf

T_잔차진단(백색잡음)_내용_정리.pdf
0.73MB

 

HTML

Export-c87bd7a2-b880-4893-b8fc-f28f28954473.zip
0.52MB

 

케라스 sequential 로 만든 모델 저장하는법 & 불러오는법

코드 참조 : https://tykimos.github.io/2017/06/10/Model_Save_Load/

참조 :https://mylifemystudy.tistory.com/69

https://ssongnote.tistory.com/12

 

  • 케라스에서 모델 구성하는법
# 0. 사용할 패키지 불러오기
from keras.utils import np_utils
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np
from numpy import argmax

# 1. 데이터셋 생성하기

# 훈련셋과 시험셋 불러오기
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 데이터셋 전처리
x_train = x_train.reshape(60000, 784).astype('float32') / 255.0
x_test = x_test.reshape(10000, 784).astype('float32') / 255.0

# 원핫인코딩 (one-hot encoding) 처리
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# 훈련셋과 검증셋 분리
x_val = x_train[:42000] # 훈련셋의 30%를 검증셋으로 사용
x_train = x_train[42000:]
y_val = y_train[:42000] # 훈련셋의 30%를 검증셋으로 사용
y_train = y_train[42000:]

# 2. 모델 구성하기
model = Sequential()
model.add(Dense(units=64, input_dim=28*28, activation='relu'))
model.add(Dense(units=10, activation='softmax'))

# 3. 모델 학습과정 설정하기
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])

# 4. 모델 학습시키기
model.fit(x_train, y_train, epochs=5, batch_size=32, validation_data=(x_val, y_val))

# 5. 모델 평가하기
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=32)
print('')
print('loss_and_metrics : ' + str(loss_and_metrics))

# 6. 모델 사용하기
xhat_idx = np.random.choice(x_test.shape[0], 5)
xhat = x_test[xhat_idx]
yhat = model.predict_classes(xhat)

for i in range(5):
    print('True : ' + str(argmax(y_test[xhat_idx[i]])) + ', Predict : ' + str(yhat[i]))
위 코드 관련된 내용

** reshape 관련참조 https://supermemi.tistory.com/12

** utils.to_categorical

** model.compile → optimizer,loss,metrics 지정해줌.

** loss 함수 참조 https://hororolol.tistory.com/375

** train (val , train ) / test 이렇게 나눠짐

** predict vs predict_class

  • predict 의 경우

[[0.22520512],[0.9520419 ],[0.9672848 ],[0.02690617]]

  • predict_classes 의 경우

[[0],[1],[1],[0]]

** argmax

 

Q. 저장한 모델은 어떻게 다시 불러오고 불러온 모델을 어떤식으로 활용하는지
  • 모델을 저장한다. 무엇을 저장하는건지

모델은 1. 모델 아키텍쳐 (모델이 어떤레이어로 쌓여있는지= 즉 모델구성) 2. 모델가중치(처음에는 임의의값으로 초기화되어있지만, 훈련셋으로 학습하면서 갱신됨) 로 이루어짐. 모델을 저장한다는 의미는 이 두개를 저장한다는 말.

  • 위코드를 실행하고나면 ~~.h5 파일이 생김. 여기에 들어있는 정보들은

(1) 모델구성정보 (2) 가중치 (3) 손실함수등등 학습설정(model.compile해준거) (4) 재학습을 할수있도록 마지막 학습상태 들로 구성되어있다.

→ 만약에 (1) 모델구성정보와 (2) 가중치를 따로 각각 저장하고 불러오는 케이스일경우, 모델을 불러온다음, model.compile을 설정해주어야한다.

 

 

Python sklearn 로 만든 모델 저장하는법

참조: https://cocook.tistory.com/46

https://www.python2.net/questions-889925.htm

Tensorflow 만든 모델 저장,불러오는법

TENSORFLOW

model.save()를 호출하면 다음과 같은 파일들이 저장된다.

  • model's architecture/config
  • model's weight values
  • model's compilation information (if compile() was called)
  • optimizer and its state

model.save('my_custom_model')시 저장되는 디렉토리는 다음과 같다.

my_custom_model 
└ assets (dir) 
└ variables (dir) 
└ saved_model.pb (file)

불러올때는 아래처럼 불러오면 된다

model_dnn = load_model('my_custom_model')

 

 

람다에서 불러올때 h5로 불러오면 에러가 나고, pb 형태로만 인식이 되나보다. 변환해주면 됨

**KERAS (.H5)→ Tensorflow (.pb) 형식

https://coredump064.tistory.com/80 참조 (h5→pb)

 

본인이 변환해서 저장한 saved_dnn_model 형태는 파일형태로 다음과 같았다.

saved_dnn_model
ㄴkeras_metadata.pb
ㄴsaved_model.pb
ㄴvariables
ㄴassets

 

 

Uploaded by Notion2Tistory v1.1.0

AJAX

  • 자바스크립트의 라이브러리중 하나
  • 브라우저가 가지고있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법 이며 JavaScript를 사용한 비동기 통신, 클라이언트와 서버간에 XML 데이터를 주고받는 기술이다. (https://velog.io/@surim014/AJAX란-무엇인가)
  • 단순히 웹화면에서 무언갈 부르거나 데이터를 조회하고 싶을때 페이지전체를 새로고침하지않기위해 사용한다.
  • 기본적으로 HTTP 프로토콜은 클라이언트쪽에서 Request를 보내고 서버쪽에서 Response를 받으면 이어졌던 연결이 끊기게 되어있다. 그래서 화면의 내용을 갱신하기 위해서는 다시 request를 하고 response를 하며 페이지 전체를 갱신하게 된다. 하지만 이렇게 할 경우, 엄청난 자원낭비와 시간낭비를 초래 → ajax를 사용
  • 서버에서 데이터를 http get, post, json 의 모든방식으로 전송한후 서버측 응답을 받으럐때 사용, http get방식으로 전송한후 서버측 응답을 json형식으로 받을떄는 $get.JSON 을 사용한다.
var serverAddress = 'https://hacker-news.firebaseio.com/v0/topstories.json';

// jQuery의 .get 메소드 사용
$.ajax({
    url: ,
    type: 'GET',
    success: function onData (data) {
        console.log(data);
    },
    error: function onError (error) {
        console.error(error);
    }
});
<script>

$(document).ready(function() {
     jQuery.ajax({
           type:"GET",
           url:"/test",
           dataType:"JSON", // 옵션이므로 JSON으로 받을게 아니면 안써도 됨
           success : function(data) {
                 // 통신이 성공적으로 이루어졌을 때 이 함수를 타게 된다.
                 // TODO
           },
           complete : function(data) {
                // 통신이 실패했어도 완료가 되었을 때 이 함수를 타게 된다.
                 // TODO
           },
           error : function(xhr, status, error) {
                 alert("에러발생");
           }
     });
});
</script>

출처: https://marobiana.tistory.com/77 [Take Action]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ko"  xml:lang="ko">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <head>
  <script src="./js/jquery-1.11.3.min.js"></script>
  <script type="text/javascript">
	$(document).ready(function() {
		$("#btn1").click(function() {
			$.ajax({
				type:"post",
				url:"./list.json",
				dataType:"text",
				success:function(data) {					
					$.each(JSON.parse(data), function(index, entry) {
						console.log("menu : " + entry["menu"] + ", page " + entry["page"]);
						$("#" + entry["menu"]).html( entry["menu"] + ", page " + entry["page"]);
					});
			}});
		});
	});
  </script>
 </head>
 <body>
	<div id="human"></div>
	<div id="animal"></div>
	<div id="fruit"></div>
	<button id="btn1">button</button>
 </body>
</html>


출처: https://leojin.tistory.com/entry/Ajax-로-json-파일-내용-읽기

header:{"Content-Type":"application/json"}

ajax로 서버에 데이터를 보낼때 header 중 content-type이 존재하는데 이를 설정하지않으면 디폴트값으로 application/x-www-form-urlencoded; charset=UTF-8 타입으로 지정됨.

그래서 json형태의 데이터를 주고싶을떄는 위의 헤더를 지정해주어야함.

문제 → request안에 포함된 json형태의 데이터를 받았을때 보통 vo,dto에서 담아 다시 사용하는데, ajax는 데이터를 문자열화해주지않아서 보낼 데이터를 json.stringfy()로 감싸주어야함

그렇지않을경우 json데이터를 인식을 못함

기본값은 true, 기본적을 key,value 값을 쿼리 스트링을 변환해서 보내줌. 이게 False 로 지정되어있으면 쿼리 String으로 설정하지않음 , 이것은 파일 전송시에 사용한다고함

전제조건 : 내가보고있는 페이지에서 다른페이지의 rest api를 호출해서 데이터를 json으로 가져오려고함. 내가 이용하는 페이지주소랑 데이터를 가지고 오기위한 서버 도메인이 서로 다를경우 crossdomain이라고 부름.

  • formData

비동기 업로드를 위해 ajax formData를 사용함. 평소엔 안쓰임 , 이미지를 ajax로 업로드할때 필요함.

  • *** 비동기?
    • 비동기 처리 ? 특정 코드의 연산이 끝날떄까지 코드의 실행을 멈추지않고 다음코드를 먼저 실행하는 자바스크립트의 특성을 의미함. → 제이쿼리의 ajax를 많이씀.
    • function getData() {
      	var tableData;
      	$.get('https://domain.com/products/1', function(response) {
      		tableData = response;
      	});
      	return tableData;
      }
      
      console.log(getData()); // undefined
      
      // get 부분이 ajax로 통신을 하는 부분임. http~ 에 get 요처응ㄹ 날려서 product정보를 요청함. 
      // 한마디로 쉽게 말하면 지정된 url에 데이터를 하나 보내주세요 라는 요청을 날리는것과 같음. 
      // http 서버에서 받아온 데이터를 respose 인자에 담김
      // getdata는 뭐임?? undefined 왜? 왜냐 이전에 미리 return 해줘서 그럼. 기다려주지않고 바로
      리턴해버려서 undefined를 출력하게됨. 
      // 이런식으로 특정로직의 실행이 끝날떄까지 기다려주지않고 나머지 코드를 먼저 실행해버리는게 비동기처리라는것임
      콜백함수로 비동기처리 방식의 문제점 해결하기
    • function getData(callbackFunc) {
      	$.get('https://domain.com/products/1', function(response) {
      		callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
      	});
      }
      
      getData(function(tableData) {
      	console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
      });

중요 : ajax formData 사용시에 contentTYpe, processData 옵션을 false로 설정해야함 !!!

사용법은 두가지가있음

(1) form 에 작성된 전체데이터 보내기 (2) form 에 작성된것 중 필요한것만 선택해서 보내기

//후자 (2)  방법
var formData = new formData();
formData.append([key],[value]);
//append는 전체데이터중에 필요한것만 선택해서 보낼때를 의미함. 더해준다는 의미가 아님.

formData.append('username', 'Chris'); //이런식으로 쓰인다~

<form id="myForm" name="myForm">
  <div>
    <label for="username">Enter name:</label>
    <input type="text" id="username" name="username">
  </div>
  <div>
    <label for="useracc">Enter account number:</label>
    <input type="text" id="useracc" name="useracc">
  </div>
  <div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
  <input type="submit" value="Submit!">
</form>

/////////////////////////////////////////////////////////////////////////////

let myForm = document.getElementById('myForm');
let formData = new FormData(myForm);
  • document.getElementById

id 로 요소를 찾고 이를 나타내는 elements 객체를 반환

  • param(obj)

폼 요소들의 값을 변환해서 직렬화한 문자열로 표현함.

  • datatype

내가보는 데이터타입 아님, 서버가 응답(response)할떄 보내줄 데이터타입임. 이는 success function에 전달될 argument의 형태를 지정하는데 사용된다고 한다

→ 한마디로 서버측에서 전송받은 데이터의 형식

  • processData

일반적으로 서버에 전달되는 데이터는 query string이라는 형태로 전달된다. data 파라미터로 전달된 데이터를 내부적으로 query string으로 만드는데 파일전송의 경우 이렇게 하면안된다.

-기본값은 true

-해당값이 true →> data 값들이 쿼리 스트링 형태인 Key=value & key2=value2 형태로 전달이된다. 하지만 리헌식으로 진행하면 file값들이 제대로 전달되지않음

-해당값이 false → { key1 : 'value1', key2 : 'value2' } 형태로 전달

  • contentType

디폴트값은 "application/x-www-form-urlencoded; charset=UTF-8" 인데 , multipart/form-data로 전송이 되게 false로 넣어줌.

  • data

http 요청후 return하는 값임

  • url

요청이 전송되는 url 이 포함되는 문자열

  • type

http 요청방식 (Get/Post)

  • async

요청시 동기유무를 선택할수 있다 ( true/False)

.ajax 에서 string으로 보내서 전송하고,

success 후에는 돌려받은걸 다시 json파일로 변환해서 출력한다

  • enctype1. application/www-form-urlencoded2. multipart/form-data3. text/plain출처: https://dydals5678.tistory.com/113
  • 이 형식은 인코딩을 하지 않은 문자 상태로 전송한다.
  • 파일이나 이미지를 서버로 전송할 경우 이 방식을 사용한다. 그렇게 하지 않으면 웹 서버로 데이터를 넘길때 파일의 경로명만 전송되고 파일 내용이 전송되지 않기 때문이다. 그리고 이떄 메소드는 post값으로 지정해줘야 한다 (핵중요)
  • 디폴트값이다. enctype을 따로 설정하지 않으면 이 값이 설정된다. 폼데이터는 서버로 전송되기 전에 URL-Encode 된다.
  • enctype 은 다음 3가지값을 지정가능

JSON 메모

  • JSON.stringify(value)

→ 인수로 전달받은 자바스크립트 객체를 문자열로 변환해서 반환해줌

예제1

<html>
<body>
	<p id="json"></p>
	<script>
		var dog = {name: "식빵", family: "웰시코기", age: 1, weight: 2.14};	// 자바스크립트 객체
		
		var data = JSON.stringify(dog);	// 자바스크립트 객체를 문자열로 변환함.
		document.getElementById("json").innerHTML = data; // json 데이터 불러옴

	</script>
</body>
</html>
//output : {"name":"식빵","family":"웰시코기","age":1,"weight":2.14}ㅁ

예제2

var obj = { name: "John", age: 30, city: "New York" }; 
var myJSON = JSON.stringify(obj); 
document.getElementById("demo").innerHTML = myJSON; 
//결과값 {"name":"John","age":30,"city":"New York"}
  • JSON.parse(text)

→인수로 전달받은 문자열을 자바스크립트 객체로 변환해서 반환해줌

<html>
<head>
	<title>parse</title>      
</head>
<body>
	<p id="json"></p>
	<script>
		// JSON 형식의 문자열
		var data = '{"name": "식빵", "family": "웰시코기", "age": 1, "weight": 2.14}';
		
		var dog = JSON.parse(data);	// JSON 형식의 문자열을 자바스크립트 객체로 변환함.
		document.getElementById("json").innerHTML = dog + "<br>";
		document.getElementById("json").innerHTML += dog.name + ", " + dog.family;
	</script>
</body>
</html>

//결과 
[object Object]
식빵, 웰시코기
const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);

console.log(obj.result);
// expected output: true
  • toJSON()

→ 자바스크립트의 Date 객체를 Json 형식의 문자열로 반환해서 변환

 

 

예제1

추가 참조 :  https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=mk1126sj&logNo=221016837263

https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

https://grip.news/archives/1397

https://galid1.tistory.com/398

 

1. 일단 opencv로 동영상을 잘라준다

2. yolo 적용해서 object detection 감지 ( 아래 사이트 참조)

coco.names
0.00MB
yolov3.cfg
0.01MB
yolo_object_detection.zip
2.76MB

* yoloc3.weighs 는 아래에서 다운로드받아서 쓰기 

 

YOLO object detection using Opencv with Python - Pysource

We’re going to learn in this tutorial YOLO object detection. Yolo is a deep learning algorythm which came out on may 2016...

pysource.com

 

mp4_cctv_list=[]
for i in file_list:
    # 현재 디렉토리에 있는 모든 파일 리스트를 가져온다
    
    path = "./task1/"+str(i)
    file_listttt = os.listdir(path)
    mp4_cctv = [file for file in file_listttt if file.endswith(".mp4")]
    mp4_cctv_list.append(mp4_cctv)


for j in range(1,len(file_list)):
    mp4_cctv = "./task1/"+str(file_list[j-1])+"/"+str(mp4_cctv_list[j-1][0])

    try : 
        # -------------------- 동영상 쪼개기 ------------------------------------------------------------   
        import cv2
        n=119  #동영상을 119개로 쪼개줄것임

        vidcap = cv2.VideoCapture(mp4_cctv)     
        total_frames = vidcap.get(cv2.CAP_PROP_FRAME_COUNT)
        frames_step = total_frames//n
        for i in range(n):
            #here, we set the parameter 1 which is the frame number to the frame (i*frames_step)
            vidcap.set(1,i*frames_step)
            success,image = vidcap.read()  
            #save your image
            globals()['col{}.jpg'.format(i)]= image
            #cv2.imwrite(globals()['./col{}.jpg'.format(i)],image)
            
            # 저장해줄 위치 지정해줌
            cv2.imwrite('./new2/col'+str(i)+'.jpg',image)
        vidcap.release()
        
        # -------------------- yolo ------------------------------------------------------------
        # Yolo 로드
        net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
        classes = []
        with open("coco.names", "r") as f:
            classes = [line.strip() for line in f.readlines()]
        layer_names = net.getLayerNames()
        output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
        colors = np.random.uniform(0, 255, size=(len(classes), 3))

        for k in range(119):  #수정 119로
            # 이미지 가져오기
            print('사진' ,k)
            img = cv2.imread("./new2/col"+str(k)+".jpg")
            img = cv2.resize(img, None, fx=0.4, fy=0.4)
            height, width, channels = img.shape

            # Detecting objects
            blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
            net.setInput(blob)
            outs = net.forward(output_layers)

            # 정보를 화면에 표시

            class_ids = []
            confidences = []
            boxes = []
            for out in outs:
                for detection in out:
                    scores = detection[5:]
                    class_id = np.argmax(scores)
                    confidence = scores[class_id]
                    if confidence > 0.5:
                        # Object detected
                        center_x = int(detection[0] * width)
                        center_y = int(detection[1] * height)
                        w = int(detection[2] * width)
                        h = int(detection[3] * height)
                        # 좌표
                        x = int(center_x - w / 2)
                        y = int(center_y - h / 2)
                        boxes.append([x, y, w, h])
                        confidences.append(float(confidence))
                        class_ids.append(class_id)

            indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

            font = cv2.FONT_HERSHEY_PLAIN
            label_lists=[]
            for i in range(len(boxes)):
                if i in indexes:
                    x, y, w, h = boxes[i]
                    label = str(classes[class_ids[i]])
                    color = colors[i]
                    cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
                    cv2.putText(img, label, (x, y + 30), font, 3, color, 3)
                    label_lists.append(label)

            cv2.imshow("Image", img) 
            cv2.waitKey(1)
            cv2.destroyAllWindows()
            print(label_lists)
            df['mp4'][:][k]=label_lists


        #맥에서 opencv 안닫힐때 꿀팁
        cv2.destroyAllWindows()
        cv2.waitKey(1)
        cv2.waitKey(1)
        cv2.waitKey(1)
        cv2.waitKey(1)

 
    except :
        print('exept',file_list[j-1],j-1)

 

이 방법은 k-means 방법처럼, 클러스터 개수 가정해줄 필요가 없습니다. 또 이방법에서 주목한점이 군집간 거리를 활용하는 방법입니다.

.............................................................................................................................

  • 군집간 거리 측정 방식

-method : single, complete, average, centroid, ward linkage 방식이 존재

-Centroid : 두 군집의 중심점(centroid)를 정의한 다음 두 중심점의 거리를 군집간의 거리로 측정

-Single : 최단 연결법, 모든 데이터 조합에서 데이터 사이 거리를 측정해서 가장

최소 거리(작은 값)를 기준으로 군집 거리를 측정

-Complete : 최장 연결법으로 두 클러스터상에서 가장 먼 거리를 이용해서 측정하는 방식

-Average : 평균 연결법, 두 군집의 데이터들 간 모든 거리들의 평균을 군집간 거리로 정의(위에서 singe.complete를 합쳐준 방법이라하면 되겠다)

-Ward : 와드연결법은 군집분석의 각 단계에서 데이터들을 하나의 군집으로 묶음으로써 생기는 정보의 손실을 군집의 평균과 데이터들 사이의 오차제곱합(SSE)으로 아래와 같이 측정한다.

.............................................................................................................................

<코드부분>

Xi = np.array([[0,17,21,31,23],[17,0,30,34,21],[21,30,0,28,39],[31,34,28,0,43],[23,21,39,43,0]]) dists = squareform(Xi) #여기서 flat하게 바꾸어 주어야한다.이거 안해주고 넣으면 어딘가 이상해짐  Z = linkage(dists, method='single')  # method는 여기서 변경해주면 된다 dendrogram(Z)   # 아래 그래프 출력 plt.axhline(20, color='k', ls='--');  #임계치값(20)에 대해 점점이 가로줄을 그어줌

 

shc.fcluster(Z, 20, criterion='distance')  #임계치20에 줄을 그어서 나누어지는 군집들

→ [a,b][c][d][e] 이렇게 나누어짐을 확인할수 있습니다.

 

 

 

<개념부분>

첫번째줄에서, 임계값을 주지않으면, 총 1개의 군집이 출력됩니다. (method별로 만들어지는 dendrogram 모양이다릅니다)

두번쨰 줄에서 임계값을 줌으로써 여러개의 군집으로 나누어줄수 있습니다.

 

 

이것은 method 별로 유사도를 처리하는 방법이 다른것을 자세히 나타내 줍니다.

(single 은 가장 가까운 거리를 채택, complete 는 가장 먼거리를 채택, average는 이 두개의 평균을 채택합니다.)

e.g. single linkage 방법에서 abce, d 사이의 거리를 구할때, d와 ab간의 거리 31, d와 c간의 거리 28, d와 e간의 거리 43중에 가장 작은값인 28을 선택해줍니다. 만약 complete linkage 방법이였다면, 43을 선택해주었을것입니다.

(centroid , ward 이 두가지 메소드는 계산과정에서 (x,y)축을 필요로 하기 때문에 x,y축에서 pdist로 유사도를 구하는 방식이 아니라 처음부터 유사도를 집어넣어서 계산하는  방법에는 바람직하지 않음

 

 

 

 

 

 

 

 

+ Recent posts