A Day In The Life

とあるプログラマの備忘録

Golangでサーバプログラミングするなら始めに読むべき記事

最近 Golng 使ってサーバのプログラム書いてます。 始める前に読んでおけばよかったと感じた記事が2つあったのでメモ程度に紹介します。

Handlerのチェインをどうやって解決するか
- Making a RESTful JSON API in Go - The New Stack
Context問題どうするか
- Go's net/context and http.Handler – joe shaw

micro:bitを使って子供と一緒に夏休みの自由研究をしてみました

夏休みのことなので少し前の話になりますが、小学生の娘と一緒に夏休みの自由研究にmicro:bit を使ったギターを制作しました。

f:id:glass-_-onion:20171009105814j:plain
エアギター

micro:bit って何ですか?

イギリスの BBC が開発した小学生向けの小型コンピュータです。子供向けではありますが、傾きセンサや光センサ、温度センサなんかもついていて本格的です。スピーカーに繋げば音を出すこともできます。Raspberry Pie や Arduino の子供版といった感じです。

マイクロソフトが開発した Scratch ライクな開発環境があるのでブラウザ上で手軽にプログラミングができます。

ギターの制作

小学2年生の娘が工作担当、自分がプログラミング担当といった感じで作りました。本当は娘にプログラミングもやって欲しかったのですが制作期間の関係で私が担当しました。以下の二つの工作例が元ネタです。

ちなみに電源供給とスピーカーは MI:power board で行いました。

ワニ口クリップがあるといろいろ捗ります

mcro:bit から音を出すためにスピーカーに繋いだりするのにワニ口クリップがあると便利です。mcro:bit 単体でも十分遊べるのですがワニ口クリップがあると遊びの幅がグッと広がるのでオススメです。

接着にはグルーガンがおすすめです

ダンボール同士をくっつける時なんかはボンドやノリを使うよりもグルーガンを使った方が丈夫に仕上がります。うちの小学2年生の娘も初めこそ苦戦してましたがそこそこちゃんと使えるようになってました。

参照ページ

数学知識ほぼ0の人間が深層学習の勉強をはじめてみた

きっかけは Magenta プロジェクト

最近巷では機械学習や深層学習(ディープラーニング)などAI系の技術が流行っていますが自分は2-3ヶ月前まで全くと言っていいほど興味がありませんでした。機械学習とかって画像解析や翻訳で使う技術でそのうち頭のいい人がなんとかしてくれるんじゃないのくらいの認識でした。その認識が一変したのが Google Magenta プロジェクト の AI Duet by Yotam Mann - AI Experiments でした。自分も深層学習を使って自動作曲やりたいということで勉強を始めることにしました。これまで自分が勉強したことや読んだ本のことをメモがてらまとめてみます。

勉強をはじめたころのスペック

  • Pythonは使ったことがある、ただしnumpyは使ったことがない
  • 数学はほどんとわからない(または忘れた)、ゲームの開発をしていたので三角関数くらいはなんとか理解できるくらい
  • 機械学習と深層学習の違いがわからない
  • 昨今流行っているAIがゲームAIとどう違うのかわからない

自動作曲やるならニューラルネットワークを勉強するのがよさげ

軽くMagenta プロジェクトのことや「自動作曲+AI」みたいなキーワードで調べてみるとニューラルネットワークを理解すると色々できるようになるっぽいということがわかりました。

数学さっぱりだけどニューラルネットワークについて勉強したい

本屋さんでニューラルネットワークの本を探して見ましたがどれも最低限の数学的な知識が必要そうな雰囲気でした。自分は数学が苦手で高校生の頃まともに数学を勉強した記憶がほとんどない....これは敷居が高いどうしようとなりました。

ライブラリを使って学ぶかライブラリ無しで勉強するか

いろいろと調べているうちに TensorFlow と Chainer この2つのライブラリが人気らしいことがわかりました。ただこれらのライブラリのチュートリアル読んでも専門用語がわからなさすぎて使いこなせる気が全くしませんでした。なのでライブラリに頼らず1から自分で実装してみるのがよさそうとなりました。

数学が苦手でも読めるニューラルネットワーク本との出会い

数学が苦手な自分でも内容がわかりライブラリに頼らず1から実装を学べるそんなわがままに答えてくれる本なんてないと思っていたらなんとも自分にぴったりな本を見つけました。

数式はあるものの初心者にもわかるように丁寧に解説してくれている、ニューラルネットワークについての基本的な用語の解説もある、Pythonの実装例まである、知りたいことほとんど載ってるじゃないか...素晴らしすぎる。バイアスの説明が省略されていること以外は必要な知識がほぼ網羅されています。

もっと基本的なところから数学の勉強したい場合は

深層学習の本ではなく機械学習の本ですが、深層学習に比べて数式が簡単なので深層学習の本よんで数式が全く理解できないって場合にオススメです。

ものすごく基本的なところから説明してあってかつPythonの実装例もあるのでかなり理解しやすいです。

深層学習を使ってどんなことができるのか

覚えた用語

  • 入力層
  • かくれ層
  • 出力層
  • 重み
  • 誤差逆伝搬

学習って何?

誤差が最小になるような重みの組み合わせを見つけること

深層学習を理解する上で必要な知識

よく出てくる数学用語

スカラー、ベクトル、行列、テンソル

次元 名前 説明
0次元 スカラー 数値
1次元 ベクトル 配列
2次元 行列 2次元配列
3次元以上 テンソル 3次元配列以上

ただしベクトルには列ベクトルと行ベクトルがある、通常は列ベクトルだけ考えれば良い

ベクトルと行列関連の用語

実装してみる

Pythonの実装例を元にSwiftで実装してみました。 github.com 3層ニューラルネットだけでは物足りず、今はLSTMの実装に挑戦中です。

参考

オブジェクト指向の次に来るもの

自分が駆け出しのプログラマだった頃(10年以上前ですかね)、必死でオブジェクト指向プログラミングの勉強をしました。最近だとオブジェクト指向プログラミングなんて当たり前すぎて技術とすら言えないくらいになったと感じてます。 エンジニアが生き残るために次に必要な技術は何かここ数年いろいろ考えてきましたが、次は間違いなくリアクティブプログラミングだと予想しています。1年半ほど前、UniRxを使ったのをきっかけに現在もRxSwiftを使って日々リアクティブプログラミングと接しています。そんな大事な技術ですがあまり専門書がないのが困ったところです。そんな折に見つけたのが本書です。

厳密にはリアクティブプログラミング(RP)について書かれた本ではなく関数型リアクティブプログラミング(FRP)について書かれた本です。関数型リアクティブプログラミングはこの本によると「関数型プログラミング(FP)とリアクティブプログラミングの交わる部分」だそうです。 FRPの考え方はRx(リアクティブプログラミング)にも応用可能ということなんでこの本を読んで知見をためたいと思います(まだ全部読んでません)。

面倒な課金処理をRx化するRxStoreKitを作りました

StoreKit の SKProductsRequest と SKPaymentQueue を Rx化して課金処理を簡単に書けるライブラリを GitHub にて公開しました。 github.com RxStoreKit を使うと課金処理を以下のような感じで書けます。

let productRequest = SKProductsRequest(productIdentifiers: Set(["xxx.xxx.xxx"]))
productRequest.rx.productsRequest
    .flatMap { response -> Observable<SKProduct> in
        return Observable.from(response.products)
    }
    .flatMap { product -> Observable<SKPaymentTransaction> in
        return SKPaymentQueue.default().rx.add(product: product)
    }
    .subscribe(onNext: { transition in
        print(transition)
    }).disposed(by: disposeBag)
productRequest.start()

Rx以前の課金処理

だいぶ前の記事ですが iOS アプリの課金処理まわりの記事を書きました。 glassonion.hatenablog.com こちら見ていただくとわかると思いますが StoreKit(In-App Purchase) のプログラムはものすごく複雑です。中でも SKPaymentTransactionObserver の処理が特に大変です。StoreKit のような非同期コールバック地獄みたいなプログラムは RxSwift とRxCocoa を使って Rx化するとものすごく簡略化できます。というわけで RxStoreKit を宜しくお願いします。

関連記事

失敗しない iOS In-App Purchase プログラミング - A Day In The Life
RxSwift DelegateProxy with required methods – LazySequence<UnsafePointer>

Swift3でMIDIファイルをパースする方法

Swift3 で MIDI ファイルのパースをしようとしたら意外に方法が見つからなくて苦労したのでメモです。 MusicEventIteratorGetEventInfo 関数で取得したデータを MIDINoteMessage オブジェクトに変換する方法がわからなくてハマりました。

import AudioToolbox

public class MIDIParser {
    
  public static func parse(url midiFileUrl: URL) {
        
    var musicSequence: MusicSequence?
    var result = OSStatus(noErr)
    result = NewMusicSequence(&musicSequence)
    guard let sequence = musicSequence else {
      print("error creating sequence : \(result)")
      return
    }
        
    // MIDIファイルの読み込み
    MusicSequenceFileLoad(sequence, midiFileUrl as CFURL, .midiType, MusicSequenceLoadFlags.smf_ChannelsToTracks)
        
    var musicTrack: MusicTrack? = nil
    var sequenceLength: MusicTimeStamp = 0
    var trackCount: UInt32 = 0
    MusicSequenceGetTrackCount(sequence, &trackCount)
    for i in 0 ..< trackCount {
      var trackLength: MusicTimeStamp = 0
      var trackLengthSize: UInt32 = 0
            
      MusicSequenceGetIndTrack(sequence, i, & musicTrack)
      guard let track = musicTrack else {
        continue
      }
            
      MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &trackLength, &trackLengthSize)
            
      if sequenceLength < trackLength {
        sequenceLength = trackLength
      }
            
      var tmpIterator: MusicEventIterator?
      NewMusicEventIterator(track, &tmpIterator)
      guard let iterator = tempIterator else {
        continue
      }
            
      var hasNext: DarwinBoolean = false
      MusicEventIteratorHasCurrentEvent(iterator, &hasNext)
            
      var type: MusicEventType = 0
      var stamp: MusicTimeStamp = -1
      var data: UnsafeRawPointer?
      var size: UInt32 = 0
            
      while hasNext.boolValue {
        MusicEventIteratorGetEventInfo(iterator, &stamp, &type, &data, &size)
        if type == kMusicEventType_MIDINoteMessage {
          let messagePtr = UnsafePointer<MIDINoteMessage>(data?.assumingMemoryBound(to: MIDINoteMessage.self))
                    
          guard let channel = messagePtr?.pointee.channel,
            let note = messagePtr?.pointee.note,
            let velocity = messagePtr?.pointee.velocity,
            let duration = messagePtr?.pointee.duration else {
              continue
          }
            
          let message = MIDINoteMessage(channel: channel,
              note: note,
              velocity: velocity,
              releaseVelocity: 0,
              duration: duration)
          print(message)
        }
                
        MusicEventIteratorNextEvent(iterator)
        MusicEventIteratorHasCurrentEvent(iterator, &hasNext)
      }
      DisposeMusicEventIterator(iterator)
      MusicSequenceDisposeTrack(sequence, track)
    }
    DisposeMusicSequence(sequence)
  }
}

参考

Objc や Swift2の情報はそこそこありました。

Swift3 のポインタ型についてちゃんと理解してればハマらなかったのかなと反省してます。

ReSwiftのステートをRxSwiftを使って監視する

普段から RxSwift(Reactive ExtensionsのSwift実装)と ReSwift(ReduxのSwift実装)を使っています。RxSwift を通信系の処理だったりデリゲートの処理(例えば StoreKit とか CoreBluetooth)だったりに使って、ReSwiftをアプリ全体で管理しなきゃいけないデータの監視なんかに使ってます。ReSwift をそのまま使ってもあまり困らないのですが、ReSwift のステートを Observable に変換してUI部品とバインドするといろいろと捗るなぁというわけで ReSwift の Rx 用ラッパークラスを作成しました。

ReduxのステートをRx化するクラス

Redux のステートを Rx の Variable に格納して、Redux からステート変更の通知が来たら Variable(エラーの発生しないBehaviorSubject)を更新するクラスを作成します。

import RxSwift
import ReSwift

class RxStore<AppStateType: StateType>: StoreSubscriber {
  // 監視する値
  let state: Variable<AppStateType>
  private let store: Store<AppStateType>
    
  init(store: Store<AppStateType>) {
    self.store = store
    self.state = Variable(store.state)
    // 購読開始
    self.store.subscribe(self)
  }
    
  deinit {
    // 購読終了
    self.store.unsubscribe(self)
  }
    
  func newState(state: AppStateType) {
    // Variableを更新する
    self.state.value = state
  }
}

使い方

Store を生成します。ここは通常の ReSwift の使い方そのままです。

// ストア
struct AppState: StateType {
  var count: Int = 0
}

// アクション
enum AppAction: Action {
  case incAction
}

// Reducer
struct AppReducer: Reducer {
  func handleAction(action: Action, state: AppState?) -> AppState {
    let state = state ?? AppState()
    return AppState(count: state.count + 1)
  }
}

// ストアオブジェクトの生成
let mainStore = Store<AppState>(
  reducer: AppReducer(),
  state: nil
)

ViewController で Rx化したステートを subscribe(購読)する場合は以下のようになります。

import UIKit
import RxSwift
import ReSwift

class ViewController: UIViewController {

  let disposeBag = DisposeBag()
    
  let rxStore = RxStore<AppState>(store: mainStore)

  override func viewDidLoad() {
    super.viewDidLoad()
    rxStore.state.asObservable()
      .subscribe(onNext: { state in
        // 更新された時の処理
        print(state.count)
      }).disposed(by: disposeBag)
  }
}
// ディスパッチ
mainStore.dispatch(AppAction.incAction)
mainStore.dispatch(AppAction.incAction)
mainStore.dispatch(AppAction.incAction)
mainStore.dispatch(AppAction.incAction)

UI部品とバインド

Rx化されて入れば UI 部品と簡単にバインドできます。

class ViewController: UIViewController {

  let disposeBag = DisposeBag()
  @IBOutlet weak var button: UIButton!

  override func viewDidLoad() {
    super.viewDidLoad()
    // カウントが3を越えたらtrueにする
    let appStateValid = rxStore.state.asObservable()
      .map { state -> Bool in
        return state.count > 3
      }.shareReplayLatestWhileConnected()
    // ボタンのEnabledとバインドする
    appStateValid
      .bind(to: button.rx.isEnabled)
      .addDisposableTo(disposeBag)
  }
}

参考記事