[컴][머신러닝] Recurrent Neural Networks 예제

ML / machine learning


Recurrent Neural Networks, RNN


관련글 :  The Unreasonable Effectiveness of Recurrent Neural Networks


원본 소스 : https://gist.github.com/karpathy/d4dee566867f8291f086

python 3 버전

# encoding=utf8

"""
Minimal character-level Vanilla RNN model. Written by Andrej Karpathy (@karpathy)
BSD License
"""
import numpy as np
import codecs

# data I/O
with codecs.open('input.txt', 'r', encoding='utf-8') as fp:
    data = fp.read()
    # data = open('input.txt', 'r').read() # should be simple plain text file
    chars = list(set(data))
    data_size, vocab_size = len(data), len(chars)
    print ('data has %d characters, %d unique.' % (data_size, vocab_size))
    char_to_ix = { ch:i for i,ch in enumerate(chars) }
    ix_to_char = { i:ch for i,ch in enumerate(chars) }

    # hyperparameters
    hidden_size = 100 # size of hidden layer of neurons
    seq_length = 25 # number of steps to unroll the RNN for
    learning_rate = 1e-1

    # model parameters
    Wxh = np.random.randn(hidden_size, vocab_size)*0.01 # input to hidden
    Whh = np.random.randn(hidden_size, hidden_size)*0.01 # hidden to hidden
    Why = np.random.randn(vocab_size, hidden_size)*0.01 # hidden to output
    bh = np.zeros((hidden_size, 1)) # hidden bias
    by = np.zeros((vocab_size, 1)) # output bias

    def lossFun(inputs, targets, hprev):
      """
      inputs,targets are both list of integers.
      hprev is Hx1 array of initial hidden state
      returns the loss, gradients on model parameters, and last hidden state
      """
      xs, hs, ys, ps = {}, {}, {}, {}
      hs[-1] = np.copy(hprev)
      loss = 0
      # forward pass
      for t in range(len(inputs)):
        xs[t] = np.zeros((vocab_size,1)) # encode in 1-of-k representation
        xs[t][inputs[t]] = 1
        hs[t] = np.tanh(np.dot(Wxh, xs[t]) + np.dot(Whh, hs[t-1]) + bh) # hidden state
        ys[t] = np.dot(Why, hs[t]) + by # unnormalized log probabilities for next chars
        ps[t] = np.exp(ys[t]) / np.sum(np.exp(ys[t])) # probabilities for next chars
        loss += -np.log(ps[t][targets[t],0]) # softmax (cross-entropy loss)
      # backward pass: compute gradients going backwards
      dWxh, dWhh, dWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
      dbh, dby = np.zeros_like(bh), np.zeros_like(by)
      dhnext = np.zeros_like(hs[0])
      for t in reversed(range(len(inputs))):
        dy = np.copy(ps[t])
        dy[targets[t]] -= 1 # backprop into y. see http://cs231n.github.io/neural-networks-case-study/#grad if confused here
        dWhy += np.dot(dy, hs[t].T)
        dby += dy
        dh = np.dot(Why.T, dy) + dhnext # backprop into h
        dhraw = (1 - hs[t] * hs[t]) * dh # backprop through tanh nonlinearity
        dbh += dhraw
        dWxh += np.dot(dhraw, xs[t].T)
        dWhh += np.dot(dhraw, hs[t-1].T)
        dhnext = np.dot(Whh.T, dhraw)
      for dparam in [dWxh, dWhh, dWhy, dbh, dby]:
        np.clip(dparam, -5, 5, out=dparam) # clip to mitigate exploding gradients
      return loss, dWxh, dWhh, dWhy, dbh, dby, hs[len(inputs)-1]

    def sample(h, seed_ix, n):
      """ 
      sample a sequence of integers from the model 
      h is memory state, seed_ix is seed letter for first time step
      """
      x = np.zeros((vocab_size, 1))
      x[seed_ix] = 1
      ixes = []
      for t in range(n):
        h = np.tanh(np.dot(Wxh, x) + np.dot(Whh, h) + bh)
        y = np.dot(Why, h) + by
        p = np.exp(y) / np.sum(np.exp(y))
        ix = np.random.choice(range(vocab_size), p=p.ravel())
        x = np.zeros((vocab_size, 1))
        x[ix] = 1
        ixes.append(ix)
      return ixes

    n, p = 0, 0
    mWxh, mWhh, mWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
    mbh, mby = np.zeros_like(bh), np.zeros_like(by) # memory variables for Adagrad
    smooth_loss = -np.log(1.0/vocab_size)*seq_length # loss at iteration 0
    while True:
      # prepare inputs (we're sweeping from left to right in steps seq_length long)
      if p+seq_length+1 >= len(data) or n == 0: 
        hprev = np.zeros((hidden_size,1)) # reset RNN memory
        p = 0 # go from start of data
      inputs = [char_to_ix[ch] for ch in data[p:p+seq_length]]
      targets = [char_to_ix[ch] for ch in data[p+1:p+seq_length+1]]

      # sample from the model now and then
      if n % 100 == 0:
        sample_ix = sample(hprev, inputs[0], 200)
        txt = ''.join(ix_to_char[ix] for ix in sample_ix)
        print ('----\n %s \n----' % (txt, ))

      # forward seq_length characters through the net and fetch gradient
      loss, dWxh, dWhh, dWhy, dbh, dby, hprev = lossFun(inputs, targets, hprev)
      smooth_loss = smooth_loss * 0.999 + loss * 0.001
      if n % 100 == 0: print ('iter %d, loss: %f' % (n, smooth_loss)) # print progress
      
      # perform parameter update with Adagrad
      for param, dparam, mem in zip([Wxh, Whh, Why, bh, by], 
                                    [dWxh, dWhh, dWhy, dbh, dby], 
                                    [mWxh, mWhh, mWhy, mbh, mby]):
        mem += dparam * dparam
        param += -learning_rate * dparam / np.sqrt(mem + 1e-8) # adagrad update

      p += seq_length # move data pointer
      n += 1 # iteration counter 
fdsfds


결과

무한 loop 이라, 적정한 시점에 알아서 멈추면 된다.

아래 결과는 대략 12시간 정도를 돌렸다. 컴퓨터 스펙은 아래와 같다.

  • CPU:  i7-6700, 3.40GHz
  • RAM: 16GB
----
 beahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela haeiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol e iohahenasen
----
iter 9309400, loss: 0.000086
----
 e nh a taei.rairrhelardr naioa aneaa ayio pe e bhnte ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9309500, loss: 0.000086
----
 jCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9309600, loss: 0.000086
----
 negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr
----
iter 9309700, loss: 0.000086
----
 aI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr neli ae e angnI hyho gben
----
iter 9309800, loss: 0.000086
----
 gehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela dr iohecgrpiahe.
Ddelnss.eelaishaner” cot AA
----
iter 9309900, loss: 0.000086
----
 piahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol e iohahenasenese hbea bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a t
----
iter 9310000, loss: 0.000086
----
 er” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nela hamnaI ayio pe e h’e btentmuhgnhi beahe
Ddabealohe bee amoi bcgdltt. gey heho grpiahe.
Ddeln
----
iter 9310100, loss: 0.000086
----
 bih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol gyio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae
----
iter 9310200, loss: 0.000086
----
 beahngy
amo k ns aeo?cdse nh a taei.rairrhelardr ntlhnegnns. e
amo k ns aeh?cdse nh a taei.rairrhelardr nol e iohehengrpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeah
----
iter 9310300, loss: 0.000086
----
 e nh a taei.rairrhelardr nol’e btentmuhgehi gcdslatha arenbggcodaeta tehr he ni.rhelaney gehnha e ar i ho  bee amote ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nol nyio chge heiohecgr
----
iter 9310400, loss: 0.000086
----
 jCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cds
----
iter 9310500, loss: 0.000086
----
 negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr
----
iter 9310600, loss: 0.000086
----
 aI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nelardae abeahngy
amo k
----
iter 9310700, loss: 0.000086
----
 gehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr ntl negnk t hi rsnse nhk br ne” a naeiarairr elirs
----
iter 9310800, loss: 0.000086
----
 piahe.
Ddelnss.eelaishaner” cot AAfhB ht ltny
ehbih a”on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr nelardaenabeahngelareierhi. aif edElobe negrcih gey gey heho grpiahe.
Ddel
----



[컴] app 에서 firebase 사용하기

파이어베이스 / fire base /


Firebase 를 app 에서 사용하기

자세한 내용은 여기 를 참고 하자.
  1. firebase project 생성
  2. app 등록
    1. 앱 닉네임 등록 : 자신의 app 이름을 적자
    2. 그러면 아래 같은 code 를 얻게 된다.
  3. sdk 를 app 에 설치 후 initialize
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.6.2/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "AsdfDQ3uOXYZp_MrNQPSauO4sdfsPn4OU8",
    authDomain: "coreal.firebaseapp.com",
    databaseURL: "https://coreal.firebaseio.com",
    projectId: "coreal",
    storageBucket: "",
    messagingSenderId: "997454353605",
    appId: "1:997454353605:web:5354b7543a6d9e68fdcad2"  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
</script>


관련 에러

app 등록을 안하면 아래같은 warning 이 보인다.

@firebase/database: FIREBASE WARNING: Provided authentication credentials for the app named "[DEFAULT]" are invalid. This usually indicates your app was not initialized correctly. Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.




[컴][js] nodejs 에서 euc-kr 인코딩 사용법

한글 사용법 / euc-kr / mbcs / convert encoding / decoding / 인코딩 변경 방법 / nodejs / node / 노드에서 인코딩 변경 / euckr / korean / utf8 / 한글파일 읽기 / 한글 읽는 법 / 파일 읽기 / read 하는 법 / write 하는 법 / euc-kr 읽기 /euckr 읽기 / euc kr excel / 엑셀 읽기

nodejs 에서 euc-kr 인코딩 사용법

iconv

iconv 를 설치하려면 build 환경(native code compilation)이 구성되어야 한다.

npm i iconv

iconv-lite

이녀석은 순수 js 로 구성되었다. README 에서는 어떤 경우에는 iconv 보다 빠르다고 이야기 한다.

npm i iconv-lite

사용법

아래처럼 사용할 수 있다.

const iconv = require('iconv-lite');


const stream = fs.createWriteStream(filename);
const header = ['이름', '주소'];

const buf = iconv.encode(header.join(','), 'euc-kr');
stream.write(buf);
stream.end();

euc-kr 로 된 file을 read 할 때는 아래처럼 하면 된다.


import * as fs from 'fs';
import iconv from 'iconv-lite'

try {
    // readFileEncoding
    const data = await fs.promises.readFile(inputPath)
    const utf8Data = iconv.decode(data, 'euc-kr')
    console.log(utf8Data)
} catch (err) {
    return console.error('Error reading file:', err);
}

References

  1. node-iconv git : GitHub - bnoordhuis/node-iconv: node.js iconv bindings - text recoding for fun and profit!
  2. GitHub - ashtuchkin/iconv-lite: Convert character encodings in pure javascript.

[컴] 메신저 별 서버 저장 기간

카톡 / 라인 / 서버 보관 / 대화내용 보관 기간

한국 메신저 대화내용 서버 보관기간

2014년 기준이여서 2019년 현재에는 달라졌을 수 있다. 참고 수준으로 알아두자.


  • 카카오톡 
    • 서버 데이터 저장기간을 2~3일 정도로 줄이기로 결정. (스크린샷 참고)
    • 서버에 보관이 안되기 때문에 누군가의 폰에 대화내용이 남아있지 않다면, 과거 대화는 복구할 수 없다.
  • 라인 : 타이머챗을 이용한 대화와 일반 대화내용은 암호화된 상태로 서버에 저장
    • 라인 '타이머챗' 기능 : 수신자가 메시지를 확인한 이후부터 최소 2초, 최장 1주일 뒤에 메시지가 자동 삭제된다. 그 순간 서버에 저장돼 있던 메시지도 사라진다.
    • 하지만 암호키가 저장된 위치와 서버 저장기간을 공개하지 않고 있다. 라인 측은 "서버 저장기간은 최소한의 기간으로 정확한 기간은 대외비"라며 "암호키의 저장위치 역시 공개할 수 없다".
  • SK플래닛 미국법인 틱톡플래닛의 '프랭클리'
    • 프랭클리 수신자가 메시지를 확인한 뒤 10초가 지나면 발신자와 수신자의 스마트폰은 물론 서버에서 메시지가 자동 삭제
  • 네이트온 : 6개월
    • 사용자가 메시지를 삭제하면 그 즉시 서버에서 메시지가 삭제
  • 마이피플 : 3개월
    • 사용자가 메시지를 삭제하면 그 즉시 서버에서 메시지가 삭제


Screenshots

카카오톡: https://cs.kakao.com/helps?articleId=470002560&service=8&category=24&device=1&locale=ko



References

  1. 카톡 아닌 메신저, 대화는 며칠이나 보관?, 2014.10.10

[컴][js] AdonisJS v3 ---> v4 에서 Encryption 문제

암호화 문제 / 마이그레이션 / encryption / simple encrypt /

Encryption (AdonisJS v3.x --> AdonisJS v4.x migration)

최신버전의 Adonis Encryption/index.js 에서 보면 아래처럼 Encryptor 를 호출할 때 object 를 parameter 로 보낸다.

하지만 옛버전의 Adonis Encryption/index.js 를 보면 그냥 string 을 parameter 로 넘긴다.

// latest version
// <root>\node_modules\@adonisjs\framework\src\Encryption\index.js
const Encryptor = require('simple-encryptor')
...
class Encryption {
  constructor (appKey, options) {
    /**
     * Throw exception when app key doesn't exists.
     */
    if (!appKey) {
      throw GE.RuntimeException.missingAppKey('Encryption')
    }
    this.appKey = appKey
    this.encryptor = Encryptor(Object.assign({ key: appKey }, options))
  }
  ...
// old version
// <root>\node_modules\@adonisjs\framework\src\Encryption\index.js
const Encryptor = require('simple-encryptor')
...
class Encryption {
  constructor (Config) {
    const appKey = Config.get('app.appKey')

    /**
     * Throw exception when app key doesn't exists.
     */
    if (!appKey) {
      throw GE.RuntimeException.missingAppKey('Encryption')
    }

    this.encryptor = Encryptor(appKey)
  }
  ...

simple-encryptor 의 option 이 변경된다.

이로 인해 발생하는 문제는 simple-encryptor 의 default option 이 변경된다.
// simple-encryptor
module.exports = function(opts) {
  if( typeof(opts) == 'string' ) {
    opts = {
      key: opts,
      hmac: true,
      debug: false
    };
  }
  var key = opts.key;
  var verifyHmac = opts.hmac;
  var debug = opts.debug;
  var reviver = opts.reviver;
  ...

해결책

그래서 혹시 이전의 option 을 사용하려 한다면 자신의 AppProvider 를 만들어서 사용해야 할 듯 하다. 아래 소스를 참고하자.
그리고 app.js 에 등록만 해주면 된다. 아래 글을 참고하면 된다.

[컴][nodejs] nodejs 의 crypto module 사용시 주의점



nodejs 의 crypto module 사용시 주의점

nodejs version 과 openssl


대략적으로 NodeJS 는 자체적으로 OpenSSL 을 포함하고 있다.(code)

아래 링크를 가면, nodejs version 에 따른 openssl 버전을 확인할 수 있다.

crypto module 사용시 주의점

How to use the crypto module | Node.js 를 보면 crypto 모듈은 openssl 를 이용한다. 그래서 openssl version 의 특별한 변화가 생기면, nodejs 의 openssl 도 영향을 받는다.

md5 --> sha256,  openssl version 1.1.0

openssl version 이 1.1.0 으로 올라가면서 기본 digest algorithm 이 md5 에서 sha256 으로 변경됐다.

nodejs 에서 openssl version 을 1.1.x 로 옮긴 것은 nodejs 의 version 이 10.0.0 이 된 순간이다.(참고)

그러므로, v10 미만을 사용할 때와 v10 이상을 사용할 때 만약 crypto module 을 사용하고 있다면 주의가 필요하다.

error

OpenSSL 1.0.x 버전에서 얻은 값을 OpenSSL 1.1.x 로 decrypt 를 시도하면 아래와 같은 error 가 발생한다.

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

알고리즘 선택

아래 처럼 algorithm 을 명시해주는 것이 나을 수 있다.
var cryptoKey = crypto.createHash('sha256').update(key).digest();

crypto 사용 예제

See Also

  1. 쿠...sal: [컴][알고리즘] AES 암호화 설명

[컴] git flow 자료들

gitflow / git flow 처음 시작 / git clone 후 git flow 적용 /



git flow

Extensions for Visual Studio Code

Git flow cheat sheet

git flow 를 사용하는 git repository 를 사용

1. git clone https://<git-address>

git clone 으로 source 를 가져온다.

2. git flow init

Which branch should be used for bringing forth production releases?
   - develop
   - master
Branch name for production releases: [master]

Which branch should be used for integration of the "next release"?
   - develop
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [C:/a/prog/mainsource/.git/hooks]

git flow feature 사용

3. git flow feature start

git flow feature start 를 이용해서 feature branch 를 만들 수 있다. 이때 어느  branch 에서 만들어도 develop branch에서 만들어준다.

4. git flow feature rebase

base 를 develop branch 의 최신 상태로 rebase 해준다.(참고)

5. git flow feature finish

현재 feature 를 develop branch 에 merge 를 해주고 --> branch 를 없애고 --> develop branch 로 돌아간다.