resize2fs /dev/xvda1: Nothing to do!

EBSがオンラインで拡張、タイプ変更、IOPSの変更ができるようになりました。 – サーバーワークスエンジニアブログ
のニュースを見てから、ディスク拡張の機会に恵まれなかったのですがついに今日その日がやってきました。
(AWSは高いので個人では使ってない)

日本語化されてない「Modify Volume」メニューからさっくりと実行。
あとはOSでコマンド叩くだけでしょ…

$ sudo resize2fs /dev/xvda1 
resize2fs 1.42.12 (29-Aug-2014)
The filesystem is already 7863803 (4k) blocks long.  Nothing to do!

…!?

$ lsblk
xvda    202:0    0  50G  0 disk 
└─xvda1 202:1    0  30G  0 part /

Linux パーティションを拡張する - Amazon Elastic Compute Cloudをやる必要がある!?それなら結局今まで通りの手順の方が楽なのでは…とか思っていたら、

Modify VolumeでAmazon Linuxのルートボリュームサイズを変更しても変わらないときの対処方法 | Developers.IOの通りgrowpartすれば解決でした。

めでたしめでたし。

PyCall-MNISTのリファクタリング(レイヤークラスを使用)

勉強用に作っている https://pycall-mnist.herokuapp.com をリファクタリングした。

O'Reilly Japan - ゼロから作るDeep Learning の第4章をベースにした素朴な実装だったが、第5章を参考にレイヤークラスで処理するようにした。

predictに(勝手に)用意していたskip_activate_outputフラグは不要になった。
必要な時にlastLayerを呼び出す形に。
※ 推論の時は生データ(スコア)でいいのでlastLayerは不要。

まずはSigmoidのまま実装して、rspecが通ることを確認。
その後、ReLUに切り替えた。

Sigmoid

train acc, test acc | 0.9468333333333333%, 0.9452%

ReLU

train acc, test acc | 0.9791166666666666%, 0.9713%

ReLUにしただけで認識精度が3%も上がった…!

PyCallのバージョンも上がっていたので合わせてアップデート。特に問題なし。

ソース

Layers by tnantoka · Pull Request #1 · tnantoka/pycall-mnist

参考

Python DeepLearningに再挑戦 15 誤差逆伝播法 Affine/Softmaxレイヤの実装 - Djangoroidの奮闘記

MNISTのデータを使った手書き数字認識をRubyで

O'Reilly Japan - ゼロから作るDeep Learning、1度読んだだけでまだ理解できてない部分もあるが、とても良い本。
手書き数字認識ぐらいなら自分でも余裕でできるんじゃね?と思わせてくれる。

読書メモ

殴り書き。

  1. [読書メモ] ゼロから作るDeep Learning: まえがき - blog.tnantoka.com
  2. [読書メモ] ゼロから作るDeep Learning: 第1章 - blog.tnantoka.com
  3. [読書メモ] ゼロから作るDeep Learning: 第2章 - blog.tnantoka.com
  4. [読書メモ] ゼロから作るDeep Learning: 第3章 - blog.tnantoka.com
  5. [読書メモ] ゼロから作るDeep Learning: 第4章 - blog.tnantoka.com
  6. [読書メモ] ゼロから作るDeep Learning: 第5章 - blog.tnantoka.com
  7. [読書メモ] ゼロから作るDeep Learning: 第6章 - blog.tnantoka.com
  8. [読書メモ] ゼロから作るDeep Learning: 第7章 - blog.tnantoka.com
  9. [読書メモ] ゼロから作るDeep Learning: 第8章 - blog.tnantoka.com

ニューラルネットワークとDeep Learning

ここまでの理解。

たとえば、16ピクセルの1と2という画像内の数字を認識したい場合。(2クラス分類問題)
3層ニューラルネットワークを使うとする。

  • 入力層(第0層)は16×16で256個。
  • 隠れ層(第1層)は100個、隠れ層(第2層)は50個とか任意で。
  • 出力層(第3層)は1か2かなので2個。
  • 各ニューロン間の信号には重みが。
  • それぞれの層にはバイアスも。
  • 各ニューロンでは活性化関数で入力を変換。

訓練データをもとに、バイアスや重みの調整をひたすら繰り返して、いい感じになるものを探す。
テストデータでも良い精度が出ればOK(汎化)。出なければ過学習。過学習ってとても人間っぽい。

これのもっと層を深くしたものがDeep Learning。

結構泥臭い。コンピュータの性能向上によって実用できるようになった、というのはそういうことだったのか。

Rubyでやってみる

写経はいまいちテンションがあがらない。今Pythonを学習したいわけではないのである。

ちょうど Ruby + PyCallで機械学習をやってみた at Pydata Okinawa #23 - The paradigm shift という記事が。
PyCallの話題を以前耳にした時は直近機械学習をやる予定ではなかったのでスルーしてしまったが、今の僕にとっては大変ありがたい存在である。

というわけでやってみた。(関係ない話題も入ってますが)

  1. PyCallでNumPyを使う - blog.tnantoka.com
  2. PyCallでMatplotlibを使う - blog.tnantoka.com
  3. PycallとNumPyで3層ニューラルネットワーク - blog.tnantoka.com
  4. PyCallをDockerで - blog.tnantoka.com
  5. HerokuでPyCall(NumPy)とSinatraを動かす - blog.tnantoka.com
  6. RubyでMNISTのデータを読む - blog.tnantoka.com
  7. PyCallでMNISTを使った推論 - blog.tnantoka.com
  8. PyCallでMNISTの学習 - blog.tnantoka.com
  9. ゼロから作るDeep Learning: 第4章のgradientをRuby化 - blog.tnantoka.com
  10. PyCallでMNISTの実データを使った学習・推論 - blog.tnantoka.com
  11. PyCallで手書き数字認識のWebアプリ - blog.tnantoka.com
  12. PyCall-MNISTのリファクタリング(レイヤークラスを使用) - blog.tnantoka.com

Rubyで書くことでただの写経より内容を理解せねば感があってよかった。

[papreclip] Content Type Spoof

このブログを別サーバーに移したら画像がアップロードできなくなった。

I, [2017-04-20T20:43:11.577928 #18952]  INFO -- : [paperclip] Content Type Spoof: Filename Screen_Shot_2017-04-20_at_20.32.44.png (["image/png"]), content type discovered from file command: . See documentation to allow this combination.

ファイルコマンドの結果が返ってきてない?

sudo yum install file

で解消。

MastodonをAWSにDockerで立てたメモ

https://github.com/tootsuite/mastodon

Mastodonのインスタンスを立ててみた - めも.net
基本はこれを参考に。

t2.mediumで20GB、セキュリティグループは80と443を開けた。

変えたのは、

  • Gitのcloneはsshじゃなくhttpsでやった
  • SECRETはそれぞれ別にした(READMEにDo this once for each of those keysって書いてあったので)

Dockerが実行できない?

$ docker-compose run --rm web rake secret
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

$ docker version
Client:
 Version:      17.04.0-ce
 API version:  1.28
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:07:42 2017
 OS/Arch:      linux/amd64
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.28/version: dial unix /var/run/docker.sock: connect: permission denied

service docker restartしても駄目で、SSHログインし直したら行けた。

S3

↓のようなインラインポリシーを持ったユーザーを作成

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt12345",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::バケット名",
                "arn:aws:s3:::バケット名/*"
            ]
        }
    ]
}

設定はSSLで運用しているmastodonとS3の連携のハマりどころ - Qiitaを参考に。

SES

SMTP_SERVER=email-smtp.us-east-1.amazonaws.com
SMTP_PORT=587
SMTP_LOGIN=****
SMTP_PASSWORD=****
SMTP_FROM_ADDRESS=notifications@ドメイン

LOGINPASSWORDCreate My SMTP Credentialsから作ったもの。(API経由で送るんじゃないのでSMTP専用のが必要)

PostgreSQL、Redisの永続化

docker-compose.ymlをアンコメント。

参考:今何かと話題のマストドン(mastodon)鯖を自分用に無料で立てる方法 - jtwp470’s blog

永続化設定の前にupしちゃうと…

$ docker-compose up -d 
Recreating mastodon_db_1
Recreating mastodon_redis_1
WARNING: Service "redis" is using volume "/data" from the previous container. Host mapping "/path/to/mastodon/redis" has no effect. Remove the existing containers (with `docker-compose rm redis`) to use the host volume mapping.
WARNING: Service "db" is using volume "/var/lib/postgresql/data" from the previous container. Host mapping "/path/to/mastodon/postgres" has no effect. Remove the existing containers (with `docker-compose rm db`) to use the host volume mapping.
Creating mastodon_web_1
Creating mastodon_sidekiq_1
Creating mastodon_streaming_1
$ docker-compose stop redis
$ docker-compose rm redis
$ docker-compose stop db
$ docker-compose rm db

データ作成する前だったので普通にやりなおした。

リダイレクト先が見つかりませんでした

リモートフォローができず。

ログを見ると、webfingerが404。
https://github.com/tootsuite/mastodon/blob/aa9079838648e9656a1bf8d10151713686e1c0dd/app/lib/webfinger_resource.rb#L64
ここでfalseになってそう。
LOCAL_DOMAINのタイポに気づく…。

デバッグ

とりあえず、

  • ログレベル買える
  • -dせずにup

すれば行けた。

証明書の自動更新とかやらないとな。

Let's Encrypt

地味に初めましてだった。

# 初回の取得
# この時点ではnginxがデフォルトの場所で起動してたのでいけた。
$ ./letsencrypt-auto certonly --webroot -w /var/www/html/ -d ドメイン

# 更新
# もはや/var/www/htmlでは動いてないのでこける
$ ./letsencrypt-auto renew --force-renewal --dry-run 

# コレなら行けた
$ /path/to/letsencrypt/certbot-auto certonly --webroot -w /path/to/mastodon/public -d ドメイン --renew-by-default --dry-run && service nginx reload

# その後はコレも通るようになった
$ ./letsencrypt-auto renew --force-renewal --dry-run 
0 0 1 * * /path/to/letsencrypt/certbot-auto certonly --webroot -w /path/to/mastodon/public -d ドメイン --renew-by-default && service nginx reload

ひとまずこれでCronに設定。