合理主義的グルメブログ

学生起業家の日常をツラツラと書いています。主に食事情報です。

【期間限定無料&50%OFF以上】電撃超感謝祭 が始まったぞ(1/10まで)

Amazonで電撃超感謝祭が始まって,電撃系列のラノベや漫画が半額以上OFFになっています(多分,Kindleだけ).
お正月休みにまとめて読むのもいいですね.

僕は最近,土橋 真二郎にハマっているので,
コロシアムシリーズとOP-TICKET GAMEシリーズを買います.

【Ruby】組み込み変数について

今更ですが,rubyのオプション変数について,詰まったことがあったのでまとめておきます.

色々と種類がありますが, 今回は自分で必要になったものだけまとめます.

組み込み変数とは

ローカルスコープ

以下の変数はスレッドローカルです.

$'

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした部分より後ろの文字列です.最後のマッチが失敗していた場合にはnilになります.

$&

現在のスコープで最後に成功した正規表現のパターンマッチでマッチした文字列です.最後のマッチが失敗していた場合にはnil

まとめ

闇が深そう....

グルコサミンは関節痛に効く?

昔はテレビでよくグルコサミンのサプリのCMが流れていたと思います.
(今はテレビを見ないので,知りませんが)

これが膝関節などの関節痛に効くようにうたっています.

結論から言うと,グルコサミンが痛みなどの軽減効果があると言う信頼できるデータはありません.

グルコサミンとは

グルコサミンは,主に3種類あります. * N-アセチルグルコサミン * グルコサミン硫酸塩 * グルコサミン塩酸塩 「N-アセチルグルコサミン」は関節の軟骨成分と同じものです.

しかし,軟骨の原料を摂ったからといって,それで効果が出ると言うのは短絡的過ぎです.
痛みの改善すると言う十分な証拠はありません.

サプリのリスク

これは全てのサプリに言えることですが,
サプリメントにはうたわれている成分以外も含まれているため, アレルギー反応やクリスとの相互作用が起きるリスクがあります

まとめ

グルコサミンサプリは効果がないし,リスクがあるから,高い金払って買う必要はないよ.

mpi4pyを試してみる

Pythonの並列処理のためのライブラリであるmpi4pyを試してみました.

公式のチュートリアルがわかりやすかったので,かなり参考になります.

Tutorial — MPI for Python 3.0.0 documentation

僕はいつも通り,Docker imageから作っていきます.

FROM python

# install via apt
USER root
RUN apt-get update
RUN pip install -U pip

# mpi4py
RUN apt-get install -y libopenmpi-dev
RUN pip install mpi4py

WORKDIR /root/work

ビルド済みイメージをDockerHubにあげておきました.

https://hub.docker.com/r/denden047/mpi4py/

なので,こんな感じで実行できます.

$ docker run --rm denden047/mpi4py /bin/bash

Hello Worldのプログラムを書いてみました.
これをmain.pyという名前で保存します.

from mpi4py import MPI

def main():
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    size = comm.Get_size()

    print(f"Hello, world! from rank {rank} out of {size}")


if __name__ == "__main__":
    main()

っでこれを実行してみますが, 並列実行させるために,mpiexecコマンドを利用します.
具体的には以下のコマンドを実行します.

$ docker run --rm denden047/mpi4py /bin/bash -c "mpiexec --allow-run-as-root -np 4 python main.py"
Hello, world! from rank 1 out of 4
Hello, world! from rank 3 out of 4
Hello, world! from rank 0 out of 4
Hello, world! from rank 2 out of 4

Dockerコンテナで動かしているので,rootでも実行できるように, --allow-run-as-rootオプションを付けています.
また,-np 4としているので,4つのプロセスで並列に実行されています.

ここまでで,大体の感覚は掴めるので,公式のチュートリアルをやっていきましょう!

Tensorboardをtensorflowなしで使用する

Tensorboardって便利ですよね?
簡単に可視化できるツールとして,かなり優秀だと感じでいます.

そんなtensorboardですが, チュートリアルなどを見ると, かならずtensorflowとセットで紹介されています.

でも,こんな便利なツールなんだから, tensorflow以外のときも使いたいな~っと思いました.
tensorflowなしでtensorboardを使う方法を調べて見ました.

早速結論ですが,以下のサイトが一番直感的に使えます.

A generic tensorboard logger for scalars and histograms or distributions · GitHub

少し解説すると,TensorBoardLoggerクラスを宣言することで, 簡単にtensorboardの形式でログを取ることができます.

このソースコードは,scalar(つまり折れ線グラフ)とhistgramにしか対応していません.

import numpy as np
import tensorflow as tf

class TensorBoardLogger(object):

    def __init__(self, log_dir, session=None):
        self.log_dir = log_dir
        self.writer = tf.summary.FileWriter(self.log_dir)
        self.episode = 0
        print('TensorBoardLogger started. Run `tensorboard --logdir={}` to visualize'.format(self.log_dir))

        self.histograms = {}
        self.histogram_inputs = {}
        self.session = session or tf.get_default_session() or tf.Session()

    def log(self, logs={}, histograms={}):
        # scalar logging
        for name, value in logs.items():
            summary = tf.Summary()
            summary_value = summary.value.add()
            summary_value.simple_value = value
            summary_value.tag = name
            self.writer.add_summary(summary, self.episode)

        # histograms
        for name, value in histograms.items():
            if name not in self.histograms:
                self.histogram_inputs[name] = tf.Variable(value,validate_shape=False)
                self.histograms[name] = tf.summary.histogram(name, self.histogram_inputs[name])

            input_tensor = self.histogram_inputs[name]
            summary = self.histograms[name]
            summary_str = summary.eval(session=self.session, feed_dict={input_tensor.name:value})
            self.writer.add_summary(summary_str, self.episode)

        self.writer.flush()
        self.episode += 1

このクラスの使い方は,簡単に以下のように使えます.

logger = TensorBoardLogger(log_dir='/tmp/test')
for i in range(10):
    logger.log(
        logs=dict(
            float_test=np.random.random(),
            int_test=np.random.randint(0,4),
        ),
        histograms=dict(
            actions=np.random.randint(0,3,size=np.random.randint(5,20))
        )
    )

インスタンス宣言時に,log_dir引数に保存先のディレクトリを指定します.
.log()関数により,好きな値を保存していくことができます.

あとは保存先のディレクトリをしていして, tensorboardを起動させます.
これで,localhost:6006などに接続することで結果を確認することができます(Macだと127.0.0.1:6006かな).

docker run --rm \
    -p 6006:6006 \
    -v ${LOG_DIR}:/logs \
    -w /logs \
    denden047/tensorboard \
    tensorboard --logdir /logs

※接続先は,dockerの設定よって変わります.

サンプルのソースコードをまとめると,こんな感じです.

import numpy as np
import tensorflow as tf

class TensorBoardLogger(object):

    def __init__(self, log_dir, session=None):
        self.log_dir = log_dir
        self.writer = tf.summary.FileWriter(self.log_dir)
        self.episode = 0
        print('TensorBoardLogger started. Run `tensorboard --logdir={}` to visualize'.format(self.log_dir))

        self.histograms = {}
        self.histogram_inputs = {}
        self.session = session or tf.get_default_session() or tf.Session()

    def log(self, logs={}, histograms={}):
        # scalar logging
        for name, value in logs.items():
            summary = tf.Summary()
            summary_value = summary.value.add()
            summary_value.simple_value = value
            summary_value.tag = name
            self.writer.add_summary(summary, self.episode)

        # histograms
        for name, value in histograms.items():
            if name not in self.histograms:
                self.histogram_inputs[name] = tf.Variable(value,validate_shape=False)
                self.histograms[name] = tf.summary.histogram(name, self.histogram_inputs[name])

            input_tensor = self.histogram_inputs[name]
            summary = self.histograms[name]
            summary_str = summary.eval(session=self.session, feed_dict={input_tensor.name:value})
            self.writer.add_summary(summary_str, self.episode)

        self.writer.flush()
        self.episode += 1

logger = TensorBoardLogger(log_dir='/tmp/test')
for i in range(10):
    logger.log(
        logs=dict(
            float_test=np.random.random(),
            int_test=np.random.randint(0,4),
        ),
        histograms=dict(
            actions=np.random.randint(0,3,size=np.random.randint(5,20))
        )
    )