ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

初めてのre:Invent4日目 (Keynoteとre:Play)

日本に帰ってこんにちは。

時差ボケなのか体力消耗なのか日本に戻って爆睡してしまってた、
ユニファのインフラ見てますすずきです。

今遅ればせながらre:Invent4日目のブログ書いてます。

最終日(re:Invent自体はもう一日ありますが私は最後…)もサクッと認定者ラウンジで朝ごはん食べつつ、
最終日はちゃんと会場でKeynote見ようと会場へ向かいました。

続きを読む

サクッとできるCSSアニメーション(transition)の使い方

Webデザイナーのmorita(こ)です。今回はCSSのアニメーションについて、ちょこっと書かせていただきました。

ボタン(hover me)

↑こんな感じのよくあるhoverアクションを1行で実現します。

 transition: .◯s;

◯の部分は数字でOK。
.4sとかにすると、0.4秒で実行されるアニメーション、
1sとかであれば、1秒で実行されるアニメーションとなります。

※ここ重要!テストに出ます。
【CSS transitionでアニメーションさせるためのポイント】

・対になるプロパティのbefore/afterを用意すること

上記の例だと、

.btn-sample{
  opacity: 1;
  transition: .4s;
}
.btn-sample:hover{
  opacity: 0.3;
}

変化させているプロパティは「opacity(透明度)」なので、beforeは「opacity: 1;(透明度100%)」、afterは「opacity: 0.3;(透明度30%)」です。このあいだの変化を「transition: .4s;(0.4秒)」かけてアニメーションさせています。

例ではCSSでのhoverアクションでしたが、JSなどでの状態変化(clickとかscroll)にもclassを作成して対応できます。(サンプルでは1回しかできません。。)

ボタン(click me)

.move-sample{
  position: relative;
  left: 0;
  transition: .4s;
}
.move-sample.is-anime{
  left: 60%;
}

clickすると、「is-anime」というclassをつけるようにJS書いてもらって、アニメーションのbefore/afterはCSSで制御する感じです。エンジニアとデザイナーが協業で行う時に重宝するやり方です。(JSはトリガーとして、CSSは表現として実装)

transitionの欠点は

・「display: none;」されているとできない。
・ループとできない。

ということです。 上の問題はよくスマホのハンバーガーメニューとかで遭遇しますね。その場合は画面の外に配置したりして、表示する時に画面内に移動してくるとかの対応をしたりしています。 どうしてもこの問題に対応するなら、CSS animationを使うことになります。(その場合、「サクッと」にならないのでググりましょう。)

【他にも色々できちゃったりするよ】
今回はもっとも短く最小のtransitionアニメーションでしたが、他にも様々な設定を指定することが可能です。
transition-property 変化させるプロパティを指定(all,opacity,top/leftなど)
transition-duration 変化させる時間(省略不可、.4sとか秒数を指定)
transition-delay 変化の開始を遅らせる
transition-timing-function イージング(デフォルトはease)

【ブラウザ対応】
IE10以上で実装されているので、ベンダープレフィックスとかもなしでいけるでしょう。

【CSSでアニメーションできる喜び】
少し前まではアニメーションさせるといえば、「JS(jQuery)で」みたいな感じもありましたが、昨今のデザイナーとエンジニアの協業体制を考えると、JSはエンジニア領域、CSSでデザイナー領域として、細部のアニメーションまでを表現(デザイン)できるのが望ましいと感じています。

酔っぱらいの千鳥歩きを参考にしたランダムウォーク メトロポリス・ヘイスティングス法(MH法)を試してみた

はじめに


こんにちわ、研究開発部の島田です。今回はMCMC法の一種である、ランダムウォーク メトロポリス・ヘイスティングス法(MH法)についてのお話です。

これまた小難しそうな名前ですが、実はMCMC法の中では最もシンプルなアルゴリズムとして有名です。今回はこちらを理解した上で実装を行い結果を見てみたいと思います。

おさらい


MH法を理解するにはまずは前回記事の内容が大事になってくるためおさらいをします。

tech.unifa-e.com

前回記事では、マルコフ連鎖について保育士さんの行動モデルを例にして理解しました。 特にある状態が確率的に変化することを遷移核と呼び、マルコフ連鎖を扱うにあたっては非常に重要な概念であることがわかりました。そして、前回記事では遷移核があらかじめわかっている状態でマルコフ連鎖を使いました。しかし、現実問題は遷移核がわからないケースがほとんどであるため、遷移核をどのように設定すればよいのかという問題を解決する必要があります。

遷移核を設定する際に、考えるべきことの一つとしてどのような条件を満たせば定常分布へ収束するのかです。これを詳細つり合いと言い、詳細つり合いを満たすと確率分布が定常分布になります。

そしてこの詳細つり合いをを満たす遷移核は簡単にはわからないため、代わりに条件つき確率分布と乱数によるサンプリング手法を使って、詳細つり合いになるように補正をかけてあげる、これがMH法の考え方になります。乱数によるサンプリング手法については、下記記事を参考にするとイメージがわきやすいです。

tech.unifa-e.com

ランダムウォーク メトロポリス・ヘイスティングス法(ランダムウォークMH法)


前項でも説明した通りMH法の考え方として、詳細つり合いをを満たす遷移核は簡単にはわからないため、サンプリングが簡単な遷移核(提案分布)で代用します。そして詳細つり合いを満たすように提案分布をあとで補正をかけます。

さて、ここで気になるのが、提案分布はどのように決めるのか?ということですね。

よく使われるのがランダムウォークという考え方で、数学や物理学の世界で頻繁に登場します。ランダムウォークという面白い名前なのですが、由来となっているのはなんと酔っ払いの千鳥歩きだそうです。これからの忘年会シーズンでよく目にする酔っ払いがフラフラ歩いている姿、そうあれです。そしてランダムウォークを使ったMH法のことを、ランダムウォークMH法と呼びます。

f:id:unifa_tech:20191203132307p:plain:w300

では、酔っ払いの千鳥歩き(ランダムウォーク)を数学的に表現してみます。まずは一番シンプルな一次元のランダムウォークは下図のように表せます。最初に豚の酔っ払いさんがいる地点から左に行くのか右に行くのかは確率的な問題です。

f:id:unifa_tech:20191206095259p:plain
(豚さんのイラスト 出典: かわいいフリー素材集 いらすとや

新しい地点θnewは下記のように表せます。

θnew = θ + ε Normal(0, 1)

ここで、εはランダムウォークが動く幅を表すパラメータです。Normal(0, 1)は0〜1の正規分布を仮定しています。

さて、ランダムウォークについて理解したところでいよいよランダムMH法の中身について理解していきます。

まずはMH法の一般的な考え方についてですが、先に詳細つり合いを形式化します。

f(θ'|θ)f(θ) = f(θ|θ')f(θ')

左辺については、例えばある確率θが発生します(実際には事後分布)。そうすると、確率θθ'に移ります(遷移核)。右辺は今度はあるθ'が発生して、θ'θに移ることを示しています。詳細つり合いを満たすということはすなわちこれらの確率の流れが等しくなることになります。

MH法では、サンプリングが簡単な提案分布q(θ'|θ)で代用しますが、このとき詳細つり合いは厳密には満たされないために、

q(θ'|θ)f(θ) > q(θ|θ')f(θ')

というような式で表せます。

そこで、詳細つり合いを満たすように補正係数γを導入します。

γq(θ'|θ)f(θ) = q(θ|θ')f(θ')

これをγについて解くと下のようになります。

γ=\dfrac{q(θ|θ')f(θ')}{q(θ'|θ)f(θ))}

すなわち、このγという補正係数を導入することで詳細つり合いを満たすような遷移が実現できることになります。

ここで、ランダムウォークの概念を取り入れると、q(θ'|θ)q(θ|θ')は等しくなるはずです。なぜならば上の一次元ランダムウォーク図を見るとわかる通り、豚さんが右に移動する確率と移動された地点から元の場所に移動する確率も等しいはずですよね。そのため、補正係数γは下記のようにシンプルに表せます。

γ=\dfrac{f(θ')}{f(θ)}

少し説明が長くなりましたが、実際にこのアルゴリズムを実装してみます。

ランダムウォークMH法の実行


今回もベータ分布で確認してみます。まずはベータ分布の確認です。

np.random.seed()
a, b = 1.8, 2.9
x = np.linspace(beta.ppf(0.001, a, b), beta.ppf(0.999, a, b), 100)
plt.plot(x, beta.pdf(x, a, b))
f:id:unifa_tech:20191203134222p:plain:w500

次にランダムウォークMH法のコアな部分ですが、流れとしては下のフローのようになります。

  1. 初期値θを決定する(適当で良い)

  2. ランダムウォークを使って次の新しいθ’を探索

  3. 次の条件式の判定。f(θ) > f(θ')

  4. Step3の条件式が、

 ・真の場合、現在位置の方が次の位置よりも確率分布の高い位置であると言えるため、γで補正する。区間[0, 1]の一様乱数を生成し、γと比べて小さい場合は受理、それ以外の場合は棄却する。

 ・偽の場合、補正せずに新しい乱数を受理する。

これを実装して、結果を確かめてみます。

def rw_MH():
    NUM_MC_STEP = 30000#モンテカルロステップ数
    theta = 0.6#ランダムウォークの初期値
    E = 0.5#ランダムウォークの幅
    theta_mc_step = [theta]
    
    for i in range(NUM_MC_STEP):
        re_theta = theta + E * np.random.randn()
        if beta.pdf(theta, a, b) > beta.pdf(re_theta, a, b):
            gamma = beta.pdf(re_theta, a, b) / beta.pdf(theta, a, b)
            if np.random.rand() < gamma:
                theta = re_theta
        else:
            theta = re_theta
        theta_mc_step.append(theta)
    
    return theta_mc_step
f:id:unifa_tech:20191203135203p:plain:w500

オレンジ色の曲線が元のベータ分布ですが、ランダムMH法によるサンプリングも同じような曲線が得られていることがわかります。

最後に


今回はMCMC法の最もシンプルなランダムウォークMH法を理解し、実装・結果を見てみました。遷移核があらかじめわかっていないケースにおいてもサンプリングが可能になりました。他にもギブスサンプラーやハメルトニアンモンテカルロ法といった様々なMCMC法があるので、是非今後も試してみたいと思います。

参考文献


・RとStanではじめるベイズ統計モデリングによるデータ分析入門(講談社)

基礎からのベイズ統計学 輪読会資料 第4章 メトロポリス・ヘイスティングス法

物体間の関係性の認識

こんにちはR&Dチームの宮崎です。ユニファアドベントカレンダーの7日目となります。どうぞよろしくお願いします。

はじめに

DeepLearningの発展に伴い、画像分類や物体検出はかなりの精度で行えるようになってきました。 そこで、近年は画像からより高レベルな情報を抽出しようと、画像の要約を生成するImage Captioningや検出した物体間の関係性を認識するVisual Relationship Detectionなどの手法が提案されています。

今回は、このVisual Relationship Detectionの手法の一つであるBAR-CNN (Box Attention Relational CNN)[1]を試してみましたので、ご紹介したいと思います。

なお、Image Captioningについては下記にて紹介されておりますので、是非そちらも参照ください。

tech.unifa-e.com

Visual Relationship Detectionについて

Visual Relationship Detectionとは、検出した物体を<主語 - 述語 - 目的語>の3要素で表すことを目的としたタスクになります。ここで主語と目的語には検出した物体が入り、述語には2つの物体の関係性を表す言葉が入ります。 例えば下記の画像のように人物がバイクに乗った画像を入力としたとき、物体の座標とともに主語: person、述語: on、目的語: mortorcycleとしてラベルを出力することが目的となります。

f:id:unifa_tech:20191125135407p:plain
Visual Relationshipの例 (引用元: [2])

これによって、画像から物体の位置や種類だけでなく、物体間の関連性まで認識できるようになります。 ちなみに、このVisual Relationship DetectionのタスクはKaggleのコンペになったりもしています。

www.kaggle.com

続きを読む

Making a 3D Snowman with Zdog

By Robin Dickson, software engineer at UniFa.

Because it's almost Christmas I thought I'd try out something new and make it Christmassy.

Zdog is a round, flat, designer-friendly pseudo-3D engine for canvas & SVG and some of the work being made with it is really inspiring. I wanted to see what I could make quickly as a non-designer with no experience in 3D.

A snowman is built from various parts so I thought it seemed like a good fit. Also I may have heard a song about building a snowman somewhere...

f:id:unifa_tech:20191203153610p:plain

I used the Zdog documentation, tutorial and examples on the official Zdog website which is a fantastic source of information.

Setup

To use Zdog all you need is HTML, CSS and JavaScript. The HTML and CSS setup is very minimal.

<canvas class="zdog-canvas" width="400" height="400"></canvas>
.zdog-canvas {
  background: skyblue;
  cursor: move;
}

Making a Basic Snowman

The snowman is built using an Illustration object as the foundation for the illustration.

const illo = new Zdog.Illustration({
  element: '.zdog-canvas',
  zoom: 4,
  dragRotate: true
});

The first thing needed for a snowman is a body, which luckily is quicker in Zdog than real life. A sphere can be created using Shape and controlling the size with the stroke property.

let body = new Zdog.Shape({
  addTo: illo,
  stroke: 40,
  translate: { y: 5 },
  color: 'white'
});

The head shares properties with the body, and in Zdog items can be copied. So the body can be copied, and then certain properties overwritten.

let head = body.copy({
  stroke: 25, // make the head smaller than the body
  translate: { y: -25 }, // move it higher
})

Now we have the basic snowman!

f:id:unifa_tech:20191206145410p:plain

To make the face, the eyes and mouth are both made from coal so they can be copied.

Adding Details

let leftEye = new Zdog.Shape({
  addTo: head,
  stroke: 3,
  translate: { x: -4, y: -4, z: 10 },
  color: 'black',
  backface: false,
});
let rightEye = leftEye.copy({
  translate: { x: 4, y: -4, z: 10 }
})

Loops like forEach can be used to make the code more concise.

let mouth = new Zdog.Shape({
  addTo: head,
  stroke: 2,
  translate: { x: 0, y: 6, z: 10 },
  color: 'black',
  backface: false,
});

[[-6, 3, 9], [-4, 5, 10], [4, 5, 10], [6, 3, 9]].forEach(coal => mouth.copy(
  { translate: { x: coal[0], y: coal[1], z: coal[2] } }
))

Next a carrot for the nose which can be a cone shape.

let nose = new Zdog.Cone({
  addTo: head,
  diameter: 5,
  length: 9,
  translate: { x: 0, y: 0, z: 10 },
  stroke: false,
  color: 'orange'
});

Coal buttons were added in the same way as the eyes and mouth.

f:id:unifa_tech:20191206145415p:plain

The arms were the most difficult part so far. The base branch was created using a Shape item. Then copied for the smaller branches.

let arm = new Zdog.Shape({
  addTo: body,
  color: 'brown',
  stroke: 2,
  path: [ { x: 0, y: 0 }, { x: 12, y: -10 } ],
  translate: { x: 18, y: -8 },
});
let finger = arm.copy({
  addTo: arm,
  path: [ { x: 0, y: 0 }, { x: 3, y: -7 } ],
  translate: { x: 5, y: -5 },
  stroke: 1.5
});
finger.copy({
  path: [ { x: 0, y: 0 }, { x: 7, y: 0 } ],
  translate: { x: 3, y: -2 } 
})

For the other arm the copyGraph function can be used to copy the arm item and the attached items. So all that is needed is to move it into place an rotate it.

arm.copyGraph({
  translate: { x: -18, y: -8 },
  rotate: { y: Zdog.TAU/2 }
})

A scarf was added and the snowman is complete!

Animation

It's also possible to add animations to Zdog creations so I added a little inspired by the many demos on the official website.

let isSpinning = true;
let direction = 'right'
function animate() {
  if (illo.rotate.y < -1) { direction = 'left' }
  if (illo.rotate.y > 1) { direction = 'right' }
  if (isSpinning && direction === 'right') {
    illo.rotate.y += -0.005;
  } else if (isSpinning && direction === 'left') {
    illo.rotate.y -= -0.005;
  }
  illo.updateRenderGraph();
  requestAnimationFrame( animate );
}

animate();

f:id:unifa_tech:20191206151752g:plain

(This is a gif, and the created SVG looks much better!)

Overall it was easy to get started due to the great documentation and examples and I am looking forward to trying to make more complex designs.

初めてのre:Invent3日目 (Hands-OnとJam)

ラスベガスからこんにちは。 異国の地で眠気と戦ってるユニファのインフラ見ているすずきです。 書くのが遅れに遅れて周回遅れ中ですが頑張ってブログ書きます。

3日目ともなるとホテルの中も覚えてきて迷わなくなりますね。
もう怖いものはない(嘘です英語怖い

さて3日目もイベントとしてはKeynoteからスタートですが、 内容がパートナー向けのイベントのため私は見ないで別のことしていました。

Hands-on Labs

AWS re:InventはAWSのサービスの説明、企業の事例の話などいろんなセッションはありますが、
それ以外にもAWSの資格試験を受けれる会場や、DeepRacerという機械学習で走らせる車の大会(日本からはDNPさんなどが参加されてます)が開かれているなど様々なイベントがあります。

そんな中で3日目最初はHands-On Labs会場に行って来ました。
その会場では、AWSのオンライン学習を体験できるようになっています。(AWSだけではなく他のクラウドサービスなどの学習もありました。

※ 学習に利用するサービス Qwiklabs - Hands-On Cloud Training

会場入場の際に学習チケットをもらい、有料の学習サービスはそのチケットを使うことで受けられるようになっています。

以下のような感じで学習していきます。 f:id:mominosin:20191204081455j:plain

学習開始すると、専用のAWS環境がデプロイされ接続できるようになります。
試しに無料の1つと有料の1つを体験しました。 追加でに有料の学習をもう1つやろうとするとチケットが使えませんでした、引き続きやりたい場合は再入場になるのだと思います。

Hands-Onをやってみて、できることはしってるけどやったことないことなどを、一通り学べてよかったです。
調べながらやるほうが身につきやすいかとは思うのですが、決まった手順にそって学ぶとさくっと頭に情報がいれられて楽ですね(不要な学習が減る 暇なときはHands-On受けに来くると良さそうです。

Jam Lounge

AWS re:Inventのイベントの中で、先程挙げなかったものにハッカソンと、なにか問題が起きている又は起こる環境を直していくものがあります(Game Day、Security Jam) とても面白そうですが、英語でチーム戦ということでとてもハードルが高いので遠慮していました。

しかし Jam Loungeという場所がEXPO会場(いろんな企業が出店してるところ)にあり、Security Jamの内容とは異なるそうですが同じようなことが1人でも体験できるようなのでやってきました。

ちなみにこれは、AWSが用意した環境にセキュリティ的に問題があるので、シナリオに沿って直していきましょうというものです。

難易度もいろいろ用意してあるし、ヒントもあるので初心者の方でも問題なく体験できるのではないかなと思います。

私は時間の都合上2問くらいしかできませんでした(全部で15問前後

セッション

セッションはSageMakerの新しいサービスのWorkshopを受けてきました。

GitHub - aws-samples/reinvent2019-aim362-sagemaker-debugger-model-monitor

これは実際の問題なので興味がある方はLab1,Lab2と進めていただけたらと思います。 私が受けたのは昨日アップデートのあった、SageMaker Debuggerとmonitorでした。

とりあえず受けて、手順通り動作は確認できましたが、今回のアプデ前の状況を理解してないので、 嬉しいものなのかどうなのかがよくわかっていません…

予めSageMakerの入門的なWorkshopを受けておいたほうが良かったなと今になって思います。

AWS資格認定者イベント

AWSの資格を持っていれば参加できるイベントがあったので参加してみました。

会場は洒落たボウリング場です。 f:id:mominosin:20191204192346j:plainf:id:mominosin:20191204192443j:plainf:id:mominosin:20191204192249j:plain

ビュッフェスタイルで飲み食べ放題で、後で知ったのでですが神戸牛のハンバーガーとかもあったらしい…!!

終始日本の方と固まって喋ってましたが、今までの期間で一度もあったことなかった人ばかりで、過去に仕事でお世話になっていた会社さんもいたのでその件で盛り上がることができました。

3日目も最後は盛り上がって終わりました。
残すところ後1日ですが、もうゆっくりしましょう体力が…

すずき

初めてのre:Invent2日目 (DeepComposerとったどー)

ラスベガスからこんにちは。 異国の地でなんとか生き残りながらユニファのインフラ見ているすずきです。

毎夜毎夜交流会で睡眠時間が足りてませんが、今日も頑張ってブログです。
去年のre:Inventの報告会イベントでどなたかがre:Inventに一番必要なものは体力と言っていたのが身にしみています…

2日目はみんなお待ちかねAndy JassyのKeynoteからのスタートですね。

続きを読む