CircleCIのmasterが動かないときの対処方法

CircleCIGitHubを連携していたら…

突然、masterブランチのときだけCIが動かなくなりました(´・ω・`)
errorとか表示されるのではなく、反応がない感じです。

さらに、他のブランチは普通に動きます。なぜかmasterだけ動きません。

config.ymlがおかしいのかな?と思い、見てもどこもおかしい所はなく…

そもそもconfig.ymlがおかしかったら、他のブランチでエラーがでる…


??????????????????


謎い…


で、ここに解決方法が!!
https://discuss.circleci.com/t/troubleshooting-when-circle-doesnt-build-after-pushes-to-github/12414/4

ここの一番下に書いてある方法でやるとうまくいけました(`・ω・´)

1
2
3
4
5
6
1. Remove all CircleCI webhooks and services from your GitHub repo settings.
(GitHubのリポジトリの設定のwebhooksのCircleCIを消してください。)
2. Unfollow the project on CircleCI through “Project settings”.
(CircleCIの「Project settings」より、プロジェクトをアンフォローしてください。)
3. Re-follow the project on CircleCI.
(再度、フォローし直してください。)


なぜかmasterだけ動かないという現象に出会ったら、一度試してみてください(`・ω・´)

このエントリーをはてなブックマークに追加

About Turi Create

Turi Createって何?

https://github.com/apple/turicreate

Appleが先日公開した機械学習のライブラリです。
READMEをみると…

1
2
You don't have to be a machine learning expert to add recommendations,
object detection, image classification, image similarity or activity classification to your app.

機械学習のエキスパートでなくても、リコメンドシステムなどが作れる…ほう(・ω・)
僕は、エキスパートではないので、僕でも本当に作れるか試してみます(`・ω・´)

ということで、この2つを作ってみます!

  • Recommender systems(リコメンド)
  • Image classification(画像分類)

導入

まずはじめにTuri Createをインストールします。
以下のようにすると、入れることができます。
※Python 2.7, 3.5, 3.6推奨

1
pip install -U turicreate

映画のリコメンド

最初は、映画のリコメンドシステムです(`・ω・´)
ユーザーさんが見た映画の履歴を元に、
次、この映画を見たほうがいいよと教えてくれるリコメンドシステムを作ります。

訓練データ

訓練データには、こちらのCSV形式(190MB)のデータを使います。
https://grouplens.org/datasets/movielens/

data

CSVのデータの中身は、こんな感じです。

data

CSVの読み込み

先ほどのCSVデータを読み込みます。

1
2
3
import turicreate as tc
data = tc.SFrame.read_csv('data.csv')
data.explore()

読み込みますと、こんな感じに表示されます。
ちなみに、この表示機能はTuri Createに標準でついている機能です。

read-csv

SFrameって何?

先ほどのコードにSFrameという見慣れないものがあると思います。

https://github.com/turi-code/SFrame

こちらは、データ分析用に作られたスケーラブルなデータ構造らしいです。
また、SQLのフィルタ, ソート, ジョインなどのようなことができます!

学習

先ほどのデータを使って、学習させます。

1
2
3
4
training_data, validation_data
= tc.recommender.util.random_split_by_user(data, 'userId', 'movieId')
model
= tc.recommender.create(training_data, 'userId', 'movieId')

結果は、こんな感じになり、無事に学習ができました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Recsys training: model = item_similarity
Warning: Ignoring columns rating, timestamp;
To use one of these as a target column, set target = <column_name>
and use a method that allows the use of a target.
Preparing data set.
Data has 80004 observations with 671 users and 8393 items.
Data prepared in: 0.06855s
Training model from provided data.
Gathering per-item and per-user statistics.
+--------------------------------+------------+
| Elapsed Time (Item Statistics) | % Complete |
+--------------------------------+------------+
| 14.361ms | 100 |
+--------------------------------+------------+
Setting up lookup tables.
Processing data in one pass using dense lookup tables.
+-------------------------------------+------------------+-----------------+
| Elapsed Time (Constructing Lookups) | Total % Complete | Items Processed |
+-------------------------------------+------------------+-----------------+
| 228.774ms | 0 | 0 |
| 547.001ms | 100 | 8393 |
+-------------------------------------+------------------+-----------------+
Finalizing lookup tables.
Generating candidate set for working with new users.
Finished training in 1.56964s

検証

先ほどの学習したものの検証を行います。

1
2
3
res = model.evaluate(validation_data)
pro = res['precision_recall_overall']
pro.print_rows(18,3)

結果は、こんな感じです(`・ω・´)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+--------+-----------------+------------------+
| cutoff | precision | recall |
+--------+-----------------+------------------+
| 1 | 0.0746268656716 | 0.00222957408534 |
| 2 | 0.0910447761194 | 0.00849339445401 |
| 3 | 0.0980099502488 | 0.0140232349614 |
| 4 | 0.10223880597 | 0.0197251532314 |
| 5 | 0.102985074627 | 0.024713370957 |
| 6 | 0.113432835821 | 0.0343338830723 |
| 7 | 0.119829424307 | 0.0423068785092 |
| 8 | 0.122388059701 | 0.0506102259718 |
| 9 | 0.122885572139 | 0.0571544479215 |
| 10 | 0.122388059701 | 0.0629408159497 |
| 11 | 0.121031207598 | 0.0676575352222 |
| 16 | 0.120335820896 | 0.0941542231187 |
| 21 | 0.122885572139 | 0.126040641884 |
| 26 | 0.127095292767 | 0.160259557501 |
| 31 | 0.128069330766 | 0.190365739974 |
| 36 | 0.128855721393 | 0.218778795533 |
| 41 | 0.128940662541 | 0.256367765626 |
| 46 | 0.131440622972 | 0.297542272455 |
+--------+-----------------+------------------+

testing

モデルの保存

学習と検証が終わったので、モデルを保存します。

1
model.save('recommend.model')

リコメンドさせてみる

先ほど作ったモデルを使いリコメンドさせてみます!
はじめに、先ほどのモデルを読み込みます。

1
model = tc.load_model('recommend.model')

そして、ユーザーID「3」の人が映画ID「1」を見たという感じでやっていきます。
(ユーザーID「15」, 「128」も同様)

1
2
3
4
5
data = tc.SFrame({
'userId': [3,15,128],
'movieId': [1,6,111]
})
print(data.join(movie, on='movieId'))
1
2
3
4
5
6
7
+---------+--------+--------------------+-------------------------------+
| movieId | userId | title | genres |
+---------+--------+--------------------+-------------------------------+
| 1 | 3 | Toy Story (1995) | Adventure|Animation|Childr... |
| 6 | 15 | Heat (1995) | Action|Crime|Thriller |
| 111 | 128 | Taxi Driver (1976) | Crime|Drama|Thriller |
+---------+--------+--------------------+-------------------------------+

では、リコメンドさせます(`・ω・´)

1
2
res = model.recommend([3, 15, 128], new_observation_data=data)
print(res.join(movie, on='movieId').sort('rank'))

結果

1
2
3
4
5
6
7
8
9
10
11
12
13
+--------+---------+-----------------+------+-------------------------------+-------------------------------+
| userId | movieId | score | rank | title | genres |
+--------+---------+-----------------+------+-------------------------------+-------------------------------+
| 3 | 2571 | 0.140675894239 | 1 | Matrix, The (1999) | Action|Sci-Fi|Thriller |
| 3 | 4993 | 0.128428682685 | 2 | Lord of the Rings: The Fel... | Adventure|Fantasy |
| 3 | 4963 | 0.120257125659 | 3 | Ocean's Eleven (2001) | Crime|Thriller |
| 15 | 1580 | 0.0189388030345 | 1 | Men in Black (a.k.a. MIB) ... | Action|Comedy|Sci-Fi |
| 15 | 103042 | 0.0183990796982 | 2 | Man of Steel (2013) | Action|Adventure|Fantasy|S... |
| 15 | 1923 | 0.0179402843312 | 3 | There's Something About Ma... | Comedy|Romance |
| 128 | 2797 | 0.0362989620521 | 1 | Big (1988) | Comedy|Drama|Fantasy|Romance |
| 128 | 1517 | 0.0334305414787 | 2 | Austin Powers: Internation... | Action|Adventure|Comedy |
| 128 | 1097 | 0.0305381224706 | 3 | E.T. the Extra-Terrestrial... | Children|Drama|Sci-Fi |
+--------+---------+-----------------+------+-------------------------------+-------------------------------+
  • ユーザーID「3」の人は、「Matrix」がおすすめされました。
  • ユーザーID「15」の人は、「Men in Black」がおすすめされました。
  • ユーザーID「128」の人は、「Big」がおすすめされました。

それっぽいものができたぞ(`・ω・´)

画像分類

次は、犬の画像分類を作ってみます(`・ω・´)
Core MLにエクスポートしてiPhoneのカメラで犬の写真を写して、
その犬の犬種を表示するというアプリを作ります。

訓練データ

こちらのデータを使いました。
http://vision.stanford.edu/aditya86/ImageNetDogs/

dog-data

モデルの読み込み

先ほどの犬の画像を読み込みます。
今回は「Border_terrier」,「cairn」,「Shih-Tzu」の3種類を判定するようにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import turicreate as tc
def path2label(path):
if "Border_terrier" in path:
return "Border_terrier"
elif "cairn" in path:
return "cairn"
elif "Shih-Tzu" in path:
return "Shih-Tzu"
else:
return "unknown"
def gen_sframe():
data = tc.image_analysis.load_images('/dog', with_path=True)
data['label'] = data['path'].apply(path2label)
data.save('train.sframe')
data.explore()
gen_sframe()

読み込みますと、こんな感じに表示されます。

dog-data-view

学習

では、読み込んだデータをもとに学習させます!

1
2
3
4
5
6
7
8
9
10
11
12
import turicreate as tc
data = tc.SFrame('train.sframe')
train_data, test_data = data.random_split(0.8)
model = tc.image_classifier.create(train_data, target='label', max_iterations=100)
metrics = model.evaluate(test_data)
print(metrics['accuracy'])
model.save('dogs.model')
model.export_coreml('dogs.mlmodel')

結果は、こんな感じになりました!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 一部省略
--------------------------------------------------------
Number of examples : 557
Number of classes : 4
Number of feature columns : 1
Number of unpacked features : 2048
Number of coefficients : 6147
Starting L-BFGS
--------------------------------------------------------
+-----------+----------+-----------+--------------+-------------------+---------------------+
| Iteration | Passes | Step size | Elapsed Time | Training-accuracy | Validation-accuracy |
+-----------+----------+-----------+--------------+-------------------+---------------------+
| 1 | 4 | 0.000898 | 1.107175 | 0.786355 | 0.960000 |
| 2 | 7 | 0.500000 | 1.213239 | 0.885099 | 0.840000 |
| 3 | 8 | 0.500000 | 1.269205 | 0.919210 | 1.000000 |
| 4 | 9 | 0.500000 | 1.332011 | 0.951526 | 1.000000 |
| 5 | 10 | 0.500000 | 1.391532 | 0.971275 | 1.000000 |
| 6 | 11 | 0.500000 | 1.458173 | 0.978456 | 1.000000 |
| 11 | 16 | 0.500000 | 1.741182 | 0.996409 | 1.000000 |
| 25 | 30 | 0.500000 | 2.535394 | 1.000000 | 1.000000 |
+-----------+----------+-----------+--------------+-------------------+---------------------+
SUCCESS: Optimal solution found.

補足

先ほどのコードでは転移学習を使います。
なので、最初に転移学習用のデータのダウンロードに時間がかかります。

Core MLにエクスポート

学習が完了したので、Core MLに書き出します!

1
model.export_coreml('recommend.mlmodel')

coreml

Xcodeに入れる

書き出したモデルをXcodeにいれます。

xcode

結果

で、こんな感じになりました!

dog

それっぽいものができたぞ(`・ω・´)
が…訓練データが少ないのか反応がイマイチ…

まとめ

  • 数行〜数10行で作ることができる。(とっつきやすい)
  • これから機械学習を始める人には良いかも。
  • 本番でも耐えれるかは未検証なので、不安は残る。
  • 今後に期待(`・ω・´)

コードはGitHubで公開しています!

https://github.com/gupuru/turi-create-playground

ありがとうございました(`・ω・´)


複数人で書いたお話

技術系同人誌 Advent Calendarの10日目の記事です(`・ω・´)

はじめに

技術書典3で、以下の4つの本を書きました。

ちなみに…技術書典2のときに出した本はこちらです。

※参加ブログは、こちら に書いているので、お暇ならぜひ(`・ω・´)

上記の本は、こちらの7名で書きました!
社会人やニートや大学生などなどちょっと変わった人たちです(笑)

さて、ここからが本題です!
7名という複数人で書きました。
どういうツールを使って7名分のドキュメントを管理したのか、スケジュール管理はどうしたのか、などなど…
複数人で、どんな感じに本を書いていったかを中心に書きます!

GitHubとRe:VIEWを使って書き書き

Re:VIEW

基本的には、Re:VIEWを使い本文を書いていきました。

一部、vscode-markdown-pdf とPagesを使用しました。

なぜ、全部Re:VIEWに統一せず、Pagesなどを使ったかというと「md2review」を使ったからです。

md2reviewを使うと、Markdownで書いたものがRe:VIEW形式に変換できます。
Re:VIEWの書き方を覚える時間がない人にとっては、とても良いツールです!
ただ、Markdownのほうで少しスペースが入ったりしていると、変換がうまくいかないことがありました。
エラーの原因を探すのが大変で、どうしてもうまくいかないところは、上記のPagesなどを使いPDFに出力しました。
そして、macのプレビューのPDFを結合できる機能を使い、1冊にまとめました。

この辺は、Re:VIEWで統一して書くとしたほうが、良かったなと思いました(`・ω・´)

GitHub

各自、書いたものはプルリクエストを出していく形にしました。
プルリクエストでは、簡単に誤字脱字がないかを確認するようにしました。
一応、CIなどをまわして自動でPDFに出力するようにしましたが…あんまり使いませんでした(笑)
ちなみに、CIは、werckerを使いました。

githubのプルリクエスト

誤字脱字などのチェックは、誤字脱字チェック会などを開き、集まれる人だけで2時間くらい集中して読みました。
誤字脱字だけではなく、「ここに画像があったほうが分かりやすいよ」などの感想も言いました。
話の内容はどちらかと言うと感想の方がメインになりました。
ここで出たものはissueを作り、書いた人に報告しました。

githubのissue

本のデザイン

こちらは、4名でそれぞれ分担してやりました。
Affinity DesignerAdobe Illustratorやペンタブなどを使いました。

スケジュール(ヽ´ω`)

7人いるので、スケジュールはこんな感じに作りました。

一次締切: 10/1(日) 17:00
誤字脱字のチェック締切: 10/8(日) 17:00
10/22: 当日

10/1に一旦出してもらい、そこから1週間くらいで誤字脱字などを洗い出し、修正するという形にしました。
え?締切守らなかったやつ?人権を剥奪しました!

デスマ

というのは冗談です(笑)

当日近くにバタバタしたくないなーと思い、できるだけ早めにできるようにスケジュールを組みました。
(結局…直前まで修正してましたが笑)

もくもく環境

定期的にカフェに集まって、複数人で書きました。
一人で書くと辛いので、何人かで集まって書くのはとても良かったです!

あと、slackで定期的に話してました!

slack

印刷

技術書典3で出したものは、ラクスルさんで印刷しました。
ちなみに、技術書典2で出した本はねこのしっぽさんで印刷しました。

まとめ

複数人で、どんな感じに本を書いていったかを簡単にですが書きましたが、いかがでしたでしょうか?
分かりにくかったら、ごめんなさい(´・ω・`)
何かの参考になれば、幸いです!

最後に…

本、書くの楽しいよ(`・ω・´)


LINEのWAVE、1週間くらい使ってみた(・ω・)

LINEのWAVEを1週間くらい使ったので、感想を書くんご\(^o^)/

8月25日に届いたというツイートしているので、だいたい1週間くらい。。。
https://twitter.com/gupuru/status/901069275506524160

line wave

(毎度思うけど、WAVEを写真に撮ると円柱にみえて、ダサい。。。)

感想

面白い製品だなと思いました!

今できることは、音楽再生したり、アラームかけたり、「じゃんけん」や「しりとり」ができるくらいですが。。。
今後が楽しみな製品と思いました!

まだ、先行発売ということなので、挙動が怪しい所もありますが。。。

どんな風に使っている?

基本的にはアラームくらいです(`・ω・´)

「クローバ、明日の8時にアラーム」みたいな感じです。
「クローバ、アラーム、ストップ」って言っても反応してくれないときがあって、ちょっとした二度寝防止になってます(笑)

音楽も、たまに再生してます(・ω・)
「リラックスできる音楽再生して」や「テンションがあがる曲を再生して」など、意外にいろいろ反応してくれます(・ω・)

ちょっと残念な所

これは人それぞれな所がありますが、少し大きいので場所をとります。。。

まとめ

WAVEを使ったサービスが作りたい!
APIやSDKを早く公開してくれいなかなー |ω・`)チラ


AzureのVideo Indexerを遊んでみたよ(・ω・)

video indexer

Video Indexerを軽く遊んでみました!

こちらは、AzureのCognitive Servicesのひとつです。

ちなみに。。。Cognitive Servicesは、Azureが提供しているAIを使ったAPIのサービスです。
写真をから人物を判定したり、言語を解析したり、様々なAPIが提供されています。

で、Video Indexerは、簡単にいうと、AIを使った動画解析です。

Video Indexerに動画をアップロードすると。。。

こんな感じに、キーワード抽出したり、喋っている人を特定してくれたり。。。

video indexer sample1

喋っている言葉をテキストに変換してくれたり。。。

video indexer sample2

その人が喋っているところに、飛べるような機能があったりと。。。なんか、いろいろあります(笑)

そして、今のところ、無料で使えるようです!

あと、APIもあるようです。

軽く試してみます(`・ω・´)

ログイン

video indexer login

こちら のページのGET STARTEDをおすと、ログインページがでてくるので、お好きなアカウントでログインします。

トップページ

video indexer top

ログイン完了すると、トップページにいきます。

Sample Videosを選択し、いろいろ動画が表示されるので、その動画を見ると、どんなサービスかが分かると思います(・ω・)

アップロード

video indexer upload

トップページにUploadというボタンがあると思うので、こちらを選択します。

ローカルの動画をアップロードするか、URLからアップロードします。
あ、ユーチューブのURLはダメでした(笑)

動画の情報入力

video indexer uploading

動画をアップロードしたあと、名前や言語などを入力します。
Privacyの「private」,「public」は、動画を公開するかどうかです。
とりあえず、privateで問題ないです。

ここの情報は、あとで変更できます。

解析中

video indexer analytics

アップロードが完了すると、自動で解析が始まります。
動画によって、解析の時間は変わってきますが、10分程度のものなら、5分〜10分ほどで終わりました(・ω・)

確認

video indexer complete

解析が終わったら、確認です!

まとめ(・ω・)

Video Indexerおもしろい(・ω・)


プロフィール

はじめまして(`・ω・´)

久しぶりに技術系のブログをやろうと思い、作ってみました(・ω・)

主に、最近でたばかりの技術の解説みたいなものとか、
何かやってみたなどを書いていく予定です(`・ω・´)

ブログ本体の方も、手を加えていく予定ですので、当分は、ちょこちょこデザインなどが変わると思います(・ω・)

SNS

このブログで使用しているもの

このブログは、Hexo を使用しています。
また、テーマにhexo-theme-apolloを使ってます。

お問い合わせ

何かありましたら、こちらにお願いします。

  • Twitter: @gupuru
  • email: info@gupuru.com