My Note Pad

エンジニアリングや日々の雑感を書いていきます

ゼロから作るDeep Learningの学習環境をDockerで作った

会社で「ゼロから作るDeep Learning」を使ってDeep Learningを学ぶ勉強会をしようということになったので、環境を作ってみた。

使用する書籍はこちら↓

www.oreilly.co.jp

なぜDockerなのか

  • Pythonや各ライブラリのバージョン差異によるメンバー間の挙動の違いが発生しないようにしたい。
  • そもそも環境の構築が面倒なのでサクッと作れるようにしたい。

といった感じ。

というわけで、Docker for Macを使って学習環境を作った。

環境・バージョンなど

Mac

  • OS X ElCapitan (10.11.6)
  • Docker for Mac 1.12.5 (最新で大丈夫な気がする)

Docker

  • Python 3.5.2 :: Anaconda 4.2.0 (64-bit)
  • Jupyter 4.2.0

Docker for Macのインストール

まだインストールしていなければこちらからDocker for Macをダウンロードしてインストールする。
詰まるところは無いと思うのでインストール方法は省略。

docs.docker.com

公式のGit HubをForkしてClone

こちらがオライリーが公式に公開している、「ゼロから作るDeep Learning」用のGitHubリポジトリ
色々コードを触りたいので、自分のGitHubアカウントにForkして、Cloneする。

github.com

今回は/Users/{USER_NAME}/github/deep-learning-from-scratchにcloneした。

$ cd ~
$ mkdir github
$ cd github
$ git clone https://github.com/{GITHUB_ACCOUNT}/deep-learning-from-scratch.git

Jupyter notebookを使うことになるので、.gitignoreに以下の行を追加しておくといい。

.ipynb_checkpoints/ 

Docker Imageの作成

※Docker for Macは起動させておく。

Docker Imageはこちらのannaconda用イメージを利用した。

docker-images/anaconda3 at master · ContinuumIO/docker-images · GitHub

# docker imageをpullする
$ docker pull continuumio/anaconda3

# docker imageを作成(ざっくり以下の設定を行っている)
# cloneしておいたGitHub用のリポジトリを、/opt/notebooks/deep-learning-from-scratchにマッピング
# 8888番ポートをフォワード
$ docker run -i -t -v /Users/{USER_NAME}/github/deep-learning-from-scratch:/opt/notebooks/deep-learning-from-scratch -p 8888:8888 continuumio/anaconda3 /bin/bash

docker runするとプロンプトがdocker内に移動するので、以下のコマンドでJupyter notebookをインストールする。

# /opt/notebooksをJupyterのルートディレクトリにし、8888番ポートを利用する
$ /opt/conda/bin/conda install jupyter -y --quiet && /opt/conda/bin/jupyter notebook --notebook-dir=/opt/notebooks --ip='*' --port=8888 --no-browser

Jupyterが起動するので一度Ctrl + Cで終了し、exitで抜けておく。

以上でDockerの環境ができた。

Docker環境完成後

2回目以降は以下の手順でDocker Imageを立ち上げることができる。

# dockerのプロセスを探す
$ docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                    PORTS               NAMES
a5f0b5dbc6db        continuumio/anaconda3   "/usr/bin/tini -- /bi"   12 hours ago        Exited (0) 10 hours ago                       serene_curran

# ↑で探したコンテナID(今回の場合:a5f0b5dbc6db)を指定してdockerを起動する
$ docker start -i a5f0b5dbc6db

dockerのプロンプトに移動するのでJupyterを起動する

$ /opt/conda/bin/jupyter notebook --notebook-dir=/opt/notebooks --ip='*' --port=8888 --no-browser

Jupyter起動中は、ブラウザでhttp://localhost:8888/にアクセスすることでJupyterを使う事ができる。

f:id:yuki10k:20170111015925p:plain

また、Mac側の指定したディレクトリとシンクされているので、deep-learning-from-scratchというディレクトリが既に存在する。
deep-learning-from-scratch以下には各チャプターごとの参考コードが載っているし、notebookを作成し、notebookから該当のコードを呼び出すことができる。
呼び出し方は書籍内に出て来るのでそちらを参照。

f:id:yuki10k:20170111020041p:plain

Mac側とディレクトリを共有しているので、当然finderで中身を見ることもできるし、ブラウザ上のJupyter notebookで編集したnotebookを、自分のGitHubリポジトリにpushすることもできる。

これで色々捗りそうなので、Deep Learningについても学んでいきたい。

【iOS】Table Viewを使ってみる

前回の続き。

yuki10.hatenablog.com

今回はTable Viewを表示する所をやってみる。
予め2ページ目の中央に配置していたLabelは削除しておく。

story boardでObject LibraryからTable Viewを探してページに置く。

f:id:yuki10k:20170110005546j:plain

続けてTable View Cellを探し、先程配置したTable Viewの上に置く。

f:id:yuki10k:20170110005600j:plain

ここで2ページ目を表示するためのView Controllerを作成する。
プロジェクトツリーで右クリック -> New File..を選択。
以下の画面でCocoa Touch Classを選択する。

f:id:yuki10k:20170110005610p:plain

クラス名にSecondPageViewControllerと入力し、
Subclass of にはUIViewControllerを選択する。
※Table Viewだけのページであれば、UITableViewControllerでも良さそう。

f:id:yuki10k:20170110005618p:plain

Storty Boardに戻り、2ページ目のView ControllerのAttribute Inspectorの設定で、classに先程作成したSecondPageViewControllerを指定する。

f:id:yuki10k:20170110005631j:plain

Assistant Editor(∞みたいなアイコン)を開くと、左側にStory Board 右側にSecondPageViewControllerが表示される。
※表示されなければ表示されるように調整する。

この状態で、Table ViewからCtrlキーを押しながらSecondPageViewControllerのクラス定義の直下にドラッグする。
↓画像のようなダイアログが出るので、tableViewという名前で設定する。

f:id:yuki10k:20170110005642j:plain

そうすると、@IBOutletでStory BoardのUITableViewとSecondPageViewControllerのUITableViewがtableViewという変数名で接続され、以下のようにコードが挿入される。

f:id:yuki10k:20170110005654p:plain

その後、クラス定義部分にUITableViewDelegateUITableViewDataSourceを追加して以下のように書き換える。

class SecondPageViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

Story Boardに戻って、tableViewConnection Inspectorを開く。

f:id:yuki10k:20170110005701j:plain

dataSourcedelegateからSecondPageViewControllerに向かってドラッグする。

f:id:yuki10k:20170110005733j:plain

そうすると、dataSourcedelegateSecondPageViewControllerに接続される。

f:id:yuki10k:20170110005742p:plain

ここでdataSourcedelegateを実装していないのでコンパイルエラーが出るけど、先にCellの定義を追加する。
新たにCocoa Touch Class作成画面を開く。
クラス名にSecondPageTableViewCellを指定し、
Subclass of: にUITableViewCellを指定する。

f:id:yuki10k:20170110005800p:plain

Story BoardでTableViewCellのIdentity Inspectorを開き、classにSecondPageTableViewCellを指定する。
ついでにCellで画面表示したい項目をLabelで配置しておく。
画像の例だと、Labelでidnameを配置している。

f:id:yuki10k:20170110005803j:plain

同様にAttributes Inspectorを開き、IdentifierにSecondPageCellを指定する。
※この項目は後ほどコード上でCellを取得するために使われる。

f:id:yuki10k:20170110005817j:plain

Assistant Editorで左にStory Board 右にSecondPageTableViewCellを開いて、
Story BoardのCellからid項目とname項目をCtrlキーを押しながらドラッグして、SecondPageTableViewCellに接続する。

f:id:yuki10k:20170110005808j:plain

更に、データセット用のメソッドを定義する。

    func setUserData(id: String!, name: String!) {
        self.id.text = id
        self.name.text = name
    }

最終的には以下のようなクラスになっている。

import UIKit

class SecondPageTableViewCell: UITableViewCell {

    @IBOutlet weak var id: UILabel!
    @IBOutlet weak var name: UILabel!
    
    func setUserData(id: String!, name: String!) {
        self.id.text = id
        self.name.text = name
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

SecondPageViewControllerに戻って、TableViewの実装を行う。

まずはtableViewが何行あるかを表示するための以下のメソッドを実装する。
今回は練習なので単純に5をreturnする。

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

さらに、対象行のCellを取得するためのメソッドを定義する。
withIdentifierに設定する項目は、Attributes InspectorでIdentifierに設定した値に合わせる必要がある。
今回の場合は、SecondPageCellになる。
また、型はSecondPageTableViewCellを指定する。
最後にsetUserDataでCellにセットする項目を入れる。
※今回の場合、現在の行のindexというidと"hoge"という名前がセットされる。

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SecondPageCell", for: indexPath) as! SecondPageTableViewCell
        cell.setUserData(id: String(indexPath.row), name: "hoge")
        return cell
    }

この状態でビルドして実行すると、以下の画面のようにTable Viewを表示することができた。

f:id:yuki10k:20170110005822p:plain

ここまで進めてきて徐々に難しくなってきた反面、楽しくなってきたので引き続きiOSアプリ開発方法を学んでいきたい。
Swiftのコード実装も増えてくるといい感じ。

【iOS】NavigationBarで前の画面に戻れるようにする

前回の続き。

yuki10.hatenablog.com

今回は画面遷移した後、元のページに戻るという部分をやってみた。
今回もソースコードの変更はなし。

まずは右下のObject LibraryからNavigation Barを探して、遷移後の画面に配置する。

f:id:yuki10k:20170109172552j:plain

続いて同様にBar Button Itemを探して、先程追加したNavigation Barの左側に配置する。

f:id:yuki10k:20170109172602j:plain

↑で配置したTitle、Itemと表示されている部分をダブルクリックすると表示名を変更できるようになるので、適当な名前に変更しておく。
今回の場合だと、

  • Title -> 2nd Page
  • Item -> Back

にそれぞれ変更した。

f:id:yuki10k:20170109172609j:plain

続いてBar Button Itemを選択した状態で、Ctrlキーを押しながら1画面目のView Controllerにドロップする。

f:id:yuki10k:20170109172617j:plain

Segueのアクションをどうするか聞かれるので、Showを選択。

f:id:yuki10k:20170109172628p:plain

そうすると、↓図のように2ページ目から1ページ目へのSegueが表示されるようになる。

f:id:yuki10k:20170109172641p:plain

この状態でシミュレータを起動すると、

  • 1ページ目のNextボタン -> 2ページ目
  • 2ページ目のBackボタン -> 1ページ目

に遷移できるようになった。

f:id:yuki10k:20170109172651p:plain

今回もコードはいじっていないので次はコードを触っていきたい。

次のMacはディスク256GBにしよう

愛用しているMacBook Pro Early 2015のディスク容量が心許なくなってきた。
early 2015の中でも一番安いモデルなので、構成は↓こんな感じ。

f:id:yuki10k:20170109021336p:plain

ディスクは載ってないけど、128GBのモデル。

以前、以下で書いたように一度 TranscendのJetDriveを購入してSDカードとして増設している。

yuki10.hatenablog.com

f:id:yuki10k:20170109020610p:plain

おかげで+64GBされているが本体側のディスク容量が既に半分以下になってしまった。
自分はあまり容量を使わないし、と油断していたらこんな結果になっていた。
容量が半分を切ると、精神衛生上あまり良くないなと感じるようになってきました。

JetDriveをもっと使えばいいと思うかもしれないけど、やっぱりいくつか不満もあって、最近では本体のSSDばかり使ってしまう。
気になっているのは以下の点。

  • 本体のSDDの方が高速
  • SDカードが刺さっているとスリープ状態でもバッテリーを消費してしまう
  • Finder上で別のデバイスとして認識されるので、少しだけ面倒

最初は気にしないようにしていたものの、長く使っていくとやっぱり気になってくるもので、、
次は少しディスクに余裕を持たせようと思うようになった。

購入するのはもう少し先になりそうだけど、Appleの商品ページを見ていたら最新のラップトップでディスクが128GBってもうMacBook Airしかなかった。
次もきっとMacBook Proを買うと思うので杞憂に終わった。

Late2016は色んな意味で話題になっているし、USB-TypeC対応の周辺機器がまだまだ出揃っていないので、自分の買い時は 2017年か2018年モデルかなという感じ。
(それまでディスクが持てば・・)

とりあえずその時までにお金を貯めよう・・!

【iOS】単純な画面遷移をやってみる

練習用にプロジェクトは作ったので、まずは単純な画面遷移をしてみる。

yuki10.hatenablog.com

今回はstoryboardで完結するのでコードの変更はなし

単純な画面遷移

まずはXcodeMain.storyboardファイルを開く。
画面右下から遷移先用画面となるView Controllerを選択して、1画面目の右にドロップする。

f:id:yuki10k:20170105015333j:plain

画面が2枚に増えるので、画面右下の検索ウィンドウでbuttonと入力。
出てきたbuttonを、1画面目の真ん中あたりにドロップする。

f:id:yuki10k:20170105015340j:plain

ボタンの表示やサイズは適当に設定する。

f:id:yuki10k:20170105015354p:plain

ボタンを選択した状態で、ctrlキーを押したまま、2画面目にドロップする。
Segueの接続先を選べるので、今回はShowを選択する。

f:id:yuki10k:20170105015408j:plain

1画面目と2画面目を接続するラインができた。(これがsegue..?)
2画面目が分かるように、適当にlabelを配置する。

f:id:yuki10k:20170105015420p:plain

この状態で保存して、実行してみる。
1画面目でNextボタンが表示され、ボタンを押すと

f:id:yuki10k:20170105015430p:plain

2画面目に遷移してmoved!と表示された。

f:id:yuki10k:20170105015438p:plain

今回は単純な画面遷移しかしていないものの、1行もコードを書くことなく画面遷移ができたのはなかなか新鮮。
次はもう少し複雑な画面遷移をやってみる。

CocoaPodsでRealmの設定をする

以前Laravelの学習用に環境を用意したものの、実際に業務で扱うのが先に伸びたので、正月休みにiOS開発の学習を始めた。

iOSアプリを開発する上で、パッケージマネージャとして有名 & よく使われているものが
CocoaPodsっぽかったのでCocoaPodsのインストールと、試しにRealm用のプロジェクトを作ってみた。

CocoaPods.org

※Swift3からは公式にSwift Package Managerが登場したらしいが、まだ主流はCocoaPodsっぽいのと、iOSなどにはまだ対応していないようなので今回は見送った。

Note that at this time the Package Manager has no support for iOS, watchOS, or tvOS platforms.

github.com

バージョン情報など

Xcode 8.2.1
Swift 最新版(3.x)
CocoaPods 1.1.1
Realm Swift 最新版

CocoaPodsのインストール

公式ページにある通り、gemでインストール。

$ sudo gem install cocoapods
・・・
$ pod --version
1.1.1

Realm Swift用のプロジェクトを作成

公式のドキュメントを参考に、進めていく。

realm.io

CocoaPodsのSpecリポジトリを更新する

※CocoaPodsインストール直後などの場合はいらない

$ pod repo update

Xcodeで新規iOSプロジェクトを作成する

目的がなければとりあえずSingleViewApplicationNext

f:id:yuki10k:20170103233017p:plain

プロジェクト設定はとりあえず適当に設定

Product NameRealmSample
Organization Nameデフォルトで設定されているもの
Organization Identifierデフォルトで設定されているもの
LanguageSwift
DevicesiPhone
Use Core Data未チェック
Include Unit Tests好みで
Include UI Tests好みで

f:id:yuki10k:20170103233032p:plain

podの設定

上で作成したXcodeプロジェクトは一度閉じておく。
作成したプロジェクトのディレクトリに移動してpod initPodfileを作成する。

$ cd ~/swift/RealmSample/
$ pod init

続いてPodfileを設定する。
以下の通り、対象のターゲットにpod 'RealmSwift'を追記し、ファイルの末尾にSwiftのバージョンを指定するように設定。

https://realm.io/jp/docs/swift/latest/

@@ -6,10 +6,12 @@ target 'RealmSample' do
   use_frameworks!

   # Pods for RealmSample
+  pod 'RealmSwift'

   target 'RealmSampleTests' do
     inherit! :search_paths
     # Pods for testing
+    pod 'RealmSwift'
   end

   target 'RealmSampleUITests' do
@@ -18,3 +20,11 @@ target 'RealmSample' do
   end

 end
+
+post_install do |installer|
+  installer.pods_project.targets.each do |target|
+    target.build_configurations.each do |config|
+      config.build_settings['SWIFT_VERSION'] = '3.0'
+    end
+  end
+end

その後、pod installを実行する。

$ pod install

実行が完了すると(多少警告は出るものの).xcworkspaceファイルが作成される

xcworkspaceファイルを開く

生成された.xcworkspaceファイルを開いてXcodeを起動する

f:id:yuki10k:20170104002417p:plain

プロジェクトのGeneral -> Linked Frameworks and Libraries+ボタンを選択

f:id:yuki10k:20170104002424p:plain

Realm.frameworkRealmSwift.frameworkを選択してAdd

f:id:yuki10k:20170104002513p:plain

一度 Cmd + Bでビルドすると、RealmSwiftが認識されてimportできるようになる

f:id:yuki10k:20170104002538p:plain

これで準備完了

VagrantでLaravelの開発環境を作った

先日、職場で「来年からPHP(Laravel)やってもらうかも」と言われたので、
少し勉強をしようと思い、まずは環境を作ってみた。

PHPといえば最近7系にメジャーバージョンアップして、色々変化があったようです。
とはいえ、ドットインストールで少しPHPをやってみた事があるくらいで、全然PHPは書けない
(やばい・・)

laravel.jp

最近はLaravel人気が高まっているらしい。

とりあえず、VagrantかDockerで環境構築できたら楽だなと思い、公式ページを見ていると、Homesteadを使うと楽にできそうだったので、試してみることにした。

Laravel Homestead - Laravel - The PHP Framework For Web Artisans

以下のソフトウェアが含まれたVagrantのBoxで簡単に環境が作れるものらしい。

手順にそってインストールしていく。

Vagrant / Virtual Boxのインストール(アップデート)

※Virtual Boxが5.1系じゃないと駄目らしく、5.0.30 + Extensionで試した所、vagrant起動時にssh key関連で止まってしまい、原因が分からなくてかなりハマった。

Before launching your Homestead environment, you must install VirtualBox 5.1, VMWare, or Parallels as well as Vagrant. All of these software packages provide easy-to-use visual installers for all popular operating systems.

vagrantのboxを追加

% vagrant box add laravel/homestead

providerを聞かれたので、2(virtualbox)を選択

==> box: Loading metadata for box 'laravel/homestead'
    box: URL: https://atlas.hashicorp.com/laravel/homestead
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) parallels
2) virtualbox
3) vmware_desktop


Enter your choice: 2
==> box: Adding box 'laravel/homestead' (v1.0.1) for provider: virtualbox
    box: Downloading: https://atlas.hashicorp.com/laravel/boxes/homestead/versions/1.0.1/providers/virtualbox.box
==> box: Successfully added box 'laravel/homestead' (v1.0.1) for 'virtualbox'!

光回線で15分くらいかかった。
※ダウンロード中に以降の手順を先に進めてしまってもok

Homesteadをホームディレクトリにclone

% cd ~
% git clone https://github.com/laravel/homestead.git Homestead

Homesteadのイニシャライズ

% cd Homestead/
% bash init.sh
Homestead initialized!

イニシャライズすると、~/.homestead/Homestead.yamlに設定ファイルが生成される

ファイルを開いて以下の点を確認した。

  • provider: virtualbox になっている
  • nfsを有効にする
    • ↓のようにtype: "nfs"を追記
provider: virtualbox

folders:
    - map: ~/Code
      to: /home/vagrant/Code
      type: "nfs"

また、vagrantのファイル共有のディレクトリが~/Codeになっているので、
それ用のディレクトリを作っておく

※ここは任意のディレクトリをfolders:のmapに指定してもok

% cd ~
% mkdir Code/

hostsの設定

/etc/hostsに以下の一行を追加する。

192.168.10.10  homestead.app

vagrantの起動

ここまで設定が終わったら、vagrantを起動する

% cd ~/Homestead/
% vagrant up

起動時のメッセージ色々

% $ vagrant status
Current machine states:

homestead-7               running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

Laravelのインストール

まずはvagrantssh

% vagrant ssh

※ここからはvagrant内での作業

laravelのインストール
※既に入っているよと言われたのでスキップして良さそう。

$ composer global require "laravel/installer"
Changed current directory to /home/vagrant/.composer
Using version ^1.3 for laravel/installer
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files

プロジェクトの作成

今回はblogというプロジェクトを作成した。

$ cd Code/
$ mkdir -p ./Laravel/public
$ cd Laravel/public/
$ laravel new blog

この状態でchromeで以下のURLを開くと

http://homestead.app/blog/public/

Laravelのページが表示された!
※自分は必要なかったが動かなければblogディレクトリの直下でphp artisan serveを実行してみる。

f:id:yuki10k:20161225193601p:plain

実際にはURLが微妙なので、~/Code直下でlaravel new blogを実行し、
~/.homestead/Homestead.yamlsitesの設定を以下のように変えてあげると
http://homestead.app/でアクセスできるはずなのでその方が良さそう。

sites:
    - map: homestead.app
      to: /home/vagrant/Code/blog/public

その他

vagrant/home/vagrant/Code/ディレクトリとホスト(mac)の/Users/${user name}/Codeディレクトリはnfsでマウントされているので、ホスト側でコードを編集すれば、すぐに反映される。

<?php
  echo "hogehoge!";
?>

f:id:yuki10k:20161225194542p:plain

なので、PhpStormやAtomなどでもそのまま開発ができそう。

環境作りで色々ハマって疲れたのでLaravelの学習はまた今度・・・