The jonki

呼ばれて飛び出てじょじょじょじょーんき

ある日倒れても大丈夫なように備える(一人暮らし編)

こんにちは.実は最近まで体調を1ヶ月半ほど崩し,会社も休んでいました.これまで自分は健康だと思ってましたが,人生初の入院や様々な検査を体験しました.色々と学ぶことも多かったので,「自分は大丈夫」と思っている方にも見て欲しい(特に一人暮らしの方)と思いこの記事を書いてみました.このブログでは基本技術ネタしか書かないのですが,今回は特別です.

何もない時にこそ準備をしておく

私の場合,特に予兆もなくいきなり体調を崩したのでゴテゴテで大変でした.この記事を読んでるあなたがまだ健康で何も準備していないのなら準備しましょう.基本的には一人暮らしの方の高熱時の準備内容になります.一人暮らしはいざというときに本当に怖い.

ポカリ

10リットルぐらいあると安心.高熱時はポカリなんて重いもの運んでられないので常備しておきましょう.どんどん飲んでおしっこ出しましょう.

非常食

冷凍食が役立ちます.私のおすすめは【焼きおにぎり】です.食べれる量を簡単に調整できる上に,レンジでチンなので調理が非常に簡単です.また災害時などの保存食も良いと思います.ただAmazonで買った保存食のおかゆはかなりまずかったので,あらかじめ美味しいものを調査しておくと良いと思います.

Amazon Prime Now

これは地域が限られますが,1,2時間で冷凍食品やポカリなどの飲み物を配送してくれるので,買い出しもきつい!という方にはピッタリです.何度かお世話になりました.

高熱対策グッズ

冷えピタは常時冷蔵庫で常備.保冷マクラは2つ用意しましょう.2つあるとぬるくなっても冷たいのにすぐ交換できるので非常に良いです.

フェイスタオルをたくさん用意

解熱剤を飲むと大量に汗をかくと思うのでタオルは欠かせません.また洗濯もこまめにできなくなるので,あらかじめフェイスタオルぐらいの体をちょっとふくのに手頃なタオルをたくさん用意しておくと便利です.うちの家はあまりタオルがなかったので苦労しました.

病院の調査

地元の小さな医院だと原因がわからず,大きな病院に行く必要があるときもあります(今回私がそうでした).その時のために家から近くて,評判の良い病院を探しておくと,いざという時に良いと思います.また紹介状がないと受け付けてくれない病院も多いので注意.診療日や時間も病院によってマチマチなので注意です.

症状をこまめにまとめておく

今回私は全部で6,7人ぐらいの先生の診断を受けたのですが,同じ病院でカルテを共有してるのにも関わらず,一から症状と経過を聞かれることが何度もありました.期間が長いとその症状も忘れると思うのでこまめにメモしておくのが大事です.私の場合,長期間の高熱や解熱剤の使用有無を覚えておきたかったので,体温のメモ&グラフ化できるアプリにひたすら保存していました.(子供用ですが気にしない)
育ログ WM[Android/iPhone] - WM(わたしムーヴ)

仕事上,重要な人のメアドを個人携帯に登録

私の場合は,チームリーダー,課長,部長,秘書の方のメールアドレスをGmailに登録しました.というのもまず会社PCを持っていないor PCを開くのもダルいという可能性があるからです.またメーリングリストなどと違い,個別のアドレスだと細かい診断状況などプライベートな情報も含めやすくなります.まぁ会社によってここはマチマチだと思いますが.

メンタルヘルス対策術を学んでおく

これ結構重要だと思うんですが,自分の場合,体調不良3週目ぐらいからひどく気持ちが落ちる時が何度かありました.また会社復帰時なども結構不安になります.基本的にはネガティブ発想から起きるので,こういう時のために簡単なメンタルヘルス対策術を学んでおくと良いと思います.と言っても私はこれ系の本をたまたま1冊読んでただけですが,それだけでもだいぶ違いました.「俺はメンタル強いから」とか思ってる人ほど読んだ方が良いと思います.

ストレスをすっきり消し去る71の技術

ストレスをすっきり消し去る71の技術

貯金の用意

よく言われますけど3ヶ月分ぐらいの生活費は用意しておきましょう.

会社の制度の勉強

高額療養費制度(基準額,限度条件など),病気による長期休暇,休職など軽く見といた方が良いと思います.

タクシー配送会社のTELを登録しておく

自分で病院に行くのも辛い可能性は大いにあるので,タクシーの配送TELは控えておくといざという時に楽です.

実家に早く帰って頼る.できなければ早く結婚する

私はそこそこ実家が近いので,早々に実家で療養してました.と言っても頼れる人が地理的に近くにいない人も多いと思うので,そういう方は早々に一人暮らしをやめて早く結婚しましょう.いや本当に.


ひとまず来年の抱負は健康第一に決まったjojonkiでした.

ソニーのラジオICF-A101をArduinoを使って赤外線リモコンで操作してみた

ソニーのラジオICF-A101といういぶし銀なラジオを持っているのですが,リモコンがないので操作が面倒でした.そこで電源だけでもリモコンで操作したいなと思ってこれを作りました.久しぶりの記事のくせに小ネタですみません.

使っているものはこんなところです.Arduinoはminiとか小さい方がスッキリしますが手持ちがなかったのでUNOで.


IR周りのコードを書くのはだるかったのでライブラリを探したらありました.ダウンロードしてArduino/librariesとかのフォルダに突っ込みましょう.
IRremote Library, Send & Receive Infrared Remote Control

サーボは9番ピンに信号線,赤外線受信モジュールは6番ピンへ.それぞれVとGNDにつなぐこともお忘れず.赤外線モジュールは目玉を自分の方に向けた時,右からV,GND,信号線の順につなげます.


コードも適当です.赤外線信号を受信するとメーカーとその信号値を出力するサンプルがあったのでこれを利用します.適当なチャンネルのコマンドの値(私の場合は2fd20dfという値にしました)と比較して見つかった時に,サーボをちょっと回転させることで電源ボタンを押しています.

#include <IRremote.h>
#include <Servo.h>


const int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
Servo myservo;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  irrecv.blink13(true);

  myservo.attach(9);
  myservo.write(10);
}

void loop() {
  if (irrecv.decode(&results)) {
    if (results.decode_type == NEC) {
      Serial.print("NEC: ");
    } else if (results.decode_type == SONY) {
      Serial.print("SONY: ");
    } else if (results.decode_type == RC5) {
      Serial.print("RC5: ");
    } else if (results.decode_type == RC6) {
      Serial.print("RC6: ");
    } else if (results.decode_type == UNKNOWN) {
      Serial.print("UNKNOWN: ");
    }
    Serial.println(results.value, HEX);
    String result_val = String(results.value, HEX);
    if(String(results.value, HEX).equals(String("2fd20df"))) {  // あなたの利用したい信号で
      Serial.println("FOUND");
      myservo.write(30); // 電源ボタンのプッシュアクション
      delay(200);
      myservo.write(10); // 元の位置に戻る
    }
    irrecv.resume(); // Receive the next value
  }
}

以上小ネタでした.

cmakeでgoogletestできる環境を作ってみる

はじめに

googletestをcmakeで動かす必要があったのでまとめました.googletestはc++のテストフレームワークで,cmakeはコンパイラに依存しないビルド自動化のソフトです.tjunさんが既に記事を書いてくれていますが,私は生Makefileはゆとりすぎて読めないのでcmakeで焼き直しました.
GoogleTestでC++のコードをテストする - Qiita

テスト用に簡単なサンプルプロジェクトをgithubにアップしました.READMEに最低限書いてますが,それを説明します.
github.com

プロジェクト構成

今回はこのようなフォルダ構成にしてみました.src/の下にmy_mathという自作のライブラリを作ってあります.それをtest/下のテストクラスで叩いてバグがないか確認してみる,という設定です.

.
|-- CMakeLists.txt
|-- src
|   |-- CMakeLists.txt
|   |-- main.cc
|   |-- my_math.cc
|   `-- my_math.h
`-- test
    |-- CMakeLists.txt
    `-- test.cc


この中のmy_mathライブラリのsum関数はあえて間違って実装しています.

#include  "my_math.h"

double sqr(double v) {
  return (v*v);
}

double sum(double v1, double v2) {
  return v1 - v2; // Oops! bug!
}

cmakeファイル

CMakeLists.txtはフォルダ毎に用意して疎に書いておくのが良いと思っています.

ルート直下のCMakeLists.txt
ここでやっていることはadd_subdirectoryで下位フォルダのCMakeLists.txtを読み込みに行きます.またenable_testingでctestを有効にし,add_testで具体的なテストを指定しています.ctestとはcmakeについているテスト実行の支援ツールです.

cmake_minimum_required(VERSION 2.8)
project (MYTEST)

add_subdirectory(src)
add_subdirectory(test)
enable_testing()
add_test(NAME MyTest COMMAND Test)

src/のCMakeLists.txt
ここではmy_mathライブラリを作り,mainのプログラムでlibmy_math.aをリンクしています.リンク時のライブラリ名の指定の時に'lib'のプレフィックスは省略できます.またこのlibmy_math.aはテストにも利用します.

cmake_minimum_required(VERSION 2.8)
add_library(my_math STATIC my_math.cc)

add_executable(demo main.cc)
target_link_libraries(demo my_math)

test/のCMakeLists.txt
少し長いですが,難しいことはありません.googletestライブラリのインクルードディレクトリ及びライブラリディレクトリを指定し,test.ccに対してlibgtest.a,libgtest_main.a,pthreadをリンクしているだけです.pthreadはgoogletestで必要になりますので忘れないように.またGTEST_ROOTで指定しているgoogletestのインストールディレクトリは適宜読み替えてください.

cmake_minimum_required(VERSION 2.8)

# set runtime directory
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

# declare GTEST_ROOT
set(GTEST_ROOT ~/googletest/googletest/)

# Include files directory
include_directories(${GTEST_ROOT}/include/)

# Library directory
link_directories(${GTEST_ROOT}/build/)

# Generate executable file
add_executable(Test ${CMAKE_CURRENT_SOURCE_DIR}/test.cc)

# Link libraries
target_link_libraries(Test my_math gtest gtest_main pthread)
テストファイルと実行

それではテストファイルです.SqrFuncCheckとSumFuncCheckの2つのテストを用意して,sqrとsum関数をテストしてみます.sum関数の実装は間違っているので,テストは通らないはずです.

#include "../src/my_math.h"
#include <gtest/gtest.h>

namespace {
  class MyLibTest : public ::testing::Test{};

  TEST_F(MyLibTest, SqrFuncCheck) {
    EXPECT_EQ(sqr(3.0), 9.0);
    EXPECT_EQ(sqr(4.0), 16.0);
  }

  TEST_F(MyLibTest, SumFuncCheck) {
    EXPECT_EQ(sum(1.0, 2.0), 3.0);
  }
}

実行してみます.ちゃんと失敗しています.make後にbuild/test/Testを直接叩いても大丈夫です.

$ git clone https://github.com/jojonki/googletest-with-cmake-sample/
$ cd googletest-with-cmake-sample/
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make test # or ctest --verbose
$ ctest --verbose
(略)
test 1
    Start 1: MyTest

1: Test command: /path/to/googletest-with-cmake-sample/build/test/Test
1: Test timeout computed to be: 9.99988e+06
1: Running main() from gtest_main.cc
1: [==========] Running 2 tests from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 2 tests from MyLibTest
1: [ RUN      ] MyLibTest.SqrFuncCheck
1: [       OK ] MyLibTest.SqrFuncCheck (0 ms)
1: [ RUN      ] MyLibTest.SumFuncCheck
1: /path/to/googletest-with-cmake-sample/test/test.cc:13: Failure
1:       Expected: sum(1.0, 2.0)
1:       Which is: -1
1: To be equal to: 3.0
1:       Which is: 3
1: [  FAILED  ] MyLibTest.SumFuncCheck (0 ms)
1: [----------] 2 tests from MyLibTest (1 ms total)
1: 
1: [----------] Global test environment tear-down
1: [==========] 2 tests from 1 test case ran. (1 ms total)
1: [  PASSED  ] 1 test.
1: [  FAILED  ] 1 test, listed below:
1: [  FAILED  ] MyLibTest.SumFuncCheck
1: 
1:  1 FAILED TEST
1/1 Test #1: MyTest ...........................***Failed    0.00 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.01 sec

The following tests FAILED:
	  1 - MyTest (Failed)
Errors while running CTest
まとめ

cmakeでgoogletestを使ったプロジェクトを作ることができるようになりました.どんどんテストしましょう.googletestをもう少し使い込みたいところです.

Q学習で最良経路をPythonで求めてみる

導入Q学習

いきなりですが強化学習の勉強始めています.強化学習は教師なし学習の1つの手法で,与えられた環境に対して様々な行動を試し,一番報酬が得られる行動を学習していきます.その中でQ値と呼ばれるものがあります.これは状態s ,行動 aをとり,方策 \piに従って得られる割引累積報酬の期待値です.ざっくりと言い切ってしまうと, s-aを実行すると将来どれぐらいの報酬が期待できるか?といったことを意味しています.

学習にはQ学習,Actor-Critic,SARSAなどがありますが,今回の記事ではQ学習を取り扱います.これは方策オフ型のTD学習であり,どうのような行動をとるか?という方策に関係なく,行動価値関数の大きな値に合わせていくスタイルです.この更新を繰り返していくことで(学習していくことで)最適な行動価値を導き出します.
{ \displaystyle
Q(s_t,a_t) \leftarrow Q(s_t,a_t) + \alpha(\gamma_{t+1} + \gamma \max_a Q(s_{t+1}, a_{t+1}) - Q(s_t, a_t))
}

今回強化学習に関しての詳しい説明はしません.いずれしたいと思いますが,今日はとてもわかりやすいリンク及び書籍を紹介しておきます.
強化学習の基礎,小池 康晴,鮫島 和行

イラストで学ぶ 人工知能概論 (KS情報科学専門書)

イラストで学ぶ 人工知能概論 (KS情報科学専門書)

手を動かして実装してみる

価値関数を最大化するためのQ学習の良い例題として,素敵なサイトを見つけたので,そこの例題をPythonで解いてみます.英語ですがとてもわかりやすく書いているのでぜひ読んで欲しいのですが,ざっくりと説明すると0〜5の6つの部屋(ステート)があり,ステート5の部屋に辿り着くように報酬を設定することで,Q学習を行っているサンプルです.
mnemstudio.org

このサイトの例だとQ値更新の式がだいぶ簡略化されています. s-aのペアで得られる即時報酬に sの次の状態 s’で報酬を最大化できる行動に \gamma をかけたものを加えて更新されます.
{ \displaystyle
Q(s,a)=R(s,a)+\gamma \max_a [Q(s’, a)]
}

ステート遷移図と行動(矢印の経路をたどること)の報酬はこんな感じです.
f:id:jonki:20160505171911p:plain:w300

今回書いたコードを載せておきます.ランダムで取得したstateから,可能な行動のうちQ値が最大となるような行動をとりつつ,各Q値を更新していきます.ゴールしたらまた適当な地点から開始します.この試行をとりあえず1000回行わせました.開始からゴールまでを1エピソードと数えるのが普通のようで,本来はこれを1000エピソード分,行わせた方がよかったかもしれませんが,まぁこんかいのでも十分に学習できるので特に問題ないと思います.

reinforcement-practice/simple-q-learning.py at master · jojonki/reinforcement-practice · GitHub

# -*- coding: utf-8 -*-
"""
Created on Thu May  5, 2016

@author: jonki
"""

import numpy as np
import random
import sys

# sample ref
# http://mnemstudio.org/path-finding-q-learning-tutorial.htm

# Reward matrix
R = np.array([
[-1, -1, -1, -1,  0,  -1],
[-1, -1, -1,  0, -1, 100],
[-1, -1, -1,  0, -1,  -1],
[-1,  0,  0, -1,  0,  -1],
[ 0, -1, -1,  0, -1, 100],
[-1,  0, -1, -1,  0, 100]
])

# Initial Q-value
Q = np.zeros((6,6))

LEARNING_COUNT = 1000
GAMMA = 0.8
GOAL_STATE = 5

class QLearning(object):
    def __init__(self):
        return
        
    def learn(self):
        # set a start state randomly
        state = self._getRandomState()
        for i in range(LEARNING_COUNT):        
            # extract possible actions in state
            possible_actions = self._getPossibleActionsFromState(state)
            
            # choise an action from possible actions randomly
            action = random.choice(possible_actions)        
            
            # Update Q-value
            # Q(s,a) = r(s,a) + Gamma * max[Q(next_s, possible_actions)]
            next_state = action # in this example, action value is same as next state
            next_possible_actions = self._getPossibleActionsFromState(next_state)
            max_Q_next_s_a = self._getMaxQvalueFromStateAndPossibleActions(next_state, next_possible_actions)
            Q[state, action] = R[state, action] + GAMMA * max_Q_next_s_a
            
            state = next_state
            
            # If an agent reached a goal state, restart an episode from a random start state
            if state == GOAL_STATE:
                state = self._getRandomState()
    
    def _getRandomState(self):
        return random.randint(0, R.shape[0] - 1)
      
    def _getPossibleActionsFromState(self, state):
        if state < 0 or state >= R.shape[0]: sys.exit("invaid state: %d" % state)
        return list(np.where(np.array(R[state] != -1)))[0]
    
    def _getMaxQvalueFromStateAndPossibleActions(self, state, possible_actions):
        return max([Q[state][i] for i in (possible_actions)])
            
    def dumpQvalue(self):
        print Q.astype(int) # convert float to int for redability

    def runGreedy(self, start_state = 0):
        print "===== START ====="
        state = start_state
        while state != GOAL_STATE:
            print "current state: %d" % state
            possible_actions = self._getPossibleActionsFromState(state)
            
            # get best action which maximaizes Q-value(s, a)
            max_Q = 0
            best_action_candidates = []
            for a in possible_actions:            
                if Q[state][a] > max_Q:
                    best_action_candidates = [a,]
                    max_Q = Q[state][a]
                elif Q[state][a] == max_Q:
                    best_action_candidates.append(a)
            
            # get a best action from candidates randomly
            best_action = random.choice(best_action_candidates)
            print "-> choose action: %d" % best_action
            state = best_action # in this example, action value is same as next state
        print "state is %d, GOAL!!" % state
            
if __name__ == "__main__":
    QL = QLearning()
    QL.learn()
    
    QL.dumpQvalue()
    
    for s in range(R.shape[0]-1):
        QL.runGreedy(s)

実行してみる

このプログラムの最後ではステート0〜4から開始して,最良の経路を通っているかテストしています.Greedyとはあらかじめわかっている報酬があるときに,探索はせずに一番高い報酬が期待出来る行動をとります.ε-グリーディ法などあるのですが,これはまたの機会に説明します.各ステートでスタートしてから一番良い経路(報酬が高い)を選択しているのがわかります.最初に出力されている行列は学習されたQ値です.行がステート,列がアクションです.

[[  0   0   0   0 395   0]
 [  0   0   0 316   0 493]
 [  0   0   0 316   0   0]
 [  0 395 252   0 395   0]
 [316   0   0 316   0 493]
 [  0 393   0   0 395 493]]
===== START =====
current state: 0
-> choose action: 4
current state: 4
-> choose action: 5
state is 5, GOAL!!
===== START =====
current state: 1
-> choose action: 5
state is 5, GOAL!!
===== START =====
current state: 2
-> choose action: 3
current state: 3
-> choose action: 1
current state: 1
-> choose action: 5
state is 5, GOAL!!
===== START =====
current state: 3
-> choose action: 4
current state: 4
-> choose action: 5
state is 5, GOAL!!
===== START =====
current state: 4
-> choose action: 5
state is 5, GOAL!!

学習された各ステートのQ値(実行枚に若干異なります)です.マップしてみるとステート5へと続く経路のQ値は他の経路よりも高くなっていることが確認できますね.
f:id:jonki:20160505171920p:plain:w300

まとめ

今回かなり単純化した問題設定のもと,Q学習を行ってみましたが,どうだったでしょうか?私自体,これが初となるQ学習の実装なので誤っているところあればビシバシ指摘していただきたいです.これぐらい簡単な問題にして実装してみることで,肌感でQ学習が何かが徐々にわかってきました.次は他のTD学習などについても触れたいですね.

MOOC (Massive Open Online Course)のススメ

f:id:jonki:20160317223620p:plain

機械学習を勉強していて色々本を漁っている昨今ですが、オンラインでもあるんじゃね?と思い、まさにMOOC (Massive Open Online Course)で良い授業を見つけました。見つけたのはAzure MLを使ったデータサイエンス&機械学習入門の授業で、本日無事テストにパスして修了証もらいました。
授業は約1ヶ月のコースになっていて(計10時間くらい?)、classification(分類)、regression(回帰)、clustering、recommender systemsの4つをMicrosoftのAzure MLという機械学習をノードベースで簡単に扱えるサービスサイトで学べます。Azure ML自体に興味がなくても非常にシンプルになっていて、データサイエンティストがどのようなワークフローでデータを扱い、有益な情報を引き出しているのか、ざっくりと体系的に学べてタメになります。英語が心配!という人でも、この授業では正しい字幕が付与されていること、講師の英語が綺麗でハッキリしているので普通にリスニングとしても良い教材でした。
DAT203x Course Info | edX

MOOCの存在は以前から知っていましたが、「ふーん」ぐらいにしか思っていませんでした。が、やり始めるとこれはハマりそうです。何より留学しなくとも海外の超超一流大学の授業がタダで、しかも字幕付き(これは動画による)で学べるなんて素敵すぎます。最近仕事でも新しい分野の論文など、読んでも前提知識がないぶん苦しんでいたので、こういう授業で体系的に学べるのは本当に良い時代になりました。
大手MOOCに関しては下記のサイト様でとても詳しく説明されています。
edtech-media.com

今はudacityで人工知能系の授業聞いています。面白そうな授業がたくさんあるので是非お試しあれ。
www.edx.org
Coursera - Free Online Courses From Top Universities
www.udacity.com