UUUM攻殻機動隊(エンジニアブログ)

UUUMのエンジニアによる技術ブログです

PHPなチームがRuby on Railsでの開発を行って得られたもの

3日連続 nazoです。

昨年から行っているチャレンジとして、Ruby on RailsによるWebサービスの開発があり、それが一段落しましたので、経緯と結果について報告させて頂きたいと思います。

続きを読む

CircleCIでRailsのDockerコンテナをECSにデプロイする

nazoです。

Graceful RestartによるRailsアプリのデプロイ を行っていたのですが、もっと手軽に環境ごとデプロイをしたいという需要もあって、Dockerを採用したデプロイも行っています。

CircleCI(1.0)では辛うじてDockerのサポートがありますが、いくつか癖があるので、ECSと含めて運用まで踏まえた手順について紹介したいと思います。

続きを読む

Docker?Vagrant?個人PCのWebアプリケーション開発環境においての環境分離方法

nazoです。

個人PC上では、複数の開発環境が同居することは珍しくありません。その際に、複数のバージョンの同一のソフトウェアが混在することもあります。 それらを切り替える度にアンインストール・インストールを繰り返すのは非効率なので、同居させつつ自動的に切り替わるような状況が最適かと思われます。

これを実現するには様々な方法がありますが、一長一短あるため、具体的にどう違うのか見ていきたいと思います。特にmacOSを中心とした話になります。

続きを読む

Google Spreadsheet のデータを自動で Google Calendar に追加する

おはこんばんちは!! 尾藤 a.k.a. BTO です!!

スギ花粉の脅威に毎日怯えている皆様、ご機嫌いかがでしょうか。 最近は Google Spreadsheet や GAS(Google Apps Script) を使って社内業務の改善などをしております。 だって会社がどんどん大きくなってるから、業務の効率化を進めないと回らないんだもん!!

Google Spreadsheet のデータを Google Calendar に追加したい!!

弊社では営業管理ツールに Salesforce 使っていて、他部署とのデータ連携のために、Salesforce のデータを Google Spreadsheet に同期しています。 ここに動画の公開日の情報があるので、Google Calendar にイベントを追加したいのが今回の目的です。 以前は、全て人が手作業で入力していたため非常にコストのかかる作業だったのが、全て自動でできるようになってので、かなり効率化することができました。

続きを読む

ニューラルネットワーク実装入門

コンピューターが賢くなって、人間がやる仕事が減るといいなと思っているkitabatakeです。 今流行りのニューラルネットワークについて説明したいと思います。

ニューラルネットワークとは

脳神経系をモデルにした情報処理システムで、

文字認識や、音声認識など、コンピュータが苦手とされている処理に対して有効です。

脳の中には多数のニューロン(神経細胞)が存在していて、 各ニューロンは多数の他のニューロンから信号を受け取り、他の多数のニューロンへ信号を受け渡していて、 信号の伝搬によって、様々な情報処理を行っています。

こういった脳内の情報処理の仕組みを真似することで、複雑な情報処理を行おうというものです。

神経細胞の仕組み

神経細胞は下記の画像になっています。

http://www-ailab.elcom.nitech.ac.jp/lecture/neuro/image/neuro.gif

ニューラルネットワーク入門 1.1 神経細胞より参照 http://www-ailab.elcom.nitech.ac.jp/lecture/neuro/neuro1.html

  • 樹状突起 ニューロンへの入力端子

  • 軸索 ニューロンの出力端子

  • シナプス ニューロン間を繋ぐ役割. 軸索から他のニューロンの樹状突起を通して伝達される

入力信号が加わると電位があがりはじめ、 閾値を超えると一時的にニューロンの電位が急激にあがり、シナプスを通じて結合しているニューロンへ出力されます(ニューロンが発火すると表現される)

ニューロンの発火イメージ

http://cdn-ak.f.st-hatena.com/images/fotolife/k/kazoo04/20151117/20151117001033.png

ニューロンの概要とそのモデル より参照 http://kazoo04.hatenablog.com/entry/agi-ac-3

こういったニューロンの仕組みをモデル化すると

http://www-ailab.elcom.nitech.ac.jp/lecture/neuro/image/n_model.gif

ニューラルネットワーク入門 1.2 ニューロンモデルより参照 http://www-ailab.elcom.nitech.ac.jp/lecture/neuro/neuro1.html

ニューロンは入力端子ごとにその入力の重要性を表す結合荷重があり、発火のしやすさを表す閾値を持っていて、 閾値を超えると出力端子から出力信号が出力されるようにモデリングできます。

このニューロンモデルの出力と入力を複雑に連携させて、ネットワーク化することで、複雑な情報処理が可能になります。

階層型ネットワークモデル

ネットワークモデルの1例で、入力層と出力層があり、その間に中間層があります。 ある層のニューロンは前の全てのニューロンからの出力を受け取り、次の層の全てのニューロンに対して出力を行います。

http://ipr20.cs.ehime-u.ac.jp/column/neural/image/layer.gif

画像処理・理解研究室 第5章 ネットワークの形態についてから参照 http://ipr20.cs.ehime-u.ac.jp/column/neural/chapter5.html

実装に入ります

上記で説明したニューロンモデルとネットワークモデルを実装に落とし込んでみたいと思います。

まずは単純パーセプトロン

パーセプトロンとは1957年に考案されたニューロンモデルで、入力層と出力層のみの2層からなるものが単純パーセプトロンと呼ばれます。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/ogidow/20160621/20160621094328.png

rubyで単純パーセプトロンより参照 http://ogidow.hateblo.jp/entry/2016/06/24/184801

各入力ごとに重みと閾値を持ち、入力値 * 重みの総和が閾値を超えると 1 超えないと 0 が出力されます。

重みにマイナスを掛けたものをバイアスと表し、常に入力値が1の入力と考えることで、ニューロンの発火条件をシンプルに表現することができます。

https://qiita-image-store.s3.amazonaws.com/0/115996/5630dd0e-faf1-d800-a073-f2248bf93d4f.png

機械学習ざっくりまとめ~パーセプトロンからディープラーニングまで~ から参照 http://qiita.com/frost_star/items/21de02ce0d77a156f53d

b + x1 * w1 + x2 * w2 が 0以上であれば発火というように表現できるようになります。

ではパーセプトロンでシンプルな回路を実装してみましょう

OR回路とAND回路を考えてみると、OR回路は発火しやすい(どちらかの入力が1であれば発火)もので、 AND回路は発火しにくい(両方の入力が1で発火)ものと考えることができ、そのようにバイアスと重みを設定すると実現できます。

例えば、

  • OR回路: バイアス: -1, 重み1: 2, 重み3

  • AND回路: バイアス: -1, 重み1: 0.5, 重み2: 0.5

と表現できます。

NAND回路はAND回路の設定値を全て正負を反転すると表現できます。

単純パーセプトロンの限界

XOR回路を考えると単純パーセプトロンでは表せないことが解ります。 2つの入力どちらも1の場合に発火しないという条件は表現できません。

そこで多層化

XOR回路は、OR回路とNAND回路をANDにつなげることで表せるので、パーセプトロンを多層化することで表現できます。

http://hokuts.com/wp-content/uploads/2015/12/xor_mlp0.png

高卒でもわかる機械学習 (3) 多層パーセプトロン より参照 http://hokuts.com/2015/12/04/ml3-mlp/

コンピュータはNAND回路の組み合わせでできているということで、パーセプトロンを多層化していくことで、かなり複雑な情報処理が行えると言えると思います。

次に活性化関数

今まで見てきたパーセプトロンでは、バイアス + 入力値 * 重みの総和の入力に対して、1か0を出力するという考えでした。 この入力から出力を生成する関数が活性化関数を呼ばれます。

パーセプトロンのような1か0で出力するものはステップ関数と呼ばれています。

ステップ関数とは別によく使われている活性化関数として、シグモイド関数というものがあります。

https://upload.wikimedia.org/wikipedia/commons/a/ac/Logistic-curve.png

wikipediaより参照 https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B0%E3%83%A2%E3%82%A4%E3%83%89%E9%96%A2%E6%95%B0

ステップ関数とは違い、0から1の間の値に収まる形で多様な値が出力されます。 シグモイド関数のこの特性は入力値の細かい調整が出力に反映されるということになるので、バイアス、重みの細かい調整(学習)に都合がいいということで、 一般的にこちらの方が使用されているようです。

シグモイド関数を活性関数に使用したニューロンをシグモイドニューロンと呼ぶことがあるようです。

手書き数字の認識

今までの知識をもとに手書き数字を認識するニューラルネットワークを実装してみたいと思います。

www.oreilly.co.jp

こちらの本が提供している学習データ、コードをベースに見ていきたいと思います。

MNISTとは

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

MNISTとは6万の手書き数字の学習用画像と、1万のテスト用画像を提供しているサービスで、python用に画像を取得するライブラリも提供されています。 MNISTから取得した学習用画像で学習したデータをもとに、テスト画像の予測の精度を出力するプログラムを見ていきたいと思います。

ネットワークの設計

MNISTの画像は 28px * 28px の画像なので、入力層のニューロンの数としては、784となり、 出力層は各数字の確率なので、0 - 9 までの個数で、10となります。

中間層は2層で、100, 50 とします。 この辺りは学習方法をまだ理解していないので、この設定する意味は理解できていないのですが、結構複雑なニューラルネットワークになっていると思います。

プログラム

配列の計算を簡単に行うために、numpy.array を使用しています。

ゼロから作るDeep Learning で提供されているコードにコメントを追加したものです。

import sys, os, pickle

sys.path.append(os.pardir)
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax
import numpy as np

# MNISTの学習用データとテスト用データを取得する
def get_data():
  (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)

  # *_trainが学習用のデータで、*_testがテスト用のデータです
  # 今回はテスト用のデータしか使いません
  # x_testがテスト用の画像データで、t_testがテスト用画像に対応した答えの数値です
  return x_test, t_test

# 学習済みのネットワーク(バイアスと重み)のデータを取得する
def init_network():
  with open('sample_weight.pkl', 'rb') as f:
    network = pickle.load(f)

  return network

# ネットワークと入力(画像データ)から数字の予測を行う
def predict(network, x):
  W1, W2, W3 = network['W1'], network['W2'], network['W3']
  b1, b2, b3 = network['b1'], network['b2'], network['b3']

  # 各層の各ニューロンへの入力値の計算(入力 * 重み + バイアス)したものをシグモイド関数に通しています。
  a1 = np.dot(x, W1) + b1
  z1 = sigmoid(a1)
  a2 = np.dot(z1, W2) + b2
  z2 = sigmoid(a2)
  a3 = np.dot(z2, W3) + b3

  # 最終的に出来上がるデータは出力層の長さが10の配列で、keyが対象数字でvalueがその数字である確率が入っています
  return a3

x, t = get_data()
network = init_network()

# 正答率の計算
accuracy_cnt = 0
for i in range(len(x)):
  y = predict(network, x[i])
  p = np.argmax(y) # 確率が一番高いものがニューラルネットワークが予測した数字で、
  if p == t[i]:
    accuracy_cnt += 1 # 予測した数値と提供されている答えが一致していると、正解数をインクリメントします

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))

これを実行すると

Accuracy:0.9352 と出力されます。

MNISTのテスト用画像は人間が見ても判別が難しい画像も含まれているので、結構高い精度が出ていると言えると思います。

次は学習アルゴリズムを勉強したいと思います!

AviUtl スクリプトで動画作成は楽できる!

こんにちは、新人エンジニアのハトネコエです!

先週はNintendo Switch 体験会があったり、
週末はGlobal Game Jam 2017があったり、
1月はゲーム大好きな人たちをわくわくさせるイベントが目白押しでしたね!

冬に発売する『スーパーマリオ オデッセイ』が楽しみです。はやく!!


さて、今回の社内勉強会は AviUtl での動画作りについて触れました。(完全に私の趣味です)

AviUtl は Windows のフリー動画編集ソフトです。
無料です! なんと無料です! やばいです。
無料なのに、できることは1万円を超えるソフト並です。

初心者のうちは取っつきにくく、私も一度挫折したくらいに難易度の高いソフトなのですが、
一度慣れてしまうと、市販の動画編集ソフトに対して
「フレーム単位での編集がしづらい!」
「スクリプトが書けない!」
と不満を持ってしまうくらいです。

ほとんどの動画編集ソフトに外部スクリプト機能はありませんから、もう AviUtl から乗り換えられません。
では、スクリプトが書けるとなにが便利なのでしょう?

続きを読む