ウォンツテック

BizteX CTO 袖山 剛 の技術のーと

2017年 個人の振り返り

今年の主なイベント

  • 会社退職
  • サラリーマン辞めた
  • 会社設立(自身の個人事業主的な会社)
  • BizteXにJoin(Co-founder & CTOになる)
  • プロダクトのゼロからの開発
  • チームビルディング
  • プロダクトリリース(ベータ&正式)
  • 40歳になった
  • プロダクトの初受注

今年は私個人にとって激動の1年でした。

長く勤めていた前職では給与面では恵まれていましたが、そんな物は風向きが変わればすぐ無くなると考えていて、没落し続けているこの日本で生き残るため、サラリーマンを辞め個人の能力や裁量で生きたいという事を5,6年前から考えていました。

とあるスタートアップの手伝いをしたり、自分で事業アイデアを考えてプロトタイプを作ったりしていましたが、去年11月くらいに、まずは自分個人が食える受託会社を作ろうと決意しました。

決意してからは、数年間の経済基盤を作るべくいくつかの目標を定めていています。

年初の目標

開発系は技術的投資という意味合いでの最新技術の吸収を重視しました。

また、前職では営業支援や炎上プロジェクトのPMとして対顧客コミュニケーションをがっつりやっていたんですが、やはり個人で生きていくには純粋な営業力が必要だろうという事で「営業」。

あとは会社の登記。

会社設立

会社設立にあたり、会社の登記などを全部一人で実施しました。 その他、商標申請などもやってみたり、そんなに時間を掛けなくても一人で色々出来るんだなという感想です。 現状は休眠状態なので設立自体は無駄といえば無駄ですが、いい経験だったなと思ってます

開発

開発系で重視したのは「プログラミングスキル」「機械学習」「スマートコントラクト」です。

「プログラミングスキル」については

  • 純粋にコードを書きまくる
  • 本読む(リーダブルコード、達人プログラマー、テスト自動化、その他たくさん)
  • レビュー

これらをやっていて、BizteXにJoinする前は個人で企画したWebサービスの開発をゴリゴリしていて、Joinする2ヶ月前くらいからはBizteX cobit (https://www.biztex.co.jp/cobit.html)の開発をゴリゴリやっています。 BizteXからはメンバーとのレビュー(レビューをしてもらう&する)を実施していて、これがスキルアップに物凄く寄与しています。

機械学習」については「ゼロから作るDeep Learning」の本を読み始めた事が大きく、この本のおかげで機械学習に興味を持ち、その他にもいくつかの本とスタンフォード大学がオンラインで提供している「Coursera Machine Learning」のコースを履修しました。その後、TensorFlowやkerasなどのライブラリを使っていくつかモデルを作って遊んでいましたが、プロダクト開発に時間を取られてあまり触れていないのが現状です。 来年こそはプロダクトに組み込みたい。

「スマートコントラクト」については数年前にBitcoinを知ってから去年末くらいにイーサリアムという別の仮想通貨を知り物凄く興味を覚えたと同時に社会を変えうる技術だと思い目標に入れました。残念ながら本を読むのとスマートコントラクトをプログラミングする言語solidityを簡単に触った程度で止まっています。来年は個人的趣味で少し触って行きます

Join

また、今年一番のイベントはやはり今のBizteXの代表嶋田に出会った事でしょう。

最初は、作ったばかりの会社で業務委託契約をしてもらおうと初期プロトタイプを作って見てもらっていたのが、技術的な課題感が面白い事や嶋田の事業に対する熱量・人柄などに惹かれJoinする事を決断しました。 元々上記のように個人力を高めるために自分で何でもやりたかったため、メンバーではなく裁量の大きいFounder&経営者として入れた事も決め手です。

Joinしてからは、まずプロダクトをゼロから生み出すために約6ヶ月間ひたすら開発を続けました。 (普段飲みに行くのが大好きな私でしたが、この6ヶ月間はほとんど飲みに行っていません笑) ベータリリース後は顧客への使用感のインタビュー・オンサイトサポート・メールサポートをしつつ開発を続け 営業支援・営業を実施しています ここで「営業やる」「何でもやる」はある程度出来たかなと思います。

あと、占いなどは一切信じていないんですが、自分の生年月日だと「2017年は12年に一度の大幸運期で、人生を左右する人物に出会う」とあり、これが嶋田だったんではないかと少し信じつつあります

受注

そして今年一番うれしかったイベントは「初受注」です。 SaaSスタートアップ最大の難関は初受注だと思っていたため、初受注した時は並々ならぬ思いがありました

受注するためにチーム全員が開発・営業に邁進し、ユーザーが抱えている課題を一つ一つ解決していき いくつかの営業案件であと一歩という所を乗り越えながら、まるでこの顧客のためにうちのサービスを作ったんだよ という課題解決を経てからの受注はまさにITが持つ本来の役割であり、BizteXの存在価値を示せた第一歩だと思いました

KPT

今現在、開発チームでイテレーションごとにKPTで振り返りを実施しているんですが、個人の振り返りとして2017年振り返りのKPTをやってみました 短時間でやってみたので代表的な物だけ記載していますが、来年はここに記載したKEEP, TRYを中心に実施して事業を加速させて行きたいと思っています

KEEP

開発関連(sodeyama)

  • 開発スキルを上げる
  • 本を読む

開発関連(チーム)

営業

  • 営業支援
  • 営業

経営関連

  • 重要な経営指標を一つ持ち、こまめに修正する
  • 長期的な展望からの逆算したスケジューリング
  • 開発のリファラル採用

Problem

開発関連(sodeyama)

  • 他プロダクトのコードリーディングが弱い
  • 機械学習の勉強が途絶えた
  • スマートコントラクトなどプロダクトと現状無関係な技術への投資が弱い

開発関連(チーム)

  • チームの開発速度をもっとあげたい
  • チームの安定性(モチベーションの持続的な意味で)
  • プロダクトのUX向上
  • リモート開発の効率化

サポート関連

  • カスタマーサポートのスケール 質を保ちながらスケールするサポートが必要 (カスタマーサクセスにもつなげられるように)

営業

  • 営業支援のスケール

経営関連

  • テクノロジー面での会社ブランドの確立
  • 今後のエンジニア採用
  • WEBマーケティング
  • グローバル展開

Try

開発関連(sodeyama)

  • 有名プロダクトのコードを読む
  • 機械学習を利用した機能をプロダクトに取り込むためのプロトタイプを作る
  • [趣味]solidityで実験的なコントラクトを書く

開発関連(チーム)

  • コードの品質をもっと上げる
  • 単体テスト(コード)のカバレッジを上げる
  • CIでのテストケースの並列実行
  • 各チームメンバーへのプロダクトへの裁量権と責任のさらなる分散
  • UXが得意な方と業務委託契約を結んで実際のプロダクトのUXを向上させる
  • リモート開発の効率化

サポート関連

  • カスタマーサクセスを意識したサポートの設計とツールの導入

営業

  • 営業支援系のインターン採用やサポート系社員への教育

経営関連

  • 社内のテクノロジー文化の開示 開発プロセス、何を重視しているか
  • 技術勉強会の共同開催
  • エンジニア採用のためにいくつかのHRサービスを使う
  • プロダクトの多言語化(2018年末予定)

機械学習 SVMを使う基準

stanford machine learning 7週目です

SVM (Support Vector Machine)というニューラルネットワークではない学習モデルの一つ。 ロジスティック回帰でやるかSVMでやるかは以下のような基準で切り分ける

学習に利用する特徴点(家の価格を予想する場合は広さ、部屋数、最寄り駅などの情報)の数をnとし、学習するトレーニングセットの数をmとした場合

n が m に比べてかなり大きい場合

例えばnが10000でmが10〜10000くらいの場合 ロジスティック回帰か、SVM without Kernel(線形カーネル)を利用する

n が m に比べてかなり小さい場合

nが1〜1000でmが10〜10000くらいの場合 SVMガウスカーネルで利用する ※mは5万くらいまでが良い。それ以上だとガウスカーネルを利用すると遅い

n が少なくて mが極めて多い場合

nが1〜1000でmが5万以上〜数百万の場合 自分で特徴点の数を増やし(新たに収集し)、ロジスティック回帰か、SVM without Kernel(線形カーネル)を利用する

ニューラルネットワークの利用について

上記の問題全てにニューラルネットワークのモデルを適切に作れば有効に働くが、計算速度が遅いケースがあるため適切にロジスティック回帰かSVMを用いる方が良い

機械学習 モデルのデバッグ

stanfordのmachine learning講習も6週目です

すごく重要な回だったので少しまとめ

アルゴリズムデバッグ手法

cross validationのチェック

学習の正当性を確認するのにデータを

  • training set
  • cross validation set
  • test set

に分けます。 トレーニングセットは学習のためのセットで残り2つは、それが妥当かの確認に使います 大体割合は60%:20%:20%で分けるとの事。 cross validation setはfeatureの数や正規化(λ)の加減、polynomial(ひとつのfeature xに対し、x2, x3などをfeatureに加える方法)の増加などを実施した際に正しく学習出来ているかを確認するためのデータセット。 学習状況の確認手順は以下

  1. training setの数をmとするとfor i =1:m とした繰り返しの中で2〜5を繰り返す
  2. training setのi個分のデータに対しを正規化されたコスト関数で学習し、最小となるパラメータを求める
  3. 2のパラメータを使い正規化していないコスト関数でtraining set i個分に対するコスト関数の値を出す
  4. 2のパラメータを使い正規化していないコスト関数でcross validation set(全データ)に対するコスト関数の値を出す
  5. 3と4の出力結果を元にhigh bias状態かhigh variance状態かを確認する
  6. 状況に合わせてパラメータに修正を加え1〜5を繰り返し試す
  7. 最適な状態でtest setでエラー率を出す

high biasな状態

under fittingで起こる。training setのエラー率が高く、cross validation setでのエラー率も高い 学習を進めるとtraining setとcross validation setのエラー率がほぼ同じになる。最終的に収束するエラー率が高いのでtraining setをいくら増やして学習させても無駄なのでこの状態が現れたら即見直し。

high varianceな状態

over fitting(過学習)で起こる。training setのエラー率が低く、cross validation setでのエラー率は高い 学習を進めると training setのエラー率がcross validation setのエラー率より低く、徐々に差は縮まってくる。 収束するエラー率は期待される値に近づくのでtraining setを集めるなり、他の対処方法でチューニングすべし。

状況に合った対応方法

high bias

  • featureを増やす -> hidden layer増やしたりhidden layerのfeature数を増やす
  • polynomial featureを増やす -> x2, x3やらx1*x2やらを増やすんだけどニューラルネットワークなら上記の方法で良さそう?
  • 正規化λを減らす -> over fitting是正するために入れたλが高すぎる場合にhigh biasになってる可能性あり

high variance

  • training setを増やす
  • featureの数を減らす -> hidden layer多すぎたりhidden layer中のparameter数が多い場合に減らす
  • 正規化λを増やす -> λは増やしすぎるとhigh biasになるので注意。まだ最適でないなら増やす

Stanford UniversityのOnline machine learningコースを受ける

ゼロから作るDeep Learningの本を読み終えた後にtensor flowのチュートリアルやkerasのチュートリアルをいくつかやっていたのですが、もう少し体系的に勉強したいなと思い

www.coursera.org

このStanford Universityが実施しているオンラインの機械学習コースを受講しています。ビデオ講義がメインで所々に選択式や埋込み式のテストが実施され80%以上の正答率だと次の講習に進めます。全体で11週分の講義があり、コードを書いて提出させる形式のテストが週に1回ほどあります。


講義ビデオですが、日本語の字幕を出せます。また講義中の英語が非常に平易なので、ある程度の専門の英単語に慣れてきたら英語字幕でも理解出来るかと思います。数学についても事細かに説明されているので数学の前提知識なしでも進められるかもしれません。


このコースの教授が勧めているのがOctaveという数式計算に特化した言語で、機械学習を勉強するにはこの言語が最適だとの事です。確かにOctaveは行列計算などが紙で計算する方法とだいぶ近いため、numpyのようなコンピュータよりな計算方法より取っ付き安いです。シリコンバレーの人達も機械学習のモデルを実験する際はOctaveを使う事が多いそうです。


Week2(全Week11)まで受けた感想としては、機械学習を勉強する以外の障壁となる知識(数学やツールの使い方等)を極力意識させないように講義をすすめている所が大変素晴らしいです。

TensorFlowを使ってみる 5

Kerasを使ってみる

tensorflowの高機能ライブラリであるcontrib.learnを使ってみたんですが
今一わかりづらかったのでもう一つの高機能ライブラリであるKerasをさわってみます

とりあえず1層でOptimizerは最降下勾配方で最も単純なネットワークを組んでみます

gist.github.com

contrib.learnと比べて層で何をやっているかが非常に明快です。
ただし、結果としてはaccuracyが0.86くらいと前回素のtensorflowで組んだ場合の0.97と比べるとかなり低いです。

と思って調べてみたら、lrの値、learning rateという1回の微分でどの程度重みを移動させるかの値が0.01とかなり低い値を指定してしまっていました。

素のtensorflowで組んだ場合と同じ値の0.5にしたらaccuracyは0.956と精度は近づいてます。

後、精度を出すのに重要なハイパーパラメータである重みの初期値を以下のように合わせてみたんですが、精度は逆に落ちて0.952くらいとなってしまいました。

std_deviation = 0.01

def my_init(shape, name=None):
    print(shape)
    value = std_deviation * np.random.randn(*shape)
    return K.variable(value, name=name)

model.add(Dense(output_dim=100, input_dim=784, init=my_init))

Keras使ってみる 2

Kerasで畳み込みニューラルネットワークを書いてみました

gist.github.com

やはりcontrib learnより何をやっているか分かり易く、Try&Errorが容易に出来そうな気がします

結果はaccuracyが0.991となりました。

TensorFlowを使ってみる 4

畳み込みニューラルネットワークチュートリアルをやってみる

Deep MNIST for Experts  |  TensorFlow

このページの「Build a Multilayer Convolutional Network」以下をやってみました

※mnistは「ゼロから作るDeepLearning本」の方で取得したデータを利用するように変えてあります

気になった所をいくつか抜粋

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def main(_):
    ...
    W_conv1 = weight_variable([5, 5, 1, 32])

フィルターのtensorの順序がゼロから作る本と違う。
内部的には正しい計算をしているはずなのでいいとして、TensorFlowのConvolutionの順序は縦、横、チャネル(色)、アウトプットチャネルです。

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

stridesに渡す配列の0と3番目の要素は必ず1とし、中の二つの値(同じにする)がstrideとなる。
この場合はstrideが1。
paddingは2種類「SAME」と「VALID」を指定出来てSAMEの場合は入力と出力のサイズが同じになるように自動でpaddingを調整してくれる。VALIDの場合は何もせず。
max_pool_2x2で定義されているstridesとpaddingも同じ。ksizeはpoolフィルタのサイズで2x2。

    W_fc1 = weight_variable([7*7*64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

2回のpoolフィルタで28x28x1→ 14x14x32→ 7x7x64までになったデータを一旦1024個のニューロンに出力してます(Affine変換で)
(2x2のフィルタをstride 2でフィルタしてるので元の半分になる)
今一何のためにやってるかわかりません。
データを圧縮するため?

   keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

過学習を防ぐためにいくつかのニューロンの伝搬を止めるdropout層というのが挿入されてます

    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

    y_ = tf.placeholder(tf.float32, [None, 10])
    cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

最後は数字のクラス分けをするために10の値で出力しています(Affine変換)

ちなみにこれでmnistを学習すると

step 11000, training accuracy 1
step 11100, training accuracy 1
step 11200, training accuracy 1
step 11300, training accuracy 0.99
step 11400, training accuracy 1
step 11500, training accuracy 1
step 11600, training accuracy 1
step 11700, training accuracy 1
step 11800, training accuracy 1
step 11900, training accuracy 1
step 12000, training accuracy 1
step 12100, training accuracy 0.99
step 12200, training accuracy 1

こんな感じで0.99を超えました。


試したコード
experiment2.py · GitHub

TensorFlowを使ってみる 3

実際自分で書いた数字で試してみる

前回書いたサンプルコードを使い、実際にmacのお絵描きソフトで書いた以下の数字を認識するかやってみました。
mnistで試してるだけだとなんだか本当に合ってんだかよくわからないですからね。


f:id:sodex:20170214171049p:plain f:id:sodex:20170214171058p:plain f:id:sodex:20170214171104p:plain


gist.github.com

結果は

0.9746
[1 5 7]

となり、こんな汚い数字でも無事認識していました。

数字の取り込みはPILを使いgrayscaleで読み込み(convert("L"))、numpyでmatrixにし、flattenで1次元配列にしたあと反転(255で引く)と正規化(255で割る)を実施しています。