読者です 読者をやめる 読者になる 読者になる

UUUM攻殻機動隊

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

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

コンピューターが賢くなって、人間がやる仕事が減るといいなと思っている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 から乗り換えられません。
では、スクリプトが書けるとなにが便利なのでしょう?

続きを読む

スクラムどうでしょう?

こんばんは! エンジニアのナカハシです。

UUUMコンテンツの総合アカウント「UUUM FANS」、カリスマブラザースのファンサイト「CBF」がオープンしました! 開発に携わるUUUMエンジニア陣も、これらのサイトがよりよいサービスになるよう、日々精進しまくっております!!!!!!!!

さて、UUUMでのソフトウェア開発は、どのチームもアジャイルで進めています。

「アジャイル開発」と一口にいっても、体制やアウトプットの形式によって様々な手法が考えられます。

今回はそのうちの一つである「スクラム」の概要を軽くまとめてみました。

続きを読む

サーバーレスアーキテクチャの事例まとめ

エンジニアのタナカです。

2015年にAWS Lambdaがリリースされて以降、サーバーレスアーキテクチャの注目度が高まっています。
サーバー管理が不要、スケーリングも自動、しかも安いと夢のような技術ですが、これまでの開発手法とは異なるため導入に躊躇している方も多いと思います。
弊社での利用はまだこれからですが、日本でのサーバーレスの採用事例も増えてきたようなので参考までにまとめて見ました。


thinkit.co.jp 日経電子版アプリ、Gunosyのほか、ゲームのバックエンドでの採用事例が紹介されています。

www.stylez.co.jp IoT通信サービスTrackrr.ioのアーキテクチャが紹介されています。spring bootを組み合わせたマイクロサービスで作られているようです。

www.publickey1.jp 一休ではサムネイル生成でLambdaを利用しているようです。

www.techscore.com イベント来場者管理システムのデータ登録APIにLambdaが利用されているようです。

www.jiji.com 有料動画配信サービスでLambdaを全面採用し3ヶ月でシステムを完成させたそうです。


2016後半から国内でもサーバーレスの採用事例が増えているようです。
IoTや動画配信システムで全面採用した事例も出てきて、2017年はさらに利用が広がりそうですね。

RailsアプリをUnicornサーバー&Symlink切り替えデプロイ環境下で安定運用する

Ruby Rails インフラ

nazoです。

Railsアプリを本番で運用する際、アプリケーションサーバーは現在ではUnicornかPumaを使うことが多いと思います。特にPumaを使う方が多いと思いますが、現在のプロジェクトではUnicornで構築しております。

Webサーバーを安定運用させるには無停止で再起動するGraceful Restartは必須ですが、いくつか注意すべき点があったので、運用例と共に紹介したいと思います。

続きを読む

UUUMにて、次世代のITを担う方々へ向けた「未踏」説明会がおこなわれました

こんにちは、新人エンジニアのハトネコエです。
12月17日(土曜日)、UUUMオフィスにて、
一般社団法人未踏がおこなう「未踏」事業の小中高生向け説明会
『未踏の魅力を知ろう - 2017年度未踏説明会』がおこなわれました。

「未踏」事業は国の『突出したIT人材の発掘と育成』を目的としておこなわれているもので、
25歳未満の方であればどなたでも研究テーマの応募ができ、採択されれば国のプロジェクトとして全力で支援されます。
誰も見たことのない未来の技術を実現しようと世界を切り拓く人たちの研究内容が知れ、説明会中はすごさのあまり「ほわぁ………」という気持ちでした。

Twitchの方々によって説明会は全世界へ生配信され、
アーカイブはこちらからご覧になることができます。
講演内容を覗いてみたい方はアクセスを。モノづくりの気持ちを思い出させてくれます。

さて、今回UUUMが会場提供をしたきっかけには、
UUUMのCTOである尾藤正人さんが「未踏」出身者という経緯があります。
尾藤さんも登壇されたのですが、当時なにを研究されていたのかという話は登壇テーマにはありませんでしたので、
このブログではそこに焦点を当てインタビューしてみたいと思います。

続きを読む