wgetでCannot write to 'filename' (Success). → mountしたらlost+found

Dropboxからファイルをダウンロード

dl=0ではなくdl=1にするとwgetで持ってこれるという知見を得た。

$ wget "https://www.dropbox.com/sh/hogehoge/fugafuga?dl=1" -O pose.zip
:
:

HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: 'video.zip'

video.zip                                                 [                                                         <=>                                                        ]   1.54G  16.9MB/s    in 97s     


Cannot write to 'video.zip' (Success).

…書き込めない? 試しにunzipしてみる。

$ unzip video.zip 
Archive:  video.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of pose.zip or
        video.zip.zip, and cannot find video.zip.ZIP, period.

出来ない。

原因と解決方法

どうやら容量がいっぱいで途中でDL出来なくなってるっぽい。 最近仮想HDDもらったからマウントしよ(もらった時にするの忘れてた)。

mountする

$ sudo mount /mnt /home/ubuntu/Code/
$ ls /home/ubuntu/Code/
lost+found

マウントの仕方間違えた。 取り敢えずアンマウントしてマウント先にmvする

$ sudo umount /home/ubuntu/Code/
$ sudo mv /home/ubuntu/Code/keras-deeplab-v3-plus /mnt
$ ls /mnt
keras-deeplab-v3-plus  lost+found

ほい。

lost+foundとは

破損したファイルの一部が入ります。
ファイルチェックを行いファイルシステムに不整合があると、修復が行われます。
その際破損したファイルがあれば、可能な限りファイルを救出し、 lost+foundフォルダーに入れます。
このフォルダーを直接いじることはありませんが、
破損したファイルを調べるためにフォルダー内にアクセスすることがあります。
このフォルダーは、ルートユーザーのみアクセス可能です。

引用:Ubuntu 12.04 フォルダー構造 その5 - /lost+found、/media、/mnt、/opt ー kledgeb

参考

エラーの原因は容量いっぱいだからだよーって書いてる

mountの基礎

ファイル復元について

lost+foundについて

scpコマンドでサーバのファイルをコピーする

scpの使い方

scp [オプション]転送元パス 転送先パス

尚、[転送元パス]と[転送先パス]は、ログイン名@ホスト名ってな感じで。

$ scp -rP 9999  /home/keras-deeplab-v3-plus username@12.34.56.789:/home/keras-deeplab-v3-plus
コマンド 内容
r 再帰的にコピー
P ポートを指定
q データの転送状況を非表示
C データの圧縮

ディレクトリを指定して大量のファイルをコピーする場合は、qオプションを指定した方が良かった…。
ログがずっと出力されていて速度に結構影響ある気がする。
あと、約2万枚の画像をコピーしたからCオプションでデータの圧縮をして転送したほうが良かったと後悔。

今後GPUを使っていく上で色々とお世話になりそうなコマンド。

グローバルIPやポート番号の確認方法は以下記事を参考。 saneeeatsu.hatenablog.com

参考

sshfsで「read: Connection reset by peer」

sshfsコマンドでマウント

【エラー】read: Connection reset by peer

# username確認
$ whoami

# IPアドレス確認
$ ip route get 8.8.8.8 | awk '{print $NF; exit}'

sshfsでマウントしようとする。

$ sshfs <username>@<IP address>:/home/ubuntu/Code/keras-deeplab-v3-plus /host/keras-deeplab-v3-plus
read: Connection reset by peer

エラー発生。

原因をさぐる

IPアドレスの確認

そもそも、今回はデフォルトのポートを使用していないので、-pで指定する必要があった。
そして、まずそもそもこのIPアドレス合ってるのか???
IPアドレスの確認方法は下に方に書いた。

$ ssh <username>@<IP address> -p 10022

全然返ってこないし合ってないっぽい。

どうやら上で確認したIPアドレスはローカルのもの。
ここではグローバルIPを使う必要があるっぽい。
グローバルIPの確認方法は下の方に書いた。

$ ssh <username>@<Global IP address> -p 10022                                                                                                                               
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.15.0-24-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

146 packages can be updated.
0 updates are security updates.

New release '18.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

*** System restart required ***
Last login: Thu Aug 23 16:42:40 2018 from 180.42.119.139

来た!

【エラー】Transport endpoint is not connected

他のサイトではsshを指定していないけど、-oオプションで秘密鍵を指定する必要がある。

$ sshfs <username>@<Global IP address>:/host/handpose-datagenerator /home/ubuntu/Code/handpose-datagenerator -o IdentityFile=/home/ubuntu/.ssh/id_rsa -p 10022
fuse: bad mount point `/home/ubuntu/Code/handpose-datagenerator': Transport endpoint is not connected

またエラー\(^o^)/

【解決】一度アンマウントする

どうやらさっきマウントしたさいにファイルは入っていないけど、「/home/ubuntu/Code/handpose-datagenerator」にマウントしたことになっているっぽいので、
一度下記コマンドでアンマウントを行う。

$ fusermount -uz handpose-datagenerator

もう一度sshfsを行い無事マウント完了!

Global IPアドレス、ポートの確認方法

ついでにGlobal IPアドレスの確認方法とかもメモっておく。

Global IP

$ curl ifconfig.io
123.123.123.123

sshfsのときはIPを「hogehoge.jp」的な感じで指定したけど、curlコマンドで出てきたIPと紐付いているのか確認する。

$ traceroute google.com
traceroute to hogehoge.jp (123.123.123.123), 64 hops max, 52 byte packets
:
:

一致してることが確認出来た。

ポート番号

Netstatで調べることが出来る。

Timer列で自分のローカルIPで(確認方法はip route get 8.8.8.8 | awk '{print $NF; exit}')、尚且「keepalive」のとこを見てみると
ローカルIPの横にIPアドレスの「10022」があることがわかる。

$ netstat -ano
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       Timer
: 
: 
tcp        0      0 192.168.10.190:10022    18.222.249.67:59212     ESTABLISHED keepalive (5545.94/0/0)
tcp        0      0 127.0.0.1:36072         127.0.0.1:58327         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:58386         127.0.0.1:37723         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:53061         127.0.0.1:60166         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:52537         127.0.0.1:34392         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:41441         127.0.0.1:37988         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:59698    104.244.42.2:443        ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:33733         127.0.0.1:59838         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:48892         127.0.0.1:37987         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:10022    192.168.10.100:49975    ESTABLISHED keepalive (1706.49/0/0)
tcp        0      0 127.0.0.1:50056         127.0.0.1:57345         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:37946         127.0.0.1:57753         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:47838         127.0.0.1:54867         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:43009         127.0.0.1:51510         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:43524    199.59.148.138:443      ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:58327         127.0.0.1:36072         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:55399         127.0.0.1:38644         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:36856         127.0.0.1:54609         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:51455         127.0.0.1:56636         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:47953         127.0.0.1:57976         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:47167         127.0.0.1:32966         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:33922         127.0.0.1:60727         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:54364         127.0.0.1:47697         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:51109         127.0.0.1:41766         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:44250         127.0.0.1:37723         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:49218         127.0.0.1:36829         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:56636         127.0.0.1:51455         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:39713         127.0.0.1:58926         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:53319         127.0.0.1:53940         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:48417         127.0.0.1:51016         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:33895         127.0.0.1:49986         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:32854         127.0.0.1:43655         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:49144    195.149.177.1:5938      ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:40178         127.0.0.1:58801         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:51109         127.0.0.1:41760         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:37348         127.0.0.1:59235         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:40286         127.0.0.1:46323         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:58507         127.0.0.1:40436         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:32942         127.0.0.1:40959         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:58507         127.0.0.1:53724         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:54502         127.0.0.1:43649         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:43987         127.0.0.1:34058         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:37723         127.0.0.1:44250         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:57753         127.0.0.1:37940         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:60727         127.0.0.1:33922         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:57753         127.0.0.1:37946         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:51455         127.0.0.1:56632         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:58801         127.0.0.1:57006         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:59235         127.0.0.1:37348         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:34994    104.244.42.66:443       ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:34058         127.0.0.1:43987         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:60539         127.0.0.1:42398         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:40959         127.0.0.1:32942         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:59834         127.0.0.1:33733         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:40436         127.0.0.1:58507         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:41766         127.0.0.1:51109         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:60166         127.0.0.1:53061         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:60727         127.0.0.1:34074         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:51016         127.0.0.1:48417         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:49986         127.0.0.1:33895         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:43655         127.0.0.1:32854         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:10022    192.168.10.20:36986     ESTABLISHED keepalive (2726.86/0/0)
tcp        0      0 127.0.0.1:34392         127.0.0.1:52537         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:57976         127.0.0.1:47953         ESTABLISHED off (0.00/0/0)
tcp        0      0 127.0.0.1:54609         127.0.0.1:36856         ESTABLISHED off (0.00/0/0)
tcp        0      0 192.168.10.190:50708    104.244.42.130:443      ESTABLISHED off (0.00/0/0)
tcp6       0      0 :::10022                :::*                    LISTEN      off (0.00/0/0)
: 
: 

.ssh/configを用いる

下のサイトのようにconfigで管理する方法も。 qiita.com

参考

ローカルIP確認

アンマウント

sshfsの使い方。-oオプションを用いた秘密鍵の指定方法。

Globel IP

ポート番号

SSHについてもっとよくわかる

複数公開鍵はauthorized_keysにまとめてパーミッションも変える!

keras-deeplab-v3-plusで人だけとってみる

github.com

Semantic Segmentationで人をとってきたいのでこのアーキテクチャを使って人と背景を分ける。

準備

# 仮想環境の準備
$ conda create -n keras-deeplab-v3-plus
$ source activate keras-deeplab-v3-plus

# モジュールインストール
$ conda install tqdm
$ conda install numpy
$ conda install keras

# 重みダウンロード
$ python extract_weights.py 
$ python load_weights.py 

Jupyterを使って画像を出力

ここからは自分用にカスタマイズしていく。 多クラス分類だが、人だけとれれば良い。

デフォルトで入っているimage1.jpgを使う。

import model
import cv2

img = cv2.imread('./imgs/image1.jpg')
img = cv2.resize(img, (512, 512)) # imgは0〜255の値をとる

model_dlv3 = model.Deeplabv3()

predicted = model_dlv3.predict(img[np.newaxis, ...])
print(predicted.shape) 
# (1, 512, 512, 21)

21クラス分類だが、どれが人なのか。
閾値がどうなっているのか知りたい。

が、プログラム内に無さげ。
「semantic segmentation 21 class names」でぐぐる

一番上にぽいのが出てくる。 github.com 0が背景で、15が人と仮定する。

追記
というかmodels.pydef Deeplabv3(weights='pascal_voc', ...という行もあるのでこれで合っていると思われる。

person_score = predicted[0, :, : ,15]
back_score = predicted[0, :, :, 0]

mask = (person_score > back_score).astype("uint8") * 255
cv2.imwrite("test.jpg", mask)

出力してみると真っ黒。

考えられる原因

  1. OpenCVはBGRだがこれはRGBを使っている
  2. 0〜255ではなく-1〜1などで処理している

追記
入力画像の大きさが小さすぎた&人が横になっていたのが原因でした(横になっていた際の出力例、RGBに変換した画像は下の方にあります)

入力の際の前処理

ところで、これはモデルとしてMobileNetv2を使用していた。
画像の前処理はどうやってるんだろう?
Kerasがmobilenetv2を提供していて、ResNetなどもpreprocess_input的な関数は提供している(らしい)。
ということで調べてみる。

こういう当たりが付けられるの強い。
といってもここらへん全部友人がやってくれた。圧倒的人任せ。

「mobilenetv2 preprocess keras」でぐぐると以下のサイトが見つかる。 github.com

preprocess_inputというのがあるのでそれを使ってみよう。

import cv2
import numpy as np

import model

from keras.applications.mobilenetv2 import preprocess_input

img = preprocess_input(cv2.imread('./imgs/image1.jpg')) ## ここでエラー
img = cv2.resize(img, (512, 512))

エラー発生

TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind''

参考: TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind'' #8635

最終的にはこんな感じに。

import cv2
import numpy as np

import model

from keras.applications.mobilenetv2 import preprocess_input

img = preprocess_input(cv2.imread('./imgs/test.jpg').astype("float"))
img = cv2.resize(img, (512, 512))

img.max() # 0.9921875
model_dlv3 = model.Deeplabv3()

predicted = model_dlv3.predict(img[np.newaxis, ...])

person_score = predicted[0, :, : ,15]
back_score = predicted[0, :, :, 0]

mask = (person_score > back_score).astype("uint8") * 255
cv2.imwrite("test.jpg", mask)

出力結果

背景はデフォルトで黒、あとは人だけ取り出してみた。 上手いこととれた! f:id:saneeeatsu:20180820183446p:plain

因みにこの人を横にすると人だと認識しない。 f:id:saneeeatsu:20180820183428p:plain

BGR→RGBにしてみる

OpenCVではデフォルトでBGRで扱うが、もしこのアーキテクチャではRGBで扱っていて、更に人を肌の色などで認識している場合、精度が異なってくる。
ってことで試す。

と言っても1行追加するだけだけど。

img = preprocess_input(cv2.imread('./imgs/R0_L0_ono_001360.jpg').astype("float"))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 追加行
img = cv2.resize(img, (512, 512))

元画像を載せていないのでよくわからないと思うが、本来白色になってほしいところ(スカートの白色の部分)が白色にきちんとなっているしRGBの方が良さげではある。 f:id:saneeeatsu:20180820184540p:plain

シェルでは使えているPythonモジュールをJupyterNotebookで実行すると「ImportError: No module named module_name」が出てくる

問題点

はじめてPytorchを使った際に以下のようなエラーが。

ImportError: No module named torch

pip installする

$ pip install torch
Requirement already satisfied: torch in /home/ubuntu/miniconda3/lib/python3.6/site-packages (0.4.1)

既にインストールされてる。
シェルでも問題なく使える

$ python 
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> 

はて…?

現状

現在はvenvで作った環境にいる。

$ conda create -n pytorch-segmentation-detection
$ source activate pytorch-segmentation-detection

(pytorch-segmentation-detection) ubuntu@ip-172-31-5-82:~/Code/pytorch-segmentation-detection$ 

が、Jupyter上で見るとこの「pytorch-segmentation-detection」というカーネルが存在しない。 f:id:saneeeatsu:20180820140843p:plain

解決策

そこで、ipykernelをインストールする。

$ conda install ipykernel
$ ipython kernel install --user --name pytorch-segmentation-detection --display-name pytorch-segmentation-detection

出てきた! f:id:saneeeatsu:20180820141009p:plain

参考

実行したファイルの残り時間をターミナルに表示する

機械学習のプログラムを書き始めると、大きいファイルを扱う機会が増えた。 そこでターミナルに残り時間を表示させたいと思ったので、 h5ファイルを作成する関数を例にしてメモっておく。

def create_h5(h5_fpath, image_fpaths, better_model, num):
    start_time = datetime.now() # 現在時刻取得
    print('============================')
    print("Start: " + str(start_time))
    print("Num  : " + str(num)) # 読み込む画像の枚数
    
    with h5py.File(h5_fpath, "w") as f:
        for i, image_fpath in enumerate(image_fpaths):
            # ここでファイルを読み込んでh5ファイルを作成する処理を行っていることとする
            
            # 100枚毎に残り時間を表示させる
            if i % 100 == 0 and i != 0:
                elapsed_time = datetime.now() - start_time  # 経過時間
                ave_time = elapsed_time/i                   # 現在における1つあたりの平均処理時間を算出
                remain_time = (ave_time*num) - elapsed_time # 「平均*画像枚数」で全体的なかかる時間を計算し、経過時間を引く
                print(str(i)+": "+str(remain_time)+" left")

実際の出力はこんな感じ。

4200: 0:00:57.961352 left
4300: 0:00:50.587814 left
4400: 0:00:43.323896 left
4500: 0:00:35.996341 left
4600: 0:00:28.692517 left
4700: 0:00:21.979801 left
4800: 0:00:14.650676 left
4900: 0:00:07.381439 left

JupyterNotebookでファイルがリロードされない

リロードさせる方法

1. importlib.reload

import load_weights
import model
importlib.reload(load_weights)
importlib.reload(model)

2. autoreload 2

以下をJupyterNotebookに貼り付ける。

% load_ext autoreload # 外部のモジュールautoreloadをロード
% autoreload 2 # 実行する度にインポートしたモジュールをリロードする。

参考