프로젝트 도중 서버에 접속하지 않고도 입력 테스트를 간단하게 진행할 수 있어 텔레그램 앱을 사용하게 되었습니다.

 매번 쉘에 접속하여 테스트 명령어를 치지 않고도 간단히 메신저로 테스트 입력값을 쏠 수 있도록 하였습니다.


 텔레그램에서는 봇을 텔레그램 내부에서 실행되는 '타사 응용 프로그램'으로 정의하고 있습니다.

'타사 응용 프로그램' 에서는 https 요청을 통하여 봇을 제어할 수 있습니다. 인증은 bot 에 대한 token 값으로 진행합니다.


 


시작하기



1. http://core.telegram.org/bots 에 접속한 뒤, BotFather 링크를 클릭합니다.






2. Send Message 링크를 클릭합니다.






3. Telegram 의 BotFather 대화방에 들어오면 시작버튼을 누릅니다.



4. 아래 /newbot 명령어로 봇 생성을 하며,  봇의 이름과 봇의 유저이름을 설정해줍니다.  유저이름의 경우 뒤에 _bot 이 들어가야 합니다.




 

5. 생성되었습니다. BotFather 가 알려준 HTTP API 토큰 값을 잘 기억해두어야 합니다.





테스트



 만든 봇을 이용하여 테스트를 진행하도록 하겠습니다.

테스트는 Python 으로 아래 링크를 참조하여 테스트를 진행하였습니다.











테스트 환경 구축


1. pip install python-telegram-bot 명령어로 설치를 진행합니다.






2. git clone https://github.com/python-telegram-bot/python-telegram-bot --recursive 명령어를 통해 샘플 코드를 받습니다.






3. examples 폴더의 echobot.py 파일을 편집합니다. (토큰을 입력합니다.)







테스트 진행


1. 텔레그램에서 만든 Bot을 전역검색하여 찾은 뒤, 아래와 같이 텍스트를 입력하였습니다. 현재까지는 아무 응답이 없습니다.






2. 설치한 서버에서 examples 폴더의 echobot.py 파일을 실행시킵니다. 




3. 입력한 문구들에 대한 답장이 한꺼번에 오는 것을 확인할 수 있습니다.  그 뒤, 텍스트를 입력하면 입력한 텍스트에 대한 답장이 바로 오는 것을 확인할 수 있습니다.



4. 아래는 텍스트 입력할 때마다 출력되는 로그입니다. 

  아래 로그는 코드 내의 update 를 출력한 것으로, 이 update 에 포함되어있는 데이터를 기반으로 Rule-based 시스템을 구축할 수 있습니다.








출처 

https://core.telegram.org/bots/ 공식홈페이지

https://github.com/python-telegram-bot/python-telegram-bot/ 파이썬 예제

https://blog.psangwoo.com/coding/2016/12/08/python-telegram-bot-1.html 설명이 잘 되어 있습니다.

1)    gRPC 관련 지식

A.    gRPC

구글에서 처음 개발하여 공개한 원격 프로시저 호출(RPC) 시스템으로 HTTP/2 를 사용하고 인터페이스 설명 언어로 프로토콜 버퍼를 사용함.

 인터페이스 설명 언어가 하나이기 때문에 다양한 언어에서 데이터를 주고 받을 수 있는 장점이 있음

 

B.     HTTP/2

HTTP/1.1의 알려진 성능 제한이 개선된 프로토콜로 헤더 필드 압축과 동일한 연결에서 다중 동시 교환 허용 등을 통한 리소스 비용 절감 및 성능 개선이 진행됨

 

C.     프로토콜 버퍼

구글에서 공개한 직렬화 데이터 구조로 다양한 언어를 지원한다는 장점이 있다. 최대 64M 까지 데이터를 전달할 수 있다고 하며, JSON 과 유연한 데이터 전환이 가능하다.

관련 출처 : http://bcho.tistory.com/1182

 


2)    gRPC 사용 (python to nodejs)

I.      사용한 소프트웨어  (ubuntu 16.04 환경에서 설치함)

l  nodejs (v6.14.4)

n  nodejs grpc module (v1.11.0)


l  mongoDB(v2.6.10)


l  Python (v2.7.12)

n  grpcio, grpcio-tool (v1.16.0)


II.    protobuf 인터페이스 선언

gRPC 를 사용하려면 받는 쪽과 주는 쪽 모두 인터페이스 모델을 정의해주어야 한다.  message 는 각 언어에서 Object 에 해당하는 값이며 Service Function 에 해당하는 값이다.


syntax = "proto3";

package json;

service Json {

  rpc grpcSend (Request) returns (Response) {}

}

message Request {

  string jsonStr = 1;

}

message Response {

  string jsonStr = 1;

}

 

III.   서버 및 클라이언트 설치


l  nodejs 설치

cd ~

curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh

bash nodesource_setup.sh

apt-get install nodejs

apt-get install build-essential

 

 

l  npm 모듈 설치 (아래 package.json 파일 작성 후 npm install 실행)

{

  "name": "myapp",

  "version": "0.1.0",

  "description": "",

  "main": "app_grpc.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "nanum",

  "license": "ISC",

  "bugs": {},

  "homepage": "",

  "dependencies": {

    "body-parser": "^1.18.3",

    "ejs": "^2.3.3",

    "express": "^4.16.3",

    "grpc-web": "^1.0.0",

    "method-override": "^3.0.0",

    "mongoose": "^5.3.0",

    "requests": "^0.2.2",

    "websocket": "^1.0.28",

    "@grpc/proto-loader": "^0.1.0",

    "async": "^1.5.2",

    "google-protobuf": "^3.0.0",

    "grpc": "^1.11.0",

    "lodash": "^4.6.1",

    "minimist": "^1.2.0"

  }

}

 

l  mongoDB 설치

vi /usr/sbin/policy-rc.d

# exit 101 대신 exit 0 으로 변경.

 

#실행까지 같이

apt-get install mongodb-clients mongodb-server

apt-get update

 

 

l  python 관련 grpc 라이브러리 설치

apt-get install python-pip

pip install --upgrade pip

python -m pip install grpcio #--ignore-installed

python -m pip install --user grpcio-tools

 

 

 

IV.  클라이언트 코드


grpc_sender.py (공통 코드)


from __future__ import print_function

import json

import time

import grpc

import json_pb2

import json_pb2_grpc

 

def make_request(_jsonStr):

    return json_pb2.Request(jsonStr=_jsonStr)

 

def grpcSend(_jsonStr):

    with grpc.insecure_channel('10.0.0.133:3002') as channel:

        request = make_request(_jsonStr)

        stub = json_pb2_grpc.JsonStub(channel)

        response = stub.grpcSend(request)

 

    print('Sent : grpc')

 

 



grpc_inference.py (main)


import sum

import base64

import time

import grpc_sender

 

#ws_sender.sendWs()

 

def toJson(message):

    jsonString = json.dumps(message, ensure_ascii=False).encode('utf8')

    return jsonString

 

def get_data(num):

 

    json_path = '/root/client_send/json/api/inference/current_tracking_'+str(num)+'.json'

    img_path = '/root/client_send/images/cam/cam ('+str(num)+').jpg'

    #json_path = '/home/star/generator/images/screenshots/conference.jpg'

    with open(json_path, 'rb') as single_json:

        json_text = single_json.read()

    with open(img_path, 'rb') as single_img:

        img_b64 = base64.b64encode(single_img.read())

 

    json_text = "{\"api-type\": \"inference\", \"current_tracking\":" + json_text + ", \"img\" : \"" + img_b64 + "\"}"

    print(json_text)

    return json_text

 

 

def main():

    type_num = 1

    while type_num <= 21:

 

        tmpString = get_data(type_num)

        print(tmpString)

        grpc_sender.grpcSend(tmpString)

        type_num = type_num+1

 

        time.sleep(2)

 

if __name__ == '__main__':

    print('start')

    main()

    print('end')

 

 

current_tracking_1.json (샘플 json 데이터)

{

    "time": "2018-10-19T14:45:04.080163+09:00",

    "state_name": "daily_ready",

    "status": null,

    "state_id": 140001861004480,

    "intent": "unknown",

    "slots": null,

    "state_group": "ready",

    "domain": "Daily",

    "state_tag": "Daily.ready.daily_ready.Ready",

    "stance": "neutral",

    "speech": "안녕",

    "subject": null

}

 

 

 

cam (1).jpg (샘플 이미지 데이터)

 


 

V.    서버 코드


l  app_grpc.js (주요 핵심 코드)


/*  proto파일에서 service descriptors 로드    */

var PROTO_PATH = __dirname + '/protobuf/json.proto';

var grpc = require('grpc');

var protoLoader = require('@grpc/proto-loader');

// Suggested options for similarity to existing grpc.load behavior

var packageDefinition = protoLoader.loadSync(

    PROTO_PATH,

    {keepCase: true,

     longs: String,

     enums: String,

     defaults: true,

     oneofs: true

    });

var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);

// The protoDescriptor object has the full package hierarchy

var json = protoDescriptor.json;

/*  proto파일에서 service descriptors 로드 end    */

 

 

 

 

function grpcSend(call, callback) {

  //sendWS(call.request.message);

  console.log(call.request.jsonStr);

  broadcast(call.request.jsonStr);

  callback(null, call.request);

}

function grpc_start() {

  var server = new grpc.Server();

  server.addService(json.Json.service, {grpcSend: grpcSend});

  server.bind('0.0.0.0:4996', grpc.ServerCredentials.createInsecure());

  server.start();

}

grpc_start();



 

VI.  통합 테스트

Receive서버 실행

node app_grpc.js

 

Send클라이언트 실행

python grpc_inference.py






 grpc 도 처음이지만, protobuf 라는 것을 처음 써보았다.


사용해본 바로는 Java의 SOAP 와 JNI 를 합친 느낌이었다.



 JNI 인터페이스 처럼 protobuf 인터페이스를 지정해서 언어에 맞는 전처리 작업을 해주고,


SOAP 처럼 gRPC도 원격으로 서버의 함수를 실행시키는 듯한 느낌을 주었다.


  

 웹 소켓으로 되어 있던 모듈을 grpc로 바꾸는 작업이었던 지라, 


웹 소켓과의 속도 비교도 할 수 있었는데, 약 1.2배정도 빠른 것을 확인할 수 있었다.  (63 kb 데이터)


'프로그래밍' 카테고리의 다른 글

이클립스 꿀팁  (0) 2016.02.12



# 클라이언트에서 수정하는 방법

1. 증상

로그인시 위와 같은 로그가 나타나며,

 접속은 되나 실제 내부망에 접속이 안되는 현상이 발생.


 

 

 

2. 원인


 위 로그 중  'do_ifconfig.tt->did_ifconfig_ip6_setup=0' 는 IPv6 을 활성화시킨 서버라는 뜻인데,

openVPN 구축시에 ip4로만 구축을 진행하였기 때문에 문제가 생김.


즉, VPN클라이언트에서 IPv6 에 대한 설정을 하지 않았음에도 IPv6 로 접속 시도하여 생기는 문제 

->openVPN PC 에서 설치시 설치되는 네트워크 어댑터의 IPv6 사용을 해제하여 해결가능하다.

 

3. 해결 방법 (설치 PC)

1.     TAP-Windows Adapter V9 어댑터 속성으로 이동

OpenVPN 설치시 TAP-Windows Adapter V9 가 기본으로 설치됩니다.

제어판 - 네트워크 연결 - 속성으로 이동합니다.

 


2.     증상재확인

 

인터넷 프로토콜 버전 6(TCP/IPv6) 를 체크해제 한 뒤 확인 버튼을 누릅니다.


 




# VPN 서버에서 수정하는 방법



클라이언트에서 IP6을 비활성화 시키는 방법이 있지만,

근본적으로는 서버에서 IP6을 사용하지 않도록 하면 된다.



vi /etc/sysctl.conf   입력하여 설정 변경


#아래 설정으로 변경

net.ipv6.conf.all.disable_ipv6 = 1

net.ipv6.conf.default.disable_ipv6 = 1

net.ipv6.conf.lo.disable_ipv6 = 1 



그리고 아래 명령어를 실행

sudo sysctl -p






출처 : https://askubuntu.com/questions/440649/how-to-disable-ipv6-in-ubuntu-14-04 

  1. TensorFlow - CNN (Convolutional Neural Networks)

  • 개요
    • Fully connected
    • Foward nn
    • split & merge 를 진행하는 NN (CNN 의 기본 원리 - 입력을 여러개로 나누어 받는다.)
  • 고양이 실험
    • 그림을 보여주었을 때 동작되는 뉴런들이 각각 다르다.
    • 입력을 나누어 받는다.

  • Conv, LELU, POOL 등을 여러번 반복한 뒤, FC 를 적용


  • Convolution Layer (32*32*3 형태의 이미지 (RGB))  -> 결과(32*32*filter_depth)
    • 1. 5*5*3 filter 지정 - 여기서 filter 는 w라 하자.
    • 2. 5*5*3 filter는 하나의 값을 가져온다.
      • Wx+b  를 이용하여 한 값으로 만들어낸다.
      • ReLU(Wx+b) 함수를 이용하여 0 이상의 값으로 출력
      • W의 
    • 3. 옆으로 filter (w) 를 옆으로 넘기면서 전체 이미지를 훑는다.
      • 이렇게 하면 28 * 28 의 Activation Map 이 생긴다.
    • 4. 다른 W 값을 준 또 다른 filter 를 만들어서 동일하게 전체 이미지를 훑는다.
    • 5. 6개의 필터를 적용하면,
      • pad 적용을 안할 경우 28*28  이다.
  • W 의 개수?  (5*5*3*depth)

  • pad : activation Map이 input 과 동일한 크기를 유지하기 위해 주는 값
    • 테두리에 0으로된 padding 을 추가해주는 방법
    • 원본 input 데이터에 대한 손실 방지

  • Activation Map 크기 계산 (N - input size , F - filter size)
    • (N - F +(2 x pad size))  / stride

  • Stride : filter 가 이동되는 값의 단위
    • Stride 값이 클수록 output 크기가 작아진다.

  • 예시) 이미지에서 7 * 7 input 일 때 3*3 filter 가 있다면, 한번 훑는 것으로 몇개의 값을 가져올 수 있을까?
    • 한칸씩 움직일 때 (stride = 1)
      • 5*5
    • 두칸씩 움직일 때 (stride = 2)
      • 3*3
    • 공식 (N - input size , F - filter size)
      • (N-F)/stride +1
    • 사이즈가 줄어들었다..


  • 예시) 이미지에서 7 * 7 input 일 때 3*3 filter 가 있다면, 한번 훑는 것으로 몇개의 값을 가져올 수 있을까? (pad 는 1px 이다.)
    • pad 를 감싸게 되면 9*9로 이미지가 변한다.
      • 즉, 결과값은 같은 사이즈의 데이터가 나온다.
    • pad 를 추가하여 이미지 사이즈가 줄어드는 것을 방지.
    • 일반적으로는 output 의 사이즈가 동일하게 맞춰줄 수 있는 pad 값을 준다.

                






  • Pooling layer (Sampling)
    • 작게 resize 한 뒤, 다시 쌓는다.
    • filter 사이즈 내에서 하나의 샘플링 데이터를 추출하는것.
  • MAX POOLING
    • max pool  filter 가 2*2일 때, stride 가 2일때,
    • 가장 큰값을 필터에서 추출.

  • Fully connected 
    • 마지막 결과값은 Softmax 를 사용하여 처리.  (sigmoid)



다양한 활용의 예

  • LeNet-5
    • input 32*32
    • filter 5*5, stride 1
    • subsampling - 2*2, stride 2

  • C1 : Activation Map(28*28) *6 (Convolution 6 filters)
  • S2 : Activation Map(14*14) *6 (subsampling)
  • C3 : Activation Map(10*10) *10 (Convolution 10 filters)
  • S4 : Activation Map(5*5) *16 (subsampling)
  • C5 : 120 (Full connection)
  • F6 : 84 (Full connection)
  • output : 10 (Gaussian connections)

(N-F)/stride +1

  • AlexNet
    • 최초로 ReLU 사용, ensemble 을 이용하여 에러율을 줄임.
    • input 227*227*3 
    • First layer : filter size(11*11*3) *96 filters , stride 4
    • -> (55*55) * 96 filters  (버림)

                





  • ResNet 
    • AlexNet : 8layers,
    • VGG : 19layers,
    • ResNet : 152 layers

    • FastFoward 를 통해서 layer 가 많을수록 학습이 어려운 문제를 해결함.
  • 알파고








CNN
  • 주어진 이미지 벡터에 필터라는 것을 대어서 한개의 값을 뽑는데, 위치를 이동하면서 뽑기 때문에 결국 여러개의 값을 뽑아낸다.
  • 샘플링의 과정을 통해 데이터량을 축소시킨다.
    • 이 두 과정이 CNN


  1. Simple Convolution Layer (예제)
  • 조건
    • 3*3*1 image
    • 2*2*1 filter
    • stride : 1*1
  • Convolution 결과 예측
    • 2*2*1 의 데이터가 추출됨.
    • tensorflow 에서는 값이 알아서 추출되기 때문에 계산할 필요 없음.

  • 이미지를 만들어볼까요?
    • 이미지 생성 코드
sess = tf.InteractiveSession()
image = np.array([[[[1],[2],[3]],
                [[4],[5],[6]]],
                [[7],[8],[9]]]], dtype=np.float32)
print(image.shape)
# 결과값 : (1,3,3,1) - 사용할 이미지는 1개이며, 3*3의 이미지이며 컬러는 1개이다.

# imshow 라는 라이브러리를 사용하여 이미지를 생성한다.
pit.imshow(image.reshape(3,3), cmap='Greys')
  • 만들어진 이미지
                            


  • 이제 W (Filter) 를 정의해보자.
    • Filter 의 shape은 (2,2,1,1) - 2*2 사이즈에 한가지 컬러, 그리고 filter 개수가 1개이다.
    • 값 : [[[1.]],[[1.]]],      - !!!!값은 네개 다 같아야하는지??- 같아야되긴하는데...왜?
                                     [[1.]],[[1.]]]]  - shape = (2,2,1,1)  
                                        


  • 계산하면? (stride 는 1*1 이며 패딩은 없음)
    • 첫번째칸 1*1 + 2*1 + 4*1 + 5*1 = 12
    • 두번째칸 2*1 + 3*1 + 5*1 + 6*1 = 16
    • 세번째칸 4*1 + 5*1 + 7*1 + 8*1 = 24
    • 네번째칸 5*1 + 6*1 + 8*1 + 9*1 = 28
                            


  • 위 계산을 tensorFlow에서는..
# print("imag:\n", image)
print("image.shape", image.shape)
# 결과값 : image.shape (1, 3, 3, 1)

# 가장 depth 가 낮은 것은 필터 개수.
weight = tf.constant([[[[1.]],[[1.]]],
                      [[[1.]],[[1.]]]])
print("weight.shape", weight.shape)
# 결과값 : weight.shape (2, 2, 1, 1)

# tf.nn.conv2d 함수 하나로 Convolution 해결.
conv2d = tf.nn.conv2d(image, weight, strides=[1, 1, 1, 1], padding='VALID')

# tensorflow 실행
conv2d_img = conv2d.eval()

###### 결과값 확인 #######
print("conv2d_img.shape", conv2d_img.shape)
# 결과값 : conv2d_img.shape (1, 2, 2, 1)

#시각화 결과 출력
conv2d_img = np.swapaxes(conv2d_img, 0, 3)
for i, one_img in enumerate(conv2d_img):
    print(one_img.reshape(2,2))
    plt.subplot(1,2,i+1), plt.imshow(one_img.reshape(2,2), cmap='gray')
 
                    
                


  • SAME Padding
    • VALID : padding 을 주지 않는다.
    • SAME : 원래 이미지와 똑같은 shape 를 원할 때 사용.
    • 소스코드
...
# tf.nn.conv2d 함수 하나로 Convolution 해결.
conv2d = tf.nn.conv2d(image, weight, strides=[1, 1, 1, 1], padding='SAME')
...

                


  • 필터를 여러개 쓸 경우.
    • 소스코드

...
# 필터가 3개.
weight = tf.constant([[[[1.,10.,-1.]],[[1.,10.,-1.]]],
                              [[[1.,10.,-1.]],[[1.,10.,-1.]]]])
...

                  




이 장은 이어서...
  • MAX POOLING
    • 소스코드
image = np.array([[[[4],[3]],
                  [[2],[1]]]], dtype=np.float32)
pool = tf.nn.max_pool(image, ksize=[1, 2, 2, 1],
                                   strides=[1, 1, 1, 1], padding='VALID')
print(pool.shape)
# 결과값 (1,1,1,1)
print(pool.eval())
# 결과값 [[[[4.]]]]
                 








출처 : https://docs.google.com/presentation/d/1h90rpyWiVlwkuCtMgTLfAVKIiqJrFunnKR7dqPNtI6I/edit#slide=id.g1ed3f9369e_0_449









'TensorFlow' 카테고리의 다른 글

TensorFlow - ReLU  (0) 2018.04.20
TensorFlow - XOR 문제 딥 러닝으로 풀기.  (0) 2018.03.26
TensorFlow - 딥러닝의 기본 개념  (0) 2018.03.26
TensorFlow - Softmax regression  (0) 2018.03.25
TensorFlow - Logistic regression  (0) 2018.03.25
TensorFlow - ReLU



ReLU 소개

  • sigmoid 는 activation function 으로 불린다.
  • 전달받은 값이 어느 값 이상이면 작용을 하는 함수를 activation function 이라 불린다.




  • XOR 를 2단의 NN 으로 구현




  • 3단 이상인 경우



  • 9단


  • 9단 시각화




  • 문제점
    • Backpropagation 은  9단 이상 가면 Accuracy 가 보장되지 못한다.
      • 9단까지 연결했는데도 Accuracy 가 0.5 가 나온다.
      • S 를 거친 output 을 input 으로 가지는 S 는 0~1 의 값을 가진다. 
        • 항상  0~1 사이의 값이 곱해지면서 계산이 진행될 수록 0에 가까워진다.
      • Vanishing gradient 문제 (경사의 기울기가 사라지는 문제)
        • 단수가 깊어질 수록 앞쪽의 경사도가 사라진다.
  • 해결 (Hinton)
    • Sigmoid 가 1보다 작은 값이 된다는 것이 문제.
    • 0보다 작으면 0, 0보다 크면 갈때까지 가면 되지 않을까?
    • ReLU : Rectified Linear Unit

  • NN 에서는 Sigmoid 가 아닌 ReLU 를 사용해야 한다.
    • 마지막에만 sigmoid 사용 (0~1 사이의 값)


  • 파생된 다른 Activiation Function 들.
    • 0 이하의 값도 표현하는 LeakyReLU




     

초기값 주는것

  • weight 에 초기값을 멍청한 값을 줘서 문제가 생겼었다 (Sigmoid)
     




  • 주의점
    • 초기값은 0이 아니여야 한다.
      • 초기값이 0이면 앞의 모든 기울기가 0이됨...
    • RBM 구조를 사용한다.

  • RBM  내용 추가.
  • RBM
    • forward 의  x 값과 backward x 추측 값을 비교하여 w 을 계속하여 조정하는 구조.
    • 다른말로 encode, decode 

  • RBM 으로 어떻게 초기화를 진행할까
    • w 을 모두 학습시킨다. 한스텝씩 foward, backward 를 진행하면서.. 


  • RBM 대신..
                    



               







  • Overfitting 
    • 트레이닝 데이터에 나오지 않은 테스트 데이터에 대한 적중률이 낮음.
    • 레이어가 많아질 수록 err가 떨어지는데, 테스트데이터는 err 가 높아짐.

  • Overfitting 방지
    • 트레이닝 데이터셋 개수를 늘린다.
    • 정규화 : 구불구불한 선을 피자.
    • Dropout
      • 훈련할 때 랜덤한 뉴런을 스킵시킨다.
      • 첫 훈련은 너 쉬어, 두번째 훈련은 너 쉬어.
      • 마지막엔 총 동원하여 예측


  • Dropout 구현
    • 마지막엔 dropout_rate 가 1이여야함. (학습때만 조절.)


  • 앙상블 (Ensemble)
    • 다양한 트레이닝셋과, 학습 모델을 합치는것.






  • Feedforward neural network
    • 가장 일반적으로 쓰이는 네트워크
    • 첫번째 레이어는 input, 마지막 레이어는 output 인 구조이다.
    • 중간의 레이어들을 'hidden' 레이어 라고 부른다.
      • 이 hidden 레이어가 1개 이상일 경우, 'Deep' 뉴런 네트워크라 불린다.
                    

  • Fast forword (less net 이라는 네트워크 구조)
    • 출력을 2단 앞으로 붙인다. (도중의 Activation Function 은 스킵이 된다.)  3% 이하로..
                    

  • Split & Merge
    • 이 네트워크는 
                    




  • Recurrent Network
    • 같은 
               






  • 초기화
    • 구글 - xavier initialization tensorflow 검색

  • Optimizers
    • 어떤것이 더 좋은지는 테스트해보자.


  • 어떤 optimizer가 시뮬레이션한 웹 페이지가 있음.
    • Adam 이 결과가 가장 좋더라..
  • Adam
# define cost/loss & optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

  • 요약
    • Softmax - 90%, NN - 94.5
    • Xivier initialization - 97.8
    • Deep NN + dropout - 98%
    • Adam 등의 optimizer
    • Batch Normalization
      • 입력값에 대한 정규화 방법
      • 이용해서 98% 이상을 뽑아내보자.

  • CNN 을 사용하면 99% 까지 올릴 수 있다.



TensorFlow -  XOR 문제 딥 러닝으로 풀기.


  • 개요
    • 하나의 Logistic regression 으로는 절대 XOR 문제를 풀 수 없다.
    • Multiple logistic regression Units 으로는 가능하다.
  • Neural Network 학습
  • NN 을 이용하여 XOR 학습이 가능한가?
    • 기존에는 +- 를 구분할 수 있는 선을 찾을 수 없었다.

  • NN 3개를 이용하여 계산.  - 값 계산 방법은 다음시간에 일단 가능한지만 확인하자.
    • 0, 0일때
                    

    • 0, 1일때
                    

    • 1, 0일때
                    

    • 1, 1일때
                    

    • Forward propagation
                    




  • 앞단의 유닛 두개는 Multinomial classfication 과 유사하여, 하나로 합친다.
    • 대신 w, b 의 rank 가 늘어난다.
                    


    • 이를 식 및 TensorFlow 로 표현하면 아래와 같다. 여기서 k(x) 는 앞의 두개 unit 의 결과값이다.





  • w, b 의 값을 기계적으로 학습할 수 있을까?

                    

    • Gradient descent algorithm 을 사용하여, 코스트가 0인 것을 찾아야하는데, 미분이 필요하다. (기울기 0)
    • 각각 unit 의 미분 값을 알아야하는데, 너무 많아서 계산할 수 없다.
      • Backpropagation Algorithm 을 사용하여 해결한다.

                    



  • Backpropagation 알고리즘
    • 예측한 값과 실제 값을 비교하여 예측한 오류(cost) 를 뒤에서부터 앞으로 돌려서 미분값 등을 구하는 알고리즘.

    • w가 f 에 미치는 여양, x가 f 에 미치는 영향, b 가 f 에 미치는 영향 등을 구한다면 아래 보라색 글씨와 같을 것이다.
    • g 와 f 를 통하여 미분을 계산.



    • Chain rule - 복합 함수. 미분 (아래 별표가 Chain rule 에 해당됨)
                    



  • Sigmoid 미분
                    


  • TensorFlow
    • 아래 그래프를 구현할 필요가 없다. TensorBoard 를 사용하면 된다.
                

               












































Back propagation 을 이해하기 위한 기본 미분 개념

  • Basic derivative

  • Partial derivative (편미분)
    • 내가 관심있는 값만 변수로 두고 나머지는 상수로 둔다.
                    













'TensorFlow' 카테고리의 다른 글

TensorFlow - CNN (Convolutional Neural Networks)  (0) 2018.04.29
TensorFlow - ReLU  (0) 2018.04.20
TensorFlow - 딥러닝의 기본 개념  (0) 2018.03.26
TensorFlow - Softmax regression  (0) 2018.03.25
TensorFlow - Logistic regression  (0) 2018.03.25


TensorFlow - 딥러닝의 기본 개념

  • 우리 대신 복잡한 문제를 풀수 있는 기계를 만들자.
  • 뇌에 대한 공부
    • 뇌가 매우 복잡하게 연결되어 있다.
    • 뉴런(유닛)이 단순하게 동작된다.
      • input 을 전해주는 길이 (w) 에 따라 바이어스 라는 값을 더한 값이 어떤 값이상이 되면 활성화된다.
    • Activation Function
      • 뉴런을 본따 만든 모델
      • 신호 x, 어떤 값w 을 곱한뒤 더 다한다음, bios 라는 값을 더하는데 이 값이 어떤 값(?)보다 크면 1, 적으면 0 
      • Logistic regresion 모델과 동일함.
                              



  • False Promises (Dr. Frank)
    • "It expects will be able to walk, talk, see, write, reproduce itself."
    • AND / OR 에 대해서도 y 를 예측 할 수 있다. 
    • XOR 에 대해서는 y 를 예측하기 어렵다는 문제가 존재.
                    


  • Marvin Minsky 가 XOR 에 대해서는  할수 없다는 것을 수학적으로 증명해냄.
    • 대신 MLP 라는 것이 필요하다. (이 모델을 여러개를 합치면 가능하다)
    • 근데 각 모델의 w, b 에 대한 학습을 시킬 수가 없다.
      • "No one on earth had found a viable way to train."

  • Backpropagation ( 1974, 1982 by Paul, 1985 by Hinton )
    • 알고리즘
    • w, b 의 값을 forward 에서 찾지 말고 backward 에서 찾으면 되겠다.
    • 더 복잡한 것의 예측이 가능해짐

  • Convolutional Neural Networks (Lecun 1980 - 라쿤) 
    • 그림의 형태에 따라 활성화되는 뉴런이 다르다는 것을 발견해냄.
      • 그림 일부 일부를 담당하는 신경망이 있고 이게 나중에 조합된다.
    • 그림을 한번에 학습시키는 것이 아닌, 레이어로 나눠서 부분부분을 보낸 다음 나중에 합치는 네트워크
    • 알파고도 이것을 사용하고 있다.
    • 84년 ~ 94년 자동주행 차량 개발.
    • 문제점
      • 단순 레이어에서는 동작하는데, 복잡한 레이어에서는 (10여개 이상) 학습이 힘듬.
      • 오류를 뒤로 보내어 w,b 를 구하는 알고리즘인데 이것이 복잡한 레이어에서는 뒤로 갈 수록 의미가 희미해져 w, b 에 대한 신빙성이 떨어짐.

  • CIFAR 
    • 캐나다에서 만든 단체. 비영리 단체.
    • 2006, 2007년도까지 어려운 시기였음

  • Breakthrough (2006, 2007 by Hinton and Bengio)
    • input 을 잘 준다면 잘 학습할 수 있다. (2006)
      • w가 똑똑한 방법으로 초기화가 된다면, 많은 레이어가 있어도 훌륭하게 학습이 가능하다.
    • 작은 수단보다 복잡한 문제를 해결하는데 있어서 효율적.
    • 뉴런 네트워크를 Deep Nets, Deep Learning 으로 이름을 바꿈.

  • ImageNet
    • 이미지를 주고 컴퓨터가 맞출 수 있는지?
    • 2010 년 : 26% -> 2012 년 : 15% 로 오류 발생률이 떨어짐.
    • 2015 년 : 4%  (스탠포드 학생 5%)
    • 한걸음 더 나아가서 그림에 대한 설명도 가능하게 됨

  • Deep API Learning 
    • 말만 하면 어떤 API 를 사용해야 하는지에 대해 알려줌. (65 % 의 정확도)





  • 왜 이전에 잘 안됬던 걸까.

  • 활용
    • 유투브 자막
    • 페이스북 피드
    • 구글 검색 엔진  - 클릭할만한.
    • NetFlex  - 추천시스템
    • 각종 예측



TensorFlow 사용법

  • 메트릭스 곱은 shape 의 앞부분이 동일해야함.
  • Shape 2, 2 와 2,1 의 메트릭스 곱의 결과 shape은 2,1 임.
  • axis : 축

  • Broadcating 
    • 기존 메트릭스 합은 shape 이 동일해야함.
    • 그런데 shape 이 다를경우?
      • Broadcating 을 이용하여 계산을 할 수 있도록 함.
      • Rank을 맞춘다.
        • 3. 일 경우 [3., 3.] 으로 맞춰줘서 계산함.

  • Reduce_mean
    • 평균을 구한다. 
    • axis 는 축으로 이해.




  • Argmax
    • 가장 큰놈의 "위치"를 찾는것, reduce_min 과 인자값은 동일하다.





  • Reshape @@@@
    • shape 를 변경하고 싶다.
      • -1 이란 알아서...
      • rank 도 바꿀 수 있다.
  • Reshape (squeeze, expand)
    • squeeze, expand_dims 의 함수를 통해 shape 를 변경할 수 있다.


  • One hot
  • 자동으로 reshape 도 되는데, reshape 가 싫다면 reshape 로 shape 원상복귀 시킨다



  • Casting
    • 변수 casting


  • Stack



  • Ones and Zeros like
    • shape 내의 값을 1 혹은 0로 모두 바꾼다.

  • Zip 
    • 반복문과 같이 사용.
    • 복수의 변수를 지정할 때 사용.













'TensorFlow' 카테고리의 다른 글

TensorFlow - ReLU  (0) 2018.04.20
TensorFlow - XOR 문제 딥 러닝으로 풀기.  (0) 2018.03.26
TensorFlow - Softmax regression  (0) 2018.03.25
TensorFlow - Logistic regression  (0) 2018.03.25
TensorFlow - Hypothesis, CostFunction  (0) 2018.03.25
TensorFlow - Softmax regression


sigmoid 란 0~1 의 값으로 조정시켜 주는것. 
소프트 맥스는 sigmoid 를 하는 기법 중의 하나로 이해할 수 있겠다.
소프트 맥스를 통과하면 0~1사이고 전체의 sum 이 1이 된다.
-> 이것을 one-hot encoding 기법으로 1. 0. 0 로 변경하는데 tensor flow 에는 argmax 함수가 있다.


cost function
  cross entropy 라는 함수를 사용한다.
  
logistic cost vs cross entropy
  동일하다.


cross entroy  = loss function 


learning_rate : 테스트를 위해 한번에 움직이는 계수.


Learning rate 가 클 경우, 그레프를 뚫고 지나간다.  cost 함수를 실행하면 NAN 이 나오는 이유.

마찬가지로 leaning rate 가 적을때에도 기울기가 0인 부분을 찾아 떠나다가 늙어죽는다.

  • Cost 함수를 출력해봐서 learning rate 를 조절하는 것이 필요.




Data (X) 의 선처리를 하는 이유

  • w 가 2개가 있다고 가장했을 때 그래프를 위와 같이 그릴 수 있는데, 값이 매우 커질 경우에는 아래와 같이 변경된 형태의 그래프가 생기게 된다. 

  • learning rate 가 적은 값임에도 불구하고 위 그림과 같이 데이터가 튈 수 있다.
  • 그래서 Nomalize를 거친다
    • zero-centered data, nomalized data 한 데이터를 만들기 위함.






Learning rate 가 적당한데도 값이 튄다면 아래 함수를 적용하여 Nomalize 를 시행하면 된다.


  • x의 값을 계산한 평균과 분산의 값을 가지고 나누어주는데 이러한 형태의 Nomalization 을 Standardization 이라 한다.
  • 수학 통계학 관점에서 봤을 때,
    • Normalization (정규화) : 전체구간을 0~100으로 설정하여 데이터를 관찰하는 방법. 
      • 우리는 전체 구간을 0~1 로 설정한다.
    • Standardization (표준화) : 평균을 기준으로 얼마나 떨어져 있는지를 나타내는 값.
      • 2개 이상의 대상이 단위가 다를 때 대상 데이터를 같은 기준으로 볼 수 있게 하기 위함.
    • 출처 : https://brunch.co.kr/@rapaellee/4


Overfitting : 학습을 통해 모델을 만들어가는데, 학습데이터에 딱 잘맞는 모델을 만들어내면 문제가 됨..
  • 실제 데이터를 넣을 경우 안맞는 경우가 생김.


  • model2 는 데이터에만 맞는 모델이여서 실제 정확도가 매우 떨어짐. (Overfitting)
  • 구부러진 형태..


Overfitting 을 줄이는 방법?
  • Training data Set,
  • features 의 중복을 줄인다.
  • Regularization 을 한다. (일반화)




  • Training data 외에도 testing, validation 데이터 셋을 만드는게 필요하다.



  • training data set 을 30% 정도로 적당히 나눠주는게 좋다.









one epoch - 한번에 도는 트레이닝 데이터셋
batch size - one epoch 이 너무 커서 자르는 데이터셋.











TensorFlow - Logistic regression
 

Logistic regression 

- Binary Classpication 을 학습한다는 것은 0 과 1을 분류하는 선을 학습하는 것이다.

- X 라는 입력이 있고 W 계산을 지나면 Z라는 값이 나오고...
이 값을 Sigmoid 함수에 통과시키면 Y햇 (H(X)) 가 나온다. (얘는 0과 1 사이의 값)

- Y가 실 데이터 결과값 Y햇은 추론한 데이터 결과값






Multinomial Classification  - 라벨이 여러개인 녀석


Softmax Regression - 위의 Multinmial Classfication 을 분석하는 기법.

2진의 Logistic Regression 과는 달리 A,B,C 등의 라벨링이 된다.

MultiVariable Regression 과 마찬가지로 matrix 를 사용한다.



Hypothesis 과정에서 softmax 사용시, 추론에 대한 확률 값이 나오게 된다.
A : 0.7, B : 0.1, C : 0.2 = 1.0 요런식으로....


여기서 One.Hot.Encoding 기법을 통하여 가장 높은 수만 1로 두고 나머지는 0으로 둔다.

 





TensorFlow - Hypothesis, CostFunction

범위
(가설 추론)
  • y=f(x)

  • 오차 : Cost
  • Cost Function 이 0이 되야 한다.

Hypothesis 하이포시시스
  • data set 의 입력값, data set 의 출력값 


Cost Function 
  • x 가 입력값 y 가 실제 결과값인데
  • H(x) 는 예측한 값
  • 결과값이 음수일 수도 있음
  • (H(x)-y)^2
    • 제곱을 한다.
    • 제곱을 하는 이유
      • W를 구할 때 미분하여 기울기가 0인것을 찾으면 됨, (알고리즘에서)
      • 음수를 없애ㅣ 위함.

  • 시그마로 표현.
  • cost 가 0에 수렴하는 W,b 를 구하는것이 목표



그레디언트 가 0이 되도록 한다. (데이터셋을 많이 넣어서)


기울기 최소값 알고리즘
  • 미분 - 기울기를 구한다.
  • 적분 - 넓이를 구한다.









+ Recent posts